1 /* asn.c
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 /*
23  * DESCRIPTION
24  * This library provides the interface to Abstract Syntax Notation One (ASN.1)
25  * objects.
26  * ASN.1 is a standard interface description language for defining data
27  * structures that can be serialized and deserialized in a cross-platform way.
28  *
29  * Encoding of ASN.1 is either using Basic Encoding Rules (BER) or
30  * Distinguished Encoding Rules (DER). DER has only one possible encoding for a
31  * ASN.1 description and the data.
32  * Encode using DER and decode BER or DER.
33  *
34  * Provides routines to convert BER into DER. Replaces indefinite length
35  * encoded items with explicit lengths.
36  */
37 #ifdef HAVE_CONFIG_H
38     #include <config.h>
39 #endif
40 
41 #include <wolfssl/wolfcrypt/settings.h>
42 
43 /*
44 ASN Options:
45  * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
46     or wishing to save space.
47  * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
48  * ASN_DUMP_OID: Allows dump of OID information for debugging.
49  * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
50  * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
51  * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
52     restore 3.13.0 behavior.
53  * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
54     must still be trusted)
55  * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
56     chain is not loaded. This only matches on subject and public key and
57     does not perform a PKI validation, so it is not a secure solution.
58     Only enabled for OCSP.
59  * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
60     disable checking of OCSP subject hash with issuer hash.
61  * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
62     DecodedCert. Doubles up on some code but allows smaller dynamic memory
63     usage.
64  * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This
65     may be required when the system's real-time clock is not very accurate.
66     It is recommended to enforce the nonce check instead if possible.
67  * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP
68     responses. The nonces are optional and may not be supported by all
69     responders. If it can be ensured that the used responder sends nonces this
70     option may improve security.
71  * WOLFSSL_ASN_TEMPLATE: Encoding and decoding using a template.
72  * WOLFSSL_DEBUG_ASN_TEMPLATE: Enables debugging output when using ASN.1
73     templates.
74  * WOLFSSL_ASN_TEMPLATE_TYPE_CHECK: Use ASN functions to better test compiler
75     type issues for testing
76  * CRLDP_VALIDATE_DATA: For ASN template only, validates the reason data
77  * WOLFSSL_AKID_NAME: Enable support for full AuthorityKeyIdentifier extension.
78     Only supports copying full AKID from an existing certificate.
79  * WOLFSSL_CUSTOM_OID: Enable custom OID support for subject and request
80     extensions
81 */
82 
83 #ifndef NO_ASN
84 
85 #include <wolfssl/wolfcrypt/asn.h>
86 #include <wolfssl/wolfcrypt/coding.h>
87 #include <wolfssl/wolfcrypt/md2.h>
88 #include <wolfssl/wolfcrypt/hmac.h>
89 #include <wolfssl/wolfcrypt/error-crypt.h>
90 #include <wolfssl/wolfcrypt/pwdbased.h>
91 #include <wolfssl/wolfcrypt/des3.h>
92 #include <wolfssl/wolfcrypt/aes.h>
93 #include <wolfssl/wolfcrypt/rc2.h>
94 #include <wolfssl/wolfcrypt/wc_encrypt.h>
95 #include <wolfssl/wolfcrypt/logging.h>
96 
97 #include <wolfssl/wolfcrypt/random.h>
98 #include <wolfssl/wolfcrypt/hash.h>
99 #ifdef NO_INLINE
100     #include <wolfssl/wolfcrypt/misc.h>
101 #else
102     #define WOLFSSL_MISC_INCLUDED
103     #include <wolfcrypt/src/misc.c>
104 #endif
105 
106 #ifndef NO_RC4
107     #include <wolfssl/wolfcrypt/arc4.h>
108 #endif
109 
110 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
111     #include <wolfssl/wolfcrypt/sha512.h>
112 #endif
113 
114 #ifndef NO_SHA256
115     #include <wolfssl/wolfcrypt/sha256.h>
116 #endif
117 
118 #ifdef HAVE_ECC
119     #include <wolfssl/wolfcrypt/ecc.h>
120 #endif
121 
122 #ifdef HAVE_ED25519
123     #include <wolfssl/wolfcrypt/ed25519.h>
124 #endif
125 #ifdef HAVE_CURVE25519
126     #include <wolfssl/wolfcrypt/curve25519.h>
127 #endif
128 
129 #ifdef HAVE_ED448
130     #include <wolfssl/wolfcrypt/ed448.h>
131 #endif
132 #ifdef HAVE_CURVE448
133     #include <wolfssl/wolfcrypt/curve448.h>
134 #endif
135 
136 #ifdef HAVE_PQC
137     #include <wolfssl/wolfcrypt/falcon.h>
138 #endif
139 
140 #ifdef WOLFSSL_QNX_CAAM
141     #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
142 #endif
143 
144 #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
145     #include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
146 #endif
147 
148 #ifndef NO_RSA
149     #include <wolfssl/wolfcrypt/rsa.h>
150 #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
151 extern int wc_InitRsaHw(RsaKey* key);
152 #endif
153 #endif
154 
155 #ifndef NO_DSA
156     #include <wolfssl/wolfcrypt/dsa.h>
157 #else
158     typedef void* DsaKey;
159 #endif
160 
161 #ifdef WOLF_CRYPTO_CB
162     #include <wolfssl/wolfcrypt/cryptocb.h>
163 #endif
164 
165 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
166     #include <wolfssl/internal.h>
167     #include <wolfssl/openssl/objects.h>
168 #endif
169 
170 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
171         !defined(WOLFCRYPT_ONLY)
172     #define WOLFSSL_X509_NAME_AVAILABLE
173 #endif
174 
175 #ifdef _MSC_VER
176     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
177     #pragma warning(disable: 4996)
178 #endif
179 
180 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
181 
182 #if !defined(NO_SKID) && (!defined(HAVE_FIPS) || !defined(HAVE_FIPS_VERSION))
183     #if !defined(HAVE_SELFTEST) || (defined(HAVE_SELFTEST) && \
184                                    (!defined(HAVE_SELFTEST_VERSION) || \
185                                     HAVE_SELFTEST_VERSION < 2))
186     #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
187     #define WOLFSSL_AES_KEY_SIZE_ENUM
188     enum Asn_Misc {
189         AES_IV_SIZE         = 16,
190         AES_128_KEY_SIZE    = 16,
191         AES_192_KEY_SIZE    = 24,
192         AES_256_KEY_SIZE    = 32
193     };
194     #endif
195     #endif /* HAVE_SELFTEST */
196 #endif
197 
198 
199 /* Calculates the minimum number of bytes required to encode the value.
200  *
201  * @param [in] value  Value to be encoded.
202  * @return  Number of bytes to encode value.
203  */
204 static word32 BytePrecision(word32 value)
205 {
206     word32 i;
207     for (i = (word32)sizeof(value); i; --i)
208         if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
209             break;
210 
211     return i;
212 }
213 
214 /* DER encodes the length value in output buffer.
215  *
216  *    0 ->  2^7-1: <len byte>.
217  *  2^7 ->       : <0x80 + #bytes> <len big-endian bytes>
218  *
219  * @param [in]      length  Value to encode.
220  * @param [in, out] output  Buffer to encode into.
221  * @return  Number of bytes used in encoding.
222  */
223 WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output)
224 {
225     word32 i = 0, j;
226 
227     if (length < ASN_LONG_LENGTH)
228         output[i++] = (byte)length;
229     else {
230         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
231 
232         for (j = BytePrecision(length); j; --j) {
233             output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
234             i++;
235         }
236     }
237 
238     return i;
239 }
240 
241 #ifdef WOLFSSL_ASN_TEMPLATE
242 /* Calculate the size of a DER encoded length value.
243  *
244  *    0 ->  2^7-1: <length byte>.
245  *  2^7 ->       : <0x80 + #bytes> <big-endian length bytes>
246  *
247  * @param [in] length  Value to encode.
248  * @return  Number of bytes required to encode.
249  */
250 static word32 SizeASNLength(word32 length)
251 {
252     return 1 + ((length >= ASN_LONG_LENGTH) ? BytePrecision(length) : 0);
253 }
254 
255 /* Calculate the size of a DER encoded header.
256  *
257  * Header = Tag | Encoded length
258  *
259  * @param [in] length  Length value to encode.
260  * @return  Number of bytes required to encode a DER header.
261  */
262 #define SizeASNHeader(length) \
263     (1 + SizeASNLength(length))
264 #endif
265 
266 #ifdef WOLFSSL_ASN_TEMPLATE
267 #ifdef WOLFSSL_SMALL_STACK
268     /* Declare the variable that is the dynamic data for decoding BER data.
269      *
270      * @param [in] name  Variable name to declare.
271      * @param [in] cnt   Number of elements required.
272      */
273     #define DECL_ASNGETDATA(name, cnt)                                         \
274         ASNGetData* name = NULL;
275 
276     /* Allocates the dynamic BER decoding data.
277      *
278      * @param [in]      name  Variable name to declare.
279      * @param [in]      cnt   Number of elements required.
280      * @param [in, out] err   Error variable.
281      * @param [in]      heap  Dynamic memory allocation hint.
282      */
283     #define ALLOC_ASNGETDATA(name, cnt, err, heap)                             \
284     do {                                                                       \
285         if (err == 0) {                                                        \
286             name = (ASNGetData*)XMALLOC(sizeof(ASNGetData) * cnt, heap,        \
287                                         DYNAMIC_TYPE_TMP_BUFFER);              \
288             if (name == NULL) {                                                \
289                 err = MEMORY_E;                                                \
290             }                                                                  \
291         }                                                                      \
292     }                                                                          \
293     while (0)
294 
295     /* Allocates the dynamic BER decoding data and clears the memory.
296      *
297      * @param [in]      name  Variable name to declare.
298      * @param [in]      cnt   Number of elements required.
299      * @param [in, out] err   Error variable.
300      * @param [in]      heap  Dynamic memory allocation hint.
301      */
302     #define CALLOC_ASNGETDATA(name, cnt, err, heap)                            \
303     do {                                                                       \
304         ALLOC_ASNGETDATA(name, cnt, err, heap);                                \
305         if (err == 0) {                                                        \
306             XMEMSET(name, 0, sizeof(ASNGetData) * cnt);                        \
307         }                                                                      \
308     }                                                                          \
309     while (0)
310 
311     /* Disposes of the dynamic BER decoding data.
312      *
313      * @param [in]      name  Variable name to declare.
314      * @param [in]      heap  Dynamic memory allocation hint.
315      */
316     #define FREE_ASNGETDATA(name, heap)                                        \
317     do {                                                                       \
318         if (name != NULL) {                                                    \
319             XFREE(name, heap, DYNAMIC_TYPE_TMP_BUFFER);                        \
320         }                                                                      \
321     }                                                                          \
322     while (0)
323 
324     /* Declare the variable that is the dynamic data for encoding DER data.
325      *
326      * @param [in] name  Variable name to declare.
327      * @param [in] cnt   Number of elements required.
328      */
329     #define DECL_ASNSETDATA(name, cnt)                                         \
330         ASNSetData* name = NULL;
331 
332     /* Allocates the dynamic DER encoding data.
333      *
334      * @param [in]      name  Variable name to declare.
335      * @param [in]      cnt   Number of elements required.
336      * @param [in, out] err   Error variable.
337      * @param [in]      heap  Dynamic memory allocation hint.
338      */
339     #define ALLOC_ASNSETDATA(name, cnt, err, heap)                             \
340     do {                                                                       \
341         if (err == 0) {                                                        \
342             name = (ASNSetData*)XMALLOC(sizeof(ASNGetData) * cnt, heap,        \
343                                     DYNAMIC_TYPE_TMP_BUFFER);                  \
344             if (name == NULL) {                                                \
345                 err = MEMORY_E;                                                \
346             }                                                                  \
347         }                                                                      \
348     }                                                                          \
349     while (0)
350 
351     /* Allocates the dynamic DER encoding data and clears the memory.
352      *
353      * @param [in]      name  Variable name to declare.
354      * @param [in]      cnt   Number of elements required.
355      * @param [in, out] err   Error variable.
356      * @param [in]      heap  Dynamic memory allocation hint.
357      */
358     #define CALLOC_ASNSETDATA(name, cnt, err, heap)                            \
359     do {                                                                       \
360         ALLOC_ASNSETDATA(name, cnt, err, heap);                                \
361         if (err == 0) {                                                        \
362             XMEMSET(name, 0, sizeof(ASNSetData) * cnt);                        \
363         }                                                                      \
364     }                                                                          \
365     while (0)
366 
367     /* Disposes of the dynamic DER encoding data.
368      *
369      * @param [in]      name  Variable name to declare.
370      * @param [in]      heap  Dynamic memory allocation hint.
371      */
372     #define FREE_ASNSETDATA(name, heap)                                        \
373     do {                                                                       \
374         if (name != NULL) {                                                    \
375             XFREE(name, heap, DYNAMIC_TYPE_TMP_BUFFER);                        \
376         }                                                                      \
377     }                                                                          \
378     while (0)
379 #else
380     /* Declare the variable that is the dynamic data for decoding BER data.
381      *
382      * @param [in] name  Variable name to declare.
383      * @param [in] cnt   Number of elements required.
384      */
385     #define DECL_ASNGETDATA(name, cnt)                  \
386         ASNGetData name[cnt];
387 
388     /* No implementation as declartion is static.
389      *
390      * @param [in]      name  Variable name to declare.
391      * @param [in]      cnt   Number of elements required.
392      * @param [in, out] err   Error variable.
393      * @param [in]      heap  Dynamic memory allocation hint.
394      */
395     #define ALLOC_ASNGETDATA(name, cnt, err, heap)
396 
397     /* Clears the memory of the dynamic BER encoding data.
398      *
399      * @param [in]      name  Variable name to declare.
400      * @param [in]      cnt   Number of elements required.
401      * @param [in, out] err   Error variable.
402      * @param [in]      heap  Dynamic memory allocation hint.
403      */
404     #define CALLOC_ASNGETDATA(name, cnt, err, heap)     \
405         XMEMSET(name, 0, sizeof(name));
406 
407     /* No implementation as declartion is static.
408      *
409      * @param [in]      name  Variable name to declare.
410      * @param [in]      heap  Dynamic memory allocation hint.
411      */
412     #define FREE_ASNGETDATA(name, heap)
413 
414     /* Declare the variable that is the dynamic data for encoding DER data.
415      *
416      * @param [in] name  Variable name to declare.
417      * @param [in] cnt   Number of elements required.
418      */
419     #define DECL_ASNSETDATA(name, cnt)                  \
420         ASNSetData name[cnt];
421 
422     /* No implementation as declartion is static.
423      *
424      * @param [in]      name  Variable name to declare.
425      * @param [in]      cnt   Number of elements required.
426      * @param [in, out] err   Error variable.
427      * @param [in]      heap  Dynamic memory allocation hint.
428      */
429     #define ALLOC_ASNSETDATA(name, cnt, err, heap)
430 
431     /* Clears the memory of the dynamic BER encoding data.
432      *
433      * @param [in]      name  Variable name to declare.
434      * @param [in]      cnt   Number of elements required.
435      * @param [in, out] err   Error variable.
436      * @param [in]      heap  Dynamic memory allocation hint.
437      */
438     #define CALLOC_ASNSETDATA(name, cnt, err, heap)     \
439         XMEMSET(name, 0, sizeof(name));
440 
441     /* No implementation as declartion is static.
442      *
443      * @param [in]      name  Variable name to declare.
444      * @param [in]      heap  Dynamic memory allocation hint.
445      */
446     #define FREE_ASNSETDATA(name, heap)
447 #endif
448 
449 
450 #ifdef DEBUG_WOLFSSL
451     /* Enable this when debugging the parsing or creation of ASN.1 data. */
452     #if 0
453         #define WOLFSSL_DEBUG_ASN_TEMPLATE
454     #endif
455 #endif
456 
457 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
458 /* String representations of tags. */
459 static const char* tagString[4][32] = {
460     /* Universal */
461     {
462         "EOC",
463         "BOOLEAN",
464         "INTEGER",
465         "BIT STRING",
466         "OCTET STRING",
467         "NULL",
468         "OBJECT ID",
469         "ObjectDescriptor",
470         "INSTANCE OF",
471         "REAL",
472         "ENUMERATED",
473         "EMBEDDED PDV",
474         "UT8String",
475         "RELATIVE-OID",
476         "(0x0e) 14",
477         "(0x0f) 15",
478         "SEQUENCE",
479         "SET",
480         "NumericString",
481         "PrintableString",
482         "T61String",
483         "VideotexString",
484         "IA5String",
485         "UTCTime",
486         "GeneralizedTime",
487         "GraphicString",
488         "ISO646String",
489         "GeneralString",
490         "UniversalString",
491         "CHARACTER STRING",
492         "BMPString",
493         "(0x1f) 31",
494     },
495     /* Application */
496     {
497          "[A 0]",  "[A 1]",  "[A 2]",  "[A 3]",
498          "[A 4]",  "[A 5]",  "[A 6]",  "[A 7]",
499          "[A 8]",  "[A 9]", "[A 10]", "[A 11]",
500         "[A 12]", "[A 13]", "[A 14]", "[A 15]",
501         "[A 16]", "[A 17]", "[A 18]", "[A 19]",
502         "[A 20]", "[A 21]", "[A 22]", "[A 23]",
503         "[A 24]", "[A 25]", "[A 26]", "[A 27]",
504         "[A 28]", "[A 20]", "[A 30]", "[A 31]"
505     },
506     /* Context-Specific */
507     {
508          "[0]",  "[1]",  "[2]",  "[3]",  "[4]",  "[5]",  "[6]",  "[7]",
509          "[8]",  "[9]", "[10]", "[11]", "[12]", "[13]", "[14]", "[15]",
510         "[16]", "[17]", "[18]", "[19]", "[20]", "[21]", "[22]", "[23]",
511         "[24]", "[25]", "[26]", "[27]", "[28]", "[20]", "[30]", "[31]"
512     },
513     /* Private */
514     {
515          "[P 0]",  "[P 1]",  "[P 2]",  "[P 3]",
516          "[P 4]",  "[P 5]",  "[P 6]",  "[P 7]",
517          "[P 8]",  "[P 9]", "[P 10]", "[P 11]",
518         "[P 12]", "[P 13]", "[P 14]", "[P 15]",
519         "[P 16]", "[P 17]", "[P 18]", "[P 19]",
520         "[P 20]", "[P 21]", "[P 22]", "[P 23]",
521         "[P 24]", "[P 25]", "[P 26]", "[P 27]",
522         "[P 28]", "[P 20]", "[P 30]", "[P 31]"
523     }
524 };
525 
526 /* Converts a tag byte to string.
527  *
528  * @param [in] tag  BER tag value to interpret.
529  * @return  String corresponding to tag.
530  */
531 static const char* TagString(byte tag)
532 {
533     return tagString[tag >> 6][tag & ASN_TYPE_MASK];
534 }
535 
536 #include <stdarg.h>
537 
538 /* Log a message that has the printf format string.
539  *
540  * @param [in] <va_args>  printf style arguments.
541  */
542 #define WOLFSSL_MSG_VSNPRINTF(...)                    \
543     do {                                              \
544       char line[81];                                  \
545       snprintf(line, sizeof(line) - 1, __VA_ARGS__);  \
546       line[sizeof(line) - 1] = '\0';                  \
547       WOLFSSL_MSG(line);                              \
548     }                                                 \
549     while (0)
550 #endif
551 
552 /* Returns whether ASN.1 item is an integer and the Most-Significant Bit is set.
553  *
554  * @param [in] asn    ASN.1 items to encode.
555  * @param [in] data   Data to place in each item. Lengths set were not known.
556  * @param [in] i      Index of item to check.
557  * @return  1 when ASN.1 item is an integer and MSB is 1.
558  * @erturn  0 otherwise.
559  */
560 #define ASNIntMSBSet(asn, data, i)                    \
561     ((asn[i].tag == ASN_INTEGER) &&                   \
562       (data[i].data.buffer.data != NULL &&            \
563       (data[i].data.buffer.data[0] & 0x80) == 0x80))
564 
565 
566 /* Calculate the size of a DER encoded number.
567  *
568  * @param [in] n     Number to be encoded.
569  * @param [in] bits  Maximum number of bits to encode.
570  * @param [in] tag   BER tag e.g. INTEGER, BIT_STRING, etc.
571  * @return  Number of bytes to the ASN.1 item.
572  */
573 static word32 SizeASN_Num(word32 n, int bits, byte tag)
574 {
575     int    j;
576     word32 len;
577 
578     len = 1 + 1 + bits / 8;
579     /* Discover actual size by checking for high zeros. */
580     for (j = bits - 8; j > 0; j -= 8) {
581         if (n >> j)
582             break;
583         len--;
584     }
585     if (tag == ASN_BIT_STRING)
586         len++;
587     else if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80))
588         len++;
589 
590     return len;
591 }
592 
593 /* Calculate the size of the data in the constructed item based on the
594  * length of the ASN.1 items below.
595  *
596  * @param [in]      asn    ASN.1 items to encode.
597  * @param [in, out] data   Data to place in each item. Lengths set were not
598  *                         known.
599  * @param [in]      idx    Index of item working on.
600  */
601 static void SizeASN_CalcDataLength(const ASNItem* asn, ASNSetData *data,
602                                    int idx, int max)
603 {
604     int j;
605 
606     data[idx].data.buffer.length = 0;
607     /* Sum the item length of all items underneath. */
608     for (j = idx + 1; j < max; j++) {
609         /* Stop looking if the next ASN.1 is same level or higher. */
610         if (asn[j].depth <= asn[idx].depth)
611             break;
612         /* Only add in length if it is one level below. */
613         if (asn[j].depth - 1 == asn[idx].depth) {
614             data[idx].data.buffer.length += data[j].length;
615             /* The length of a header only item doesn't include the data unless
616              * a replacement buffer is supplied.
617              */
618             if (asn[j].headerOnly && data[j].data.buffer.data == NULL &&
619                     data[j].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
620                 data[idx].data.buffer.length += data[j].data.buffer.length;
621             }
622         }
623     }
624 }
625 
626 /* Calculate the size of the DER encoding.
627  *
628  * Call SetASN_Items() to write encoding to a buffer.
629  *
630  * @param [in]      asn    ASN.1 items to encode.
631  * @param [in, out] data   Data to place in each item. Lengths set were not
632  *                         known.
633  * @param [in]      count  Count of items to encode.
634  * @param [out]     encSz  Length of the DER encoding.
635  * @return  0 on success.
636  * @return  BAD_STATE_E when the data type is not supported.
637  */
638 int SizeASN_Items(const ASNItem* asn, ASNSetData *data, int count, int* encSz)
639 {
640     int    i;
641     word32 sz = 0;
642     word32 len;
643     word32 dataLen;
644     int    length;
645 
646 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
647     WOLFSSL_ENTER("SizeASN_Items");
648 #endif
649 
650     for (i = count - 1; i >= 0; i--) {
651         /* Skip this ASN.1 item when encoding. */
652         if (data[i].noOut) {
653             /* Set the offset to the current size - used in writing DER. */
654             data[i].offset = sz;
655             continue;
656         }
657 
658         len = 0;
659         switch (data[i].dataType) {
660             /* Calculate the size of the number of different sizes. */
661             case ASN_DATA_TYPE_WORD8:
662                 len = SizeASN_Num(data[i].data.u8, 8, asn[i].tag);
663                 break;
664             case ASN_DATA_TYPE_WORD16:
665                 len = SizeASN_Num(data[i].data.u16, 16, asn[i].tag);
666                 break;
667         #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
668             /* Not used yet! */
669             case ASN_DATA_TYPE_WORD32:
670                 len = SizeASN_Num(data[i].data.u32, 32, asn[i].tag);
671                 break;
672         #endif
673 
674             case ASN_DATA_TYPE_MP:
675                 /* Calculate the size of the MP integer data. */
676                 length = mp_unsigned_bin_size(data[i].data.mp);
677                 length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
678                 len = SizeASNHeader(length) + length;
679                 break;
680 
681             case ASN_DATA_TYPE_REPLACE_BUFFER:
682                 /* Buffer is put in directly - use the length. */
683                 len = data[i].data.buffer.length;
684                 break;
685 
686             case ASN_DATA_TYPE_NONE:
687                 /* Calculate the size based on the data to be included.
688                  * Mostly used for constructed items.
689                  */
690                 if (asn[i].headerOnly) {
691                     if (data[i].data.buffer.data != NULL) {
692                         /* Force all child nodes to be ignored. Buffer
693                          * overwrites children. */
694                         {
695                             int ii;
696                             for (ii = i + 1; ii < count; ii++) {
697                                 if (asn[ii].depth <= asn[i].depth)
698                                     break;
699                                 sz -= data[ii].length;
700                                 data[ii].noOut = 1;
701                             }
702                         }
703                     }
704                     else {
705                         /* Calculate data length from items below if no buffer
706                          * supplied. */
707                         SizeASN_CalcDataLength(asn, data, i, count);
708                     }
709                 }
710                 if (asn[i].tag == ASN_BOOLEAN) {
711                     dataLen = 1;
712                 }
713                 else {
714                     dataLen = data[i].data.buffer.length;
715                 }
716                 /* BIT_STRING and INTEGER have one byte prepended. */
717                 if ((asn[i].tag == ASN_BIT_STRING) ||
718                                                    ASNIntMSBSet(asn, data, i)) {
719                     dataLen++;
720                     /* ASN.1 items are below and cannot include extra byte. */
721                     if (asn[i].headerOnly) {
722                         len++;
723                     }
724                 }
725                 /* Add in the size of tag and length. */
726                 len += SizeASNHeader(dataLen);
727                 /* Include data in length if not header only or if
728                  * buffer supplied. */
729                 if (!asn[i].headerOnly || data[i].data.buffer.data != NULL) {
730                     len += dataLen;
731                 }
732                 break;
733 
734         #ifdef DEBUG_WOLFSSL
735             default:
736             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
737                 WOLFSSL_MSG_VSNPRINTF("%2d: %d", i, data[i].dataType);
738                 WOLFSSL_MSG("Bad data type");
739             #endif
740                 return BAD_STATE_E;
741         #endif
742         }
743 
744         /* Set the total length of the item. */
745         data[i].length = len;
746         /* Add length to total size. */
747         sz += len;
748         /* Set the offset to the current size - used in writing DER. */
749         data[i].offset = sz;
750 
751     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
752         WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
753                 data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
754                 asn[i].depth, "", TagString(asn[i].tag));
755     #endif
756     }
757 
758     *encSz = sz;
759     return 0;
760 }
761 
762 /* Create the DER encoding of a number.
763  *
764  * Assumes that the out buffer is large enough for encoding.
765  *
766  * @param [in] n     Number to be encoded.
767  * @param [in] bits  Maximum number of bits to encode.
768  * @param [in] tag   DER tag e.g. INTEGER, BIT_STRING, etc.
769  */
770 static void SetASN_Num(word32 n, int bits, byte* out, byte tag)
771 {
772     int    j;
773     word32 idx;
774     byte   len;
775 
776     /* Encoding: Tag (1 byte) | Length (1 byte) | Data (number) */
777 
778     /* Data will start at index 2 unless BIT_STRING or INTEGER */
779     idx = 2;
780 
781     /* Set the length of the number based on maximum bit length. */
782     len = bits / 8;
783     /* Discover actual size by checking for leading zero bytes. */
784     for (j = bits - 8; j > 0; j -= 8) {
785         if ((n >> j) != 0) {
786             break;
787         }
788         len--;
789     }
790     /* Keep j, index of first non-zero byte, for writing out. */
791 
792     /* A BIT_STRING has the number of unused bits in last byte prepended to
793      * data.
794      */
795     if (tag == ASN_BIT_STRING) {
796         byte unusedBits = 0;
797         byte lastByte = n >> j;
798 
799         /* Quick check last bit. */
800         if ((lastByte & 0x01) == 0x00) {
801             unusedBits++;
802             /* Check each bit for first least significant bit set. */
803             while (((lastByte >> unusedBits) & 0x01) == 0x00)
804                 unusedBits++;
805         }
806         /* Add unused bits byte. */
807         len++;
808         out[idx++] = unusedBits;
809     }
810 
811     /* An INTEGER has a prepended byte if MSB of number is 1 - makes encoded
812      * value positive. */
813     if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80)) {
814         len++;
815         out[idx++] = 0;
816     }
817 
818     /* Go back and put in length. */
819     out[1] = len;
820     /* Place in the required bytes of the number. */
821     for (; j >= 0; j -= 8)
822         out[idx++] = n >> j;
823 }
824 
825 /* Creates the DER encoding of the ASN.1 items.
826  *
827  * Assumes the output buffer is large enough to hold encoding.
828  * Must call SizeASN_Items() to determine size of encoding and offsets.
829  *
830  * @param [in]      asn     ASN.1 items to encode.
831  * @param [in]      data    Data to place in each item.
832  * @param [in]      count   Count of items to encode.
833  * @param [in, out] output  Buffer to write encoding into.
834  * @return  Size of the DER encoding in bytes.
835  */
836 int SetASN_Items(const ASNItem* asn, ASNSetData *data, int count, byte* output)
837 {
838     int    i;
839     int    length;
840     int    err;
841     word32 sz;
842     word32 idx;
843     byte*  out;
844 
845 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
846     WOLFSSL_ENTER("SetASN_Items");
847 #endif
848 
849     /* Offset of first item is the total length.
850      * SizeASN_Items() calculated this. */
851     sz = data[0].offset;
852 
853     /* Write out each item. */
854     for (i = 0; i < count; i++) {
855         /* Skip items not writing out. */
856         if (data[i].noOut)
857             continue;
858 
859         /* Start position to write item based on reverse offsets. */
860         out = output + sz - data[i].offset;
861         /* Index from start of item out. */
862         idx = 0;
863 
864         if (data[i].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
865             /* Put in the tag - not dumping in DER from buffer. */
866             out[idx++] = asn[i].tag |
867                          (asn[i].constructed ? ASN_CONSTRUCTED : 0);
868         }
869 
870     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
871         WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
872                 sz - data[i].offset,
873                 data[i].length, asn[i].constructed ? '+' : ' ', asn[i].depth,
874                 "", TagString(asn[i].tag));
875     #endif
876 
877         switch (data[i].dataType) {
878             /* Write out the length and data of a number. */
879             case ASN_DATA_TYPE_WORD8:
880                 SetASN_Num(data[i].data.u8, 8, out, asn[i].tag);
881                 break;
882             case ASN_DATA_TYPE_WORD16:
883                 SetASN_Num(data[i].data.u16, 16, out, asn[i].tag);
884                 break;
885         #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
886             /* Not used yet! */
887             case ASN_DATA_TYPE_WORD32:
888                 SetASN_Num(data[i].data.u32, 32, out, asn[i].tag);
889                 break;
890         #endif
891 
892             /* Write out the length and data of a multi-precision number. */
893             case ASN_DATA_TYPE_MP:
894                 /* Get length in bytes. */
895                 length = mp_unsigned_bin_size(data[i].data.mp);
896                 /* Add one for leading zero to make encoding a positive num. */
897                 length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
898                 /* Write out length. */
899                 idx += SetASNLength(length, out + idx);
900                 /* Write out leading zero to make positive. */
901                 if (mp_leading_bit(data[i].data.mp)) {
902                     out[idx++] = 0;
903                 }
904                 /* Encode number in big-endian byte array. */
905                 err = mp_to_unsigned_bin(data[i].data.mp, out + idx);
906                 if (err != MP_OKAY) {
907                     WOLFSSL_MSG("SetASN_Items: Failed to write mp_int");
908                     return MP_TO_E;
909                 }
910                 break;
911 
912             case ASN_DATA_TYPE_REPLACE_BUFFER:
913                 if (data[i].data.buffer.data == NULL) {
914                     /* Return pointer for caller to use. */
915                     data[i].data.buffer.data = out + idx;
916                 }
917                 else {
918                     /* Dump in the DER encoded data. */
919                     XMEMCPY(out + idx, data[i].data.buffer.data,
920                             data[i].data.buffer.length);
921                 }
922                 break;
923 
924             case ASN_DATA_TYPE_NONE:
925                 if (asn[i].tag == ASN_BOOLEAN) {
926                     /* Always one byte of data. */
927                     out[idx++] = 1;
928                     /* TRUE = 0xff, FALSE = 0x00 */
929                     out[idx] = data[i].data.u8 ? -1 : 0;
930                 }
931                 else if (asn[i].tag == ASN_TAG_NULL) {
932                     /* NULL tag is always a zero length item. */
933                     out[idx] = 0;
934                 }
935                 else {
936                     word32 dataLen = data[i].data.buffer.length;
937                     /* Add one to data length for BIT_STRING unused bits and
938                      * INTEGER leading zero to make positive.
939                      */
940                     if ((asn[i].tag == ASN_BIT_STRING) ||
941                                                    ASNIntMSBSet(asn, data, i)) {
942                         dataLen++;
943                     }
944                     /* Write out length. */
945                     idx += SetASNLength(dataLen, out + idx);
946                     if ((asn[i].tag == ASN_BIT_STRING) ||
947                                                    ASNIntMSBSet(asn, data, i)) {
948                        /* Write out leading byte. BIT_STRING has no unused bits
949                         * - use number data types if needed. */
950                         out[idx++] = 0x00;
951                     }
952                     /* Record pointer for caller if data not supplied. */
953                     if (data[i].data.buffer.data == NULL) {
954                         data[i].data.buffer.data = out + idx;
955                     }
956                     /* Copy supplied data if not putting out header only or
957                      * if buffer supplied. */
958                     else if (!asn[i].headerOnly ||
959                             data[i].data.buffer.data != NULL) {
960                         /* Allow data to come from output buffer. */
961                         XMEMMOVE(out + idx, data[i].data.buffer.data,
962                                  data[i].data.buffer.length);
963                     }
964                 }
965                 break;
966 
967         #ifdef DEBUG_WOLFSSL
968             default:
969             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
970                 WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data[i].dataType);
971             #endif
972                 return BAD_STATE_E;
973         #endif
974         }
975     }
976 
977     return sz;
978 }
979 
980 
981 static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
982                   word32 oidType, int length);
983 
984 /* Maximum supported depth in ASN.1 description. */
985 #define GET_ASN_MAX_DEPTH          7
986 /* Maximum number of checked numbered choices. Only one of the items with the
987  * number is allowed.
988  */
989 #define GET_ASN_MAX_CHOICES        2
990 
991 /* Use existing function to decode BER length encoding. */
992 #define GetASN_Length GetLength_ex
993 
994 /* Check an INTEGER's first byte - must be a positive number.
995  *
996  * @param [in] input    BER encoded data.
997  * @param [in] idx      Index of BIT_STRING data.
998  * @param [in] length   Length of input data.
999  * @param [in] positive Indicates number must be positive.
1000  * @return  0 on success.
1001  * @return  ASN_PARSE_E when 0 is not required but seen.
1002  * @return  ASN_EXPECT_0_E when 0 is required and not seen.
1003  */
1004 static int GetASN_Integer(const byte* input, word32 idx, int length,
1005                           int positive)
1006 {
1007     if (input[idx] == 0) {
1008         /* Check leading zero byte required. */
1009         if ((length > 1) && ((input[idx + 1] & 0x80) == 0)) {
1010         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1011             WOLFSSL_MSG("Zero not required on INTEGER");
1012         #endif
1013             return ASN_PARSE_E;
1014         }
1015     }
1016     /* Check whether a leading zero byte was required. */
1017     else if (positive && (input[idx] & 0x80)) {
1018     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1019         WOLFSSL_MSG("INTEGER is negative");
1020     #endif
1021         return ASN_EXPECT_0_E;
1022     }
1023 
1024     return 0;
1025 }
1026 
1027 /* Check a BIT_STRING's first byte - unused bits.
1028  *
1029  * @param [in] input   BER encoded data.
1030  * @param [in] idx     Index of BIT_STRING data.
1031  * @param [in] length  Length of input data.
1032  * @return  0 on success.
1033  * @return  ASN_PARSE_E when unused bits is invalid.
1034  */
1035 static int GetASN_BitString(const byte* input, word32 idx, int length)
1036 {
1037     /* Ensure unused bits value is valid range. */
1038     if (input[idx] > 7) {
1039     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1040         WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits too big: %d > 7",
1041                 input[idx]);
1042     #endif
1043         return ASN_PARSE_E;
1044     }
1045     /* Ensure unused bits are zero. */
1046     if ((byte)(input[idx + length - 1] << (8 - input[idx])) != 0) {
1047     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1048         WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits used: %d %02x",
1049                 input[idx], input[idx + length - 1]);
1050     #endif
1051         return ASN_PARSE_E;
1052     }
1053 
1054     return 0;
1055 }
1056 
1057 /* Get the ASN.1 items from the BER encoding.
1058  *
1059  * @param [in] asn         ASN.1 item expected.
1060  * @param [in] data        Data array to place found item into.
1061  * @param [in] input       BER encoded data.
1062  * @param [in] idx         Starting index of item data.
1063  * @param [in] len         Length of input buffer upto end of this item's data.
1064  * @param [in] zeroPadded  INTEGER was zero padded to make positive.
1065  * @return  0 on success.
1066  * @return  ASN_PARSE_E when BER encoded data is invalid.
1067  * @return  ASN_EXPECT_0_E when NULL tagged item has a non-zero length.
1068  * @return  MP_INIT_E when the unable to initialize an mp_int.
1069  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1070  * @return  BAD_STATE_E when the data type is not supported.
1071  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1072  */
1073 static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data,
1074                             const byte* input, word32 idx, int len,
1075                             int zeroPadded)
1076 {
1077     int i;
1078     int err;
1079 
1080     /* Parse data based on data type to extract. */
1081     switch (data->dataType) {
1082         /* Parse a data into a number of specified bits. */
1083         case ASN_DATA_TYPE_WORD8:
1084             /* Check data is small enough to fit. */
1085             if (len != 1) {
1086             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1087                 WOLFSSL_MSG_VSNPRINTF("Expecting one byte: %d", len);
1088             #endif
1089                 return ASN_PARSE_E;
1090             }
1091             /* Fill number with all of data. */
1092             *data->data.u8 = input[idx];
1093             break;
1094         case ASN_DATA_TYPE_WORD16:
1095             /* Check data is small enough to fit. */
1096             if (len == 0 || len > 2) {
1097             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1098                 WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", len);
1099             #endif
1100                 return ASN_PARSE_E;
1101             }
1102             /* Fill number with all of data. */
1103             *data->data.u16 = 0;
1104             for (i = 0; i < len; i++) {
1105                 *data->data.u16 <<= 8;
1106                 *data->data.u16 |= input[idx + i] ;
1107             }
1108             break;
1109         case ASN_DATA_TYPE_WORD32:
1110             /* Check data is small enough to fit. */
1111             if (len == 0 || len > 4) {
1112             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1113                 WOLFSSL_MSG_VSNPRINTF("Expecting 1 to 4 bytes: %d", len);
1114             #endif
1115                 return ASN_PARSE_E;
1116             }
1117             /* Fill number with all of data. */
1118             *data->data.u32 = 0;
1119             for (i = 0; i < len; i++) {
1120                 *data->data.u32 <<= 8;
1121                 *data->data.u32 |= input[idx + i] ;
1122             }
1123             break;
1124 
1125         case ASN_DATA_TYPE_BUFFER:
1126             /* Check buffer is big enough to hold data. */
1127             if (len > (int)*data->data.buffer.length) {
1128             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1129                 WOLFSSL_MSG_VSNPRINTF("Buffer too small for data: %d %d", len,
1130                         *data->data.buffer.length);
1131             #endif
1132                 return ASN_PARSE_E;
1133             }
1134             /* Copy in data and record actual length seen. */
1135             XMEMCPY(data->data.buffer.data, input + idx, len);
1136             *data->data.buffer.length = len;
1137             break;
1138 
1139         case ASN_DATA_TYPE_EXP_BUFFER:
1140             /* Check data is same size expected. */
1141             if (len != (int)data->data.ref.length) {
1142             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1143                 WOLFSSL_MSG_VSNPRINTF("Data not expected length: %d %d", len,
1144                         data->data.ref.length);
1145             #endif
1146                 return ASN_PARSE_E;
1147             }
1148             /* Check data is same as expected. */
1149             if (XMEMCMP(data->data.ref.data, input + idx, len) != 0) {
1150             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1151                 WOLFSSL_MSG("Data not as expected");
1152             #endif
1153                 return ASN_PARSE_E;
1154             }
1155             break;
1156 
1157         case ASN_DATA_TYPE_MP:
1158         case ASN_DATA_TYPE_MP_POS_NEG:
1159             /* Initialize mp_int and read in big-endian byte array. */
1160             if (mp_init(data->data.mp) != MP_OKAY) {
1161             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1162                 WOLFSSL_MSG_VSNPRINTF("Failed to init mp: %p", data->data.mp);
1163             #endif
1164                 return MP_INIT_E;
1165             }
1166             err = mp_read_unsigned_bin(data->data.mp, (byte*)input + idx, len);
1167             if (err != 0) {
1168             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1169                 WOLFSSL_MSG_VSNPRINTF("Failed to read mp: %d", err);
1170             #endif
1171                 mp_clear(data->data.mp);
1172                 return ASN_GETINT_E;
1173             }
1174         #ifdef HAVE_WOLF_BIGINT
1175             err = wc_bigint_from_unsigned_bin(&data->data.mp->raw, input + idx,
1176                     len);
1177             if (err != 0) {
1178             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1179                 WOLFSSL_MSG_VSNPRINTF("Failed to create bigint: %d", err);
1180             #endif
1181                 mp_clear(data->data.mp);
1182                 return ASN_GETINT_E;
1183             }
1184         #endif /* HAVE_WOLF_BIGINT */
1185             /* Don't always read as positive. */
1186             if ((data->dataType == ASN_DATA_TYPE_MP_POS_NEG) && (!zeroPadded) &&
1187                 (input[idx] & 0x80)) {
1188                 data->data.mp->sign = MP_NEG;
1189             }
1190             break;
1191 
1192         case ASN_DATA_TYPE_CHOICE:
1193             /* Check if tag matched any of the choices specified. */
1194             for (i = 0; data->data.choice[i] != 0; i++)
1195                 if (data->data.choice[i] == data->tag)
1196                     break;
1197             if (data->data.choice[i] == 0) {
1198             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1199                 WOLFSSL_MSG("Tag didn't match a choice");
1200             #endif
1201                 return ASN_PARSE_E;
1202             }
1203 
1204             /* Store data pointer and length for caller. */
1205             data->data.ref.data = input + idx;
1206             data->data.ref.length = len;
1207             break;
1208 
1209         case ASN_DATA_TYPE_NONE:
1210             /* Default behaviour based on tag. */
1211             if (asn->tag == ASN_BOOLEAN) {
1212                 /* BOOLEAN has only one byte of data in BER. */
1213                 if (len != 1) {
1214                 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1215                     WOLFSSL_MSG_VSNPRINTF("BOOLEAN length too long: %d", len);
1216                 #endif
1217                     return ASN_PARSE_E;
1218                 }
1219                 /* Store C boolean value. */
1220                 *data->data.u8 = (input[idx] != 0);
1221                 break;
1222             }
1223             if (asn->tag == ASN_TAG_NULL) {
1224                 /* NULL has no data in BER. */
1225                 if (len != 0) {
1226                 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1227                     WOLFSSL_MSG_VSNPRINTF("NULL length too long: %d", len);
1228                 #endif
1229                     return ASN_EXPECT_0_E;
1230                 }
1231                 data->data.ref.data = input + idx;
1232                 break;
1233             }
1234             if (asn->tag == ASN_OBJECT_ID) {
1235                 word32 oidIdx = 0;
1236                 /* Store OID data pointer and length */
1237                 data->data.oid.data = input + idx;
1238                 data->data.oid.length = len;
1239                 /* Get the OID sum. */
1240                 err = GetOID(input + idx, &oidIdx, &data->data.oid.sum,
1241                         data->data.oid.type, len);
1242                 if (err < 0) {
1243                 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1244                     WOLFSSL_MSG_VSNPRINTF("OID check failed: %d", err);
1245                 #endif
1246                     return err;
1247                 }
1248                 break;
1249             }
1250 
1251             /* Otherwise store data pointer and length. */
1252             data->data.ref.data = input + idx;
1253             data->data.ref.length = len;
1254             break;
1255 
1256     #ifdef DEBUG_WOLFSSL
1257         default:
1258             /* Bad ASN data type. */
1259         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1260             WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data->dataType);
1261         #endif
1262             return BAD_STATE_E;
1263     #endif
1264     }
1265 
1266     return 0;
1267 }
1268 
1269 /* Get the ASN.1 items from the BER encoding.
1270  *
1271  * @param [in]      asn       ASN.1 items expected.
1272  * @param [in]      data      Data array to place found items into.
1273  * @param [in]      count     Count of items to parse.
1274  * @param [in]      complete  Whether the whole buffer is to be used up.
1275  * @param [in]      input     BER encoded data.
1276  * @param [in, out] inOutIdx  On in, starting index of data.
1277  *                            On out, end of parsed data.
1278  * @param [in]      length    Length of input buffer.
1279  * @return  0 on success.
1280  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1281  *          is invalid.
1282  * @return  BUFFER_E when data in buffer is too small.
1283  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1284  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1285  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1286  *          non-zero length.
1287  * @return  MP_INIT_E when the unable to initialize an mp_int.
1288  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1289  * @return  BAD_STATE_E when the data type is not supported.
1290  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1291  */
1292 int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete,
1293                  const byte* input, word32* inOutIdx, word32 length)
1294 {
1295     int    i;
1296     int    j;
1297     int    err;
1298     int    len;
1299     /* Current index into buffer. */
1300     word32 idx = *inOutIdx;
1301     /* Initialize the end index at each depth to be the length. */
1302     word32 endIdx[GET_ASN_MAX_DEPTH] = { length, length, length, length, length,
1303                                          length, length };
1304     /* Set choices to -1 to indicate they haven't been seen or found. */
1305     char   choiceMet[GET_ASN_MAX_CHOICES] = { -1, -1 };
1306     /* Not matching a choice right now. */
1307     int    choice = 0;
1308     /* Current depth of ASN.1 item. */
1309     int    depth;
1310     /* Minimum depth value seen. */
1311     int    minDepth;
1312     /* Integer had a zero prepended. */
1313     int    zeroPadded;
1314 
1315 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1316     WOLFSSL_ENTER("GetASN_Items");
1317 #endif
1318 
1319     /* Start depth at first items depth. */
1320     minDepth = depth = asn[0].depth;
1321     /* Check every ASN.1 item. */
1322     for (i = 0; i < count; i++) {
1323         /* Store offset of ASN.1 item. */
1324         data[i].offset = idx;
1325         /* Length of data in ASN.1 item starts empty. */
1326         data[i].length = 0;
1327         /* Get current item depth. */
1328         depth = asn[i].depth;
1329     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1330         if (depth > GET_ASN_MAX_DEPTH) {
1331             WOLFSSL_MSG("Depth in template too large");
1332             return ASN_PARSE_E;
1333         }
1334     #endif
1335         /* Keep track of minimum depth. */
1336         if (depth < minDepth) {
1337             minDepth = depth;
1338         }
1339 
1340         /* Reset choice if different from previous. */
1341         if (choice > 0 && asn[i].optional != choice) {
1342             choice = 0;
1343         }
1344         /* Check if first of numbered choice. */
1345         if (choice == 0 && asn[i].optional > 1) {
1346             choice = asn[i].optional;
1347             if (choiceMet[choice - 2] == -1) {
1348                 /* Choice seen but not found a match yet. */
1349                 choiceMet[choice - 2] = 0;
1350             }
1351         }
1352 
1353         /* Check for end of data or not a choice and tag not matching. */
1354         if (idx == endIdx[depth] || (data[i].dataType != ASN_DATA_TYPE_CHOICE &&
1355                               (input[idx] & ~ASN_CONSTRUCTED) != asn[i].tag)) {
1356             if (asn[i].optional) {
1357                 /* Skip over ASN.1 items underneath this optional item. */
1358                 for (j = i + 1; j < count; j++) {
1359                     if (asn[i].depth >= asn[j].depth)
1360                         break;
1361                     data[j].offset = idx;
1362                     data[j].length = 0;
1363                 }
1364                 i = j - 1;
1365                 continue;
1366             }
1367 
1368             /* Check for end of data. */
1369             if (idx == length) {
1370         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1371                 WOLFSSL_MSG_VSNPRINTF(
1372                     "%2d: %4d %4d %c %*s %-16s%*s  (index past end)",
1373                     i, data[i].offset, data[i].length,
1374                     asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1375                     TagString(asn[i].tag), 6 - asn[i].depth, "");
1376                 WOLFSSL_MSG_VSNPRINTF("Index past end of data: %d %d", idx,
1377                         length);
1378         #endif
1379                 return BUFFER_E;
1380             }
1381         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1382             /* Show expected versus found. */
1383             WOLFSSL_MSG_VSNPRINTF(
1384                 "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1385                 i, data[i].offset, data[i].length,
1386                 asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1387                 TagString(asn[i].tag), 6 - asn[i].depth, "",
1388                 input[idx], TagString(input[idx]));
1389         #endif
1390             /* Check for end of data at this depth. */
1391             if (idx == endIdx[depth]) {
1392             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1393                 WOLFSSL_MSG_VSNPRINTF("Index past outer item: %d %d", idx,
1394                         endIdx[depth]);
1395             #endif
1396                 return ASN_PARSE_E;
1397             }
1398 
1399             /* Expecting an OBJECT_ID */
1400             if (asn[i].tag == ASN_OBJECT_ID) {
1401             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1402                 WOLFSSL_MSG("Expecting OBJECT ID");
1403             #endif
1404                 return ASN_OBJECT_ID_E;
1405             }
1406             /* Expecting a BIT_STRING */
1407             if (asn[i].tag == ASN_BIT_STRING) {
1408             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1409                 WOLFSSL_MSG("Expecting BIT STRING");
1410             #endif
1411                 return ASN_BITSTR_E;
1412             }
1413             /* Not the expected tag. */
1414         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1415             WOLFSSL_MSG("Bad tag");
1416         #endif
1417             return ASN_PARSE_E;
1418         }
1419 
1420         /* Store found tag in data. */
1421         data[i].tag = input[idx];
1422         if (data[i].dataType != ASN_DATA_TYPE_CHOICE) {
1423             int constructed = (input[idx] & ASN_CONSTRUCTED) == ASN_CONSTRUCTED;
1424             /* Check constructed match expected for non-choice ASN.1 item. */
1425             if (asn[i].constructed != constructed) {
1426             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1427                 WOLFSSL_MSG_VSNPRINTF(
1428                         "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1429                         i, data[i].offset, data[i].length,
1430                         asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1431                         TagString(asn[i].tag), 6 - asn[i].depth, "",
1432                         input[idx], TagString(input[idx]));
1433                 if (!constructed) {
1434                     WOLFSSL_MSG("Not constructed");
1435                 }
1436                 else {
1437                     WOLFSSL_MSG("Not expected to be constructed");
1438                 }
1439             #endif
1440                 return ASN_PARSE_E;
1441             }
1442         }
1443         /* Move index to start of length. */
1444         idx++;
1445         /* Get the encoded length. */
1446         if ((err = GetASN_Length(input, &idx, &len, endIdx[depth], 1)) < 0) {
1447         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1448             WOLFSSL_MSG_VSNPRINTF("%2d: idx=%d len=%d end=%d", i, idx, len,
1449                     endIdx[depth]);
1450         #endif
1451             return ASN_PARSE_E;
1452         }
1453         /* Store length of data. */
1454         data[i].length = len;
1455         /* Note the max length of items under this one. */
1456         endIdx[depth + 1] = idx + len;
1457         if (choice > 1) {
1458             /* Note we found a number choice. */
1459             choiceMet[choice - 2] = 1;
1460         }
1461 
1462     #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1463         WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
1464                 data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
1465                 asn[i].depth, "", TagString(data[i].tag));
1466     #endif
1467 
1468         /* Assume no zero padding on INTEGER. */
1469         zeroPadded = 0;
1470         /* Check data types that prepended a byte. */
1471         if (asn[i].tag == ASN_INTEGER) {
1472             /* Check validity of first byte. */
1473             err = GetASN_Integer(input, idx, len,
1474                     data[i].dataType == ASN_DATA_TYPE_MP);
1475             if (err != 0)
1476                 return err;
1477             if (len > 1 && input[idx] == 0) {
1478                 zeroPadded = 1;
1479                 /* Move over prepended byte. */
1480                 idx++;
1481                 len--;
1482             }
1483         }
1484         else if (asn[i].tag == ASN_BIT_STRING) {
1485             /* Check prepended byte is correct. */
1486             err = GetASN_BitString(input, idx, len);
1487             if (err != 0)
1488                 return err;
1489             /* Move over prepended byte. */
1490             idx++;
1491             len--;
1492         }
1493 
1494         /* Don't parse data if only header required. */
1495         if (asn[i].headerOnly) {
1496             /* Store reference to data and length. */
1497             data[i].data.ref.data = input + idx;
1498             data[i].data.ref.length = len;
1499             continue;
1500         }
1501 
1502         /* Store the data at idx in the ASN data item. */
1503         err = GetASN_StoreData(&asn[i], &data[i], input, idx, len, zeroPadded);
1504         if (err != 0) {
1505             return err;
1506         }
1507 
1508         /* Move index to next item. */
1509         idx += len;
1510 
1511         /* When matched numbered choice ... */
1512         if (asn[i].optional > 1) {
1513             /* Skip over other ASN.1 items of the same number. */
1514             for (j = i + 1; j < count; j++) {
1515                 if (asn[j].depth <= asn[i].depth &&
1516                                            asn[j].optional != asn[i].optional) {
1517                    break;
1518                 }
1519             }
1520             i = j - 1;
1521         }
1522     }
1523 
1524     if (complete) {
1525         /* When expecting ASN.1 items to completely use data, check we did. */
1526         for (j = depth; j > minDepth; j--) {
1527             if (idx < endIdx[j]) {
1528             #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1529                 WOLFSSL_MSG_VSNPRINTF(
1530                     "More data in constructed item at depth: %d", j - 1);
1531             #endif
1532                 return ASN_PARSE_E;
1533             }
1534         }
1535     }
1536 
1537     /* Check all choices where met - found an item for them. */
1538     for (j = 0; j < GET_ASN_MAX_CHOICES; j++) {
1539         if (choiceMet[j] == 0) {
1540         #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1541             WOLFSSL_MSG_VSNPRINTF("No choice seen: %d", j + 2);
1542         #endif
1543             return ASN_PARSE_E;
1544         }
1545     }
1546 
1547     /* Return index after ASN.1 data has been parsed. */
1548     *inOutIdx = idx;
1549 
1550     return 0;
1551 }
1552 
1553 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1554 /* Calculate the size of the DER encoding.
1555  *
1556  * Call SetASN_Items() to write encoding to a buffer.
1557  *
1558  * @param [in]      asn    ASN.1 items to encode.
1559  * @param [in, out] data   Data to place in each item. Lengths set were not
1560  *                         known.
1561  * @param [in]      count  Count of items to encode.
1562  * @param [out]     len    Length of the DER encoding.
1563  * @return  Size of the DER encoding in bytes.
1564  */
1565 static int SizeASN_ItemsDebug(const char* name, const ASNItem* asn,
1566     ASNSetData *data, int count, int* encSz)
1567 {
1568     WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1569     return SizeASN_Items(asn, data, count, encSz);
1570 }
1571 
1572 /* Creates the DER encoding of the ASN.1 items.
1573  *
1574  * Assumes the output buffer is large enough to hold encoding.
1575  * Must call SizeASN_Items() to determine size of encoding and offsets.
1576  *
1577  * Displays the template name first.
1578  *
1579  * @param [in]      name    Name of ASN.1 template.
1580  * @param [in]      asn     ASN.1 items to encode.
1581  * @param [in]      data    Data to place in each item.
1582  * @param [in]      count   Count of items to encode.
1583  * @param [in, out] output  Buffer to write encoding into.
1584  * @return  Size of the DER encoding in bytes.
1585  */
1586 static int SetASN_ItemsDebug(const char* name, const ASNItem* asn,
1587     ASNSetData *data, int count, byte* output)
1588 {
1589     WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1590     return SetASN_Items(asn, data, count, output);
1591 }
1592 
1593 /* Get the ASN.1 items from the BER encoding.
1594  *
1595  * Displays the template name first.
1596  *
1597  * @param [in]      name      Name of ASN.1 template.
1598  * @param [in]      asn       ASN.1 items expected.
1599  * @param [in]      data      Data array to place found items into.
1600  * @param [in]      count     Count of items to parse.
1601  * @param [in]      complete  Whether the whole buffer is to be used up.
1602  * @param [in]      input     BER encoded data.
1603  * @param [in, out] inOutIdx  On in, starting index of data.
1604  *                            On out, end of parsed data.
1605  * @param [in]      maxIdx    Maximum index of input data.
1606  * @return  0 on success.
1607  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1608  * is invalid.
1609  * @return  BUFFER_E when data in buffer is too small.
1610  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1611  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1612  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1613  *          non-zero length.
1614  * @return  MP_INIT_E when the unable to initialize an mp_int.
1615  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1616  * @return  BAD_STATE_E when the data type is not supported.
1617  */
1618 static int GetASN_ItemsDebug(const char* name, const ASNItem* asn,
1619     ASNGetData *data, int count, int complete, const byte* input,
1620     word32* inOutIdx, word32 maxIdx)
1621 {
1622     WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1623     return GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx);
1624 }
1625 
1626 /* Calculate the size of the DER encoding.
1627  *
1628  * Call SetASN_Items() to write encoding to a buffer.
1629  *
1630  * @param [in]      asn    ASN.1 items to encode.
1631  * @param [in, out] data   Data to place in each item. Lengths set were not
1632  *                         known.
1633  * @param [in]      count  Count of items to encode.
1634  * @param [out]     len    Length of the DER encoding.
1635  * @return  Size of the DER encoding in bytes.
1636  */
1637 #define SizeASN_Items(asn, data, count, encSz)  \
1638     SizeASN_ItemsDebug(#asn, asn, data, count, encSz)
1639 
1640 /* Creates the DER encoding of the ASN.1 items.
1641  *
1642  * Assumes the output buffer is large enough to hold encoding.
1643  * Must call SizeASN_Items() to determine size of encoding and offsets.
1644  *
1645  * Displays the template name first.
1646  *
1647  * @param [in]      name    Name of ASN.1 template.
1648  * @param [in]      asn     ASN.1 items to encode.
1649  * @param [in]      data    Data to place in each item.
1650  * @param [in]      count   Count of items to encode.
1651  * @param [in, out] output  Buffer to write encoding into.
1652  * @return  Size of the DER encoding in bytes.
1653  */
1654 #define SetASN_Items(asn, data, count, output)  \
1655     SetASN_ItemsDebug(#asn, asn, data, count, output)
1656 
1657 /* Get the ASN.1 items from the BER encoding.
1658  *
1659  * Displays the template name first.
1660  *
1661  * @param [in]      name      Name of ASN.1 template.
1662  * @param [in]      asn       ASN.1 items expected.
1663  * @param [in]      data      Data array to place found items into.
1664  * @param [in]      count     Count of items to parse.
1665  * @param [in]      complete  Whether the whole buffer is to be used up.
1666  * @param [in]      input     BER encoded data.
1667  * @param [in, out] inOutIdx  On in, starting index of data.
1668  *                            On out, end of parsed data.
1669  * @param [in]      maxIdx    Maximum index of input data.
1670  * @return  0 on success.
1671  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1672  * is invalid.
1673  * @return  BUFFER_E when data in buffer is too small.
1674  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1675  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1676  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1677  *          non-zero length.
1678  * @return  MP_INIT_E when the unable to initialize an mp_int.
1679  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1680  * @return  BAD_STATE_E when the data type is not supported.
1681  */
1682 #define GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx)  \
1683     GetASN_ItemsDebug(#asn, asn, data, count, complete, input, inOutIdx, maxIdx)
1684 #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
1685 
1686 /* Decode a BER encoded constructed sequence.
1687  *
1688  * @param [in]       input     Buffer of BER encoded data.
1689  * @param [in, out]  inOutIdx  On in, index to start decoding from.
1690  *                             On out, index of next encoded byte.
1691  * @param [out]      len       Length of data under SEQUENCE.
1692  * @param [in]       maxIdx    Maximim index of data. Index of byte after SEQ.
1693  * @param [in]       complete  All data used with SEQUENCE and data under.
1694  * @return  0 on success.
1695  * @return  BUFFER_E when not enough data to complete decode.
1696  * @return  ASN_PARSE when decoding failed.
1697  */
1698 static int GetASN_Sequence(const byte* input, word32* inOutIdx, int* len,
1699                            word32 maxIdx, int complete)
1700 {
1701     int ret = 0;
1702     word32 idx = *inOutIdx;
1703 
1704     /* Check buffer big enough for tag. */
1705     if (idx + 1 > maxIdx) {
1706         ret = BUFFER_E;
1707     }
1708     /* Check it is a constructed SEQUENCE. */
1709     if ((ret == 0) && (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
1710         ret = ASN_PARSE_E;
1711     }
1712     /* Get the length. */
1713     if ((ret == 0) && (GetASN_Length(input, &idx, len, maxIdx, 1) < 0)) {
1714         ret = ASN_PARSE_E;
1715     }
1716     /* Check all data used if complete set. */
1717     if ((ret == 0) && complete && (idx + *len != maxIdx)) {
1718         ret = ASN_PARSE_E;
1719     }
1720     if (ret == 0) {
1721         /* Return index of next byte of encoded data. */
1722         *inOutIdx = idx;
1723     }
1724 
1725     return ret;
1726 }
1727 
1728 
1729 #ifdef WOLFSSL_ASN_TEMPLATE_TYPE_CHECK
1730 /* Setup ASN data item to get an 8-bit number.
1731  *
1732  * @param [in] dataASN  Dynamic ASN data item.
1733  * @param [in] num      Pointer to an 8-bit variable.
1734  */
1735 void GetASN_Int8Bit(ASNGetData *dataASN, byte* num)
1736 {
1737     dataASN->dataType = ASN_DATA_TYPE_WORD8;
1738     dataASN->data.u8  = num;
1739 }
1740 
1741 /* Setup ASN data item to get a 16-bit number.
1742  *
1743  * @param [in] dataASN  Dynamic ASN data item.
1744  * @param [in] num      Pointer to a 16-bit variable.
1745  */
1746 void GetASN_Int16Bit(ASNGetData *dataASN, word16* num)
1747 {
1748     dataASN->dataType = ASN_DATA_TYPE_WORD16;
1749     dataASN->data.u16 = num;
1750 }
1751 
1752 /* Setup ASN data item to get a 32-bit number.
1753  *
1754  * @param [in] dataASN  Dynamic ASN data item.
1755  * @param [in] num      Pointer to a 32-bit variable.
1756  */
1757 void GetASN_Int32Bit(ASNGetData *dataASN, word32* num)
1758 {
1759     dataASN->dataType = ASN_DATA_TYPE_WORD32;
1760     dataASN->data.u32 = num;
1761 }
1762 
1763 /* Setup ASN data item to get data into a buffer of a specific length.
1764  *
1765  * @param [in] dataASN  Dynamic ASN data item.
1766  * @param [in] data     Buffer to hold data.
1767  * @param [in] length   Length of buffer in bytes.
1768  */
1769 void GetASN_Buffer(ASNGetData *dataASN, byte* data, word32* length)
1770 {
1771     dataASN->dataType           = ASN_DATA_TYPE_BUFFER;
1772     dataASN->data.buffer.data   = data;
1773     dataASN->data.buffer.length = length;
1774 }
1775 
1776 /* Setup ASN data item to check parsed data against expected buffer.
1777  *
1778  * @param [in] dataASN  Dynamic ASN data item.
1779  * @param [in] data     Buffer containing expected data.
1780  * @param [in] length   Length of buffer in bytes.
1781  */
1782 void GetASN_ExpBuffer(ASNGetData *dataASN, const byte* data, word32 length)
1783 {
1784     dataASN->dataType        = ASN_DATA_TYPE_EXP_BUFFER;
1785     dataASN->data.ref.data   = data;
1786     dataASN->data.ref.length = length;
1787 }
1788 
1789 /* Setup ASN data item to get a number into an mp_int.
1790  *
1791  * @param [in] dataASN  Dynamic ASN data item.
1792  * @param [in] num      Multi-precision number object.
1793  */
1794 void GetASN_MP(ASNGetData *dataASN, mp_int* num)
1795 {
1796     dataASN->dataType = ASN_DATA_TYPE_MP;
1797     dataASN->data.mp  = num;
1798 }
1799 
1800 /* Setup ASN data item to get a positive or negative number into an mp_int.
1801  *
1802  * @param [in] dataASN  Dynamic ASN data item.
1803  * @param [in] num      Multi-precision number object.
1804  */
1805 void GetASN_MP_PosNeg(ASNGetData *dataASN, mp_int* num)
1806 {
1807     dataASN->dataType = ASN_DATA_TYPE_MP_POS_NEG;
1808     dataASN->data.mp  = num;
1809 }
1810 
1811 /* Setup ASN data item to be a choice of tags.
1812  *
1813  * @param [in] dataASN  Dynamic ASN data item.
1814  * @param [in] options  0 terminated list of tags that are valid.
1815  */
1816 void GetASN_Choice(ASNGetData *dataASN, const byte* options)
1817 {
1818     dataASN->dataType    = ASN_DATA_TYPE_CHOICE;
1819     dataASN->data.choice = options;
1820 }
1821 
1822 /* Setup ASN data item to get a boolean value.
1823  *
1824  * @param [in] dataASN  Dynamic ASN data item.
1825  * @param [in] num      Pointer to an 8-bit variable.
1826  */
1827 void GetASN_Boolean(ASNGetData *dataASN, byte* num)
1828 {
1829     dataASN->dataType    = ASN_DATA_TYPE_NONE;
1830     dataASN->data.choice = num;
1831 }
1832 
1833 /* Setup ASN data item to be a an OID of a specific type.
1834  *
1835  * @param [in] dataASN  Dynamic ASN data item.
1836  * @param [in] oidType  Type of OID to expect.
1837  */
1838 void GetASN_OID(ASNGetData *dataASN, int oidType)
1839 {
1840     dataASN->data.oid.type = oidType;
1841 }
1842 
1843 /* Get the data and length from an ASN data item.
1844  *
1845  * @param [in]  dataASN  Dynamic ASN data item.
1846  * @param [out] data     Pointer to data of item.
1847  * @param [out] length   Length of buffer in bytes.
1848  */
1849 void GetASN_GetConstRef(ASNGetData * dataASN, const byte** data, word32* length)
1850 {
1851     *data   = dataASN->data.ref.data;
1852     *length = dataASN->data.ref.length;
1853 }
1854 
1855 /* Get the data and length from an ASN data item.
1856  *
1857  * @param [in]  dataASN  Dynamic ASN data item.
1858  * @param [out] data     Pointer to data of item.
1859  * @param [out] length   Length of buffer in bytes.
1860  */
1861 void GetASN_GetRef(ASNGetData * dataASN, byte** data, word32* length)
1862 {
1863     *data   = (byte*)dataASN->data.ref.data;
1864     *length =        dataASN->data.ref.length;
1865 }
1866 
1867 /* Get the data and length from an ASN data item that is an OID.
1868  *
1869  * @param [in]  dataASN  Dynamic ASN data item.
1870  * @param [out] data     Pointer to .
1871  * @param [out] length   Length of buffer in bytes.
1872  */
1873 void GetASN_OIDData(ASNGetData * dataASN, byte** data, word32* length)
1874 {
1875     *data   = (byte*)dataASN->data.oid.data;
1876     *length =        dataASN->data.oid.length;
1877 }
1878 
1879 /* Setup an ASN data item to set a boolean.
1880  *
1881  * @param [in] dataASN  Dynamic ASN data item.
1882  * @param [in] val      Boolean value.
1883  */
1884 void SetASN_Boolean(ASNSetData *dataASN, byte val)
1885 {
1886     dataASN->dataType = ASN_DATA_TYPE_NONE;
1887     dataASN->data.u8  = val;
1888 }
1889 
1890 /* Setup an ASN data item to set an 8-bit number.
1891  *
1892  * @param [in] dataASN  Dynamic ASN data item.
1893  * @param [in] num      8-bit number to set.
1894  */
1895 void SetASN_Int8Bit(ASNSetData *dataASN, byte num)
1896 {
1897     dataASN->dataType = ASN_DATA_TYPE_WORD8;
1898     dataASN->data.u8  = num;
1899 }
1900 
1901 /* Setup an ASN data item to set a 16-bit number.
1902  *
1903  * @param [in] dataASN  Dynamic ASN data item.
1904  * @param [in] num      16-bit number to set.
1905  */
1906 void SetASN_Int16Bit(ASNSetData *dataASN, word16 num)
1907 {
1908     dataASN->dataType = ASN_DATA_TYPE_WORD16;
1909     dataASN->data.u16 = num;
1910 }
1911 
1912 /* Setup an ASN data item to set the data in a buffer.
1913  *
1914  * @param [in] dataASN  Dynamic ASN data item.
1915  * @param [in] data     Buffer containing data to set.
1916  * @param [in] length   Length of data in buffer in bytes.
1917  */
1918 void SetASN_Buffer(ASNSetData *dataASN, const byte* data, word32 length)
1919 {
1920     dataASN->data.buffer.data   = data;
1921     dataASN->data.buffer.length = length;
1922 }
1923 
1924 /* Setup an ASN data item to set the DER encode data in a buffer.
1925  *
1926  * @param [in] dataASN  Dynamic ASN data item.
1927  * @param [in] data     Buffer containing BER encoded data to set.
1928  * @param [in] length   Length of data in buffer in bytes.
1929  */
1930 void SetASN_ReplaceBuffer(ASNSetData *dataASN, const byte* data, word32 length)
1931 {
1932     dataASN->dataType           = ASN_DATA_TYPE_REPLACE_BUFFER;
1933     dataASN->data.buffer.data   = data;
1934     dataASN->data.buffer.length = length;
1935 }
1936 
1937 /* Setup an ASN data item to set an multi-precision number.
1938  *
1939  * @param [in] dataASN  Dynamic ASN data item.
1940  * @param [in] num      Multi-precision number.
1941  */
1942 void SetASN_MP(ASNSetData *dataASN, mp_int* num)
1943 {
1944     dataASN->dataType = ASN_DATA_TYPE_MP;
1945     dataASN->data.mp  = num;
1946 }
1947 
1948 /* Setup an ASN data item to set an OID based on id and type.
1949  *
1950  * oid and oidType pair are unique.
1951  *
1952  * @param [in] dataASN  Dynamic ASN data item.
1953  * @param [in] oid      OID identifier.
1954  * @param [in] oidType  Type of OID.
1955  */
1956 void SetASN_OID(ASNSetData *dataASN, int oid, int oidType)
1957 {
1958     dataASN->data.buffer.data = OidFromId(oid, oidType,
1959                                                   &dataASN->data.buffer.length);
1960 }
1961 #endif /* WOLFSSL_ASN_TEMPLATE_TYPE_CHECK */
1962 
1963 #ifdef CRLDP_VALIDATE_DATA
1964 /* Get the data of the BIT_STRING as a 16-bit number.
1965  *
1966  * @param [in]  dataASN  Dynamic ASN data item.
1967  * @param [out] val      ASN.1 item's data as a 16-bit number.
1968  * @return  0 on success.
1969  * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
1970  * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
1971  */
1972 static int GetASN_BitString_Int16Bit(ASNGetData* dataASN, word16* val)
1973 {
1974     int ret;
1975     int i;
1976     const byte* input = dataASN->data.ref.data;
1977     int length = dataASN->data.ref.length;
1978 
1979     /* Validate the BIT_STRING data. */
1980     ret = GetASN_BitString(input, 0, length);
1981     if (ret == 0) {
1982         /* Skip unused bits byte. */
1983         input++;
1984         length--;
1985 
1986         /* Check the data is usable. */
1987         if (length == 0 || length > 2) {
1988 #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1989             WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", length);
1990 #endif
1991             ret = ASN_PARSE_E;
1992         }
1993     }
1994     if (ret == 0) {
1995         /* Fill 16-bit var with all the data. */
1996         *val = 0;
1997         for (i = 0; i < length; i++) {
1998             *val <<= 8;
1999             *val |= input[i];
2000         }
2001     }
2002     return ret;
2003 }
2004 #endif /* CRLDP_VALIDATE_DATA */
2005 
2006 #endif /* WOLFSSL_ASN_TEMPLATE */
2007 
2008 
2009 /* Decode the BER/DER length field.
2010  *
2011  * @param [in]      input     BER encoded data.
2012  * @param [in, out] inOutIdx  On in, starting index of length.
2013  *                            On out, end of parsed length.
2014  * @param [out]     len       Length value decoded.
2015  * @param [in]      maxIdx    Maximum index of input data.
2016  * @return  0 on success.
2017  * @return  ASN_PARSE_E if the encoding is invalid.
2018  * @return  BUFFER_E when not enough data to complete decode.
2019  */
2020 int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2021 {
2022     return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
2023 }
2024 
2025 
2026 /* Decode the BER/DER length field and check the length is valid on request.
2027  *
2028  * BER/DER has Type-Length-Value triplets.
2029  * When requested will check that the Length decoded, indicating the number
2030  * of bytes in the Value, is available in the buffer after the Length bytes.
2031  *
2032  * Only supporting a length upto INT_MAX.
2033  *
2034  * @param [in]      input     BER encoded data.
2035  * @param [in, out] inOutIdx  On in, starting index of length.
2036  *                            On out, end of parsed length.
2037  * @param [out]     len       Length value decoded.
2038  * @param [in]      maxIdx    Maximum index of input data.
2039  * @param [in]      check     Whether to check the buffer has at least the
2040  *                            decoded length of bytes remaining.
2041  * @return  0 on success.
2042  * @return  ASN_PARSE_E if the encoding is invalid.
2043  * @return  BUFFER_E when not enough data to complete decode.
2044  */
2045 int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
2046                  int check)
2047 {
2048     int     length = 0;
2049     word32  idx = *inOutIdx;
2050     byte    b;
2051 
2052     /* Ensure zero return length on error. */
2053     *len = 0;
2054 
2055     /* Check there is at least on byte available containing length information.
2056      */
2057     if ((idx + 1) > maxIdx) {
2058         WOLFSSL_MSG("GetLength - bad index on input");
2059         return BUFFER_E;
2060     }
2061 
2062     /* Get the first length byte. */
2063     b = input[idx++];
2064     /* Check if the first byte indicates the count of bytes. */
2065     if (b >= ASN_LONG_LENGTH) {
2066         /* Bottom 7 bits are the number of bytes to calculate length with.
2067          * Note: 0 indicates indefinte length encoding *not* 0 bytes of length.
2068          */
2069         word32 bytes = b & 0x7F;
2070 
2071         /* Check the number of bytes required are available. */
2072         if ((idx + bytes) > maxIdx) {
2073             WOLFSSL_MSG("GetLength - bad long length");
2074             return BUFFER_E;
2075         }
2076 
2077         /* Only support up to the number of bytes that fit into return var. */
2078         if (bytes > sizeof(length)) {
2079             return ASN_PARSE_E;
2080         }
2081         /* Big-endian encoding of number. */
2082         while (bytes--) {
2083             b = input[idx++];
2084             length = (length << 8) | b;
2085         }
2086         /* Negative value indicates we overflowed the signed int. */
2087         if (length < 0) {
2088             return ASN_PARSE_E;
2089         }
2090     }
2091     else {
2092         /* Length in first byte. */
2093         length = b;
2094     }
2095 
2096     /* When request, check the buffer has at least length bytes left. */
2097     if (check && ((idx + length) > maxIdx)) {
2098         WOLFSSL_MSG("GetLength - value exceeds buffer length");
2099         return BUFFER_E;
2100     }
2101 
2102     /* Return index after length encoding. */
2103     *inOutIdx = idx;
2104     /* Return length if valid. */
2105     if (length > 0) {
2106         *len = length;
2107     }
2108 
2109     /* Return length calculated or error code. */
2110     return length;
2111 }
2112 
2113 
2114 /* Gets the tag of next BER/DER encoded item.
2115  *
2116  * Checks there is enough data in the buffer for the tag byte.
2117  *
2118  * @param [in]      input     BER encoded data.
2119  * @param [in, out] inOutIdx  On in, starting index of tag.
2120  *                            On out, end of parsed tag.
2121  * @param [out]     tag       Tag value found.
2122  * @param [in]      maxIdx    Maximum index of input data.
2123  *
2124  * return  0 on success
2125  * return  BAD_FUNC_ARG when tag, inOutIdx or input is NULL.
2126  * return  BUFFER_E when not enough space in buffer for tag.
2127  */
2128 int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
2129 {
2130     int ret = 0;
2131     word32 idx = 0;
2132 
2133     /* Check validity of parameters. */
2134     if ((tag == NULL) || (inOutIdx == NULL) || (input == NULL)) {
2135         ret = BAD_FUNC_ARG;
2136     }
2137     if (ret == 0) {
2138         /* Get index and ensure space for tag. */
2139         idx = *inOutIdx;
2140         if (idx + ASN_TAG_SZ > maxIdx) {
2141             WOLFSSL_MSG("Buffer too small for ASN tag");
2142             ret = BUFFER_E;
2143         }
2144     }
2145     if (ret == 0) {
2146         /* Return the tag and the index after tag. */
2147         *tag = input[idx];
2148         *inOutIdx = idx + ASN_TAG_SZ;
2149     }
2150     /* Return error code. */
2151     return ret;
2152 }
2153 
2154 
2155 /* Decode the DER/BER header (Type-Length) and check the length when requested.
2156  *
2157  * BER/DER has Type-Length-Value triplets.
2158  * Check that the tag/type is the required value.
2159  * When requested will check that the Length decoded, indicating the number
2160  * of bytes in the Value, is available in the buffer after the Length bytes.
2161  *
2162  * Only supporting a length upto INT_MAX.
2163  *
2164  * @param [in]      input     Buffer holding DER/BER encoded data.
2165  * @param [in]      tag       ASN.1 tag value expected in header.
2166  * @param [in, out] inOutIdx  On in, starting index of header.
2167  *                            On out, end of parsed header.
2168  * @param [out]     len       Number of bytes in the ASN.1 data.
2169  * @param [in]      maxIdx    Length of data in buffer.
2170  * @param [in]      check     Whether to check the buffer has at least the
2171  *                            decoded length of bytes remaining.
2172  * @return  Number of bytes in the ASN.1 data on success.
2173  * @return  BUFFER_E when there is not enough data to parse.
2174  * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2175  */
2176 static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx,
2177                            int* len, word32 maxIdx, int check)
2178 {
2179     int    ret = 0;
2180     word32 idx = *inOutIdx;
2181     byte   tagFound;
2182     int    length = 0;
2183 
2184     /* Get tag/type. */
2185     if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0) {
2186         ret = ASN_PARSE_E;
2187     }
2188     /* Ensure tag is the expected value. */
2189     if ((ret == 0) && (tagFound != tag)) {
2190         ret = ASN_PARSE_E;
2191     }
2192     /* Get the encoded length. */
2193     if ((ret == 0) && (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)) {
2194         ret = ASN_PARSE_E;
2195     }
2196     if (ret == 0) {
2197         /* Return the length of data and index after header. */
2198         *len      = length;
2199         *inOutIdx = idx;
2200         ret = length;
2201     }
2202     /* Return number of data bytes or error code. */
2203     return ret;
2204 }
2205 
2206 
2207 /* Decode the DER/BER header (Type-Length) and check the length.
2208  *
2209  * BER/DER has Type-Length-Value triplets.
2210  * Check that the tag/type is the required value.
2211  * Checks that the Length decoded, indicating the number of bytes in the Value,
2212  * is available in the buffer after the Length bytes.
2213  *
2214  * @param [in]      input     Buffer holding DER/BER encoded data.
2215  * @param [in]      tag       ASN.1 tag value expected in header.
2216  * @param [in, out] inOutIdx  On in, starting index of header.
2217  *                            On out, end of parsed header.
2218  * @param [out]     len       Number of bytes in the ASN.1 data.
2219  * @param [in]      maxIdx    Length of data in buffer.
2220  * @return  Number of bytes in the ASN.1 data on success.
2221  * @return  BUFFER_E when there is not enough data to parse.
2222  * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2223  */
2224 static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
2225                         word32 maxIdx)
2226 {
2227     return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
2228 }
2229 
2230 #ifndef WOLFSSL_ASN_TEMPLATE
2231 static int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,
2232                      word32 maxIdx, int check)
2233 {
2234     word32 idx = *inOutIdx;
2235     int    length;
2236 
2237     if ((idx + 1) > maxIdx)
2238         return BUFFER_E;
2239 
2240     *tag = input[idx++];
2241 
2242     if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
2243         return ASN_PARSE_E;
2244 
2245     *len      = length;
2246     *inOutIdx = idx;
2247     return length;
2248 }
2249 #endif
2250 
2251 /* Decode the header of a BER/DER encoded SEQUENCE.
2252  *
2253  * @param [in]      input     Buffer holding DER/BER encoded data.
2254  * @param [in, out] inOutIdx  On in, starting index of header.
2255  *                            On out, end of parsed header.
2256  * @param [out]     len       Number of bytes in the ASN.1 data.
2257  * @param [in]      maxIdx    Length of data in buffer.
2258  * @return  Number of bytes in the ASN.1 data on success.
2259  * @return  BUFFER_E when there is not enough data to parse.
2260  * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2261  */
2262 int GetSequence(const byte* input, word32* inOutIdx, int* len,
2263                            word32 maxIdx)
2264 {
2265     return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2266                         maxIdx);
2267 }
2268 
2269 /* Decode the header of a BER/DER encoded SEQUENCE.
2270  *
2271  * @param [in]      input     Buffer holding DER/BER encoded data.
2272  * @param [in, out] inOutIdx  On in, starting index of header.
2273  *                            On out, end of parsed header.
2274  * @param [out]     len       Number of bytes in the ASN.1 data.
2275  * @param [in]      maxIdx    Length of data in buffer.
2276  * @param [in]      check     Whether to check the buffer has at least the
2277  *                            decoded length of bytes remaining.
2278  * @return  Number of bytes in the ASN.1 data on success.
2279  * @return  BUFFER_E when there is not enough data to parse.
2280  * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2281  */
2282 int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
2283                            word32 maxIdx, int check)
2284 {
2285     return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2286                         maxIdx, check);
2287 }
2288 
2289 /* Decode the header of a BER/DER encoded SET.
2290  *
2291  * @param [in]      input     Buffer holding DER/BER encoded data.
2292  * @param [in, out] inOutIdx  On in, starting index of header.
2293  *                            On out, end of parsed header.
2294  * @param [out]     len       Number of bytes in the ASN.1 data.
2295  * @param [in]      maxIdx    Length of data in buffer.
2296  * @return  Number of bytes in the ASN.1 data on success.
2297  * @return  BUFFER_E when there is not enough data to parse.
2298  * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2299  */
2300 int GetSet(const byte* input, word32* inOutIdx, int* len,
2301                         word32 maxIdx)
2302 {
2303     return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2304                         maxIdx);
2305 }
2306 
2307 /* Decode the header of a BER/DER encoded SET.
2308  *
2309  * @param [in]      input     Buffer holding DER/BER encoded data.
2310  * @param [in, out] inOutIdx  On in, starting index of header.
2311  *                            On out, end of parsed header.
2312  * @param [out]     len       Number of bytes in the ASN.1 data.
2313  * @param [in]      maxIdx    Length of data in buffer.
2314  * @param [in]      check     Whether to check the buffer has at least the
2315  *                            decoded length of bytes remaining.
2316  * @return  Number of bytes in the ASN.1 data on success.
2317  * @return  BUFFER_E when there is not enough data to parse.
2318  * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2319  */
2320 int GetSet_ex(const byte* input, word32* inOutIdx, int* len,
2321                         word32 maxIdx, int check)
2322 {
2323     return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2324                         maxIdx, check);
2325 }
2326 
2327 #if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_OCSP)
2328 /* Decode the BER/DER encoded NULL.
2329  *
2330  * No data in a NULL ASN.1 item.
2331  * Ensure that the all fields are as expected and move index past the element.
2332  *
2333  * @param [in]      input     Buffer holding DER/BER encoded data.
2334  * @param [in, out] inOutIdx  On in, starting index of NULL item.
2335  *                            On out, end of parsed NULL item.
2336  * @param [in]      maxIdx    Length of data in buffer.
2337  * @return  0 on success.
2338  * @return  BUFFER_E when there is not enough data to parse.
2339  * @return  ASN_TAG_NULL_E when the NULL tag is not found.
2340  * @return  ASN_EXPECT_0_E when the length is not zero.
2341  */
2342 static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
2343 {
2344     int ret = 0;
2345     word32 idx = *inOutIdx;
2346 
2347     /* Check buffer has enough data for a NULL item. */
2348     if ((idx + 2) > maxIdx) {
2349         ret = BUFFER_E;
2350     }
2351     /* Check the tag is NULL. */
2352     if ((ret == 0) && (input[idx++] != ASN_TAG_NULL)) {
2353         ret = ASN_TAG_NULL_E;
2354     }
2355     /* Check the length is zero. */
2356     if ((ret == 0) && (input[idx++] != 0)) {
2357         ret = ASN_EXPECT_0_E;
2358     }
2359     if (ret == 0) {
2360         /* Return the index after NULL tag. */
2361         *inOutIdx = idx;
2362     }
2363     /* Return error code. */
2364     return ret;
2365 }
2366 #endif
2367 
2368 #ifndef WOLFSSL_ASN_TEMPLATE
2369 /* Set the DER/BER encoding of the ASN.1 NULL element.
2370  *
2371  * output  Buffer to write into.
2372  * returns the number of bytes added to the buffer.
2373  */
2374 static int SetASNNull(byte* output)
2375 {
2376     output[0] = ASN_TAG_NULL;
2377     output[1] = 0;
2378 
2379     return 2;
2380 }
2381 #endif
2382 
2383 #ifndef NO_CERTS
2384 #ifndef WOLFSSL_ASN_TEMPLATE
2385 /* Get the DER/BER encoding of an ASN.1 BOOLEAN.
2386  *
2387  * input     Buffer holding DER/BER encoded data.
2388  * inOutIdx  Current index into buffer to parse.
2389  * maxIdx    Length of data in buffer.
2390  * returns BUFFER_E when there is not enough data to parse.
2391  *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
2392  *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
2393  */
2394 static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
2395 {
2396     word32 idx = *inOutIdx;
2397     byte   b;
2398 
2399     if ((idx + 3) > maxIdx)
2400         return BUFFER_E;
2401 
2402     b = input[idx++];
2403     if (b != ASN_BOOLEAN)
2404         return ASN_PARSE_E;
2405 
2406     if (input[idx++] != 1)
2407         return ASN_PARSE_E;
2408 
2409     b = input[idx++] != 0;
2410 
2411     *inOutIdx = idx;
2412     return b;
2413 }
2414 #endif
2415 #endif /* !NO_CERTS*/
2416 
2417 
2418 /* Decode the header of a BER/DER encoded OCTET STRING.
2419  *
2420  * @param [in]      input     Buffer holding DER/BER encoded data.
2421  * @param [in, out] inOutIdx  On in, starting index of header.
2422  *                            On out, end of parsed header.
2423  * @param [out]     len       Number of bytes in the ASN.1 data.
2424  * @param [in]      maxIdx    Length of data in buffer.
2425  * @return  Number of bytes in the ASN.1 data on success.
2426  * @return  BUFFER_E when there is not enough data to parse.
2427  * @return  ASN_PARSE_E when the tag is not a OCTET STRING or length is invalid.
2428  */
2429 int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2430 {
2431     return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
2432 }
2433 
2434 #ifndef WOLFSSL_ASN_TEMPLATE
2435 /* Get the DER/BER encoding of an ASN.1 INTEGER header.
2436  *
2437  * Removes the leading zero byte when found.
2438  *
2439  * input     Buffer holding DER/BER encoded data.
2440  * inOutIdx  Current index into buffer to parse.
2441  * len       The number of bytes in the ASN.1 data (excluding any leading zero).
2442  * maxIdx    Length of data in buffer.
2443  * returns BUFFER_E when there is not enough data to parse.
2444  *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
2445  *         or invalid use of or missing leading zero.
2446  *         Otherwise, 0 to indicate success.
2447  */
2448 static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
2449                      word32 maxIdx)
2450 {
2451     int    ret;
2452 
2453     ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
2454     if (ret < 0)
2455         return ret;
2456 
2457     if (*len > 0) {
2458 
2459 #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2460         /* check for invalid padding on negative integer.
2461          * c.f. X.690 (ISO/IEC 8825-2:2003 (E)) 10.4.6; RFC 5280 4.1
2462          */
2463         if (*len > 1) {
2464             if ((input[*inOutIdx] == 0xff) && (input[*inOutIdx + 1] & 0x80))
2465                 return ASN_PARSE_E;
2466         }
2467 #endif
2468 
2469         /* remove leading zero, unless there is only one 0x00 byte */
2470         if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
2471             (*inOutIdx)++;
2472             (*len)--;
2473 
2474 #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2475             if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
2476                 return ASN_PARSE_E;
2477 #endif
2478         }
2479     }
2480 
2481     return 0;
2482 }
2483 
2484 #ifndef NO_CERTS
2485 /* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2486  * 7 bits.
2487  *
2488  * input     Buffer holding DER/BER encoded data.
2489  * inOutIdx  Current index into buffer to parse.
2490  * maxIdx    Length of data in buffer.
2491  * returns BUFFER_E when there is not enough data to parse.
2492  *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2493  *         Otherwise, the 7-bit value.
2494  */
2495 static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2496 {
2497     word32 idx = *inOutIdx;
2498     byte   b;
2499 
2500     if ((idx + 3) > maxIdx)
2501         return BUFFER_E;
2502 
2503     if (GetASNTag(input, &idx, &b, maxIdx) != 0)
2504         return ASN_PARSE_E;
2505     if (b != ASN_INTEGER)
2506         return ASN_PARSE_E;
2507     if (input[idx++] != 1)
2508         return ASN_PARSE_E;
2509     b = input[idx++];
2510 
2511     *inOutIdx = idx;
2512     return b;
2513 }
2514 #endif /* !NO_CERTS */
2515 #endif /* !WOLFSSL_ASN_TEMPLATE */
2516 
2517 #if !defined(NO_DSA) && !defined(NO_SHA)
2518 static const char sigSha1wDsaName[] = "SHAwDSA";
2519 static const char sigSha256wDsaName[] = "SHA256wDSA";
2520 #endif /* NO_DSA */
2521 #ifndef NO_RSA
2522 #ifdef WOLFSSL_MD2
2523     static const char  sigMd2wRsaName[] = "md2WithRSAEncryption";
2524 #endif
2525 #ifndef NO_MD5
2526     static const char  sigMd5wRsaName[] = "md5WithRSAEncryption";
2527 #endif
2528 #ifndef NO_SHA
2529     static const char  sigSha1wRsaName[] = "sha1WithRSAEncryption";
2530 #endif
2531 #ifdef WOLFSSL_SHA224
2532     static const char sigSha224wRsaName[] = "sha224WithRSAEncryption";
2533 #endif
2534 #ifndef NO_SHA256
2535     static const char sigSha256wRsaName[] = "sha256WithRSAEncryption";
2536 #endif
2537 #ifdef WOLFSSL_SHA384
2538     static const char sigSha384wRsaName[] = "sha384WithRSAEncryption";
2539 #endif
2540 #ifdef WOLFSSL_SHA512
2541     static const char sigSha512wRsaName[] = "sha512WithRSAEncryption";
2542 #endif
2543 #ifdef WOLFSSL_SHA3
2544 #ifndef WOLFSSL_NOSHA3_224
2545     static const char sigSha3_224wRsaName[] = "sha3_224WithRSAEncryption";
2546 #endif
2547 #ifndef WOLFSSL_NOSHA3_256
2548     static const char sigSha3_256wRsaName[] = "sha3_256WithRSAEncryption";
2549 #endif
2550 #ifndef WOLFSSL_NOSHA3_384
2551     static const char sigSha3_384wRsaName[] = "sha3_384WithRSAEncryption";
2552 #endif
2553 #ifndef WOLFSSL_NOSHA3_512
2554     static const char sigSha3_512wRsaName[] = "sha3_512WithRSAEncryption";
2555 #endif
2556 #endif
2557 #endif /* NO_RSA */
2558 #ifdef HAVE_ECC
2559 #ifndef NO_SHA
2560     static const char sigSha1wEcdsaName[] = "SHAwECDSA";
2561 #endif
2562 #ifdef WOLFSSL_SHA224
2563     static const char sigSha224wEcdsaName[] = "SHA224wECDSA";
2564 #endif
2565 #ifndef NO_SHA256
2566     static const char sigSha256wEcdsaName[] = "SHA256wECDSA";
2567 #endif
2568 #ifdef WOLFSSL_SHA384
2569     static const char sigSha384wEcdsaName[] = "SHA384wECDSA";
2570 #endif
2571 #ifdef WOLFSSL_SHA512
2572     static const char sigSha512wEcdsaName[] = "SHA512wECDSA";
2573 #endif
2574 #ifdef WOLFSSL_SHA3
2575 #ifndef WOLFSSL_NOSHA3_224
2576     static const char sigSha3_224wEcdsaName[] = "SHA3_224wECDSA";
2577 #endif
2578 #ifndef WOLFSSL_NOSHA3_256
2579     static const char sigSha3_256wEcdsaName[] = "SHA3_256wECDSA";
2580 #endif
2581 #ifndef WOLFSSL_NOSHA3_384
2582     static const char sigSha3_384wEcdsaName[] = "SHA3_384wECDSA";
2583 #endif
2584 #ifndef WOLFSSL_NOSHA3_512
2585     static const char sigSha3_512wEcdsaName[] = "SHA3_512wECDSA";
2586 #endif
2587 #endif
2588 #endif /* HAVE_ECC */
2589 static const char sigUnknownName[] = "Unknown";
2590 
2591 
2592 /* Get the human readable string for a signature type
2593  *
2594  * oid  Oid value for signature
2595  */
2596 const char* GetSigName(int oid) {
2597     switch (oid) {
2598     #if !defined(NO_DSA) && !defined(NO_SHA)
2599         case CTC_SHAwDSA:
2600             return sigSha1wDsaName;
2601         case CTC_SHA256wDSA:
2602             return sigSha256wDsaName;
2603     #endif /* NO_DSA && NO_SHA */
2604     #ifndef NO_RSA
2605         #ifdef WOLFSSL_MD2
2606         case CTC_MD2wRSA:
2607             return sigMd2wRsaName;
2608         #endif
2609         #ifndef NO_MD5
2610         case CTC_MD5wRSA:
2611             return sigMd5wRsaName;
2612         #endif
2613         #ifndef NO_SHA
2614         case CTC_SHAwRSA:
2615             return sigSha1wRsaName;
2616         #endif
2617         #ifdef WOLFSSL_SHA224
2618         case CTC_SHA224wRSA:
2619             return sigSha224wRsaName;
2620         #endif
2621         #ifndef NO_SHA256
2622         case CTC_SHA256wRSA:
2623             return sigSha256wRsaName;
2624         #endif
2625         #ifdef WOLFSSL_SHA384
2626         case CTC_SHA384wRSA:
2627             return sigSha384wRsaName;
2628         #endif
2629         #ifdef WOLFSSL_SHA512
2630         case CTC_SHA512wRSA:
2631             return sigSha512wRsaName;
2632         #endif
2633         #ifdef WOLFSSL_SHA3
2634         #ifndef WOLFSSL_NOSHA3_224
2635         case CTC_SHA3_224wRSA:
2636             return sigSha3_224wRsaName;
2637         #endif
2638         #ifndef WOLFSSL_NOSHA3_256
2639         case CTC_SHA3_256wRSA:
2640             return sigSha3_256wRsaName;
2641         #endif
2642         #ifndef WOLFSSL_NOSHA3_384
2643         case CTC_SHA3_384wRSA:
2644             return sigSha3_384wRsaName;
2645         #endif
2646         #ifndef WOLFSSL_NOSHA3_512
2647         case CTC_SHA3_512wRSA:
2648             return sigSha3_512wRsaName;
2649         #endif
2650         #endif
2651     #endif /* NO_RSA */
2652     #ifdef HAVE_ECC
2653         #ifndef NO_SHA
2654         case CTC_SHAwECDSA:
2655             return sigSha1wEcdsaName;
2656         #endif
2657         #ifdef WOLFSSL_SHA224
2658         case CTC_SHA224wECDSA:
2659             return sigSha224wEcdsaName;
2660         #endif
2661         #ifndef NO_SHA256
2662         case CTC_SHA256wECDSA:
2663             return sigSha256wEcdsaName;
2664         #endif
2665         #ifdef WOLFSSL_SHA384
2666         case CTC_SHA384wECDSA:
2667             return sigSha384wEcdsaName;
2668         #endif
2669         #ifdef WOLFSSL_SHA512
2670         case CTC_SHA512wECDSA:
2671             return sigSha512wEcdsaName;
2672         #endif
2673         #ifdef WOLFSSL_SHA3
2674         #ifndef WOLFSSL_NOSHA3_224
2675         case CTC_SHA3_224wECDSA:
2676             return sigSha3_224wEcdsaName;
2677         #endif
2678         #ifndef WOLFSSL_NOSHA3_256
2679         case CTC_SHA3_256wECDSA:
2680             return sigSha3_256wEcdsaName;
2681         #endif
2682         #ifndef WOLFSSL_NOSHA3_384
2683         case CTC_SHA3_384wECDSA:
2684             return sigSha3_384wEcdsaName;
2685         #endif
2686         #ifndef WOLFSSL_NOSHA3_512
2687         case CTC_SHA3_512wECDSA:
2688             return sigSha3_512wEcdsaName;
2689         #endif
2690         #endif
2691     #endif /* HAVE_ECC */
2692         default:
2693             return sigUnknownName;
2694     }
2695 }
2696 
2697 
2698 #if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7) || \
2699     defined(OPENSSL_EXTRA)
2700 #if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
2701    (!defined(NO_RSA) && \
2702         (defined(WOLFSSL_CERT_GEN) || \
2703         ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
2704 /* Set the DER/BER encoding of the ASN.1 INTEGER header.
2705  *
2706  * When output is NULL, calculate the header length only.
2707  *
2708  * @param [in]  len        Length of INTEGER data in bytes.
2709  * @param [in]  firstByte  First byte of data, most significant byte of integer,
2710  *                         to encode.
2711  * @param [out] output     Buffer to write into.
2712  * @return  Number of bytes added to the buffer.
2713  */
2714 int SetASNInt(int len, byte firstByte, byte* output)
2715 {
2716     word32 idx = 0;
2717 
2718     if (output) {
2719         /* Write out tag. */
2720         output[idx] = ASN_INTEGER;
2721     }
2722     /* Step over tag. */
2723     idx += ASN_TAG_SZ;
2724     /* Check if first byte has top bit set in which case a 0 is needed to
2725      * maintain positive value. */
2726     if (firstByte & 0x80) {
2727         /* Add pre-prepended byte to length of data in INTEGER. */
2728         len++;
2729     }
2730     /* Encode length - passing NULL for output will not encode. */
2731     idx += SetLength(len, output ? output + idx : NULL);
2732     /* Put out pre-pended 0 as well. */
2733     if (firstByte & 0x80) {
2734         if (output) {
2735             /* Write out 0 byte. */
2736             output[idx] = 0x00;
2737         }
2738         /* Update index. */
2739         idx++;
2740     }
2741 
2742     /* Return index after header. */
2743     return idx;
2744 }
2745 #endif
2746 #endif
2747 
2748 #ifndef WOLFSSL_ASN_TEMPLATE
2749 #if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \
2750     !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \
2751     (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
2752     defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
2753 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
2754  * The number is assumed to be positive.
2755  *
2756  * n       Multi-precision integer to encode.
2757  * maxSz   Maximum size of the encoded integer.
2758  *         A negative value indicates no check of length requested.
2759  * output  Buffer to write into.
2760  * returns BUFFER_E when the data is too long for the buffer.
2761  *         MP_TO_E when encoding the integer fails.
2762  *         Otherwise, the number of bytes added to the buffer.
2763  */
2764 static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
2765 {
2766     int idx = 0;
2767     int leadingBit;
2768     int length;
2769     int err;
2770 
2771     leadingBit = mp_leading_bit(n);
2772     length = mp_unsigned_bin_size(n);
2773     if (maxSz >= 0 && (1 + length + (leadingBit ? 1 : 0)) > maxSz)
2774         return BUFFER_E;
2775     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
2776     if (maxSz >= 0 && (idx + length) > maxSz)
2777         return BUFFER_E;
2778 
2779     if (output) {
2780         err = mp_to_unsigned_bin(n, output + idx);
2781         if (err != MP_OKAY)
2782             return MP_TO_E;
2783     }
2784     idx += length;
2785 
2786     return idx;
2787 }
2788 #endif
2789 
2790 #if !defined(NO_RSA) && defined(HAVE_USER_RSA) && \
2791     (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
2792 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
2793  * an RSA key.
2794  * The number is assumed to be positive.
2795  *
2796  * n       Multi-precision integer to encode.
2797  * output  Buffer to write into.
2798  * returns BUFFER_E when the data is too long for the buffer.
2799  *         MP_TO_E when encoding the integer fails.
2800  *         Otherwise, the number of bytes added to the buffer.
2801  */
2802 static int SetASNIntRSA(void* n, byte* output)
2803 {
2804     int idx = 0;
2805     int leadingBit;
2806     int length;
2807     int err;
2808 
2809     leadingBit = wc_Rsa_leading_bit(n);
2810     length = wc_Rsa_unsigned_bin_size(n);
2811     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
2812     if ((idx + length) > MAX_RSA_INT_SZ)
2813         return BUFFER_E;
2814 
2815     if (output) {
2816         err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
2817         if (err != MP_OKAY)
2818             return MP_TO_E;
2819     }
2820     idx += length;
2821 
2822     return idx;
2823 }
2824 #endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
2825 #endif /* !WOLFSSL_ASN_TEMPLATE */
2826 
2827 #ifdef WOLFSSL_ASN_TEMPLATE
2828 /* ASN.1 template for an INTEGER. */
2829 static const ASNItem intASN[] = {
2830 /* INT */ { 0, ASN_INTEGER, 0, 0, 0 }
2831 };
2832 enum {
2833     INTASN_IDX_INT = 0
2834 };
2835 
2836 /* Number of items in ASN.1 template for an INTEGER. */
2837 #define intASN_Length (sizeof(intASN) / sizeof(ASNItem))
2838 #endif /* WOLFSSL_ASN_TEMPLATE */
2839 
2840 /* Windows header clash for WinCE using GetVersion */
2841 /* Decode Version - one byte INTEGER.
2842  *
2843  * @param [in]      input     Buffer of BER data.
2844  * @param [in, out] inOutIdx  On in, start of encoded Version.
2845  *                            On out, start of next encode ASN.1 item.
2846  * @param [out]     version   Number encoded in INTEGER.
2847  * @param [in]      maxIdx    Maximum index of data in buffer.
2848  * @return  0 on success.
2849  * @return  ASN_PARSE_E when encoding is invalid.
2850  * @return  BUFFER_E when data in buffer is too small.
2851  * @return  ASN_EXPECT_0_E when the most significant bit is set.
2852  */
2853 int GetMyVersion(const byte* input, word32* inOutIdx,
2854                                int* version, word32 maxIdx)
2855 {
2856 #ifndef WOLFSSL_ASN_TEMPLATE
2857     word32 idx = *inOutIdx;
2858     byte   tag;
2859 
2860     if ((idx + MIN_VERSION_SZ) > maxIdx)
2861         return ASN_PARSE_E;
2862 
2863     if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2864         return ASN_PARSE_E;
2865 
2866     if (tag != ASN_INTEGER)
2867         return ASN_PARSE_E;
2868 
2869     if (input[idx++] != 0x01)
2870         return ASN_VERSION_E;
2871 
2872     *version  = input[idx++];
2873     *inOutIdx = idx;
2874 
2875     return *version;
2876 #else
2877     ASNGetData dataASN[intASN_Length];
2878     int ret;
2879     byte num;
2880 
2881     /* Clear dynamic data and set the version number variable. */
2882     XMEMSET(dataASN, 0, sizeof(dataASN));
2883     GetASN_Int8Bit(&dataASN[INTASN_IDX_INT], &num);
2884     /* Decode the version (INTEGER). */
2885     ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
2886                        maxIdx);
2887     if (ret == 0) {
2888         /* Return version through variable and return value. */
2889         *version = num;
2890         ret = num;
2891     }
2892     return ret;
2893 #endif /* WOLFSSL_ASN_TEMPLATE */
2894 }
2895 
2896 
2897 #ifndef NO_PWDBASED
2898 /* Decode small integer, 32 bits or less.
2899  *
2900  * @param [in]      input     Buffer of BER data.
2901  * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
2902  *                            On out, start of next encode ASN.1 item.
2903  * @param [out]     number    Number encoded in INTEGER.
2904  * @param [in]      maxIdx    Maximum index of data in buffer.
2905  * @return  0 on success.
2906  * @return  ASN_PARSE_E when encoding is invalid.
2907  * @return  BUFFER_E when data in buffer is too small.
2908  * @return  ASN_EXPECT_0_E when the most significant bit is set.
2909  */
2910 int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
2911 {
2912 #ifndef WOLFSSL_ASN_TEMPLATE
2913     word32 idx = *inOutIdx;
2914     word32 len;
2915     byte   tag;
2916 
2917     *number = 0;
2918 
2919     /* check for type and length bytes */
2920     if ((idx + 2) > maxIdx)
2921         return BUFFER_E;
2922 
2923     if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2924         return ASN_PARSE_E;
2925 
2926     if (tag != ASN_INTEGER)
2927         return ASN_PARSE_E;
2928 
2929     len = input[idx++];
2930     if (len > 4)
2931         return ASN_PARSE_E;
2932 
2933     if (len + idx > maxIdx)
2934         return ASN_PARSE_E;
2935 
2936     while (len--) {
2937         *number  = *number << 8 | input[idx++];
2938     }
2939 
2940     *inOutIdx = idx;
2941 
2942     return *number;
2943 #else
2944     ASNGetData dataASN[intASN_Length];
2945     int ret;
2946     word32 num;
2947 
2948     /* Clear dynamic data and set the 32-bit number variable. */
2949     XMEMSET(dataASN, 0, sizeof(dataASN));
2950     GetASN_Int32Bit(&dataASN[INTASN_IDX_INT], &num);
2951     /* Decode the short int (INTEGER). */
2952     ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
2953                        maxIdx);
2954     if (ret == 0) {
2955         /* Return number through variable and return value. */
2956         *number = num;
2957         ret = num;
2958     }
2959     return ret;
2960 #endif
2961 }
2962 
2963 
2964 #if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS12)
2965 /* Set small integer, 32 bits or less. DER encoding with no leading 0s
2966  * returns total amount written including ASN tag and length byte on success */
2967 int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)
2968 {
2969     word32 idx = *inOutIdx;
2970     word32 len = 0;
2971     int    i;
2972     byte ar[MAX_LENGTH_SZ];
2973 
2974     /* check for room for type and length bytes */
2975     if ((idx + 2) > maxIdx)
2976         return BUFFER_E;
2977 
2978     input[idx++] = ASN_INTEGER;
2979     idx++; /* place holder for length byte */
2980     if (MAX_LENGTH_SZ + idx > maxIdx)
2981         return ASN_PARSE_E;
2982 
2983     /* find first non zero byte */
2984     XMEMSET(ar, 0, MAX_LENGTH_SZ);
2985     c32toa(number, ar);
2986     for (i = 0; i < MAX_LENGTH_SZ; i++) {
2987         if (ar[i] != 0) {
2988             break;
2989         }
2990     }
2991 
2992     /* handle case of 0 */
2993     if (i == MAX_LENGTH_SZ) {
2994         input[idx++] = 0; len++;
2995     }
2996 
2997     for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
2998         input[idx++] = ar[i]; len++;
2999     }
3000 
3001     /* jump back to beginning of input buffer using unaltered inOutIdx value
3002      * and set number of bytes for integer, then update the index value */
3003     input[*inOutIdx + 1] = (byte)len;
3004     *inOutIdx = idx;
3005 
3006     return len + 2; /* size of integer bytes plus ASN TAG and length byte */
3007 }
3008 #endif /* !WOLFSSL_ASN_TEMPLATE */
3009 #endif /* !NO_PWDBASED */
3010 
3011 #ifndef WOLFSSL_ASN_TEMPLATE
3012 /* May not have one, not an error */
3013 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
3014                               word32 maxIdx)
3015 {
3016     word32 idx = *inOutIdx;
3017     byte tag;
3018 
3019     WOLFSSL_ENTER("GetExplicitVersion");
3020 
3021     if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3022         return ASN_PARSE_E;
3023 
3024     if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3025         int ret;
3026 
3027         *inOutIdx = ++idx;  /* skip header */
3028         ret = GetMyVersion(input, inOutIdx, version, maxIdx);
3029         if (ret >= 0) {
3030             /* check if version is expected value rfc 5280 4.1 {0, 1, 2} */
3031             if (*version > MAX_X509_VERSION || *version < MIN_X509_VERSION) {
3032                 WOLFSSL_MSG("Unexpected certificate version");
3033                 ret = ASN_VERSION_E;
3034             }
3035         }
3036         return ret;
3037     }
3038 
3039     /* go back as is */
3040     *version = 0;
3041 
3042     return 0;
3043 }
3044 #endif
3045 
3046 /* Decode small integer, 32 bits or less.
3047  *
3048  * mp_int is initialized.
3049  *
3050  * @param [out]     mpi       mp_int to hold number.
3051  * @param [in]      input     Buffer of BER data.
3052  * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3053  *                            On out, start of next encode ASN.1 item.
3054  * @param [in]      maxIdx    Maximum index of data in buffer.
3055  * @return  0 on success.
3056  * @return  ASN_PARSE_E when encoding is invalid.
3057  * @return  BUFFER_E when data in buffer is too small.
3058  * @return  ASN_EXPECT_0_E when the most significant bit is set.
3059  * @return  MP_INIT_E when the unable to initialize an mp_int.
3060  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
3061  */
3062 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
3063 {
3064 #ifndef WOLFSSL_ASN_TEMPLATE
3065     word32 idx = *inOutIdx;
3066     int    ret;
3067     int    length;
3068 
3069     ret = GetASNInt(input, &idx, &length, maxIdx);
3070     if (ret != 0)
3071         return ret;
3072 
3073     if (mp_init(mpi) != MP_OKAY)
3074         return MP_INIT_E;
3075 
3076     if (mp_read_unsigned_bin(mpi, input + idx, length) != 0) {
3077         mp_clear(mpi);
3078         return ASN_GETINT_E;
3079     }
3080 
3081 #ifdef HAVE_WOLF_BIGINT
3082     if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3083         mp_clear(mpi);
3084         return ASN_GETINT_E;
3085     }
3086 #endif /* HAVE_WOLF_BIGINT */
3087 
3088     *inOutIdx = idx + length;
3089 
3090     return 0;
3091 #else
3092     ASNGetData dataASN[intASN_Length];
3093 
3094     /* Clear dynamic data and set the mp_int to fill with value. */
3095     XMEMSET(dataASN, 0, sizeof(dataASN));
3096     GetASN_MP_PosNeg(&dataASN[INTASN_IDX_INT], mpi);
3097     /* Decode the big number (INTEGER). */
3098     return GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3099                         maxIdx);
3100 #endif
3101 }
3102 
3103 #ifndef WOLFSSL_ASN_TEMPLATE
3104 #if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
3105     || defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DSA))
3106 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || !defined(NO_DSA)
3107 static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
3108 {
3109     word32 idx = *inOutIdx;
3110     int    ret;
3111     int    length;
3112 
3113     ret = GetASNInt(input, &idx, &length, maxIdx);
3114     if (ret != 0)
3115         return ret;
3116 
3117     *inOutIdx = idx + length;
3118 
3119     return 0;
3120 }
3121 #endif
3122 #endif
3123 #endif /* !WOLFSSL_ASN_TEMPLATE */
3124 
3125 #ifdef WOLFSSL_ASN_TEMPLATE
3126 /* ASN.1 template for a BIT_STRING. */
3127 static const ASNItem bitStringASN[] = {
3128 /* BIT_STR */ { 0, ASN_BIT_STRING, 0, 1, 0 }
3129 };
3130 enum {
3131     BITSTRINGASN_IDX_BIT_STR = 0
3132 };
3133 
3134 /* Number of items in ASN.1 template for a BIT_STRING. */
3135 #define bitStringASN_Length (sizeof(bitStringASN) / sizeof(ASNItem))
3136 #endif
3137 
3138 /* Decode and check the BIT_STRING is valid. Return length and unused bits.
3139  *
3140  * @param [in]      input       Buffer holding BER encoding.
3141  * @param [in, out] inOutIdx    On in, start of BIT_STRING.
3142  *                              On out, start of ASN.1 item after BIT_STRING.
3143  * @param [out]     len         Length of BIT_STRING data.
3144  * @param [in]      maxIdx      Maximum index of data in buffer.
3145  * @param [in]      zeroBits    Indicates whether zero unused bits is expected.
3146  * @param [in]      unusedBits  Number of unused bits in last byte.
3147  * @return  0 on success.
3148  * @return  ASN_PARSE_E when encoding is invalid.
3149  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
3150  * @return  BUFFER_E when data in buffer is too small.
3151  * @return  ASN_EXPECT_0_E when unused bits is not zero when expected.
3152  */
3153 int CheckBitString(const byte* input, word32* inOutIdx, int* len,
3154                           word32 maxIdx, int zeroBits, byte* unusedBits)
3155 {
3156 #ifndef WOLFSSL_ASN_TEMPLATE
3157     word32 idx = *inOutIdx;
3158     int    length;
3159     byte   b;
3160 
3161     if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
3162         return ASN_BITSTR_E;
3163     }
3164 
3165     if (b != ASN_BIT_STRING) {
3166         return ASN_BITSTR_E;
3167     }
3168 
3169     if (GetLength(input, &idx, &length, maxIdx) < 0)
3170         return ASN_PARSE_E;
3171 
3172     /* extra sanity check that length is greater than 0 */
3173     if (length <= 0) {
3174         WOLFSSL_MSG("Error length was 0 in CheckBitString");
3175         return BUFFER_E;
3176     }
3177 
3178     if (idx + 1 > maxIdx) {
3179         WOLFSSL_MSG("Attempted buffer read larger than input buffer");
3180         return BUFFER_E;
3181     }
3182 
3183     b = input[idx];
3184     if (zeroBits && b != 0x00)
3185         return ASN_EXPECT_0_E;
3186     if (b >= 0x08)
3187         return ASN_PARSE_E;
3188     if (b != 0) {
3189         if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
3190             return ASN_PARSE_E;
3191     }
3192     idx++;
3193     length--; /* length has been checked for greater than 0 */
3194 
3195     *inOutIdx = idx;
3196     if (len != NULL)
3197         *len = length;
3198     if (unusedBits != NULL)
3199         *unusedBits = b;
3200 
3201     return 0;
3202 #else
3203     ASNGetData dataASN[bitStringASN_Length];
3204     int ret;
3205     int bits;
3206 
3207     /* Parse BIT_STRING and check validity of unused bits. */
3208     XMEMSET(dataASN, 0, sizeof(dataASN));
3209     /* Decode BIT_STRING. */
3210     ret = GetASN_Items(bitStringASN, dataASN, bitStringASN_Length, 0, input,
3211             inOutIdx, maxIdx);
3212     if (ret == 0) {
3213         /* Get unused bits from dynamic ASN.1 data. */
3214         bits = GetASNItem_UnusedBits(dataASN[BITSTRINGASN_IDX_BIT_STR]);
3215         /* Check unused bits is 0 when expected. */
3216         if (zeroBits && (bits != 0)) {
3217             ret = ASN_EXPECT_0_E;
3218         }
3219     }
3220     if (ret == 0) {
3221         /* Return length of data and unused bits if required. */
3222         if (len != NULL) {
3223             *len = dataASN[BITSTRINGASN_IDX_BIT_STR].data.ref.length;
3224         }
3225         if (unusedBits != NULL) {
3226             *unusedBits = bits;
3227         }
3228     }
3229 
3230     return ret;
3231 #endif
3232 }
3233 
3234 /* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or
3235  * KeyGen) */
3236 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
3237      (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3238       defined(OPENSSL_EXTRA))) || \
3239     (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
3240     ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
3241      (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3242       defined(OPENSSL_EXTRA))) || \
3243     (defined(WC_ENABLE_ASYM_KEY_EXPORT) && !defined(NO_CERT)) || \
3244     (!defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN))
3245 
3246 /* Set the DER/BER encoding of the ASN.1 BIT STRING header.
3247  *
3248  * When output is NULL, calculate the header length only.
3249  *
3250  * @param [in]  len         Length of BIT STRING data.
3251  *                          That is, the number of least significant zero bits
3252  *                          before a one.
3253  *                          The last byte is the most-significant non-zero byte
3254  *                          of a number.
3255  * @param [out] output      Buffer to write into.
3256  * @return  Number of bytes added to the buffer.
3257  */
3258 word32 SetBitString(word32 len, byte unusedBits, byte* output)
3259 {
3260     word32 idx = 0;
3261 
3262     if (output) {
3263         /* Write out tag. */
3264         output[idx] = ASN_BIT_STRING;
3265     }
3266     /* Step over tag. */
3267     idx += ASN_TAG_SZ;
3268 
3269     /* Encode length - passing NULL for output will not encode.
3270      * Add one to length for unused bits. */
3271     idx += SetLength(len + 1, output ? output + idx : NULL);
3272     if (output) {
3273         /* Write out unused bits. */
3274         output[idx] = unusedBits;
3275     }
3276     /* Skip over unused bits. */
3277     idx++;
3278 
3279     /* Return index after header. */
3280     return idx;
3281 }
3282 #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
3283 
3284 #ifdef ASN_BER_TO_DER
3285 /* Convert BER to DER */
3286 
3287 /* Pull informtation from the ASN.1 BER encoded item header */
3288 static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
3289                         byte* pTag, word32* pLen, int* indef)
3290 {
3291     int len = 0;
3292     byte tag;
3293     word32 i = *idx;
3294 
3295     *indef = 0;
3296 
3297     /* Check there is enough data for a minimal header */
3298     if (i + 2 > maxIdx) {
3299         return ASN_PARSE_E;
3300     }
3301 
3302     /* Retrieve tag */
3303     tag = data[i++];
3304 
3305     /* Indefinite length handled specially */
3306     if (data[i] == ASN_INDEF_LENGTH) {
3307         /* Check valid tag for indefinite */
3308         if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
3309             return ASN_PARSE_E;
3310         }
3311         i++;
3312         *indef = 1;
3313     }
3314     else if (GetLength(data, &i, &len, maxIdx) < 0) {
3315         return ASN_PARSE_E;
3316     }
3317 
3318     /* Return tag, length and index after BER item header */
3319     *pTag = tag;
3320     *pLen = len;
3321     *idx = i;
3322     return 0;
3323 }
3324 
3325 #ifndef INDEF_ITEMS_MAX
3326 #define INDEF_ITEMS_MAX       20
3327 #endif
3328 
3329 /* Indef length item data */
3330 typedef struct Indef {
3331     word32 start;
3332     int depth;
3333     int headerLen;
3334     word32 len;
3335 } Indef;
3336 
3337 /* Indef length items */
3338 typedef struct IndefItems
3339 {
3340     Indef len[INDEF_ITEMS_MAX];
3341     int cnt;
3342     int idx;
3343     int depth;
3344 } IndefItems;
3345 
3346 
3347 /* Get header length of current item */
3348 static int IndefItems_HeaderLen(IndefItems* items)
3349 {
3350     return items->len[items->idx].headerLen;
3351 }
3352 
3353 /* Get data length of current item */
3354 static word32 IndefItems_Len(IndefItems* items)
3355 {
3356     return items->len[items->idx].len;
3357 }
3358 
3359 /* Add a indefinite length item */
3360 static int IndefItems_AddItem(IndefItems* items, word32 start)
3361 {
3362     int ret = 0;
3363     int i;
3364 
3365     if (items->cnt == INDEF_ITEMS_MAX) {
3366         ret = MEMORY_E;
3367     }
3368     else {
3369         i = items->cnt++;
3370         items->len[i].start = start;
3371         items->len[i].depth = items->depth++;
3372         items->len[i].headerLen = 1;
3373         items->len[i].len = 0;
3374         items->idx = i;
3375     }
3376 
3377     return ret;
3378 }
3379 
3380 /* Increase data length of current item */
3381 static void IndefItems_AddData(IndefItems* items, word32 length)
3382 {
3383     items->len[items->idx].len += length;
3384 }
3385 
3386 /* Update header length of current item to reflect data length */
3387 static void IndefItems_UpdateHeaderLen(IndefItems* items)
3388 {
3389     items->len[items->idx].headerLen +=
3390                                     SetLength(items->len[items->idx].len, NULL);
3391 }
3392 
3393 /* Go to indefinite parent of current item */
3394 static void IndefItems_Up(IndefItems* items)
3395 {
3396     int i;
3397     int depth = items->len[items->idx].depth - 1;
3398 
3399     for (i = items->cnt - 1; i >= 0; i--) {
3400         if (items->len[i].depth == depth) {
3401             break;
3402         }
3403     }
3404     items->idx = i;
3405     items->depth = depth + 1;
3406 }
3407 
3408 /* Calculate final length by adding length of indefinite child items */
3409 static void IndefItems_CalcLength(IndefItems* items)
3410 {
3411     int i;
3412     int idx = items->idx;
3413 
3414     for (i = idx + 1; i < items->cnt; i++) {
3415         if (items->len[i].depth == items->depth) {
3416             items->len[idx].len += items->len[i].headerLen;
3417             items->len[idx].len += items->len[i].len;
3418         }
3419     }
3420     items->len[idx].headerLen += SetLength(items->len[idx].len, NULL);
3421 }
3422 
3423 /* Add more data to indefinite length item */
3424 static void IndefItems_MoreData(IndefItems* items, word32 length)
3425 {
3426     if (items->cnt > 0 && items->idx >= 0) {
3427         items->len[items->idx].len += length;
3428     }
3429 }
3430 
3431 /* Convert a BER encoding with indefinite length items to DER.
3432  *
3433  * ber    BER encoded data.
3434  * berSz  Length of BER encoded data.
3435  * der    Buffer to hold DER encoded version of data.
3436  *        NULL indicates only the length is required.
3437  * derSz  The size of the buffer to hold the DER encoded data.
3438  *        Will be set if der is NULL, otherwise the value is checked as der is
3439  *        filled.
3440  * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
3441  * derSz are NULL.
3442  */
3443 int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
3444 {
3445     int ret = 0;
3446     word32 i, j;
3447 #ifdef WOLFSSL_SMALL_STACK
3448     IndefItems* indefItems = NULL;
3449 #else
3450     IndefItems indefItems[1];
3451 #endif
3452     byte tag, basic;
3453     word32 length;
3454     int indef;
3455 
3456     if (ber == NULL || derSz == NULL)
3457         return BAD_FUNC_ARG;
3458 
3459 #ifdef WOLFSSL_SMALL_STACK
3460     indefItems = (IndefItems *)XMALLOC(sizeof(IndefItems), NULL,
3461                                                        DYNAMIC_TYPE_TMP_BUFFER);
3462     if (indefItems == NULL) {
3463         ret = MEMORY_E;
3464         goto end;
3465     }
3466 #endif
3467 
3468     XMEMSET(indefItems, 0, sizeof(*indefItems));
3469 
3470     /* Calculate indefinite item lengths */
3471     for (i = 0; i < berSz; ) {
3472         word32 start = i;
3473 
3474         /* Get next BER item */
3475         ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3476         if (ret != 0) {
3477             goto end;
3478         }
3479 
3480         if (indef) {
3481             /* Indefinite item - add to list */
3482             ret = IndefItems_AddItem(indefItems, i);
3483             if (ret != 0) {
3484                 goto end;
3485             }
3486 
3487             if ((tag & 0xC0) == 0 &&
3488                 tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3489                 tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3490                 /* Constructed basic type - get repeating tag */
3491                 basic = tag & (~ASN_CONSTRUCTED);
3492 
3493                 /* Add up lengths of each item below */
3494                 for (; i < berSz; ) {
3495                     /* Get next BER_item */
3496                     ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3497                     if (ret != 0) {
3498                         goto end;
3499                     }
3500 
3501                     /* End of content closes item */
3502                     if (tag == ASN_EOC) {
3503                         /* Must be zero length */
3504                         if (length != 0) {
3505                             ret = ASN_PARSE_E;
3506                             goto end;
3507                         }
3508                         break;
3509                     }
3510 
3511                     /* Must not be indefinite and tag must match parent */
3512                     if (indef || tag != basic) {
3513                         ret = ASN_PARSE_E;
3514                         goto end;
3515                     }
3516 
3517                     /* Add to length */
3518                     IndefItems_AddData(indefItems, length);
3519                     /* Skip data */
3520                     i += length;
3521                 }
3522 
3523                 /* Ensure we got an EOC and not end of data */
3524                 if (tag != ASN_EOC) {
3525                     ret = ASN_PARSE_E;
3526                     goto end;
3527                 }
3528 
3529                 /* Set the header length to include the length field */
3530                 IndefItems_UpdateHeaderLen(indefItems);
3531                 /* Go to indefinte parent item */
3532                 IndefItems_Up(indefItems);
3533             }
3534         }
3535         else if (tag == ASN_EOC) {
3536             /* End-of-content must be 0 length */
3537             if (length != 0) {
3538                 ret = ASN_PARSE_E;
3539                 goto end;
3540             }
3541             /* Check there is an item to close - missing EOC */
3542             if (indefItems->depth == 0) {
3543                 ret = ASN_PARSE_E;
3544                 goto end;
3545             }
3546 
3547             /* Finish calculation of data length for indefinite item */
3548             IndefItems_CalcLength(indefItems);
3549             /* Go to indefinte parent item */
3550             IndefItems_Up(indefItems);
3551         }
3552         else {
3553             /* Known length item to add in - make sure enough data for it */
3554             if (i + length > berSz) {
3555                 ret = ASN_PARSE_E;
3556                 goto end;
3557             }
3558 
3559             /* Include all data - can't have indefinite inside definite */
3560             i += length;
3561             /* Add entire item to current indefinite item */
3562             IndefItems_MoreData(indefItems, i - start);
3563         }
3564     }
3565     /* Check we had a EOC for each indefinite item */
3566     if (indefItems->depth != 0) {
3567         ret = ASN_PARSE_E;
3568         goto end;
3569     }
3570 
3571     /* Write out DER */
3572 
3573     j = 0;
3574     /* Reset index */
3575     indefItems->idx = 0;
3576     for (i = 0; i < berSz; ) {
3577         word32 start = i;
3578 
3579         /* Get item - checked above */
3580         (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3581         if (indef) {
3582             if (der != NULL) {
3583                 /* Check enough space for header */
3584                 if (j + IndefItems_HeaderLen(indefItems) > *derSz) {
3585                     ret = BUFFER_E;
3586                     goto end;
3587                 }
3588 
3589                 if ((tag & 0xC0) == 0 &&
3590                     tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3591                     tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3592                     /* Remove constructed tag for basic types */
3593                     tag &= ~ASN_CONSTRUCTED;
3594                 }
3595                 /* Add tag and length */
3596                 der[j] = tag;
3597                 (void)SetLength(IndefItems_Len(indefItems), der + j + 1);
3598             }
3599             /* Add header length of indefinite item */
3600             j += IndefItems_HeaderLen(indefItems);
3601 
3602             if ((tag & 0xC0) == 0 &&
3603                 tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3604                 tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3605                 /* For basic type - get each child item and add data */
3606                 for (; i < berSz; ) {
3607                     (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3608                     if (tag == ASN_EOC) {
3609                         break;
3610                     }
3611                     if (der != NULL) {
3612                         if (j + length > *derSz) {
3613                             ret = BUFFER_E;
3614                             goto end;
3615                         }
3616                         XMEMCPY(der + j, ber + i, length);
3617                     }
3618                     j += length;
3619                     i += length;
3620                 }
3621             }
3622 
3623             /* Move to next indef item in list */
3624             indefItems->idx++;
3625         }
3626         else if (tag == ASN_EOC) {
3627             /* End-Of-Content is not written out in DER */
3628         }
3629         else {
3630             /* Write out definite length item as is. */
3631             i += length;
3632             if (der != NULL) {
3633                 /* Ensure space for item */
3634                 if (j + i - start > *derSz) {
3635                     ret = BUFFER_E;
3636                     goto end;
3637                 }
3638                 /* Copy item as is */
3639                 XMEMCPY(der + j, ber + start, i - start);
3640             }
3641             j += i - start;
3642         }
3643     }
3644 
3645     /* Return the length of the DER encoded ASN.1 */
3646     *derSz = j;
3647     if (der == NULL) {
3648         ret = LENGTH_ONLY_E;
3649     }
3650 end:
3651 #ifdef WOLFSSL_SMALL_STACK
3652     if (indefItems != NULL) {
3653         XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3654     }
3655 #endif
3656     return ret;
3657 }
3658 #endif
3659 
3660 #ifndef WOLFSSL_ASN_TEMPLATE
3661 #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
3662 /* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
3663  *
3664  * val         16-bit value to encode.
3665  * output      Buffer to write into.
3666  * returns the number of bytes added to the buffer.
3667  */
3668 static word32 SetBitString16Bit(word16 val, byte* output)
3669 {
3670     word32 idx;
3671     int    len;
3672     byte   lastByte;
3673     byte   unusedBits = 0;
3674 
3675     if ((val >> 8) != 0) {
3676         len = 2;
3677         lastByte = (byte)(val >> 8);
3678     }
3679     else {
3680         len = 1;
3681         lastByte = (byte)val;
3682     }
3683 
3684     while (((lastByte >> unusedBits) & 0x01) == 0x00)
3685         unusedBits++;
3686 
3687     idx = SetBitString(len, unusedBits, output);
3688     output[idx++] = (byte)val;
3689     if (len > 1)
3690         output[idx++] = (byte)(val >> 8);
3691 
3692     return idx;
3693 }
3694 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_CERT_GEN */
3695 #endif /* !WOLFSSL_ASN_TEMPLATE */
3696 
3697 /* hashType */
3698 #ifdef WOLFSSL_MD2
3699     static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
3700 #endif
3701 #ifndef NO_MD5
3702     static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
3703 #endif
3704 #ifndef NO_SHA
3705     static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
3706 #endif
3707 #ifdef WOLFSSL_SHA224
3708     static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
3709 #endif
3710 #ifndef NO_SHA256
3711     static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
3712 #endif
3713 #ifdef WOLFSSL_SHA384
3714     static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
3715 #endif
3716 #ifdef WOLFSSL_SHA512
3717     static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
3718 #endif
3719 #ifdef WOLFSSL_SHA3
3720 #ifndef WOLFSSL_NOSHA3_224
3721     static const byte hashSha3_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 7};
3722 #endif /* WOLFSSL_NOSHA3_224 */
3723 #ifndef WOLFSSL_NOSHA3_256
3724     static const byte hashSha3_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 8};
3725 #endif /* WOLFSSL_NOSHA3_256 */
3726 #ifndef WOLFSSL_NOSHA3_384
3727     static const byte hashSha3_384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 9};
3728 #endif /* WOLFSSL_NOSHA3_384 */
3729 #ifndef WOLFSSL_NOSHA3_512
3730     static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
3731 #endif /* WOLFSSL_NOSHA3_512 */
3732 #endif /* WOLFSSL_SHA3 */
3733 
3734 /* hmacType */
3735 #ifndef NO_HMAC
3736     #ifdef WOLFSSL_SHA224
3737     static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
3738     #endif
3739     #ifndef NO_SHA256
3740     static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
3741     #endif
3742     #ifdef WOLFSSL_SHA384
3743     static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
3744     #endif
3745     #ifdef WOLFSSL_SHA512
3746     static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
3747     #endif
3748 #endif
3749 
3750 /* sigType */
3751 #if !defined(NO_DSA) && !defined(NO_SHA)
3752     static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
3753     static const byte sigSha256wDsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 2};
3754 #endif /* NO_DSA */
3755 #ifndef NO_RSA
3756     #ifdef WOLFSSL_MD2
3757     static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
3758     #endif
3759     #ifndef NO_MD5
3760     static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
3761     #endif
3762     #ifndef NO_SHA
3763     static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
3764     #endif
3765     #ifdef WOLFSSL_SHA224
3766     static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
3767     #endif
3768     #ifndef NO_SHA256
3769     static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
3770     #endif
3771     #ifdef WOLFSSL_SHA384
3772     static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
3773     #endif
3774     #ifdef WOLFSSL_SHA512
3775     static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
3776     #endif
3777     #ifdef WOLFSSL_SHA3
3778     #ifndef WOLFSSL_NOSHA3_224
3779     static const byte sigSha3_224wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 13};
3780     #endif
3781     #ifndef WOLFSSL_NOSHA3_256
3782     static const byte sigSha3_256wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 14};
3783     #endif
3784     #ifndef WOLFSSL_NOSHA3_384
3785     static const byte sigSha3_384wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 15};
3786     #endif
3787     #ifndef WOLFSSL_NOSHA3_512
3788     static const byte sigSha3_512wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 16};
3789     #endif
3790     #endif
3791 #endif /* NO_RSA */
3792 #ifdef HAVE_ECC
3793     #ifndef NO_SHA
3794     static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
3795     #endif
3796     #ifdef WOLFSSL_SHA224
3797     static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
3798     #endif
3799     #ifndef NO_SHA256
3800     static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
3801     #endif
3802     #ifdef WOLFSSL_SHA384
3803     static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
3804     #endif
3805     #ifdef WOLFSSL_SHA512
3806     static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
3807     #endif
3808     #ifdef WOLFSSL_SHA3
3809     #ifndef WOLFSSL_NOSHA3_224
3810     static const byte sigSha3_224wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 9};
3811     #endif
3812     #ifndef WOLFSSL_NOSHA3_256
3813     static const byte sigSha3_256wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 10};
3814     #endif
3815     #ifndef WOLFSSL_NOSHA3_384
3816     static const byte sigSha3_384wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 11};
3817     #endif
3818     #ifndef WOLFSSL_NOSHA3_512
3819     static const byte sigSha3_512wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 12};
3820     #endif
3821     #endif
3822 #endif /* HAVE_ECC */
3823 #ifdef HAVE_ED25519
3824     static const byte sigEd25519Oid[] = {43, 101, 112};
3825 #endif /* HAVE_ED25519 */
3826 #ifdef HAVE_ED448
3827     static const byte sigEd448Oid[] = {43, 101, 113};
3828 #endif /* HAVE_ED448 */
3829 #ifdef HAVE_PQC
3830     /* Falcon Level 1: 1 3 9999 3 1 */
3831     static const byte sigFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
3832 
3833     /* Falcon Level 5: 1 3 9999 3 4 */
3834     static const byte sigFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
3835 #endif /* HAVE_PQC */
3836 
3837 /* keyType */
3838 #ifndef NO_DSA
3839     static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
3840 #endif /* NO_DSA */
3841 #ifndef NO_RSA
3842     static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
3843 #endif /* NO_RSA */
3844 #ifdef HAVE_ECC
3845     static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
3846 #endif /* HAVE_ECC */
3847 #ifdef HAVE_ED25519
3848     static const byte keyEd25519Oid[] = {43, 101, 112};
3849 #endif /* HAVE_ED25519 */
3850 #ifdef HAVE_CURVE25519
3851     static const byte keyCurve25519Oid[] = {43, 101, 110};
3852 #endif
3853 #ifdef HAVE_ED448
3854     static const byte keyEd448Oid[] = {43, 101, 113};
3855 #endif /* HAVE_ED448 */
3856 #ifdef HAVE_CURVE448
3857     static const byte keyCurve448Oid[] = {43, 101, 111};
3858 #endif /* HAVE_CURVE448 */
3859 #ifndef NO_DH
3860     static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
3861 #endif /* !NO_DH */
3862 #ifdef HAVE_PQC
3863     /* Falcon Level 1: 1 3 9999 3 1 */
3864     static const byte keyFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
3865 
3866     /* Falcon Level 5: 1 3 9999 3 4 */
3867     static const byte keyFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
3868 #endif /* HAVE_PQC */
3869 
3870 /* curveType */
3871 #ifdef HAVE_ECC
3872     /* See "ecc_sets" table in ecc.c */
3873 #endif /* HAVE_ECC */
3874 
3875 #ifdef HAVE_AES_CBC
3876 /* blkType */
3877     #ifdef WOLFSSL_AES_128
3878     static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
3879     #endif
3880     #ifdef WOLFSSL_AES_192
3881     static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
3882     #endif
3883     #ifdef WOLFSSL_AES_256
3884     static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
3885     #endif
3886 #endif /* HAVE_AES_CBC */
3887 #ifdef HAVE_AESGCM
3888     #ifdef WOLFSSL_AES_128
3889     static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
3890     #endif
3891     #ifdef WOLFSSL_AES_192
3892     static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
3893     #endif
3894     #ifdef WOLFSSL_AES_256
3895     static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
3896     #endif
3897 #endif /* HAVE_AESGCM */
3898 #ifdef HAVE_AESCCM
3899     #ifdef WOLFSSL_AES_128
3900     static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
3901     #endif
3902     #ifdef WOLFSSL_AES_192
3903     static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
3904     #endif
3905     #ifdef WOLFSSL_AES_256
3906     static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
3907     #endif
3908 #endif /* HAVE_AESCCM */
3909 
3910 #ifndef NO_DES3
3911     static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
3912     static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
3913 #endif
3914 
3915 /* keyWrapType */
3916 #ifdef WOLFSSL_AES_128
3917     static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
3918 #endif
3919 #ifdef WOLFSSL_AES_192
3920     static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
3921 #endif
3922 #ifdef WOLFSSL_AES_256
3923     static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
3924 #endif
3925 #ifdef HAVE_PKCS7
3926 /* From RFC 3211 */
3927 static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
3928 #endif
3929 
3930 /* cmsKeyAgreeType */
3931 #ifndef NO_SHA
3932     static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
3933                                           {43, 129, 5, 16, 134, 72, 63, 0, 2};
3934 #endif
3935 #ifdef WOLFSSL_SHA224
3936     static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
3937 #endif
3938 #ifndef NO_SHA256
3939     static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
3940 #endif
3941 #ifdef WOLFSSL_SHA384
3942     static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
3943 #endif
3944 #ifdef WOLFSSL_SHA512
3945     static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
3946 #endif
3947 
3948 /* ocspType */
3949 #ifdef HAVE_OCSP
3950     static const byte ocspBasicOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 1};
3951     static const byte ocspNonceOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 2};
3952     static const byte ocspNoCheckOid[]  = {43, 6, 1, 5, 5, 7, 48, 1, 5};
3953 #endif /* HAVE_OCSP */
3954 
3955 /* certExtType */
3956 static const byte extBasicCaOid[] = {85, 29, 19};
3957 static const byte extAltNamesOid[] = {85, 29, 17};
3958 static const byte extCrlDistOid[] = {85, 29, 31};
3959 static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
3960 static const byte extAuthKeyOid[] = {85, 29, 35};
3961 static const byte extSubjKeyOid[] = {85, 29, 14};
3962 static const byte extCertPolicyOid[] = {85, 29, 32};
3963 static const byte extKeyUsageOid[] = {85, 29, 15};
3964 static const byte extInhibitAnyOid[] = {85, 29, 54};
3965 static const byte extExtKeyUsageOid[] = {85, 29, 37};
3966 #ifndef IGNORE_NAME_CONSTRAINTS
3967     static const byte extNameConsOid[] = {85, 29, 30};
3968 #endif
3969 #ifdef HAVE_CRL
3970 static const byte extCrlNumberOid[] = {85, 29, 20};
3971 #endif
3972 
3973 /* certAuthInfoType */
3974 static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
3975 static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
3976 
3977 /* certPolicyType */
3978 static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
3979 
3980 /* certAltNameType */
3981 static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
3982 
3983 /* certKeyUseType */
3984 static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
3985 static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
3986 static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
3987 static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
3988 static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
3989 static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
3990 static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
3991 
3992 #if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
3993     defined(WOLFSSL_ASN_TEMPLATE)
3994 /* csrAttrType */
3995 #define CSR_ATTR_TYPE_OID_BASE(num) {42, 134, 72, 134, 247, 13, 1, 9, num}
3996 static const byte attrEmailOid[] =             CSR_ATTR_TYPE_OID_BASE(1);
3997 #ifdef WOLFSSL_CERT_REQ
3998 static const byte attrUnstructuredNameOid[] =  CSR_ATTR_TYPE_OID_BASE(2);
3999 static const byte attrPkcs9ContentTypeOid[] =  CSR_ATTR_TYPE_OID_BASE(3);
4000 static const byte attrChallengePasswordOid[] = CSR_ATTR_TYPE_OID_BASE(7);
4001 static const byte attrExtensionRequestOid[] =  CSR_ATTR_TYPE_OID_BASE(14);
4002 static const byte attrSerialNumberOid[] = {85, 4, 5};
4003 #endif
4004 #endif
4005 
4006 /* kdfType */
4007 static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
4008 
4009 /* PKCS5 */
4010 #if !defined(NO_DES3) && !defined(NO_MD5)
4011 static const byte pbeMd5Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 3};
4012 #endif
4013 #if !defined(NO_DES3) && !defined(NO_SHA)
4014 static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
4015 #endif
4016 static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
4017 
4018 /* PKCS12 */
4019 #if !defined(NO_RC4) && !defined(NO_SHA)
4020 static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
4021 #endif
4022 #if !defined(NO_DES3) && !defined(NO_SHA)
4023 static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
4024 #endif
4025 
4026 #ifdef HAVE_LIBZ
4027 /* zlib compression */
4028 static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
4029 #endif
4030 #ifdef WOLFSSL_APACHE_HTTPD
4031 /* tlsExtType */
4032 static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};
4033 /* certNameType */
4034 static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};
4035 #endif
4036 
4037 #if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4038     defined(WOLFSSL_ASN_TEMPLATE)
4039 /* Pilot attribute types (0.9.2342.19200300.100.1.*) */
4040 #ifdef WOLFSSL_ASN_TEMPLATE
4041 static const byte uidOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 1}; /* user id */
4042 #endif
4043 static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */
4044 #endif
4045 
4046 
4047 /* Looks up the ID/type of an OID.
4048  *
4049  * When known returns the OID as a byte array and its length.
4050  * ID-type are unique.
4051  *
4052  * Use oidIgnoreType to autofail.
4053  *
4054  * @param [in]  id     OID id.
4055  * @param [in]  type   Type of OID (enum Oid_Types).
4056  * @param [out] oidSz  Length of OID byte array returned.
4057  * @return  Array of bytes for the OID.
4058  * @return  NULL when ID/type not recognized.
4059  */
4060 const byte* OidFromId(word32 id, word32 type, word32* oidSz)
4061 {
4062     const byte* oid = NULL;
4063 
4064     *oidSz = 0;
4065 
4066     switch (type) {
4067 
4068         case oidHashType:
4069             switch (id) {
4070             #ifdef WOLFSSL_MD2
4071                 case MD2h:
4072                     oid = hashMd2hOid;
4073                     *oidSz = sizeof(hashMd2hOid);
4074                     break;
4075             #endif
4076             #ifndef NO_MD5
4077                 case MD5h:
4078                     oid = hashMd5hOid;
4079                     *oidSz = sizeof(hashMd5hOid);
4080                     break;
4081             #endif
4082             #ifndef NO_SHA
4083                 case SHAh:
4084                     oid = hashSha1hOid;
4085                     *oidSz = sizeof(hashSha1hOid);
4086                     break;
4087             #endif
4088             #ifdef WOLFSSL_SHA224
4089                 case SHA224h:
4090                     oid = hashSha224hOid;
4091                     *oidSz = sizeof(hashSha224hOid);
4092                     break;
4093             #endif
4094             #ifndef NO_SHA256
4095                 case SHA256h:
4096                     oid = hashSha256hOid;
4097                     *oidSz = sizeof(hashSha256hOid);
4098                     break;
4099             #endif
4100             #ifdef WOLFSSL_SHA384
4101                 case SHA384h:
4102                     oid = hashSha384hOid;
4103                     *oidSz = sizeof(hashSha384hOid);
4104                     break;
4105             #endif
4106             #ifdef WOLFSSL_SHA512
4107                 case SHA512h:
4108                     oid = hashSha512hOid;
4109                     *oidSz = sizeof(hashSha512hOid);
4110                     break;
4111             #endif
4112             #ifdef WOLFSSL_SHA3
4113             #ifndef WOLFSSL_NOSHA3_224
4114                 case SHA3_224h:
4115                     oid = hashSha3_224hOid;
4116                     *oidSz = sizeof(hashSha3_224hOid);
4117                     break;
4118             #endif /* WOLFSSL_NOSHA3_224 */
4119             #ifndef WOLFSSL_NOSHA3_256
4120                 case SHA3_256h:
4121                     oid = hashSha3_256hOid;
4122                     *oidSz = sizeof(hashSha3_256hOid);
4123                     break;
4124             #endif /* WOLFSSL_NOSHA3_256 */
4125             #ifndef WOLFSSL_NOSHA3_384
4126                 case SHA3_384h:
4127                     oid = hashSha3_384hOid;
4128                     *oidSz = sizeof(hashSha3_384hOid);
4129                     break;
4130             #endif /* WOLFSSL_NOSHA3_384 */
4131             #ifndef WOLFSSL_NOSHA3_512
4132                 case SHA3_512h:
4133                     oid = hashSha3_512hOid;
4134                     *oidSz = sizeof(hashSha3_512hOid);
4135                     break;
4136             #endif /* WOLFSSL_NOSHA3_512 */
4137             #endif /* WOLFSSL_SHA3 */
4138                 default:
4139                     break;
4140             }
4141             break;
4142 
4143         case oidSigType:
4144             switch (id) {
4145                 #if !defined(NO_DSA) && !defined(NO_SHA)
4146                 case CTC_SHAwDSA:
4147                     oid = sigSha1wDsaOid;
4148                     *oidSz = sizeof(sigSha1wDsaOid);
4149                     break;
4150                 case CTC_SHA256wDSA:
4151                     oid = sigSha256wDsaOid;
4152                     *oidSz = sizeof(sigSha256wDsaOid);
4153                     break;
4154                 #endif /* NO_DSA */
4155                 #ifndef NO_RSA
4156                 #ifdef WOLFSSL_MD2
4157                 case CTC_MD2wRSA:
4158                     oid = sigMd2wRsaOid;
4159                     *oidSz = sizeof(sigMd2wRsaOid);
4160                     break;
4161                 #endif
4162                 #ifndef NO_MD5
4163                 case CTC_MD5wRSA:
4164                     oid = sigMd5wRsaOid;
4165                     *oidSz = sizeof(sigMd5wRsaOid);
4166                     break;
4167                 #endif
4168                 #ifndef NO_SHA
4169                 case CTC_SHAwRSA:
4170                     oid = sigSha1wRsaOid;
4171                     *oidSz = sizeof(sigSha1wRsaOid);
4172                     break;
4173                 #endif
4174                 #ifdef WOLFSSL_SHA224
4175                 case CTC_SHA224wRSA:
4176                     oid = sigSha224wRsaOid;
4177                     *oidSz = sizeof(sigSha224wRsaOid);
4178                     break;
4179                 #endif
4180                 #ifndef NO_SHA256
4181                 case CTC_SHA256wRSA:
4182                     oid = sigSha256wRsaOid;
4183                     *oidSz = sizeof(sigSha256wRsaOid);
4184                     break;
4185                 #endif
4186                 #ifdef WOLFSSL_SHA384
4187                 case CTC_SHA384wRSA:
4188                     oid = sigSha384wRsaOid;
4189                     *oidSz = sizeof(sigSha384wRsaOid);
4190                     break;
4191                 #endif
4192                 #ifdef WOLFSSL_SHA512
4193                 case CTC_SHA512wRSA:
4194                     oid = sigSha512wRsaOid;
4195                     *oidSz = sizeof(sigSha512wRsaOid);
4196                     break;
4197                 #endif /* WOLFSSL_SHA512 */
4198                 #ifdef WOLFSSL_SHA3
4199                 #ifndef WOLFSSL_NOSHA3_224
4200                 case CTC_SHA3_224wRSA:
4201                     oid = sigSha3_224wRsaOid;
4202                     *oidSz = sizeof(sigSha3_224wRsaOid);
4203                     break;
4204                 #endif
4205                 #ifndef WOLFSSL_NOSHA3_256
4206                 case CTC_SHA3_256wRSA:
4207                     oid = sigSha3_256wRsaOid;
4208                     *oidSz = sizeof(sigSha3_256wRsaOid);
4209                     break;
4210                 #endif
4211                 #ifndef WOLFSSL_NOSHA3_384
4212                 case CTC_SHA3_384wRSA:
4213                     oid = sigSha3_384wRsaOid;
4214                     *oidSz = sizeof(sigSha3_384wRsaOid);
4215                     break;
4216                 #endif
4217                 #ifndef WOLFSSL_NOSHA3_512
4218                 case CTC_SHA3_512wRSA:
4219                     oid = sigSha3_512wRsaOid;
4220                     *oidSz = sizeof(sigSha3_512wRsaOid);
4221                     break;
4222                 #endif
4223                 #endif
4224                 #endif /* NO_RSA */
4225                 #ifdef HAVE_ECC
4226                 #ifndef NO_SHA
4227                 case CTC_SHAwECDSA:
4228                     oid = sigSha1wEcdsaOid;
4229                     *oidSz = sizeof(sigSha1wEcdsaOid);
4230                     break;
4231                 #endif
4232                 #ifdef WOLFSSL_SHA224
4233                 case CTC_SHA224wECDSA:
4234                     oid = sigSha224wEcdsaOid;
4235                     *oidSz = sizeof(sigSha224wEcdsaOid);
4236                     break;
4237                 #endif
4238                 #ifndef NO_SHA256
4239                 case CTC_SHA256wECDSA:
4240                     oid = sigSha256wEcdsaOid;
4241                     *oidSz = sizeof(sigSha256wEcdsaOid);
4242                     break;
4243                 #endif
4244                 #ifdef WOLFSSL_SHA384
4245                 case CTC_SHA384wECDSA:
4246                     oid = sigSha384wEcdsaOid;
4247                     *oidSz = sizeof(sigSha384wEcdsaOid);
4248                     break;
4249                 #endif
4250                 #ifdef WOLFSSL_SHA512
4251                 case CTC_SHA512wECDSA:
4252                     oid = sigSha512wEcdsaOid;
4253                     *oidSz = sizeof(sigSha512wEcdsaOid);
4254                     break;
4255                 #endif
4256                 #ifdef WOLFSSL_SHA3
4257                 #ifndef WOLFSSL_NOSHA3_224
4258                 case CTC_SHA3_224wECDSA:
4259                     oid = sigSha3_224wEcdsaOid;
4260                     *oidSz = sizeof(sigSha3_224wEcdsaOid);
4261                     break;
4262                 #endif
4263                 #ifndef WOLFSSL_NOSHA3_256
4264                 case CTC_SHA3_256wECDSA:
4265                     oid = sigSha3_256wEcdsaOid;
4266                     *oidSz = sizeof(sigSha3_256wEcdsaOid);
4267                     break;
4268                 #endif
4269                 #ifndef WOLFSSL_NOSHA3_384
4270                 case CTC_SHA3_384wECDSA:
4271                     oid = sigSha3_384wEcdsaOid;
4272                     *oidSz = sizeof(sigSha3_384wEcdsaOid);
4273                     break;
4274                 #endif
4275                 #ifndef WOLFSSL_NOSHA3_512
4276                 case CTC_SHA3_512wECDSA:
4277                     oid = sigSha3_512wEcdsaOid;
4278                     *oidSz = sizeof(sigSha3_512wEcdsaOid);
4279                     break;
4280                 #endif
4281                 #endif
4282                 #endif /* HAVE_ECC */
4283                 #ifdef HAVE_ED25519
4284                 case CTC_ED25519:
4285                     oid = sigEd25519Oid;
4286                     *oidSz = sizeof(sigEd25519Oid);
4287                     break;
4288                 #endif
4289                 #ifdef HAVE_ED448
4290                 case CTC_ED448:
4291                     oid = sigEd448Oid;
4292                     *oidSz = sizeof(sigEd448Oid);
4293                     break;
4294                 #endif
4295                 #ifdef HAVE_PQC
4296                 case CTC_FALCON_LEVEL1:
4297                     oid = sigFalcon_Level1Oid;
4298                     *oidSz = sizeof(sigFalcon_Level1Oid);
4299                     break;
4300                 case CTC_FALCON_LEVEL5:
4301                     oid = sigFalcon_Level5Oid;
4302                     *oidSz = sizeof(sigFalcon_Level5Oid);
4303                     break;
4304                 #endif
4305                 default:
4306                     break;
4307             }
4308             break;
4309 
4310         case oidKeyType:
4311             switch (id) {
4312                 #ifndef NO_DSA
4313                 case DSAk:
4314                     oid = keyDsaOid;
4315                     *oidSz = sizeof(keyDsaOid);
4316                     break;
4317                 #endif /* NO_DSA */
4318                 #ifndef NO_RSA
4319                 case RSAk:
4320                     oid = keyRsaOid;
4321                     *oidSz = sizeof(keyRsaOid);
4322                     break;
4323                 #endif /* NO_RSA */
4324                 #ifdef HAVE_ECC
4325                 case ECDSAk:
4326                     oid = keyEcdsaOid;
4327                     *oidSz = sizeof(keyEcdsaOid);
4328                     break;
4329                 #endif /* HAVE_ECC */
4330                 #ifdef HAVE_ED25519
4331                 case ED25519k:
4332                     oid = keyEd25519Oid;
4333                     *oidSz = sizeof(keyEd25519Oid);
4334                     break;
4335                 #endif /* HAVE_ED25519 */
4336                 #ifdef HAVE_CURVE25519
4337                 case X25519k:
4338                     oid = keyCurve25519Oid;
4339                     *oidSz = sizeof(keyCurve25519Oid);
4340                     break;
4341                 #endif /* HAVE_CURVE25519 */
4342                 #ifdef HAVE_ED448
4343                 case ED448k:
4344                     oid = keyEd448Oid;
4345                     *oidSz = sizeof(keyEd448Oid);
4346                     break;
4347                 #endif /* HAVE_ED448 */
4348                 #ifdef HAVE_CURVE448
4349                 case X448k:
4350                     oid = keyCurve448Oid;
4351                     *oidSz = sizeof(keyCurve448Oid);
4352                     break;
4353                 #endif /* HAVE_CURVE448 */
4354                 #ifndef NO_DH
4355                 case DHk:
4356                     oid = keyDhOid;
4357                     *oidSz = sizeof(keyDhOid);
4358                     break;
4359                 #endif /* !NO_DH */
4360                 #ifdef HAVE_PQC
4361                 case FALCON_LEVEL1k:
4362                     oid = keyFalcon_Level1Oid;
4363                     *oidSz = sizeof(keyFalcon_Level1Oid);
4364                     break;
4365                 case FALCON_LEVEL5k:
4366                     oid = keyFalcon_Level5Oid;
4367                     *oidSz = sizeof(keyFalcon_Level5Oid);
4368                     break;
4369                 #endif
4370                 default:
4371                     break;
4372             }
4373             break;
4374 
4375         #ifdef HAVE_ECC
4376         case oidCurveType:
4377             if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
4378                 WOLFSSL_MSG("ECC OID not found");
4379             }
4380             break;
4381         #endif /* HAVE_ECC */
4382 
4383         case oidBlkType:
4384             switch (id) {
4385     #ifdef HAVE_AES_CBC
4386         #ifdef WOLFSSL_AES_128
4387                 case AES128CBCb:
4388                     oid = blkAes128CbcOid;
4389                     *oidSz = sizeof(blkAes128CbcOid);
4390                     break;
4391         #endif
4392         #ifdef WOLFSSL_AES_192
4393                 case AES192CBCb:
4394                     oid = blkAes192CbcOid;
4395                     *oidSz = sizeof(blkAes192CbcOid);
4396                     break;
4397         #endif
4398         #ifdef WOLFSSL_AES_256
4399                 case AES256CBCb:
4400                     oid = blkAes256CbcOid;
4401                     *oidSz = sizeof(blkAes256CbcOid);
4402                     break;
4403         #endif
4404     #endif /* HAVE_AES_CBC */
4405     #ifdef HAVE_AESGCM
4406         #ifdef WOLFSSL_AES_128
4407                 case AES128GCMb:
4408                     oid = blkAes128GcmOid;
4409                     *oidSz = sizeof(blkAes128GcmOid);
4410                     break;
4411         #endif
4412         #ifdef WOLFSSL_AES_192
4413                 case AES192GCMb:
4414                     oid = blkAes192GcmOid;
4415                     *oidSz = sizeof(blkAes192GcmOid);
4416                     break;
4417         #endif
4418         #ifdef WOLFSSL_AES_256
4419                 case AES256GCMb:
4420                     oid = blkAes256GcmOid;
4421                     *oidSz = sizeof(blkAes256GcmOid);
4422                     break;
4423         #endif
4424     #endif /* HAVE_AESGCM */
4425     #ifdef HAVE_AESCCM
4426         #ifdef WOLFSSL_AES_128
4427                 case AES128CCMb:
4428                     oid = blkAes128CcmOid;
4429                     *oidSz = sizeof(blkAes128CcmOid);
4430                     break;
4431         #endif
4432         #ifdef WOLFSSL_AES_192
4433                 case AES192CCMb:
4434                     oid = blkAes192CcmOid;
4435                     *oidSz = sizeof(blkAes192CcmOid);
4436                     break;
4437         #endif
4438         #ifdef WOLFSSL_AES_256
4439                 case AES256CCMb:
4440                     oid = blkAes256CcmOid;
4441                     *oidSz = sizeof(blkAes256CcmOid);
4442                     break;
4443         #endif
4444     #endif /* HAVE_AESCCM */
4445     #ifndef NO_DES3
4446                 case DESb:
4447                     oid = blkDesCbcOid;
4448                     *oidSz = sizeof(blkDesCbcOid);
4449                     break;
4450                 case DES3b:
4451                     oid = blkDes3CbcOid;
4452                     *oidSz = sizeof(blkDes3CbcOid);
4453                     break;
4454     #endif /* !NO_DES3 */
4455                 default:
4456                     break;
4457             }
4458             break;
4459 
4460         #ifdef HAVE_OCSP
4461         case oidOcspType:
4462             switch (id) {
4463                 case OCSP_BASIC_OID:
4464                     oid = ocspBasicOid;
4465                     *oidSz = sizeof(ocspBasicOid);
4466                     break;
4467                 case OCSP_NONCE_OID:
4468                     oid = ocspNonceOid;
4469                     *oidSz = sizeof(ocspNonceOid);
4470                     break;
4471                 default:
4472                     break;
4473             }
4474             break;
4475         #endif /* HAVE_OCSP */
4476 
4477         case oidCertExtType:
4478             switch (id) {
4479                 case BASIC_CA_OID:
4480                     oid = extBasicCaOid;
4481                     *oidSz = sizeof(extBasicCaOid);
4482                     break;
4483                 case ALT_NAMES_OID:
4484                     oid = extAltNamesOid;
4485                     *oidSz = sizeof(extAltNamesOid);
4486                     break;
4487                 case CRL_DIST_OID:
4488                     oid = extCrlDistOid;
4489                     *oidSz = sizeof(extCrlDistOid);
4490                     break;
4491                 case AUTH_INFO_OID:
4492                     oid = extAuthInfoOid;
4493                     *oidSz = sizeof(extAuthInfoOid);
4494                     break;
4495                 case AUTH_KEY_OID:
4496                     oid = extAuthKeyOid;
4497                     *oidSz = sizeof(extAuthKeyOid);
4498                     break;
4499                 case SUBJ_KEY_OID:
4500                     oid = extSubjKeyOid;
4501                     *oidSz = sizeof(extSubjKeyOid);
4502                     break;
4503                 case CERT_POLICY_OID:
4504                     oid = extCertPolicyOid;
4505                     *oidSz = sizeof(extCertPolicyOid);
4506                     break;
4507                 case KEY_USAGE_OID:
4508                     oid = extKeyUsageOid;
4509                     *oidSz = sizeof(extKeyUsageOid);
4510                     break;
4511                 case INHIBIT_ANY_OID:
4512                     oid = extInhibitAnyOid;
4513                     *oidSz = sizeof(extInhibitAnyOid);
4514                     break;
4515                 case EXT_KEY_USAGE_OID:
4516                     oid = extExtKeyUsageOid;
4517                     *oidSz = sizeof(extExtKeyUsageOid);
4518                     break;
4519             #ifndef IGNORE_NAME_CONSTRAINTS
4520                 case NAME_CONS_OID:
4521                     oid = extNameConsOid;
4522                     *oidSz = sizeof(extNameConsOid);
4523                     break;
4524             #endif
4525             #ifdef HAVE_OCSP
4526                 case OCSP_NOCHECK_OID:
4527                     oid = ocspNoCheckOid;
4528                     *oidSz = sizeof(ocspNoCheckOid);
4529                     break;
4530             #endif
4531                 default:
4532                     break;
4533             }
4534             break;
4535 
4536         case oidCrlExtType:
4537             #ifdef HAVE_CRL
4538             switch (id) {
4539                 case AUTH_KEY_OID:
4540                     oid = extAuthKeyOid;
4541                     *oidSz = sizeof(extAuthKeyOid);
4542                     break;
4543                 case CRL_NUMBER_OID:
4544                     oid = extCrlNumberOid;
4545                     *oidSz = sizeof(extCrlNumberOid);
4546                     break;
4547                 default:
4548                     break;
4549             }
4550             #endif
4551             break;
4552 
4553         case oidCertAuthInfoType:
4554             switch (id) {
4555                 case AIA_OCSP_OID:
4556                     oid = extAuthInfoOcspOid;
4557                     *oidSz = sizeof(extAuthInfoOcspOid);
4558                     break;
4559                 case AIA_CA_ISSUER_OID:
4560                     oid = extAuthInfoCaIssuerOid;
4561                     *oidSz = sizeof(extAuthInfoCaIssuerOid);
4562                     break;
4563                 default:
4564                     break;
4565             }
4566             break;
4567 
4568         case oidCertPolicyType:
4569             switch (id) {
4570                 case CP_ANY_OID:
4571                     oid = extCertPolicyAnyOid;
4572                     *oidSz = sizeof(extCertPolicyAnyOid);
4573                     break;
4574                 default:
4575                     break;
4576             }
4577             break;
4578 
4579         case oidCertAltNameType:
4580             switch (id) {
4581                 case HW_NAME_OID:
4582                     oid = extAltNamesHwNameOid;
4583                     *oidSz = sizeof(extAltNamesHwNameOid);
4584                     break;
4585                 default:
4586                     break;
4587             }
4588             break;
4589 
4590         case oidCertKeyUseType:
4591             switch (id) {
4592                 case EKU_ANY_OID:
4593                     oid = extExtKeyUsageAnyOid;
4594                     *oidSz = sizeof(extExtKeyUsageAnyOid);
4595                     break;
4596                 case EKU_SERVER_AUTH_OID:
4597                     oid = extExtKeyUsageServerAuthOid;
4598                     *oidSz = sizeof(extExtKeyUsageServerAuthOid);
4599                     break;
4600                 case EKU_CLIENT_AUTH_OID:
4601                     oid = extExtKeyUsageClientAuthOid;
4602                     *oidSz = sizeof(extExtKeyUsageClientAuthOid);
4603                     break;
4604                 case EKU_CODESIGNING_OID:
4605                     oid = extExtKeyUsageCodeSigningOid;
4606                     *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
4607                     break;
4608                 case EKU_EMAILPROTECT_OID:
4609                     oid = extExtKeyUsageEmailProtectOid;
4610                     *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
4611                     break;
4612                 case EKU_TIMESTAMP_OID:
4613                     oid = extExtKeyUsageTimestampOid;
4614                     *oidSz = sizeof(extExtKeyUsageTimestampOid);
4615                     break;
4616                 case EKU_OCSP_SIGN_OID:
4617                     oid = extExtKeyUsageOcspSignOid;
4618                     *oidSz = sizeof(extExtKeyUsageOcspSignOid);
4619                     break;
4620                 default:
4621                     break;
4622             }
4623             break;
4624 
4625         case oidKdfType:
4626             switch (id) {
4627                 case PBKDF2_OID:
4628                     oid = pbkdf2Oid;
4629                     *oidSz = sizeof(pbkdf2Oid);
4630                     break;
4631                 default:
4632                     break;
4633             }
4634             break;
4635 
4636         case oidPBEType:
4637             switch (id) {
4638         #if !defined(NO_SHA) && !defined(NO_RC4)
4639                 case PBE_SHA1_RC4_128_SUM:
4640                 case PBE_SHA1_RC4_128:
4641                     oid = pbeSha1RC4128;
4642                     *oidSz = sizeof(pbeSha1RC4128);
4643                     break;
4644         #endif
4645         #if !defined(NO_MD5) && !defined(NO_DES3)
4646                 case PBE_MD5_DES_SUM:
4647                 case PBE_MD5_DES:
4648                     oid = pbeMd5Des;
4649                     *oidSz = sizeof(pbeMd5Des);
4650                     break;
4651 
4652         #endif
4653         #if !defined(NO_SHA) && !defined(NO_DES3)
4654                 case PBE_SHA1_DES_SUM:
4655                 case PBE_SHA1_DES:
4656                     oid = pbeSha1Des;
4657                     *oidSz = sizeof(pbeSha1Des);
4658                     break;
4659 
4660         #endif
4661         #if !defined(NO_SHA) && !defined(NO_DES3)
4662                 case PBE_SHA1_DES3_SUM:
4663                 case PBE_SHA1_DES3:
4664                     oid = pbeSha1Des3;
4665                     *oidSz = sizeof(pbeSha1Des3);
4666                     break;
4667         #endif
4668                 case PBES2_SUM:
4669                 case PBES2:
4670                     oid = pbes2;
4671                     *oidSz = sizeof(pbes2);
4672                     break;
4673                 default:
4674                     break;
4675             }
4676             break;
4677 
4678         case oidKeyWrapType:
4679             switch (id) {
4680             #ifdef WOLFSSL_AES_128
4681                 case AES128_WRAP:
4682                     oid = wrapAes128Oid;
4683                     *oidSz = sizeof(wrapAes128Oid);
4684                     break;
4685             #endif
4686             #ifdef WOLFSSL_AES_192
4687                 case AES192_WRAP:
4688                     oid = wrapAes192Oid;
4689                     *oidSz = sizeof(wrapAes192Oid);
4690                     break;
4691             #endif
4692             #ifdef WOLFSSL_AES_256
4693                 case AES256_WRAP:
4694                     oid = wrapAes256Oid;
4695                     *oidSz = sizeof(wrapAes256Oid);
4696                     break;
4697             #endif
4698             #ifdef HAVE_PKCS7
4699                 case PWRI_KEK_WRAP:
4700                     oid = wrapPwriKekOid;
4701                     *oidSz = sizeof(wrapPwriKekOid);
4702                     break;
4703             #endif
4704                 default:
4705                     break;
4706             }
4707             break;
4708 
4709         case oidCmsKeyAgreeType:
4710             switch (id) {
4711             #ifndef NO_SHA
4712                 case dhSinglePass_stdDH_sha1kdf_scheme:
4713                     oid = dhSinglePass_stdDH_sha1kdf_Oid;
4714                     *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
4715                     break;
4716             #endif
4717             #ifdef WOLFSSL_SHA224
4718                 case dhSinglePass_stdDH_sha224kdf_scheme:
4719                     oid = dhSinglePass_stdDH_sha224kdf_Oid;
4720                     *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
4721                     break;
4722             #endif
4723             #ifndef NO_SHA256
4724                 case dhSinglePass_stdDH_sha256kdf_scheme:
4725                     oid = dhSinglePass_stdDH_sha256kdf_Oid;
4726                     *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
4727                     break;
4728             #endif
4729             #ifdef WOLFSSL_SHA384
4730                 case dhSinglePass_stdDH_sha384kdf_scheme:
4731                     oid = dhSinglePass_stdDH_sha384kdf_Oid;
4732                     *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
4733                     break;
4734             #endif
4735             #ifdef WOLFSSL_SHA512
4736                 case dhSinglePass_stdDH_sha512kdf_scheme:
4737                     oid = dhSinglePass_stdDH_sha512kdf_Oid;
4738                     *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
4739                     break;
4740             #endif
4741                 default:
4742                     break;
4743             }
4744             break;
4745 
4746 #ifndef NO_HMAC
4747         case oidHmacType:
4748             switch (id) {
4749         #ifdef WOLFSSL_SHA224
4750                 case HMAC_SHA224_OID:
4751                     oid = hmacSha224Oid;
4752                     *oidSz = sizeof(hmacSha224Oid);
4753                     break;
4754         #endif
4755         #ifndef NO_SHA256
4756                 case HMAC_SHA256_OID:
4757                     oid = hmacSha256Oid;
4758                     *oidSz = sizeof(hmacSha256Oid);
4759                     break;
4760         #endif
4761         #ifdef WOLFSSL_SHA384
4762                 case HMAC_SHA384_OID:
4763                     oid = hmacSha384Oid;
4764                     *oidSz = sizeof(hmacSha384Oid);
4765                     break;
4766         #endif
4767         #ifdef WOLFSSL_SHA512
4768                 case HMAC_SHA512_OID:
4769                     oid = hmacSha512Oid;
4770                     *oidSz = sizeof(hmacSha512Oid);
4771                     break;
4772         #endif
4773                 default:
4774                     break;
4775             }
4776             break;
4777 #endif /* !NO_HMAC */
4778 
4779 #ifdef HAVE_LIBZ
4780         case oidCompressType:
4781             switch (id) {
4782                 case ZLIBc:
4783                     oid = zlibCompress;
4784                     *oidSz = sizeof(zlibCompress);
4785                     break;
4786                 default:
4787                     break;
4788             }
4789             break;
4790 #endif /* HAVE_LIBZ */
4791 #ifdef WOLFSSL_APACHE_HTTPD
4792         case oidCertNameType:
4793             switch (id) {
4794                  case NID_id_on_dnsSRV:
4795                     oid = dnsSRVOid;
4796                     *oidSz = sizeof(dnsSRVOid);
4797                     break;
4798                 default:
4799                     break;
4800             }
4801             break;
4802         case oidTlsExtType:
4803             switch (id) {
4804                 case TLS_FEATURE_OID:
4805                     oid = tlsFeatureOid;
4806                     *oidSz = sizeof(tlsFeatureOid);
4807                     break;
4808                 default:
4809                     break;
4810             }
4811             break;
4812 #endif /* WOLFSSL_APACHE_HTTPD */
4813 #ifdef WOLFSSL_CERT_REQ
4814         case oidCsrAttrType:
4815             switch (id) {
4816                 case UNSTRUCTURED_NAME_OID:
4817                     oid = attrUnstructuredNameOid;
4818                     *oidSz = sizeof(attrUnstructuredNameOid);
4819                     break;
4820                 case PKCS9_CONTENT_TYPE_OID:
4821                     oid = attrPkcs9ContentTypeOid;
4822                     *oidSz = sizeof(attrPkcs9ContentTypeOid);
4823                     break;
4824                 case CHALLENGE_PASSWORD_OID:
4825                     oid = attrChallengePasswordOid;
4826                     *oidSz = sizeof(attrChallengePasswordOid);
4827                     break;
4828                 case SERIAL_NUMBER_OID:
4829                     oid = attrSerialNumberOid;
4830                     *oidSz = sizeof(attrSerialNumberOid);
4831                     break;
4832                 case EXTENSION_REQUEST_OID:
4833                     oid = attrExtensionRequestOid;
4834                     *oidSz = sizeof(attrExtensionRequestOid);
4835                     break;
4836                 default:
4837                     break;
4838             }
4839             break;
4840 #endif
4841         case oidIgnoreType:
4842         default:
4843             break;
4844     }
4845 
4846     return oid;
4847 }
4848 
4849 #ifdef HAVE_ECC
4850 
4851 /* Check the OID id is for a known elliptic curve.
4852  *
4853  * @param [in]  oid  OID id.
4854  * @return  ECC set id on success.
4855  * @return  ALGO_ID_E when OID id is 0 or not supported.
4856  */
4857 static int CheckCurve(word32 oid)
4858 {
4859     int ret;
4860     word32 oidSz;
4861 
4862     /* Lookup OID id. */
4863     ret = wc_ecc_get_oid(oid, NULL, &oidSz);
4864     /* Check for error or zero length OID size (can't get OID for encoding). */
4865     if ((ret < 0) || (oidSz == 0)) {
4866         WOLFSSL_MSG("CheckCurve not found");
4867         ret = ALGO_ID_E;
4868     }
4869 
4870     /* Return ECC set id or error code. */
4871     return ret;
4872 }
4873 
4874 #endif
4875 
4876 #ifdef HAVE_OID_ENCODING
4877 /* Encode dotted form of OID into byte array version.
4878  *
4879  * @param [in]      in     Dotted form of OID.
4880  * @param [in]      inSz   Count of numbers in dotted form.
4881  * @param [in]      out    Buffer to hold OID.
4882  * @param [in, out] outSz  On in, size of buffer.
4883  *                         On out, number of bytes in buffer.
4884  * @return  0 on success
4885  * @return  BAD_FUNC_ARG when in or outSz is NULL.
4886  * @return  BUFFER_E when buffer too small.
4887  */
4888 int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
4889 {
4890     int i, x, len;
4891     word32 d, t;
4892 
4893     /* check args */
4894     if (in == NULL || outSz == NULL) {
4895         return BAD_FUNC_ARG;
4896     }
4897 
4898     /* compute length of encoded OID */
4899     d = (in[0] * 40) + in[1];
4900     len = 0;
4901     for (i = 1; i < (int)inSz; i++) {
4902         x = 0;
4903         t = d;
4904         while (t) {
4905             x++;
4906             t >>= 1;
4907         }
4908         len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
4909 
4910         if (i < (int)inSz - 1) {
4911             d = in[i + 1];
4912         }
4913     }
4914 
4915     if (out) {
4916         /* verify length */
4917         if ((int)*outSz < len) {
4918             return BUFFER_E; /* buffer provided is not large enough */
4919         }
4920 
4921         /* calc first byte */
4922         d = (in[0] * 40) + in[1];
4923 
4924         /* encode bytes */
4925         x = 0;
4926         for (i = 1; i < (int)inSz; i++) {
4927             if (d) {
4928                 int y = x, z;
4929                 byte mask = 0;
4930                 while (d) {
4931                     out[x++] = (byte)((d & 0x7F) | mask);
4932                     d     >>= 7;
4933                     mask  |= 0x80;  /* upper bit is set on all but the last byte */
4934                 }
4935                 /* now swap bytes y...x-1 */
4936                 z = x - 1;
4937                 while (y < z) {
4938                     mask = out[y];
4939                     out[y] = out[z];
4940                     out[z] = mask;
4941                     ++y;
4942                     --z;
4943                 }
4944             }
4945             else {
4946               out[x++] = 0x00; /* zero value */
4947             }
4948 
4949             /* next word */
4950             if (i < (int)inSz - 1) {
4951                 d = in[i + 1];
4952             }
4953         }
4954     }
4955 
4956     /* return length */
4957     *outSz = len;
4958 
4959     return 0;
4960 }
4961 #endif /* HAVE_OID_ENCODING */
4962 
4963 #ifdef HAVE_OID_DECODING
4964 /* Encode dotted form of OID into byte array version.
4965  *
4966  * @param [in]      in     Byte array containing OID.
4967  * @param [in]      inSz   Size of OID in bytes.
4968  * @param [in]      out    Array to hold dotted form of OID.
4969  * @param [in, out] outSz  On in, number of elemnts in array.
4970  *                         On out, count of numbers in dotted form.
4971  * @return  0 on success
4972  * @return  BAD_FUNC_ARG when in or outSz is NULL.
4973  * @return  BUFFER_E when dotted form buffer too small.
4974  */
4975 int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
4976 {
4977     int x = 0, y = 0;
4978     word32 t = 0;
4979 
4980     /* check args */
4981     if (in == NULL || outSz == NULL) {
4982         return BAD_FUNC_ARG;
4983     }
4984 
4985     /* decode bytes */
4986     while (inSz--) {
4987         t = (t << 7) | (in[x] & 0x7F);
4988         if (!(in[x] & 0x80)) {
4989             if (y >= (int)*outSz) {
4990                 return BUFFER_E;
4991             }
4992             if (y == 0) {
4993                 out[0] = (t / 40);
4994                 out[1] = (t % 40);
4995                 y = 2;
4996             }
4997             else {
4998                 out[y++] = t;
4999             }
5000             t = 0; /* reset tmp */
5001         }
5002         x++;
5003     }
5004 
5005     /* return length */
5006     *outSz = y;
5007 
5008     return 0;
5009 }
5010 #endif /* HAVE_OID_DECODING */
5011 
5012 /* Decode the header of a BER/DER encoded OBJECT ID.
5013  *
5014  * @param [in]      input     Buffer holding DER/BER encoded data.
5015  * @param [in, out] inOutIdx  On in, starting index of header.
5016  *                            On out, end of parsed header.
5017  * @param [out]     len       Number of bytes in the ASN.1 data.
5018  * @param [in]      maxIdx    Length of data in buffer.
5019  * @return  0 on success.
5020  * @return  BUFFER_E when there is not enough data to parse.
5021  * @return  ASN_PARSE_E when the tag is not a OBJECT ID or length is invalid.
5022  */
5023 int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
5024 {
5025     int ret = GetASNHeader(input, ASN_OBJECT_ID, inOutIdx, len, maxIdx);
5026     if (ret > 0) {
5027         /* Only return 0 on success. */
5028         ret = 0;
5029     }
5030     return ret;
5031 }
5032 
5033 /* Set the DER/BER encoding of the ASN.1 OBJECT ID header.
5034  *
5035  * When output is NULL, calculate the header length only.
5036  *
5037  * @param [in]  len        Length of OBJECT ID data in bytes.
5038  * @param [out] output     Buffer to write into.
5039  * @return  Number of bytes added to the buffer.
5040  */
5041 int SetObjectId(int len, byte* output)
5042 {
5043     int idx = 0;
5044 
5045     if (output) {
5046         /* Write out tag. */
5047         output[idx] = ASN_OBJECT_ID;
5048     }
5049     /* Skip tag. */
5050     idx += ASN_TAG_SZ;
5051     /* Encode length - passing NULL for output will not encode. */
5052     idx += SetLength(len, output ? output + idx : NULL);
5053 
5054     /* Return index after header. */
5055     return idx;
5056 }
5057 
5058 #ifdef ASN_DUMP_OID
5059 /* Dump the OID information.
5060  *
5061  * Decode the OID too if function available.
5062  *
5063  * @param [in] oidData  OID data from buffer.
5064  * @param [in] oidSz    Size of OID data in buffer.
5065  * @param [in] oid      OID id.
5066  * @param [in] oidType  Type of OID.
5067  * @return  0 on success.
5068  * @return  BUFFER_E when not enough bytes for proper decode.
5069  *          (HAVE_OID_DECODING)
5070  */
5071 static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
5072                    word32 oidType)
5073 {
5074     int    ret = 0;
5075     word32 i;
5076 
5077     /* support for dumping OID information */
5078     printf("OID (Type %d, Sz %d, Sum %d): ", oidType, oidSz, oid);
5079     /* Dump bytes in decimal. */
5080     for (i = 0; i < oidSz; i++) {
5081         printf("%d, ", oidData[i]);
5082     }
5083     printf("\n");
5084     /* Dump bytes in hexadecimal. */
5085     for (i = 0; i < oidSz; i++) {
5086         printf("%02x, ", oidData[i]);
5087     }
5088     printf("\n");
5089 
5090     #ifdef HAVE_OID_DECODING
5091     {
5092         word16 decOid[16];
5093         word32 decOidSz = sizeof(decOid);
5094         /* Decode the OID into dotted form. */
5095         ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
5096         if (ret == 0) {
5097             printf("  Decoded (Sz %d): ", decOidSz);
5098             for (i=0; i<decOidSz; i++) {
5099                 printf("%d.", decOid[i]);
5100             }
5101             printf("\n");
5102         }
5103         else {
5104             printf("DecodeObjectId failed: %d\n", ret);
5105         }
5106     }
5107     #endif /* HAVE_OID_DECODING */
5108 
5109     return ret;
5110 }
5111 #endif /* ASN_DUMP_OID */
5112 
5113 /* Get the OID data and verify it is of the type specified when compiled in.
5114  *
5115  * @param [in]      input     Buffer holding OID.
5116  * @param [in, out] inOutIdx  On in, starting index of OID.
5117  *                            On out, end of parsed OID.
5118  * @param [out]     oid       OID id.
5119  * @param [in]      oidType   Expected type of OID. Define NO_VERIFY_OID to
5120  *                            not compile in check.
5121  * @param [in]      length    Length of OID data in buffer.
5122  * @return  0 on success.
5123  * @return  ASN_UNKNOWN_OID_E when OID is not recognized.
5124  * @return  BUFFER_E when not enough bytes for proper decode. (ASN_DUMP_OID and
5125  *          HAVE_OID_DECODING)
5126  */
5127 static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
5128                   word32 oidType, int length)
5129 {
5130     int    ret = 0;
5131     word32 idx = *inOutIdx;
5132 #ifndef NO_VERIFY_OID
5133     word32 actualOidSz;
5134     const byte* actualOid;
5135     const byte* checkOid = NULL;
5136     word32 checkOidSz;
5137 #endif /* NO_VERIFY_OID */
5138 
5139     (void)oidType;
5140     *oid = 0;
5141 
5142 #ifndef NO_VERIFY_OID
5143     /* Keep references to OID data and length for check. */
5144     actualOid = &input[idx];
5145     actualOidSz = (word32)length;
5146 #endif /* NO_VERIFY_OID */
5147 
5148     /* Sum it up for now. */
5149     while (length--) {
5150         /* odd HC08 compiler behavior here when input[idx++] */
5151         *oid += (word32)input[idx];
5152         idx++;
5153     }
5154 
5155     /* Return the index after the OID data. */
5156     *inOutIdx = idx;
5157 
5158 #ifndef NO_VERIFY_OID
5159     /* 'Ignore' type means we don't care which OID it is. */
5160     if (oidType != oidIgnoreType) {
5161         /* Get the OID data for the id-type. */
5162         checkOid = OidFromId(*oid, oidType, &checkOidSz);
5163 
5164     #ifdef ASN_DUMP_OID
5165         /* Dump out the data for debug. */
5166         ret = DumpOID(actualOid, actualOidSz, *oid, oidType);
5167     #endif
5168 
5169         /* TODO: Want to fail when checkOid is NULL.
5170          * Can't as too many situations where unknown OID is to be
5171          * supported. Extra parameter for must not be NULL?
5172          */
5173         /* Check that the OID data matches what we found for the OID id. */
5174         if ((ret == 0) && (checkOid != NULL) && ((checkOidSz != actualOidSz) ||
5175                 (XMEMCMP(actualOid, checkOid, checkOidSz) != 0))) {
5176             WOLFSSL_MSG("OID Check Failed");
5177             ret = ASN_UNKNOWN_OID_E;
5178         }
5179     }
5180 #endif /* NO_VERIFY_OID */
5181 
5182     return ret;
5183 }
5184 
5185 #ifdef WOLFSSL_ASN_TEMPLATE
5186 /* ASN.1 template for an OBJECT_ID. */
5187 static const ASNItem objectIdASN[] = {
5188 /* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 }
5189 };
5190 enum {
5191     OBJECTIDASN_IDX_OID = 0
5192 };
5193 
5194 /* Number of items in ASN.1 template for an OBJECT_ID. */
5195 #define objectIdASN_Length (sizeof(objectIdASN) / sizeof(ASNItem))
5196 #endif
5197 
5198 /* Get the OID id/sum from the BER encoded OBJECT_ID.
5199  *
5200  * @param [in]      input     Buffer holding BER encoded data.
5201  * @param [in, out] inOutIdx  On in, start of OBJECT_ID.
5202  *                            On out, start of ASN.1 item after OBJECT_ID.
5203  * @param [out]     oid       Id of OID in OBJECT_ID data.
5204  * @param [in]      oidType   Type of OID to expect.
5205  * @param [in]      maxIdx    Maximum index of data in buffer.
5206  * @return  0 on success.
5207  * @return  ASN_PARSE_E when encoding is invalid.
5208  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5209  */
5210 int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
5211                                   word32 oidType, word32 maxIdx)
5212 {
5213 #ifndef WOLFSSL_ASN_TEMPLATE
5214     int ret, length;
5215 
5216     WOLFSSL_ENTER("GetObjectId()");
5217 
5218     ret = GetASNObjectId(input, inOutIdx, &length, maxIdx);
5219     if (ret != 0)
5220         return ret;
5221 
5222     return GetOID(input, inOutIdx, oid, oidType, length);
5223 #else
5224     ASNGetData dataASN[objectIdASN_Length];
5225     int ret;
5226 
5227     WOLFSSL_ENTER("GetObjectId()");
5228 
5229     /* Clear dynamic data and set OID type expected. */
5230     XMEMSET(dataASN, 0, sizeof(dataASN));
5231     GetASN_OID(&dataASN[OBJECTIDASN_IDX_OID], oidType);
5232     /* Decode OBJECT_ID. */
5233     ret = GetASN_Items(objectIdASN, dataASN, objectIdASN_Length, 0, input,
5234                        inOutIdx, maxIdx);
5235     if (ret == 0) {
5236         /* Return the id/sum. */
5237         *oid = dataASN[OBJECTIDASN_IDX_OID].data.oid.sum;
5238     }
5239     return ret;
5240 #endif /* WOLFSSL_ASN_TEMPLATE */
5241 }
5242 
5243 #ifndef WOLFSSL_ASN_TEMPLATE
5244 static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
5245 {
5246     word32 idx = *inOutIdx;
5247     int    length;
5248     int ret;
5249 
5250     ret = GetASNObjectId(input, &idx, &length, maxIdx);
5251     if (ret != 0)
5252         return ret;
5253 
5254     idx += length;
5255     *inOutIdx = idx;
5256 
5257     return 0;
5258 }
5259 #endif
5260 
5261 #ifdef WOLFSSL_ASN_TEMPLATE
5262 /* ASN.1 template for an algorithm identifier. */
5263 static const ASNItem algoIdASN[] = {
5264 /*  SEQ  */    { 0, ASN_SEQUENCE, 1, 1, 0 },
5265 /*  OID  */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
5266 /*  NULL */        { 1, ASN_TAG_NULL, 0, 0, 1 },
5267 };
5268 enum {
5269     ALGOIDASN_IDX_SEQ = 0,
5270     ALGOIDASN_IDX_OID,
5271     ALGOIDASN_IDX_NULL
5272 };
5273 
5274 /* Number of items in ASN.1 template for an algorithm identifier. */
5275 #define algoIdASN_Length (sizeof(algoIdASN) / sizeof(ASNItem))
5276 #endif
5277 
5278 /* Get the OID id/sum from the BER encoding of an algorithm identifier.
5279  *
5280  * NULL tag is skipped if present.
5281  *
5282  * @param [in]      input     Buffer holding BER encoded data.
5283  * @param [in, out] inOutIdx  On in, start of algorithm identifier.
5284  *                            On out, start of ASN.1 item after algorithm id.
5285  * @param [out]     oid       Id of OID in algorithm identifier data.
5286  * @param [in]      oidType   Type of OID to expect.
5287  * @param [in]      maxIdx    Maximum index of data in buffer.
5288  * @return  0 on success.
5289  * @return  ASN_PARSE_E when encoding is invalid.
5290  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5291  */
5292 int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
5293                      word32 oidType, word32 maxIdx)
5294 {
5295 #ifndef WOLFSSL_ASN_TEMPLATE
5296     int    length;
5297     word32 idx = *inOutIdx;
5298     int    ret;
5299     *oid = 0;
5300 
5301     WOLFSSL_ENTER("GetAlgoId");
5302 
5303     if (GetSequence(input, &idx, &length, maxIdx) < 0)
5304         return ASN_PARSE_E;
5305 
5306     if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
5307         return ASN_OBJECT_ID_E;
5308 
5309     /* could have NULL tag and 0 terminator, but may not */
5310     if (idx < maxIdx) {
5311         word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
5312         byte   tag;
5313 
5314         if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
5315             if (tag == ASN_TAG_NULL) {
5316                 ret = GetASNNull(input, &idx, maxIdx);
5317                 if (ret != 0)
5318                     return ret;
5319             }
5320         }
5321     }
5322 
5323     *inOutIdx = idx;
5324 
5325     return 0;
5326 #else
5327     DECL_ASNGETDATA(dataASN, algoIdASN_Length);
5328     int ret = 0;
5329 
5330     WOLFSSL_ENTER("GetAlgoId");
5331 
5332     CALLOC_ASNGETDATA(dataASN, algoIdASN_Length, ret, NULL);
5333     if (ret == 0) {
5334         /* Set OID type expected. */
5335         GetASN_OID(&dataASN[ALGOIDASN_IDX_OID], oidType);
5336         /* Decode the algorithm identifier. */
5337         ret = GetASN_Items(algoIdASN, dataASN, algoIdASN_Length, 0, input, inOutIdx,
5338                            maxIdx);
5339     }
5340     if (ret == 0) {
5341         /* Return the OID id/sum. */
5342         *oid = dataASN[ALGOIDASN_IDX_OID].data.oid.sum;
5343     }
5344 
5345     FREE_ASNGETDATA(dataASN, NULL);
5346     return ret;
5347 #endif /* WOLFSSL_ASN_TEMPLATE */
5348 }
5349 
5350 #ifndef NO_RSA
5351 
5352 #ifndef HAVE_USER_RSA
5353 #if defined(WOLFSSL_ASN_TEMPLATE) || (!defined(NO_CERTS) && \
5354     (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
5355 /* Byte offset of numbers in RSA key. */
5356 size_t rsaIntOffset[] = {
5357     OFFSETOF(RsaKey, n),
5358     OFFSETOF(RsaKey, e),
5359 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
5360     OFFSETOF(RsaKey, d),
5361     OFFSETOF(RsaKey, p),
5362     OFFSETOF(RsaKey, q),
5363     OFFSETOF(RsaKey, dP),
5364     OFFSETOF(RsaKey, dQ),
5365     OFFSETOF(RsaKey, u)
5366 #endif
5367 };
5368 
5369 /* Get a number from the RSA key based on an index.
5370  *
5371  * Order: { n, e, d, p, q, dP, dQ, u }
5372  *
5373  * Caller must ensure index is not invalid!
5374  *
5375  * @param [in] key  RSA key object.
5376  * @param [in] idx  Index of number.
5377  * @return  A pointer to an mp_int when valid index.
5378  * @return  NULL when invalid index.
5379  */
5380 static mp_int* GetRsaInt(RsaKey* key, byte idx)
5381 {
5382     /* Cast key to byte array to and use offset to get to mp_int field. */
5383     return (mp_int*)(((byte*)key) + rsaIntOffset[idx]);
5384 }
5385 #endif
5386 
5387 #ifdef WOLFSSL_ASN_TEMPLATE
5388 /* ASN.1 template for an RSA private key.
5389  * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
5390  */
5391 static const ASNItem rsaKeyASN[] = {
5392 /*  SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
5393 /*  VER */        { 1, ASN_INTEGER, 0, 0, 0 },
5394                 /* Integers need to be in this specific order
5395                  * as asn code depends on this. */
5396 /*  N   */        { 1, ASN_INTEGER, 0, 0, 0 },
5397 /*  E   */        { 1, ASN_INTEGER, 0, 0, 0 },
5398 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
5399 /*  D   */        { 1, ASN_INTEGER, 0, 0, 0 },
5400 /*  P   */        { 1, ASN_INTEGER, 0, 0, 0 },
5401 /*  Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
5402 /*  DP  */        { 1, ASN_INTEGER, 0, 0, 0 },
5403 /*  DQ  */        { 1, ASN_INTEGER, 0, 0, 0 },
5404 /*  U   */        { 1, ASN_INTEGER, 0, 0, 0 },
5405                 /* otherPrimeInfos  OtherPrimeInfos OPTIONAL
5406                  * v2 - multiprime */
5407 #endif
5408 };
5409 enum {
5410     RSAKEYASN_IDX_SEQ = 0,
5411     RSAKEYASN_IDX_VER,
5412     /* Integers need to be in this specific order
5413      * as asn code depends on this. */
5414     RSAKEYASN_IDX_N,
5415     RSAKEYASN_IDX_E,
5416 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
5417     RSAKEYASN_IDX_D,
5418     RSAKEYASN_IDX_P,
5419     RSAKEYASN_IDX_Q,
5420     RSAKEYASN_IDX_DP,
5421     RSAKEYASN_IDX_DQ,
5422     RSAKEYASN_IDX_U,
5423 #endif
5424 };
5425 
5426 /* Number of items in ASN.1 template for an RSA private key. */
5427 #define rsaKeyASN_Length (sizeof(rsaKeyASN) / sizeof(ASNItem))
5428 #endif
5429 
5430 /* Decode RSA private key.
5431  *
5432  * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
5433  *
5434  * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
5435  * being extracted.
5436  *
5437  * @param [in]      input     Buffer holding BER encoded data.
5438  * @param [in, out] inOutIdx  On in, start of RSA private key.
5439  *                            On out, start of ASN.1 item after RSA private key.
5440  * @param [in, out] key       RSA key object.
5441  * @param [in]      inSz      Number of bytes in buffer.
5442  * @return  0 on success.
5443  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
5444  *          is invalid.
5445  * @return  BUFFER_E when data in buffer is too small.
5446  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
5447  *          non-zero length.
5448  * @return  MP_INIT_E when the unable to initialize an mp_int.
5449  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
5450  */
5451 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
5452                         word32 inSz)
5453 {
5454 #ifndef WOLFSSL_ASN_TEMPLATE
5455     int version, length;
5456     word32 algId = 0;
5457 
5458     if (inOutIdx == NULL || input == NULL || key == NULL) {
5459         return BAD_FUNC_ARG;
5460     }
5461 
5462     /* if has pkcs8 header skip it */
5463     if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
5464         /* ignore error, did not have pkcs8 header */
5465     }
5466 
5467     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
5468         return ASN_PARSE_E;
5469 
5470     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
5471         return ASN_PARSE_E;
5472 
5473     key->type = RSA_PRIVATE;
5474 
5475     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
5476         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
5477 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
5478         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
5479         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
5480         GetInt(&key->q,  input, inOutIdx, inSz) < 0
5481 #else
5482         SkipInt(input, inOutIdx, inSz) < 0 ||
5483         SkipInt(input, inOutIdx, inSz) < 0 ||
5484         SkipInt(input, inOutIdx, inSz) < 0
5485 #endif
5486        ) {
5487             return ASN_RSA_KEY_E;
5488        }
5489 #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
5490     && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
5491     if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
5492         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
5493         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
5494 #else
5495     if (SkipInt(input, inOutIdx, inSz) < 0 ||
5496         SkipInt(input, inOutIdx, inSz) < 0 ||
5497         SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
5498 #endif
5499 
5500 #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
5501     if (wc_InitRsaHw(key) != 0) {
5502         return BAD_STATE_E;
5503     }
5504 #endif
5505 
5506     return 0;
5507 #else
5508     DECL_ASNGETDATA(dataASN, rsaKeyASN_Length);
5509     int        ret = 0;
5510     byte       i;
5511     byte       version;
5512 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
5513     word32 algId = 0;
5514 #endif
5515 
5516     /* Check validity of parameters. */
5517     if (inOutIdx == NULL || input == NULL || key == NULL) {
5518         ret = BAD_FUNC_ARG;
5519     }
5520 
5521 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
5522     if (ret == 0) {
5523         /* if has pkcs8 header skip it */
5524         if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
5525             /* ignore error, did not have pkcs8 header */
5526         }
5527     }
5528 #endif
5529 
5530     CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
5531 
5532     if (ret == 0) {
5533         /* Register variable to hold version field. */
5534         GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
5535         /* Setup data to store INTEGER data in mp_int's in RSA object. */
5536     #if defined(WOLFSSL_RSA_PUBLIC_ONLY)
5537         /* Extract all public fields. */
5538         for (i = 0; i < RSA_PUB_INTS; i++) {
5539             GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
5540         }
5541         /* Not extracting all data from BER encoding. */
5542         #define RSA_ASN_COMPLETE    0
5543     #else
5544         /* Extract all private fields. */
5545         for (i = 0; i < RSA_INTS; i++) {
5546             GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
5547         }
5548         /* Extracting all data from BER encoding. */
5549         #define RSA_ASN_COMPLETE    1
5550     #endif
5551         /* Parse BER encoding for RSA private key. */
5552         ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
5553             RSA_ASN_COMPLETE, input, inOutIdx, inSz);
5554     }
5555     /* Check version: 0 - two prime, 1 - multi-prime
5556      * Multi-prime has optional sequence after coefficient for extra primes.
5557      * If extra primes, parsing will fail as not all the buffer was used.
5558      */
5559     if ((ret == 0) && (version > PKCS1v1)) {
5560         ret = ASN_PARSE_E;
5561     }
5562     if (ret == 0) {
5563     #if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
5564         /* RSA key object has all private key values. */
5565         key->type = RSA_PRIVATE;
5566     #else
5567         /* RSA key object has all public key values. */
5568         key->type = RSA_PUBLIC;
5569     #endif
5570 
5571     #ifdef WOLFSSL_XILINX_CRYPT
5572         if (wc_InitRsaHw(key) != 0)
5573             ret = BAD_STATE_E;
5574     #endif
5575     }
5576 
5577     FREE_ASNGETDATA(dataASN, key->heap);
5578     return ret;
5579 #endif /* WOLFSSL_ASN_TEMPLATE */
5580 }
5581 #endif /* HAVE_USER_RSA */
5582 #endif /* NO_RSA */
5583 
5584 #ifdef WOLFSSL_ASN_TEMPLATE
5585 /* ASN.1 template for a PKCS #8 key.
5586  * Ignoring optional attributes and public key.
5587  * PKCS #8: RFC 5958, 2 - PrivateKeyInfo
5588  */
5589 static const ASNItem pkcs8KeyASN[] = {
5590 /*  SEQ                 */    { 0, ASN_SEQUENCE, 1, 1, 0 },
5591 /*  VER                 */        { 1, ASN_INTEGER, 0, 0, 0 },
5592 /*  PKEY_ALGO_SEQ       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
5593 /*  PKEY_ALGO_OID_KEY   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
5594 /*  PKEY_ALGO_OID_CURVE */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
5595 /*  PKEY_ALGO_NULL      */            { 2, ASN_TAG_NULL, 0, 0, 1 },
5596 /*  PKEY_DATA           */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
5597                 /* attributes            [0] Attributes OPTIONAL */
5598                 /* [[2: publicKey        [1] PublicKey OPTIONAL ]] */
5599 };
5600 enum {
5601     PKCS8KEYASN_IDX_SEQ = 0,
5602     PKCS8KEYASN_IDX_VER,
5603     PKCS8KEYASN_IDX_PKEY_ALGO_SEQ,
5604     PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY,
5605     PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE,
5606     PKCS8KEYASN_IDX_PKEY_ALGO_NULL,
5607     PKCS8KEYASN_IDX_PKEY_DATA,
5608 };
5609 
5610 /* Number of items in ASN.1 template for a PKCS #8 key. */
5611 #define pkcs8KeyASN_Length (sizeof(pkcs8KeyASN) / sizeof(ASNItem))
5612 #endif
5613 
5614 /* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, Ed448, or Falcon key.
5615  *
5616  * @param [in]       input     Buffer holding BER data.
5617  * @param [in, out]  inOutIdx  On in, start of PKCS #8 encoding.
5618  *                             On out, start of encoded key.
5619  * @param [in]       sz        Size of data in buffer.
5620  * @param [out]      algId     Key's algorithm id from PKCS #8 header.
5621  * @return  Length of key data on success.
5622  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
5623  *          is invalid.
5624  * @return  BUFFER_E when data in buffer is too small.
5625  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
5626  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
5627  *          non-zero length.
5628  */
5629 int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
5630                            word32* algId)
5631 {
5632 #ifndef WOLFSSL_ASN_TEMPLATE
5633     word32 idx;
5634     int    version, length;
5635     int    ret;
5636     byte   tag;
5637 
5638     if (input == NULL || inOutIdx == NULL)
5639         return BAD_FUNC_ARG;
5640 
5641     idx = *inOutIdx;
5642 
5643     if (GetSequence(input, &idx, &length, sz) < 0)
5644         return ASN_PARSE_E;
5645 
5646     if (GetMyVersion(input, &idx, &version, sz) < 0)
5647         return ASN_PARSE_E;
5648 
5649     if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
5650         return ASN_PARSE_E;
5651 
5652     if (GetASNTag(input, &idx, &tag, sz) < 0)
5653         return ASN_PARSE_E;
5654     idx = idx - 1; /* reset idx after finding tag */
5655 
5656     if (tag == ASN_OBJECT_ID) {
5657         if (SkipObjectId(input, &idx, sz) < 0)
5658             return ASN_PARSE_E;
5659     }
5660 
5661     ret = GetOctetString(input, &idx, &length, sz);
5662     if (ret < 0) {
5663         if (ret == BUFFER_E)
5664             return ASN_PARSE_E;
5665         /* Some private keys don't expect an octet string */
5666         WOLFSSL_MSG("Couldn't find Octet string");
5667     }
5668 
5669     *inOutIdx = idx;
5670 
5671     return length;
5672 #else
5673     DECL_ASNGETDATA(dataASN, pkcs8KeyASN_Length);
5674     int ret = 0;
5675     word32 oid = 9;
5676     byte version;
5677     word32 idx = *inOutIdx;
5678 
5679     /* Check validity of parameters. */
5680     if (input == NULL || inOutIdx == NULL) {
5681         ret = BAD_FUNC_ARG;
5682     }
5683 
5684     CALLOC_ASNGETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
5685 
5686     if (ret == 0) {
5687         /* Get version, check key type and curve type. */
5688         GetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], &version);
5689         GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], oidKeyType);
5690         GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], oidCurveType);
5691         /* Parse data. */
5692         ret = GetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, 1, input,
5693                            &idx, sz);
5694     }
5695 
5696     if (ret == 0) {
5697         /* Key type OID. */
5698         oid = dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY].data.oid.sum;
5699 
5700         /* Version 1 includes an optional public key.
5701          * If public key is included then the parsing will fail as it did not
5702          * use all the data.
5703          */
5704         if (version > PKCS8v1) {
5705             ret = ASN_PARSE_E;
5706         }
5707     }
5708     if (ret == 0) {
5709         switch (oid) {
5710         #ifndef NO_RSA
5711             case RSAk:
5712                 /* Must have NULL item but not OBJECT_ID item. */
5713                 if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag == 0) ||
5714                     (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
5715                     ret = ASN_PARSE_E;
5716                 }
5717                 break;
5718         #endif
5719         #ifdef HAVE_ECC
5720             case ECDSAk:
5721                 /* Must not have NULL item. */
5722                 if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
5723                     ret = ASN_PARSE_E;
5724                 }
5725                 break;
5726         #endif
5727         #ifdef HAVE_ED25519
5728             case ED25519k:
5729                 /* Neither NULL item nor OBJECT_ID item allowed. */
5730                 if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
5731                     (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
5732                     ret = ASN_PARSE_E;
5733                 }
5734                 break;
5735         #endif
5736         #ifdef HAVE_CURVE25519
5737             case X25519k:
5738                 /* Neither NULL item nor OBJECT_ID item allowed. */
5739                 if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
5740                     (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
5741                     ret = ASN_PARSE_E;
5742                 }
5743                 break;
5744         #endif
5745         #ifdef HAVE_ED448
5746             case ED448k:
5747                 /* Neither NULL item nor OBJECT_ID item allowed. */
5748                 if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
5749                     (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
5750                     ret = ASN_PARSE_E;
5751                 }
5752                 break;
5753         #endif
5754         #ifdef HAVE_CURVE448
5755             case X448k:
5756                 /* Neither NULL item nor OBJECT_ID item allowed. */
5757                 if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
5758                     (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
5759                     ret = ASN_PARSE_E;
5760                 }
5761                 break;
5762         #endif
5763             /* DSAk not supported. */
5764             /* Ignore OID lookup failures. */
5765             default:
5766                 break;
5767         }
5768     }
5769     if (ret == 0) {
5770         /* Return algorithm id of internal key. */
5771         *algId = oid;
5772         /* Return index to start of internal key. */
5773         *inOutIdx = GetASNItem_DataIdx(dataASN[PKCS8KEYASN_IDX_PKEY_DATA], input);
5774         /* Return value is length of internal key. */
5775         ret = dataASN[PKCS8KEYASN_IDX_PKEY_DATA].data.ref.length;
5776     }
5777 
5778     FREE_ASNGETDATA(dataASN, NULL);
5779     return ret;
5780 #endif
5781 }
5782 
5783 /* TODO: test case  */
5784 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
5785 {
5786     word32 oid;
5787 
5788     return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
5789 }
5790 
5791 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
5792 
5793 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
5794 int ToTraditional_ex(byte* input, word32 sz, word32* algId)
5795 {
5796     word32 inOutIdx = 0;
5797     int    length;
5798 
5799     if (input == NULL)
5800         return BAD_FUNC_ARG;
5801 
5802     length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
5803     if (length < 0)
5804         return length;
5805 
5806     if (length + inOutIdx > sz)
5807         return BUFFER_E;
5808 
5809     XMEMMOVE(input, input + inOutIdx, length);
5810 
5811     return length;
5812 }
5813 
5814 int ToTraditional(byte* input, word32 sz)
5815 {
5816     word32 oid;
5817 
5818     return ToTraditional_ex(input, sz, &oid);
5819 }
5820 
5821 #endif /* HAVE_PKCS8 || HAVE_PKCS12 */
5822 
5823 #if defined(HAVE_PKCS8) && !defined(NO_CERTS)
5824 
5825 int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
5826 {
5827     int length;
5828     word32 algId;
5829 
5830     if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
5831         return BAD_FUNC_ARG;
5832 
5833     length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
5834 
5835     return length;
5836 }
5837 
5838 int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
5839         int algoID, const byte* curveOID, word32 oidSz)
5840 {
5841 #ifndef WOLFSSL_ASN_TEMPLATE
5842     word32 keyIdx = 0;
5843     word32 tmpSz  = 0;
5844     word32 sz;
5845     word32 tmpAlgId = 0;
5846 
5847     /* If out is NULL then return the max size needed
5848      * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
5849     if (out == NULL && outSz != NULL) {
5850         *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
5851                  + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
5852 
5853         if (curveOID != NULL)
5854             *outSz += oidSz + MAX_LENGTH_SZ + 1;
5855 
5856         WOLFSSL_MSG("Checking size of PKCS8");
5857 
5858         return LENGTH_ONLY_E;
5859     }
5860 
5861     WOLFSSL_ENTER("wc_CreatePKCS8Key()");
5862 
5863     if (key == NULL || out == NULL || outSz == NULL) {
5864         return BAD_FUNC_ARG;
5865     }
5866 
5867     /* check the buffer has enough room for largest possible size */
5868     if (curveOID != NULL) {
5869         if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
5870                + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
5871             return BUFFER_E;
5872     }
5873     else {
5874         oidSz = 0; /* with no curveOID oid size must be 0 */
5875         if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
5876                   + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
5877             return BUFFER_E;
5878     }
5879 
5880     /* sanity check: make sure the key doesn't already have a PKCS 8 header */
5881     if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
5882         (void)tmpAlgId;
5883         return ASN_PARSE_E;
5884     }
5885 
5886     /* PrivateKeyInfo ::= SEQUENCE */
5887     keyIdx = MAX_SEQ_SZ; /* save room for sequence */
5888 
5889     /*  version Version
5890      *  no header information just INTEGER */
5891     sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
5892     tmpSz += sz; keyIdx += sz;
5893     /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
5894     sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
5895     if (curveOID != NULL && oidSz > 0) {
5896         byte buf[MAX_LENGTH_SZ];
5897         sz = SetLength(oidSz, buf);
5898         sz += 1; /* plus one for ASN object id */
5899     }
5900     sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
5901     tmpSz += sz; keyIdx += sz;
5902 
5903     /*  privateKey          PrivateKey *
5904      * pkcs8 ecc uses slightly different format. Places curve oid in
5905      * buffer */
5906     if (curveOID != NULL && oidSz > 0) {
5907         sz = SetObjectId(oidSz, out + keyIdx);
5908         keyIdx += sz; tmpSz += sz;
5909         XMEMCPY(out + keyIdx, curveOID, oidSz);
5910         keyIdx += oidSz; tmpSz += oidSz;
5911     }
5912 
5913     sz = SetOctetString(keySz, out + keyIdx);
5914     keyIdx += sz; tmpSz += sz;
5915     XMEMCPY(out + keyIdx, key, keySz);
5916     tmpSz += keySz;
5917 
5918     /*  attributes          optional
5919      * No attributes currently added */
5920 
5921     /* rewind and add sequence */
5922     sz = SetSequence(tmpSz, out);
5923     XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
5924 
5925     *outSz = tmpSz + sz;
5926     return tmpSz + sz;
5927 #else
5928     DECL_ASNSETDATA(dataASN, pkcs8KeyASN_Length);
5929     int sz;
5930     int ret = 0;
5931     word32 keyIdx = 0;
5932     word32 tmpAlgId = 0;
5933 
5934     WOLFSSL_ENTER("wc_CreatePKCS8Key()");
5935 
5936     /* Check validity of parameters. */
5937     if (out == NULL && outSz != NULL) {
5938     }
5939     else if (key == NULL || out == NULL || outSz == NULL) {
5940         ret = BAD_FUNC_ARG;
5941     }
5942 
5943     /* Sanity check: make sure key doesn't have PKCS #8 header. */
5944     if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
5945         (void)tmpAlgId;
5946         ret = ASN_PARSE_E;
5947     }
5948 
5949     CALLOC_ASNSETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
5950 
5951     if (ret == 0) {
5952         /* Only support default PKCS #8 format - v0. */
5953         SetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], PKCS8v0);
5954         /* Set key OID that corresponds to key data. */
5955         SetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], algoID, oidKeyType);
5956         if (curveOID != NULL && oidSz > 0) {
5957             /* ECC key and curveOID set to write. */
5958             SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], curveOID, oidSz);
5959         }
5960         else {
5961             /* EC curve OID to encode. */
5962             dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].noOut = 1;
5963         }
5964         /* Only RSA keys have NULL tagged item after OID. */
5965         dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].noOut = (algoID != RSAk);
5966         /* Set key data to encode. */
5967         SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_DATA], key, keySz);
5968 
5969         /* Get the size of the DER encoding. */
5970         ret = SizeASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, &sz);
5971     }
5972     if (ret == 0) {
5973         /* Always return the calculated size. */
5974         *outSz = sz;
5975     }
5976     /* Check for buffer to encoded into. */
5977     if ((ret == 0) && (out == NULL)) {
5978         WOLFSSL_MSG("Checking size of PKCS8");
5979         ret = LENGTH_ONLY_E;
5980     }
5981     if (ret == 0) {
5982         /*  Encode PKCS #8 key into buffer. */
5983         SetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, out);
5984         ret = sz;
5985     }
5986 
5987     FREE_ASNSETDATA(dataASN, NULL);
5988     return ret;
5989 #endif /* WOLFSSL_ASN_TEMPLATE */
5990 }
5991 
5992 #endif /* HAVE_PKCS8 && !NO_CERTS */
5993 
5994 #if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
5995 /* check that the private key is a pair for the public key
5996  * return 1 (true) on match
5997  * return 0 or negative value on failure/error
5998  *
5999  * privKey   : buffer holding DER format private key
6000  * privKeySz : size of private key buffer
6001  * pubKey    : buffer holding DER format public key
6002  * pubKeySz  : size of public key buffer
6003  * ks        : type of key */
6004 int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
6005                        const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
6006 {
6007     int ret;
6008     (void)privKeySz;
6009     (void)pubKeySz;
6010     (void)ks;
6011 
6012     if (privKey == NULL || pubKey == NULL) {
6013         return BAD_FUNC_ARG;
6014     }
6015 
6016     #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
6017     /* test if RSA key */
6018     if (ks == RSAk) {
6019     #ifdef WOLFSSL_SMALL_STACK
6020         RsaKey* a;
6021         RsaKey* b = NULL;
6022     #else
6023         RsaKey a[1], b[1];
6024     #endif
6025         word32 keyIdx = 0;
6026 
6027     #ifdef WOLFSSL_SMALL_STACK
6028         a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6029         if (a == NULL)
6030             return MEMORY_E;
6031         b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6032         if (b == NULL) {
6033             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6034             return MEMORY_E;
6035         }
6036     #endif
6037 
6038         if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
6039     #ifdef WOLFSSL_SMALL_STACK
6040             XFREE(b, NULL, DYNAMIC_TYPE_RSA);
6041             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6042     #endif
6043             return ret;
6044         }
6045         if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
6046             wc_FreeRsaKey(a);
6047     #ifdef WOLFSSL_SMALL_STACK
6048             XFREE(b, NULL, DYNAMIC_TYPE_RSA);
6049             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6050     #endif
6051             return ret;
6052         }
6053         if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
6054             WOLFSSL_MSG("Checking RSA key pair");
6055             keyIdx = 0; /* reset to 0 for parsing public key */
6056 
6057             if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
6058                     pubKeySz)) == 0) {
6059                 /* limit for user RSA crypto because of RsaKey
6060                  * dereference. */
6061             #if defined(HAVE_USER_RSA)
6062                 WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
6063                 ret = 1; /* return first RSA cert as match */
6064             #else
6065                 /* both keys extracted successfully now check n and e
6066                  * values are the same. This is dereferencing RsaKey */
6067                 if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
6068                     mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
6069                     ret = MP_CMP_E;
6070                 }
6071                 else
6072                     ret = 1;
6073             #endif
6074             }
6075         }
6076         wc_FreeRsaKey(b);
6077         wc_FreeRsaKey(a);
6078     #ifdef WOLFSSL_SMALL_STACK
6079         XFREE(b, NULL, DYNAMIC_TYPE_RSA);
6080         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6081     #endif
6082     }
6083     else
6084     #endif /* !NO_RSA && !NO_ASN_CRYPT */
6085 
6086     #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
6087     if (ks == ECDSAk) {
6088     #ifdef WOLFSSL_SMALL_STACK
6089         ecc_key* key_pair;
6090         byte*    privDer;
6091     #else
6092         ecc_key  key_pair[1];
6093         byte     privDer[MAX_ECC_BYTES];
6094     #endif
6095         word32   privSz = MAX_ECC_BYTES;
6096         word32   keyIdx = 0;
6097 
6098     #ifdef WOLFSSL_SMALL_STACK
6099         key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
6100         if (key_pair == NULL)
6101             return MEMORY_E;
6102         privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6103         if (privDer == NULL) {
6104             XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
6105             return MEMORY_E;
6106         }
6107     #endif
6108 
6109         if ((ret = wc_ecc_init(key_pair)) < 0) {
6110     #ifdef WOLFSSL_SMALL_STACK
6111             XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6112             XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
6113     #endif
6114             return ret;
6115         }
6116 
6117         if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
6118                 privKeySz)) == 0) {
6119             WOLFSSL_MSG("Checking ECC key pair");
6120 
6121             if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
6122                                                                          == 0) {
6123                 wc_ecc_free(key_pair);
6124                 ret = wc_ecc_init(key_pair);
6125                 if (ret == 0) {
6126                     ret = wc_ecc_import_private_key(privDer,
6127                                             privSz, pubKey,
6128                                             pubKeySz, key_pair);
6129                 }
6130 
6131                 /* public and private extracted successfully now check if is
6132                  * a pair and also do sanity checks on key. wc_ecc_check_key
6133                  * checks that private * base generator equals pubkey */
6134                 if (ret == 0) {
6135                     if ((ret = wc_ecc_check_key(key_pair)) == 0) {
6136                         ret = 1;
6137                     }
6138                 }
6139                 ForceZero(privDer, privSz);
6140             }
6141         }
6142         wc_ecc_free(key_pair);
6143     #ifdef WOLFSSL_SMALL_STACK
6144         XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6145         XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
6146     #endif
6147     }
6148     else
6149     #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
6150 
6151     #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
6152     if (ks == ED25519k) {
6153     #ifdef WOLFSSL_SMALL_STACK
6154         ed25519_key* key_pair;
6155     #else
6156         ed25519_key  key_pair[1];
6157     #endif
6158         word32       keyIdx = 0;
6159 
6160     #ifdef WOLFSSL_SMALL_STACK
6161         key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
6162                                                           DYNAMIC_TYPE_ED25519);
6163         if (key_pair == NULL)
6164             return MEMORY_E;
6165     #endif
6166 
6167         if ((ret = wc_ed25519_init(key_pair)) < 0) {
6168     #ifdef WOLFSSL_SMALL_STACK
6169             XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
6170     #endif
6171             return ret;
6172         }
6173         if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
6174                 privKeySz)) == 0) {
6175             WOLFSSL_MSG("Checking ED25519 key pair");
6176             keyIdx = 0;
6177             if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
6178                     key_pair)) == 0) {
6179                 /* public and private extracted successfully no check if is
6180                  * a pair and also do sanity checks on key. wc_ecc_check_key
6181                  * checks that private * base generator equals pubkey */
6182                 if ((ret = wc_ed25519_check_key(key_pair)) == 0)
6183                     ret = 1;
6184             }
6185         }
6186         wc_ed25519_free(key_pair);
6187     #ifdef WOLFSSL_SMALL_STACK
6188         XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
6189     #endif
6190     }
6191     else
6192     #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
6193 
6194     #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
6195     if (ks == ED448k) {
6196     #ifdef WOLFSSL_SMALL_STACK
6197         ed448_key* key_pair = NULL;
6198     #else
6199         ed448_key  key_pair[1];
6200     #endif
6201         word32     keyIdx = 0;
6202 
6203     #ifdef WOLFSSL_SMALL_STACK
6204         key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
6205                                                             DYNAMIC_TYPE_ED448);
6206         if (key_pair == NULL)
6207             return MEMORY_E;
6208     #endif
6209 
6210         if ((ret = wc_ed448_init(key_pair)) < 0) {
6211     #ifdef WOLFSSL_SMALL_STACK
6212             XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
6213     #endif
6214             return ret;
6215         }
6216         if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
6217                 privKeySz)) == 0) {
6218             WOLFSSL_MSG("Checking ED448 key pair");
6219             keyIdx = 0;
6220             if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
6221                     key_pair)) == 0) {
6222                 /* public and private extracted successfully no check if is
6223                  * a pair and also do sanity checks on key. wc_ecc_check_key
6224                  * checks that private * base generator equals pubkey */
6225                 if ((ret = wc_ed448_check_key(key_pair)) == 0)
6226                     ret = 1;
6227             }
6228         }
6229         wc_ed448_free(key_pair);
6230     #ifdef WOLFSSL_SMALL_STACK
6231         XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
6232     #endif
6233     }
6234     else
6235     #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
6236     #if defined(HAVE_PQC)
6237     if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
6238     #ifdef WOLFSSL_SMALL_STACK
6239         falcon_key* key_pair = NULL;
6240     #else
6241         falcon_key  key_pair[1];
6242     #endif
6243         word32     keyIdx = 0;
6244 
6245     #ifdef WOLFSSL_SMALL_STACK
6246         key_pair = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
6247                                         DYNAMIC_TYPE_FALCON);
6248         if (key_pair == NULL)
6249             return MEMORY_E;
6250     #endif
6251         ret = wc_falcon_init(key_pair);
6252         if (ret  < 0) {
6253     #ifdef WOLFSSL_SMALL_STACK
6254             XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
6255     #endif
6256             return ret;
6257         }
6258 
6259         if (ks == FALCON_LEVEL1k) {
6260             ret = wc_falcon_set_level(key_pair, 1);
6261         }
6262         else if (ks == FALCON_LEVEL5k) {
6263             ret = wc_falcon_set_level(key_pair, 5);
6264         }
6265 
6266         if (ret  < 0) {
6267     #ifdef WOLFSSL_SMALL_STACK
6268             XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
6269     #endif
6270             return ret;
6271         }
6272         if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
6273                                              privKeySz)) == 0) {
6274             WOLFSSL_MSG("Checking Falcon_ key pair");
6275             keyIdx = 0;
6276             if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
6277                                                key_pair)) == 0) {
6278                 /* Public and private extracted successfully. Sanity check. */
6279                 if ((ret = wc_falcon_check_key(key_pair)) == 0)
6280                     ret = 1;
6281             }
6282         }
6283         wc_falcon_free(key_pair);
6284     #ifdef WOLFSSL_SMALL_STACK
6285         XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
6286     #endif
6287     }
6288     else
6289     #endif /* HAVE_PQC */
6290     {
6291         ret = 0;
6292     }
6293     (void)ks;
6294 
6295     return ret;
6296 }
6297 
6298 /* check that the private key is a pair for the public key in certificate
6299  * return 1 (true) on match
6300  * return 0 or negative value on failure/error
6301  *
6302  * key   : buffer holding DER format key
6303  * keySz : size of key buffer
6304  * der   : a initialized and parsed DecodedCert holding a certificate */
6305 int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der)
6306 {
6307     if (key == NULL || der == NULL) {
6308         return BAD_FUNC_ARG;
6309     }
6310 
6311     return wc_CheckPrivateKey(key, keySz, der->publicKey,
6312             der->pubKeySize, (enum Key_Sum) der->keyOID);
6313 }
6314 
6315 #endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
6316 
6317 #ifndef NO_PWDBASED
6318 
6319 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6320 /* Check the PBE algorithm is supported and return wolfSSL id, version and block
6321  * size of encryption algorithm.
6322  *
6323  * When PBES2, version is PKCS5v2, CheckAlgoV2() must be called to get id and
6324  * blockSz based on encryption algorithm.
6325  *
6326  * @param [in]  first    First byte of OID to use in check.
6327  * @param [in]  second   Second byte of OID to use in check.
6328  * @param [out] id       wolfSSL id for PBE algorithm.
6329  * @param [out] version  Version of PBE OID:
6330  *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
6331  * @param [out] blockSz  Block size of encryption algorithm.
6332  * @return  0 on success.
6333  * @return  ALGO_ID_E when OID not supported.
6334  * @return  ASN_INPUT_E when first byte is invalid.
6335  */
6336 static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
6337 {
6338     int ret = 0;
6339 
6340     (void)id;
6341     (void)version;
6342     (void)blockSz;
6343 
6344     /* pkcs-12 1 = pkcs-12PbeIds */
6345     if (first == 1) {
6346         /* PKCS #12: Appendix C */
6347         switch (second) {
6348 #if !defined(NO_SHA)
6349     #ifndef NO_RC4
6350         case PBE_SHA1_RC4_128:
6351             *id = PBE_SHA1_RC4_128;
6352             *version = PKCS12v1;
6353             if (blockSz != NULL) {
6354                 *blockSz = 1;
6355             }
6356             break;
6357     #endif
6358     #ifndef NO_DES3
6359         case PBE_SHA1_DES3:
6360             *id = PBE_SHA1_DES3;
6361             *version = PKCS12v1;
6362             if (blockSz != NULL) {
6363                 *blockSz = DES_BLOCK_SIZE;
6364             }
6365             break;
6366     #endif
6367     #ifdef WC_RC2
6368         case PBE_SHA1_40RC2_CBC:
6369             *id = PBE_SHA1_40RC2_CBC;
6370             *version = PKCS12v1;
6371             if (blockSz != NULL) {
6372                 *blockSz = RC2_BLOCK_SIZE;
6373             }
6374             break;
6375     #endif
6376 #endif /* !NO_SHA */
6377         default:
6378             ret = ALGO_ID_E;
6379             break;
6380         }
6381     }
6382     else if (first != PKCS5) {
6383         /* Bad OID. */
6384         ret = ASN_INPUT_E;
6385     }
6386     /* PKCS #5 PBES2: Appendix A.4
6387      * pkcs-5 13 = id-PBES2 */
6388     else if (second == PBES2) {
6389         *version = PKCS5v2;
6390         /* Id and block size come from CheckAlgoV2() */
6391     }
6392     else  {
6393         /* PKCS #5 PBES1: Appendix A.3 */
6394         /* see RFC 2898 for ids */
6395         switch (second) {
6396     #ifndef NO_DES3
6397         #ifndef NO_MD5
6398         case PBES1_MD5_DES:
6399             *id = PBE_MD5_DES;
6400             *version = PKCS5;
6401             if (blockSz != NULL) {
6402                 *blockSz = DES_BLOCK_SIZE;
6403             }
6404             break;
6405         #endif
6406         #ifndef NO_SHA
6407         case PBES1_SHA1_DES:
6408             *id = PBE_SHA1_DES;
6409             *version = PKCS5;
6410             if (blockSz != NULL) {
6411                 *blockSz = DES_BLOCK_SIZE;
6412             }
6413             break;
6414         #endif
6415     #endif /* !NO_DES3 */
6416         default:
6417             ret = ALGO_ID_E;
6418             break;
6419         }
6420     }
6421 
6422     /* Return error code. */
6423     return ret;
6424 }
6425 
6426 #endif /* HAVE_PKCS8 || HAVE_PKCS12 */
6427 
6428 #ifdef HAVE_PKCS8
6429 
6430 /* Check the encryption algorithm with PBES2 is supported and return block size
6431  * and wolfSSL id for the PBE.
6432  *
6433  * @param [in]  oid      Encryption algorithm OID id.
6434  * @param [out] id       wolfSSL id for PBE algorithm.
6435  * @param [out] version  Version of PBE OID:
6436  *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
6437  * @return  0 on success.
6438  * @return  ALGO_ID_E when encryption algorithm is not supported with PBES2.
6439  */
6440 static int CheckAlgoV2(int oid, int* id, int* blockSz)
6441 {
6442     int ret = 0;
6443 
6444     (void)id;
6445     (void)blockSz;
6446 
6447     switch (oid) {
6448 #if !defined(NO_DES3) && !defined(NO_SHA)
6449     case DESb:
6450         *id = PBE_SHA1_DES;
6451         if (blockSz != NULL) {
6452             *blockSz = DES_BLOCK_SIZE;
6453         }
6454         break;
6455     case DES3b:
6456         *id = PBE_SHA1_DES3;
6457         if (blockSz != NULL) {
6458             *blockSz = DES_BLOCK_SIZE;
6459         }
6460         break;
6461 #endif
6462 #ifdef WOLFSSL_AES_256
6463     case AES256CBCb:
6464         *id = PBE_AES256_CBC;
6465         if (blockSz != NULL) {
6466             *blockSz = AES_BLOCK_SIZE;
6467         }
6468         break;
6469 #endif
6470 #ifdef WOLFSSL_AES_128
6471     case AES128CBCb:
6472         *id = PBE_AES128_CBC;
6473         if (blockSz != NULL) {
6474             *blockSz = AES_BLOCK_SIZE;
6475         }
6476         break;
6477 #endif
6478     default:
6479         WOLFSSL_MSG("No PKCS v2 algo found");
6480         ret = ALGO_ID_E;
6481         break;
6482     }
6483 
6484     /* Return error code. */
6485     return ret;
6486 }
6487 
6488 #endif /* HAVE_PKCS8 */
6489 
6490 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6491 
6492 int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
6493         int* algoID, void* heap)
6494 {
6495     word32 tmpIdx = 0;
6496 
6497     if (key == NULL || algoID == NULL)
6498         return BAD_FUNC_ARG;
6499 
6500     *algoID = 0;
6501 
6502     #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
6503     {
6504         RsaKey *rsa = (RsaKey *)XMALLOC(sizeof *rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
6505         if (rsa == NULL)
6506             return MEMORY_E;
6507 
6508         wc_InitRsaKey(rsa, heap);
6509         if (wc_RsaPrivateKeyDecode(key, &tmpIdx, rsa, keySz) == 0) {
6510             *algoID = RSAk;
6511         }
6512         else {
6513             WOLFSSL_MSG("Not RSA DER key");
6514         }
6515         wc_FreeRsaKey(rsa);
6516         XFREE(rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
6517     }
6518     #endif /* !NO_RSA && !NO_ASN_CRYPT */
6519     #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
6520     if (*algoID == 0) {
6521         ecc_key *ecc = (ecc_key *)XMALLOC(sizeof *ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
6522         if (ecc == NULL)
6523             return MEMORY_E;
6524 
6525         tmpIdx = 0;
6526         wc_ecc_init_ex(ecc, heap, INVALID_DEVID);
6527         if (wc_EccPrivateKeyDecode(key, &tmpIdx, ecc, keySz) == 0) {
6528             *algoID = ECDSAk;
6529 
6530             /* now find oid */
6531             if (wc_ecc_get_oid(ecc->dp->oidSum, curveOID, oidSz) < 0) {
6532                 WOLFSSL_MSG("Error getting ECC curve OID");
6533                 wc_ecc_free(ecc);
6534                 XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
6535                 return BAD_FUNC_ARG;
6536             }
6537         }
6538         else {
6539             WOLFSSL_MSG("Not ECC DER key either");
6540         }
6541         wc_ecc_free(ecc);
6542         XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
6543     }
6544 #endif /* HAVE_ECC && !NO_ASN_CRYPT */
6545 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
6546     if (*algoID == 0) {
6547         ed25519_key *ed25519 = (ed25519_key *)XMALLOC(sizeof *ed25519, heap,
6548             DYNAMIC_TYPE_TMP_BUFFER);
6549         if (ed25519 == NULL)
6550             return MEMORY_E;
6551 
6552         tmpIdx = 0;
6553         if (wc_ed25519_init_ex(ed25519, heap, INVALID_DEVID) == 0) {
6554             if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, ed25519, keySz) == 0) {
6555                 *algoID = ED25519k;
6556             }
6557             else {
6558                 WOLFSSL_MSG("Not ED25519 DER key");
6559             }
6560             wc_ed25519_free(ed25519);
6561         }
6562         else {
6563             WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
6564         }
6565         XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER);
6566     }
6567 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
6568 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
6569     if (*algoID == 0) {
6570         ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap,
6571             DYNAMIC_TYPE_TMP_BUFFER);
6572         if (ed448 == NULL)
6573             return MEMORY_E;
6574 
6575         tmpIdx = 0;
6576         if (wc_ed448_init(ed448) == 0) {
6577             if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, ed448, keySz) == 0) {
6578                 *algoID = ED448k;
6579             }
6580             else {
6581                 WOLFSSL_MSG("Not ED448 DER key");
6582             }
6583             wc_ed448_free(ed448);
6584         }
6585         else {
6586             WOLFSSL_MSG("GetKeyOID wc_ed448_init failed");
6587         }
6588         XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER);
6589     }
6590 #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
6591 #if defined(HAVE_PQC)
6592     if (*algoID == 0) {
6593         falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(*falcon), heap,
6594             DYNAMIC_TYPE_TMP_BUFFER);
6595         if (falcon == NULL)
6596             return MEMORY_E;
6597 
6598         if (wc_falcon_init(falcon) != 0) {
6599             tmpIdx = 0;
6600             if (wc_falcon_set_level(falcon, 1) == 0) {
6601                 if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
6602                     == 0) {
6603                     *algoID = FALCON_LEVEL1k;
6604                 }
6605                 else {
6606                     WOLFSSL_MSG("Not Falcon Level 1 DER key");
6607                 }
6608             }
6609             else if (wc_falcon_set_level(falcon, 5) == 0) {
6610                 if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
6611                     == 0) {
6612                     *algoID = FALCON_LEVEL5k;
6613                 }
6614                 else {
6615                     WOLFSSL_MSG("Not Falcon Level 5 DER key");
6616                 }
6617             }
6618             else {
6619                 WOLFSSL_MSG("GetKeyOID falcon initialization failed");
6620             }
6621             wc_falcon_free(falcon);
6622         }
6623         XFREE(falcon, heap, DYNAMIC_TYPE_TMP_BUFFER);
6624     }
6625 #endif /* HAVE_PQC */
6626 
6627     /* if flag is not set then this is not a key that we understand. */
6628     if (*algoID == 0) {
6629         WOLFSSL_MSG("Bad key DER or compile options");
6630         return BAD_FUNC_ARG;
6631     }
6632 
6633     (void)tmpIdx;
6634     (void)curveOID;
6635     (void)oidSz;
6636     (void)keySz;
6637     (void)heap;
6638 
6639     return 1;
6640 }
6641 
6642 #endif /* HAVE_PKCS8 || HAVE_PKCS12 */
6643 
6644 #ifdef WOLFSSL_ASN_TEMPLATE
6645 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6646 /* ASN.1 template for PBES2 parameters.
6647  * PKCS #5: RFC 8018, A.4 - PBES2-params without outer SEQUENCE
6648  *                    A.2 - PBKDF2-params
6649  *                    B.2 - Encryption schemes
6650  *                    C   - AlgorithmIdentifier
6651  */
6652 static const ASNItem pbes2ParamsASN[] = {
6653 /* KDF_SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
6654                /* PBKDF2 */
6655 /* KDF_OID                */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
6656 /* PBKDF2_PARAMS_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
6657                    /* Salt */
6658 /* PBKDF2_PARAMS_SALT     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
6659                    /* Iteration count */
6660 /* PBKDF2_PARAMS_ITER     */         { 2, ASN_INTEGER, 0, 0, 0 },
6661                    /* Key length */
6662 /* PBKDF2_PARAMS_KEYLEN   */         { 2, ASN_INTEGER, 0, 0, 1 },
6663                    /* PRF - default is HMAC-SHA1 */
6664 /* PBKDF2_PARAMS_PRF      */         { 2, ASN_SEQUENCE, 1, 1, 1 },
6665 /* PBKDF2_PARAMS_PRF_OID  */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
6666 /* PBKDF2_PARAMS_PRF_NULL */             { 3, ASN_TAG_NULL, 0, 0, 1 },
6667 /* ENCS_SEQ               */ { 0, ASN_SEQUENCE, 1, 1, 0 },
6668                    /* Encryption algorithm */
6669 /* ENCS_OID               */   { 1, ASN_OBJECT_ID, 0, 0, 0 },
6670                    /* IV for CBC */
6671 /* ENCS_PARAMS            */   { 1, ASN_OCTET_STRING, 0, 0, 0 },
6672 };
6673 enum {
6674     PBES2PARAMSASN_IDX_KDF_SEQ = 0,
6675     PBES2PARAMSASN_IDX_KDF_OID,
6676     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SEQ,
6677     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT,
6678     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER,
6679     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_KEYLEN,
6680     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF,
6681     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID,
6682     PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_NULL,
6683     PBES2PARAMSASN_IDX_ENCS_SEQ,
6684     PBES2PARAMSASN_IDX_ENCS_OID,
6685     PBES2PARAMSASN_IDX_ENCS_PARAMS,
6686 };
6687 
6688 /* Number of items in ASN.1 template for PBES2 parameters. */
6689 #define pbes2ParamsASN_Length (sizeof(pbes2ParamsASN) / sizeof(ASNItem))
6690 
6691 /* ASN.1 template for PBES1 parameters.
6692  * PKCS #5: RFC 8018, A.3. - PBEParameter without outer SEQUENCE
6693  */
6694 static const ASNItem pbes1ParamsASN[] = {
6695             /* Salt */
6696 /* SALT */    { 0, ASN_OCTET_STRING, 0, 0, 0 },
6697             /* Iteration count */
6698 /* ITER */    { 0, ASN_INTEGER, 0, 0, 0 },
6699 };
6700 enum {
6701     PBES1PARAMSASN_IDX_SALT = 0,
6702     PBES1PARAMSASN_IDX_ITER,
6703 };
6704 
6705 /* Number of items in ASN.1 template for PBES1 parameters. */
6706 #define pbes1ParamsASN_Length (sizeof(pbes1ParamsASN) / sizeof(ASNItem))
6707 #endif /* HAVE_PKCS8 || HAVE_PKCS12 */
6708 #endif /* WOLFSSL_ASN_TEMPLATE */
6709 
6710 #ifdef HAVE_PKCS8
6711 
6712 /*
6713  * Equivalent to calling TraditionalEnc with the same parameters but with
6714  * encAlgId set to 0. This function must be kept alive because it's sometimes
6715  * part of the API (WOLFSSL_ASN_API).
6716  */
6717 int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
6718         const char* password, int passwordSz, int vPKCS, int vAlgo,
6719         byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
6720 {
6721     return TraditionalEnc(key, keySz, out, outSz, password, passwordSz,
6722                 vPKCS, vAlgo, 0, salt, saltSz, itt, rng, heap);
6723 }
6724 
6725 static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
6726                      int *blkSz)
6727 {
6728     int ret = 0;
6729 
6730     switch (encAlgId) {
6731 #if !defined(NO_DES3) && !defined(NO_SHA)
6732     case DESb:
6733         *len = sizeof(blkDesCbcOid);
6734         *oid = blkDesCbcOid;
6735         *id = PBE_SHA1_DES;
6736         *blkSz = 8;
6737         break;
6738     case DES3b:
6739         *len = sizeof(blkDes3CbcOid);
6740         *oid = blkDes3CbcOid;
6741         *id = PBE_SHA1_DES3;
6742         *blkSz = 8;
6743         break;
6744 #endif
6745 #if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
6746     case AES256CBCb:
6747         *len = sizeof(blkAes256CbcOid);
6748         *oid = blkAes256CbcOid;
6749         *id = PBE_AES256_CBC;
6750         *blkSz = 16;
6751         break;
6752 #endif
6753     default:
6754         (void)len;
6755         (void)oid;
6756         (void)id;
6757         (void)blkSz;
6758         ret = ALGO_ID_E;
6759     }
6760 
6761     return ret;
6762 }
6763 
6764 int wc_EncryptPKCS8Key(byte* key, word32 keySz, byte* out, word32* outSz,
6765         const char* password, int passwordSz, int vPKCS, int pbeOid,
6766         int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
6767         void* heap)
6768 {
6769 #ifdef WOLFSSL_SMALL_STACK
6770     byte* saltTmp = NULL;
6771 #else
6772     byte saltTmp[MAX_SALT_SIZE];
6773 #endif
6774     int genSalt = 0;
6775     int ret = 0;
6776     int version = 0;
6777     int pbeId = 0;
6778     int blockSz = 0;
6779     const byte* encOid = NULL;
6780     int encOidSz = 0;
6781     word32 padSz = 0;
6782     word32 innerLen = 0;
6783     word32 outerLen = 0;
6784     const byte* pbeOidBuf = NULL;
6785     word32 pbeOidBufSz = 0;
6786     word32 pbeLen = 0;
6787     word32 kdfLen = 0;
6788     word32 encLen = 0;
6789     byte cbcIv[MAX_IV_SIZE];
6790     word32 idx = 0;
6791     word32 encIdx = 0;
6792 
6793     (void)heap;
6794 
6795     WOLFSSL_ENTER("wc_EncryptPKCS8Key");
6796 
6797     if (key == NULL || outSz == NULL || password == NULL) {
6798         ret = BAD_FUNC_ARG;
6799     }
6800 
6801     if (ret == 0) {
6802         ret = CheckAlgo(vPKCS, pbeOid, &pbeId, &version, &blockSz);
6803     }
6804     if (ret == 0 && (salt == NULL || saltSz == 0)) {
6805         genSalt = 1;
6806         saltSz = 8;
6807     }
6808     if (ret == 0 && version == PKCS5v2) {
6809         ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &pbeId, &blockSz);
6810     }
6811     if (ret == 0) {
6812         padSz = (blockSz - (keySz & (blockSz - 1))) & (blockSz - 1);
6813         /* inner = OCT salt INT itt */
6814         innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
6815 
6816         if (version != PKCS5v2) {
6817             pbeOidBuf = OidFromId(pbeId, oidPBEType, &pbeOidBufSz);
6818             /* pbe = OBJ pbse1 SEQ [ inner ] */
6819             pbeLen = 2 + pbeOidBufSz + 2 + innerLen;
6820         }
6821         else {
6822             pbeOidBuf = pbes2;
6823             pbeOidBufSz = sizeof(pbes2);
6824             /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
6825             kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
6826             /* enc = OBJ enc_alg OCT iv */
6827             encLen = 2 + encOidSz + 2 + blockSz;
6828             /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
6829             pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
6830 
6831             ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
6832         }
6833     }
6834     if (ret == 0) {
6835         /* outerLen = length of PBE encoding + octet string data */
6836         /* Plus 2 for tag and length for pbe */
6837         outerLen = 2 + pbeLen;
6838         /* Octet string tag, length */
6839         outerLen += 1 + SetLength(keySz + padSz, NULL);
6840         /* Octet string bytes */
6841         outerLen += keySz + padSz;
6842         if (out == NULL) {
6843             /* Sequence tag, length */
6844             *outSz = 1 + SetLength(outerLen, NULL) + outerLen;
6845             return LENGTH_ONLY_E;
6846         }
6847         SetOctetString(keySz + padSz, out);
6848 
6849         idx += SetSequence(outerLen, out + idx);
6850 
6851         encIdx = idx + outerLen - keySz - padSz;
6852         /* Put Encrypted content in place. */
6853         XMEMCPY(out + encIdx, key, keySz);
6854         if (padSz > 0) {
6855             XMEMSET(out + encIdx + keySz, padSz, padSz);
6856             keySz += padSz;
6857         }
6858 
6859         if (genSalt == 1) {
6860         #ifdef WOLFSSL_SMALL_STACK
6861             saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
6862             if (saltTmp == NULL) {
6863                 ret = MEMORY_E;
6864             }
6865             else
6866         #endif
6867             {
6868                 salt = saltTmp;
6869                 if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
6870                     WOLFSSL_MSG("Error generating random salt");
6871                 }
6872             }
6873         }
6874     }
6875     if (ret == 0) {
6876         ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, pbeId,
6877                   out + encIdx, keySz, version, cbcIv, 1, 0);
6878     }
6879     if (ret == 0) {
6880         if (version != PKCS5v2) {
6881             /* PBE algorithm */
6882             idx += SetSequence(pbeLen, out + idx);
6883             idx += SetObjectId(pbeOidBufSz, out + idx);
6884             XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
6885             idx += pbeOidBufSz;
6886         }
6887         else {
6888             /* PBES2 algorithm identifier */
6889             idx += SetSequence(pbeLen, out + idx);
6890             idx += SetObjectId(pbeOidBufSz, out + idx);
6891             XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
6892             idx += pbeOidBufSz;
6893             /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
6894             idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
6895             /* KDF Algorithm Identifier */
6896             idx += SetSequence(kdfLen, out + idx);
6897             idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
6898             XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
6899             idx += sizeof(pbkdf2Oid);
6900         }
6901         idx += SetSequence(innerLen, out + idx);
6902         idx += SetOctetString(saltSz, out + idx);
6903         XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
6904         ret = SetShortInt(out, &idx, itt, *outSz);
6905         if (ret > 0)
6906             ret = 0;
6907     }
6908     if (ret == 0) {
6909         if (version == PKCS5v2) {
6910             /* Encryption Algorithm Identifier */
6911             idx += SetSequence(encLen, out + idx);
6912             idx += SetObjectId(encOidSz, out + idx);
6913             XMEMCPY(out + idx, encOid, encOidSz);
6914             idx += encOidSz;
6915             /* Encryption Algorithm Parameter: CBC IV */
6916             idx += SetOctetString(blockSz, out + idx);
6917             XMEMCPY(out + idx, cbcIv, blockSz);
6918             idx += blockSz;
6919         }
6920         idx += SetOctetString(keySz, out + idx);
6921         /* Default PRF - no need to write out OID */
6922         idx += keySz;
6923 
6924         ret = idx;
6925     }
6926 
6927 #ifdef WOLFSSL_SMALL_STACK
6928     if (saltTmp != NULL) {
6929         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
6930     }
6931 #endif
6932 
6933     WOLFSSL_LEAVE("wc_EncryptPKCS8Key", ret);
6934 
6935     return ret;
6936 }
6937 
6938 int wc_DecryptPKCS8Key(byte* input, word32 sz, const char* password,
6939         int passwordSz)
6940 {
6941     int ret;
6942     int length;
6943     word32 inOutIdx = 0;
6944 
6945     if (input == NULL || password == NULL) {
6946         return BAD_FUNC_ARG;
6947     }
6948 
6949     if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
6950         ret = ASN_PARSE_E;
6951     }
6952     else {
6953         ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password,
6954                 passwordSz);
6955         if (ret > 0) {
6956             XMEMMOVE(input, input + inOutIdx, ret);
6957         }
6958     }
6959 
6960     if (ret > 0) {
6961         /* DecryptContent will decrypt the data, but it will leave any padding
6962          * bytes intact. This code calculates the length without the padding
6963          * and we return that to the user. */
6964         inOutIdx = 0;
6965         if (GetSequence(input, &inOutIdx, &length, ret) < 0) {
6966             ret = ASN_PARSE_E;
6967         }
6968         else {
6969             ret = inOutIdx + length;
6970         }
6971     }
6972 
6973     return ret;
6974 }
6975 
6976 /* Takes an unencrypted, traditional DER-encoded key and converts it to a PKCS#8
6977  * encrypted key. If out is not NULL, it will hold the encrypted key. If it's
6978  * NULL, LENGTH_ONLY_E will be returned and outSz will have the required out
6979  * buffer size. */
6980 int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
6981         const char* password, int passwordSz, int vPKCS, int vAlgo,
6982         int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
6983         void* heap)
6984 {
6985     int ret = 0;
6986     byte *pkcs8Key = NULL;
6987     word32 pkcs8KeySz = 0;
6988     int algId = 0;
6989     const byte* curveOid = NULL;
6990     word32 curveOidSz = 0;
6991 
6992     if (ret == 0) {
6993         /* check key type and get OID if ECC */
6994         ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
6995         if (ret == 1)
6996             ret = 0;
6997     }
6998     if (ret == 0) {
6999         ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
7000                                                                     curveOidSz);
7001         if (ret == LENGTH_ONLY_E)
7002             ret = 0;
7003     }
7004     if (ret == 0) {
7005         pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, heap, DYNAMIC_TYPE_TMP_BUFFER);
7006         if (pkcs8Key == NULL)
7007             ret = MEMORY_E;
7008     }
7009     if (ret == 0) {
7010         ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
7011             curveOid, curveOidSz);
7012         if (ret >= 0) {
7013             pkcs8KeySz = ret;
7014             ret = 0;
7015         }
7016     }
7017     if (ret == 0) {
7018         ret = wc_EncryptPKCS8Key(pkcs8Key, pkcs8KeySz, out, outSz, password,
7019             passwordSz, vPKCS, vAlgo, encAlgId, salt, saltSz, itt, rng, heap);
7020     }
7021 
7022     if (pkcs8Key != NULL) {
7023         ForceZero(pkcs8Key, pkcs8KeySz);
7024         XFREE(pkcs8Key, heap, DYNAMIC_TYPE_TMP_BUFFER);
7025     }
7026 
7027     (void)rng;
7028 
7029     return ret;
7030 }
7031 
7032 /* Same as TraditionalEnc, but in the public API. */
7033 int wc_CreateEncryptedPKCS8Key(byte* key, word32 keySz, byte* out,
7034         word32* outSz, const char* password, int passwordSz, int vPKCS,
7035         int pbeOid, int encAlgId, byte* salt, word32 saltSz, int itt,
7036         WC_RNG* rng, void* heap)
7037 {
7038     return TraditionalEnc(key, keySz, out, outSz, password, passwordSz, vPKCS,
7039         pbeOid, encAlgId, salt, saltSz, itt, rng, heap);
7040 }
7041 
7042 
7043 #ifdef WOLFSSL_ASN_TEMPLATE
7044 /* ASN.1 template for PKCS #8/#7 encrypted key for decrypting
7045  * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
7046  * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
7047  */
7048 static const ASNItem pkcs8DecASN[] = {
7049 /* ENCALGO_SEQ    */ { 1, ASN_SEQUENCE, 1, 1, 0 },
7050 /* ENCALGO_OID    */     { 2, ASN_OBJECT_ID, 0, 0, 0 },
7051 /* ENCALGO_PARAMS */     { 2, ASN_SEQUENCE, 1, 0, 0 },
7052             /* PKCS #7 */
7053 /* ENCCONTENT     */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ENC_CONTENT,
7054                                        0, 0, 2 },
7055             /* PKCS #8 */
7056 /* ENCDATA        */ { 1, ASN_OCTET_STRING, 0, 0, 2 },
7057 };
7058 enum {
7059     PKCS8DECASN_IDX_ENCALGO_SEQ = 0,
7060     PKCS8DECASN_IDX_ENCALGO_OID,
7061     PKCS8DECASN_IDX_ENCALGO_PARAMS,
7062     PKCS8DECASN_IDX_ENCCONTENT,
7063     PKCS8DECASN_IDX_ENCDATA,
7064 };
7065 
7066 /* Number of items in ASN.1 template for PKCS #8/#7 encrypted key. */
7067 #define pkcs8DecASN_Length (sizeof(pkcs8DecASN) / sizeof(ASNItem))
7068 #endif
7069 
7070 /* Decrypt data using PBE algorithm.
7071  *
7072  * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
7073  * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
7074  *
7075  * Note: input buffer is overwritten with decrypted data!
7076  *
7077  * Salt is in KDF parameters and IV is PBE parameters when needed.
7078  *
7079  * @param [in] input       Data to decrypt and unwrap.
7080  * @param [in] sz          Size of encrypted data.
7081  * @param [in] password    Password to derive encryption key with.
7082  * @param [in] passwordSz  Size of password in bytes.
7083  * @return  Length of decrypted data on success.
7084  * @return  MEMORY_E when dynamic memory allocation fails.
7085  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7086  *          is invalid.
7087  * @return  BUFFER_E when data in buffer is too small.
7088  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
7089  * @return  Other when decryption fails.
7090  */
7091 int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
7092 {
7093 #ifndef WOLFSSL_ASN_TEMPLATE
7094     word32 inOutIdx = 0, seqEnd, oid, shaOid = 0;
7095     int    ret = 0, first, second, length = 0, version, saltSz, id = 0;
7096     int    iterations = 0, keySz = 0;
7097 #ifdef WOLFSSL_SMALL_STACK
7098     byte*  salt = NULL;
7099     byte*  cbcIv = NULL;
7100 #else
7101     byte   salt[MAX_SALT_SIZE];
7102     byte   cbcIv[MAX_IV_SIZE];
7103 #endif
7104     byte   tag;
7105 
7106     if (passwordSz < 0) {
7107         WOLFSSL_MSG("Bad password size");
7108         return BAD_FUNC_ARG;
7109     }
7110 
7111     if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
7112         ERROR_OUT(ASN_PARSE_E, exit_dc);
7113     }
7114 
7115     first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
7116     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
7117 
7118     if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
7119         ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
7120     }
7121 
7122     if (version == PKCS5v2) {
7123         if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
7124             ERROR_OUT(ASN_PARSE_E, exit_dc);
7125         }
7126 
7127         if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
7128             ERROR_OUT(ASN_PARSE_E, exit_dc);
7129         }
7130 
7131         if (oid != PBKDF2_OID) {
7132             ERROR_OUT(ASN_PARSE_E, exit_dc);
7133         }
7134     }
7135 
7136     if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
7137         ERROR_OUT(ASN_PARSE_E, exit_dc);
7138     }
7139     /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
7140      * DEFAULT items. */
7141     seqEnd = inOutIdx + length;
7142 
7143     ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
7144     if (ret < 0)
7145         goto exit_dc;
7146 
7147     if (saltSz > MAX_SALT_SIZE) {
7148         ERROR_OUT(ASN_PARSE_E, exit_dc);
7149     }
7150 
7151 #ifdef WOLFSSL_SMALL_STACK
7152     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7153     if (salt == NULL) {
7154         ERROR_OUT(MEMORY_E, exit_dc);
7155     }
7156 #endif
7157 
7158     XMEMCPY(salt, &input[inOutIdx], saltSz);
7159     inOutIdx += saltSz;
7160 
7161     if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
7162         ERROR_OUT(ASN_PARSE_E, exit_dc);
7163     }
7164 
7165     /* OPTIONAL key length */
7166     if (seqEnd > inOutIdx) {
7167         word32 localIdx = inOutIdx;
7168 
7169         if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
7170             ERROR_OUT(ASN_PARSE_E, exit_dc);
7171         }
7172 
7173         if (tag == ASN_INTEGER &&
7174                 GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
7175             ERROR_OUT(ASN_PARSE_E, exit_dc);
7176         }
7177     }
7178 
7179     /* DEFAULT HMAC is SHA-1 */
7180     if (seqEnd > inOutIdx) {
7181         if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
7182             ERROR_OUT(ASN_PARSE_E, exit_dc);
7183         }
7184 
7185         shaOid = oid;
7186     }
7187 
7188 #ifdef WOLFSSL_SMALL_STACK
7189     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7190     if (cbcIv == NULL) {
7191         ERROR_OUT(MEMORY_E, exit_dc);
7192     }
7193 #endif
7194 
7195     if (version == PKCS5v2) {
7196         /* get encryption algo */
7197         if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
7198             ERROR_OUT(ASN_PARSE_E, exit_dc);
7199         }
7200 
7201         if (CheckAlgoV2(oid, &id, NULL) < 0) {
7202             ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
7203         }
7204 
7205         if (shaOid == 0)
7206             shaOid = oid;
7207 
7208         ret = GetOctetString(input, &inOutIdx, &length, sz);
7209         if (ret < 0)
7210             goto exit_dc;
7211 
7212         if (length > MAX_IV_SIZE) {
7213             ERROR_OUT(ASN_PARSE_E, exit_dc);
7214         }
7215 
7216         XMEMCPY(cbcIv, &input[inOutIdx], length);
7217         inOutIdx += length;
7218     }
7219 
7220     if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
7221         ERROR_OUT(ASN_PARSE_E, exit_dc);
7222     }
7223 
7224     if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
7225         ERROR_OUT(ASN_PARSE_E, exit_dc);
7226     }
7227 
7228     if (GetLength(input, &inOutIdx, &length, sz) < 0) {
7229         ERROR_OUT(ASN_PARSE_E, exit_dc);
7230     }
7231 
7232     ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
7233                    input + inOutIdx, length, version, cbcIv, 0, shaOid);
7234 
7235 exit_dc:
7236 #ifdef WOLFSSL_SMALL_STACK
7237     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
7238     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7239 #endif
7240 
7241     if (ret == 0) {
7242         XMEMMOVE(input, input + inOutIdx, length);
7243         ret = length;
7244     }
7245 
7246     return ret;
7247 #else
7248     /* pbes2ParamsASN longer than pkcs8DecASN_Length/pbes1ParamsASN_Length. */
7249     DECL_ASNGETDATA(dataASN, pbes2ParamsASN_Length);
7250     int    ret = 0;
7251     int    id;
7252     int    version;
7253     word32 idx = 0;
7254     word32 pIdx = 0;
7255     word32 iterations;
7256     word32 keySz = 0;
7257     word32 saltSz;
7258     word32 shaOid = 0;
7259     byte*  salt = NULL;
7260     byte*  key = NULL;
7261     byte   cbcIv[MAX_IV_SIZE];
7262     byte*  params;
7263 
7264     WOLFSSL_ENTER("DecryptContent");
7265 
7266     CALLOC_ASNGETDATA(dataASN, pbes2ParamsASN_Length, ret, NULL);
7267 
7268     if (ret == 0) {
7269         /* Check OID is a PBE Type */
7270         GetASN_OID(&dataASN[PKCS8DECASN_IDX_ENCALGO_OID], oidPBEType);
7271         ret = GetASN_Items(pkcs8DecASN, dataASN, pkcs8DecASN_Length, 0, input,
7272                            &idx, sz);
7273     }
7274     if (ret == 0) {
7275         /* Check the PBE algorithm and get the version and id. */
7276         idx = dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.length;
7277         /* Second last byte: 1 (PKCS #12 PBE Id) or 5 (PKCS #5)
7278          * Last byte: Alg or PBES2 */
7279         CheckAlgo(dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 2],
7280                   dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 1],
7281                   &id, &version, NULL);
7282 
7283         /* Get the parameters data. */
7284         GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCALGO_PARAMS], &params, &sz);
7285         /* Having a numbered choice means none or both will have errored out. */
7286         if (dataASN[PKCS8DECASN_IDX_ENCCONTENT].tag != 0)
7287             GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCCONTENT], &key, &keySz);
7288         else if (dataASN[PKCS8DECASN_IDX_ENCDATA].tag != 0)
7289             GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCDATA], &key, &keySz);
7290     }
7291 
7292     if (ret == 0) {
7293         if (version != PKCS5v2) {
7294             /* Initialize for PBES1 parameters and put iterations in var. */
7295             XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes1ParamsASN_Length);
7296             GetASN_Int32Bit(&dataASN[PBES1PARAMSASN_IDX_ITER], &iterations);
7297             /* Parse the PBES1 parameters. */
7298             ret = GetASN_Items(pbes1ParamsASN, dataASN, pbes1ParamsASN_Length,
7299                                0, params, &pIdx, sz);
7300             if (ret == 0) {
7301                 /* Get the salt data. */
7302                 GetASN_GetRef(&dataASN[PBES1PARAMSASN_IDX_SALT], &salt, &saltSz);
7303             }
7304         }
7305         else {
7306             word32 ivSz = MAX_IV_SIZE;
7307 
7308             /* Initialize for PBES2 parameters. Put iterations in var; match
7309              * KDF, HMAC and cipher, and copy CBC into buffer. */
7310             XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes2ParamsASN_Length);
7311             GetASN_ExpBuffer(&dataASN[PBES2PARAMSASN_IDX_KDF_OID], pbkdf2Oid, sizeof(pbkdf2Oid));
7312             GetASN_Int32Bit(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER], &iterations);
7313             GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID], oidHmacType);
7314             GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_ENCS_OID], oidBlkType);
7315             GetASN_Buffer(&dataASN[PBES2PARAMSASN_IDX_ENCS_PARAMS], cbcIv, &ivSz);
7316             /* Parse the PBES2 parameters  */
7317             ret = GetASN_Items(pbes2ParamsASN, dataASN, pbes2ParamsASN_Length,
7318                                0, params, &pIdx, sz);
7319             if (ret == 0) {
7320                 /* Get the salt data. */
7321                 GetASN_GetRef(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT], &salt, &saltSz);
7322                 /* Get the digest and encryption algorithm id. */
7323                 shaOid = dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID].data.oid.sum; /* Default HMAC-SHA1 */
7324                 id     = dataASN[PBES2PARAMSASN_IDX_ENCS_OID].data.oid.sum;
7325                 /* Convert encryption algorithm to a PBE algorithm if needed. */
7326                 CheckAlgoV2(id, &id, NULL);
7327             }
7328         }
7329     }
7330 
7331     if (ret == 0) {
7332         /* Decrypt the key. */
7333         ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
7334                           key, keySz, version, cbcIv, 0, shaOid);
7335     }
7336     if (ret == 0) {
7337         /* Copy the decrypted key into the input (inline). */
7338         XMEMMOVE(input, key, keySz);
7339         ret = keySz;
7340     }
7341 
7342     FREE_ASNGETDATA(dataASN, NULL);
7343     return ret;
7344 #endif
7345 }
7346 
7347 /* Decrypt data using PBE algorithm and get key from PKCS#8 wrapping.
7348  *
7349  * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
7350  * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo
7351  *
7352  * Note: input buffer is overwritten with decrypted key!
7353  *
7354  * Salt is in KDF parameters and IV is PBE parameters when needed.
7355  *
7356  * @param [in]  input       Data to decrypt and unwrap.
7357  * @param [in]  sz          Size of encrypted data.
7358  * @param [in]  password    Password to derive encryption key with.
7359  * @param [in]  passwordSz  Size of password in bytes.
7360  * @param [out] algId       Key algorithm from PKCS#8 wrapper.
7361  * @return  Length of decrypted data on success.
7362  * @return  MEMORY_E when dynamic memory allocation fails.
7363  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7364  *          is invalid.
7365  * @return  BUFFER_E when data in buffer is too small.
7366  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
7367  * @return  Other when decryption fails.
7368  */
7369 int ToTraditionalEnc(byte* input, word32 sz, const char* password,
7370                      int passwordSz, word32* algId)
7371 {
7372     int ret;
7373 
7374     ret = wc_DecryptPKCS8Key(input, sz, password, passwordSz);
7375     if (ret > 0) {
7376         ret = ToTraditional_ex(input, ret, algId);
7377     }
7378 
7379     return ret;
7380 }
7381 
7382 #endif /* HAVE_PKCS8 */
7383 
7384 #ifdef HAVE_PKCS12
7385 
7386 #define PKCS8_MIN_BLOCK_SIZE 8
7387 static int Pkcs8Pad(byte* buf, int sz, int blockSz)
7388 {
7389     int i, padSz;
7390 
7391     /* calculate pad size */
7392     padSz = blockSz - (sz & (blockSz - 1));
7393 
7394     /* pad with padSz value */
7395     if (buf) {
7396         for (i = 0; i < padSz; i++) {
7397             buf[sz+i] = (byte)(padSz & 0xFF);
7398         }
7399     }
7400 
7401     /* return adjusted length */
7402     return sz + padSz;
7403 }
7404 
7405 #ifdef WOLFSSL_ASN_TEMPLATE
7406 /* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
7407  * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
7408  * PKCS #5: RFC 8018, A.3 - PBEParameter
7409  */
7410 static const ASNItem p8EncPbes1ASN[] = {
7411 /* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
7412 /* ENCALGO_SEQ           */     { 1, ASN_SEQUENCE, 1, 1, 0 },
7413                     /* PBE algorithm */
7414 /* ENCALGO_OID           */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
7415 /* ENCALGO_PBEPARAM_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
7416                         /* Salt */
7417 /* ENCALGO_PBEPARAM_SALT */             { 3, ASN_OCTET_STRING, 0, 0, 0 },
7418                         /* Iteration Count */
7419 /* ENCALGO_PBEPARAM_ITER */             { 3, ASN_INTEGER, 0, 0, 0 },
7420 /* ENCDATA               */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
7421 };
7422 enum {
7423     P8ENCPBES1ASN_IDX_SEQ = 0,
7424     P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
7425     P8ENCPBES1ASN_IDX_ENCALGO_OID,
7426     P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SEQ,
7427     P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT,
7428     P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER,
7429     P8ENCPBES1ASN_IDX_ENCDATA,
7430 };
7431 
7432 #define p8EncPbes1ASN_Length (sizeof(p8EncPbes1ASN) / sizeof(ASNItem))
7433 #endif
7434 
7435 /* Wrap a private key in PKCS#8 and encrypt.
7436  *
7437  * Used for PKCS#12 and PKCS#7.
7438  * vPKCS is the version of PKCS to use.
7439  * vAlgo is the algorithm version to use.
7440  *
7441  * When salt is NULL, a random number is generated.
7442  *
7443  * data returned is :
7444  * [ seq - obj [ seq -salt,itt]] , construct with encrypted data
7445  *
7446  * @param [in]  input       Data to encrypt.
7447  * @param [in]  inputSz     Length of data in bytes.
7448  * @param [out] out         Buffer to write wrapped encrypted data into.
7449  * @param [out] outSz       Length of encrypted data in bytes.
7450  * @param [in]  password    Password used to create encryption key.
7451  * @param [in]  passwordSz  Length of password in bytes.
7452  * @param [in]  vPKCS       First byte used to determine PBE algorithm.
7453  * @param [in]  vAlgo       Second byte used to determine PBE algorithm.
7454  * @param [in]  salt        Salt to use with KDF.
7455  * @param [in]  saltSz      Length of salt in bytes.
7456  * @param [in]  itt         Number of iterations to use in KDF.
7457  * @param [in]  rng         Random number generator to use to generate salt.
7458  * @param [in]  heap        Dynamic memory allocator hint.
7459  * @return  The size of encrypted data on success
7460  * @return  LENGTH_ONLY_E when out is NULL and able to encode.
7461  * @return  ASN_PARSE_E when the salt size is too large.
7462  * @return  ASN_VERSION_E when attempting to use a PBES2 algorithm (use
7463  *          TraditionalEnc).
7464  * @return  MEMORY_E when dynamic memory allocation fails.
7465  * @return  Other when encryption or random number generation fails.
7466  */
7467 int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
7468         const char* password, int passwordSz, int vPKCS, int vAlgo,
7469         byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
7470 {
7471 #ifndef WOLFSSL_ASN_TEMPLATE
7472     word32 sz;
7473     word32 inOutIdx = 0;
7474     word32 tmpIdx   = 0;
7475     word32 totalSz  = 0;
7476     word32 seqSz;
7477     word32 innerSz;
7478     int    ret;
7479     int    version, id, blockSz = 0;
7480 #ifdef WOLFSSL_SMALL_STACK
7481     byte*  saltTmp = NULL;
7482     byte*  cbcIv   = NULL;
7483 #else
7484     byte   saltTmp[MAX_SALT_SIZE];
7485     byte   cbcIv[MAX_IV_SIZE];
7486 #endif
7487     byte   seq[MAX_SEQ_SZ];
7488     byte   shr[MAX_SHORT_SZ];
7489     word32 maxShr = MAX_SHORT_SZ;
7490     word32 algoSz;
7491     const  byte* algoName;
7492 
7493     (void)heap;
7494 
7495     WOLFSSL_ENTER("EncryptContent()");
7496 
7497     if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
7498         return ASN_INPUT_E;  /* Algo ID error */
7499 
7500     if (version == PKCS5v2) {
7501         WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
7502         return BAD_FUNC_ARG;
7503     }
7504 
7505     if (saltSz > MAX_SALT_SIZE)
7506         return ASN_PARSE_E;
7507 
7508     if (outSz == NULL) {
7509         return BAD_FUNC_ARG;
7510     }
7511 
7512     /* calculate size */
7513     /* size of constructed string at end */
7514     sz = Pkcs8Pad(NULL, inputSz, blockSz);
7515     totalSz  = ASN_TAG_SZ;
7516     totalSz += SetLength(sz, seq);
7517     totalSz += sz;
7518 
7519     /* size of sequence holding object id and sub sequence of salt and itt */
7520     algoName = OidFromId(id, oidPBEType, &algoSz);
7521     if (algoName == NULL) {
7522         WOLFSSL_MSG("Unknown Algorithm");
7523         return 0;
7524     }
7525     innerSz = SetObjectId(algoSz, seq);
7526     innerSz += algoSz;
7527 
7528     /* get subsequence of salt and itt */
7529     if (salt == NULL || saltSz == 0) {
7530         sz = 8;
7531     }
7532     else {
7533         sz = saltSz;
7534     }
7535     seqSz  = SetOctetString(sz, seq);
7536     seqSz += sz;
7537 
7538     tmpIdx = 0;
7539     ret = SetShortInt(shr, &tmpIdx, itt, maxShr);
7540     if (ret >= 0) {
7541         seqSz += ret;
7542     }
7543     else {
7544         return ret;
7545     }
7546     innerSz += seqSz + SetSequence(seqSz, seq);
7547     totalSz += innerSz + SetSequence(innerSz, seq);
7548 
7549     if (out == NULL) {
7550         *outSz = totalSz;
7551         return LENGTH_ONLY_E;
7552     }
7553 
7554     inOutIdx = 0;
7555     if (totalSz > *outSz)
7556         return BUFFER_E;
7557 
7558     inOutIdx += SetSequence(innerSz, out + inOutIdx);
7559     inOutIdx += SetObjectId(algoSz, out + inOutIdx);
7560     XMEMCPY(out + inOutIdx, algoName, algoSz);
7561     inOutIdx += algoSz;
7562     inOutIdx += SetSequence(seqSz, out + inOutIdx);
7563 
7564     /* create random salt if one not provided */
7565     if (salt == NULL || saltSz == 0) {
7566         saltSz = 8;
7567     #ifdef WOLFSSL_SMALL_STACK
7568         saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
7569         if (saltTmp == NULL)
7570             return MEMORY_E;
7571     #endif
7572         salt = saltTmp;
7573 
7574         if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
7575             WOLFSSL_MSG("Error generating random salt");
7576         #ifdef WOLFSSL_SMALL_STACK
7577             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7578         #endif
7579             return ret;
7580         }
7581     }
7582     inOutIdx += SetOctetString(saltSz, out + inOutIdx);
7583     if (saltSz + inOutIdx > *outSz) {
7584     #ifdef WOLFSSL_SMALL_STACK
7585         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7586     #endif
7587         return BUFFER_E;
7588     }
7589     XMEMCPY(out + inOutIdx, salt, saltSz);
7590     inOutIdx += saltSz;
7591 
7592     /* place iteration setting in buffer */
7593     ret = SetShortInt(out, &inOutIdx, itt, *outSz);
7594     if (ret < 0) {
7595     #ifdef WOLFSSL_SMALL_STACK
7596         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7597     #endif
7598         return ret;
7599     }
7600 
7601     if (inOutIdx + 1 > *outSz) {
7602     #ifdef WOLFSSL_SMALL_STACK
7603         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7604     #endif
7605         return BUFFER_E;
7606     }
7607     out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
7608 
7609     /* get pad size and verify buffer room */
7610     sz = Pkcs8Pad(NULL, inputSz, blockSz);
7611     if (sz + inOutIdx > *outSz) {
7612     #ifdef WOLFSSL_SMALL_STACK
7613         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7614     #endif
7615         return BUFFER_E;
7616     }
7617     inOutIdx += SetLength(sz, out + inOutIdx);
7618 
7619     /* copy input to output buffer and pad end */
7620     XMEMCPY(out + inOutIdx, input, inputSz);
7621     sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);
7622 #ifdef WOLFSSL_SMALL_STACK
7623     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
7624     if (cbcIv == NULL) {
7625         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7626         return MEMORY_E;
7627     }
7628 #endif
7629 
7630     /* encrypt */
7631     if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
7632                    out + inOutIdx, sz, version, cbcIv, 1, 0)) < 0) {
7633 
7634     #ifdef WOLFSSL_SMALL_STACK
7635         XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
7636         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7637     #endif
7638         return ret;  /* encrypt failure */
7639     }
7640 
7641 #ifdef WOLFSSL_SMALL_STACK
7642     XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
7643     XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
7644 #endif
7645 
7646     (void)rng;
7647 
7648     return inOutIdx + sz;
7649 #else
7650     DECL_ASNSETDATA(dataASN, p8EncPbes1ASN_Length);
7651     int ret = 0;
7652     int sz;
7653     int version;
7654     int id;
7655     int blockSz = 0;
7656     byte* pkcs8;
7657     word32 pkcs8Sz;
7658     byte cbcIv[MAX_IV_SIZE];
7659 
7660     (void)heap;
7661 
7662     WOLFSSL_ENTER("EncryptContent()");
7663 
7664     /* Must have a output size to return or check. */
7665     if (outSz == NULL) {
7666         ret = BAD_FUNC_ARG;
7667     }
7668     /* Check salt size is valid. */
7669     if ((ret == 0) && (saltSz > MAX_SALT_SIZE)) {
7670         ret = ASN_PARSE_E;
7671     }
7672     /* Get algorithm parameters for algorithm identifier. */
7673     if ((ret == 0) && CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
7674         ret = ASN_INPUT_E;
7675     }
7676     /* Check PKCS #5 version - only PBSE1 parameters supported. */
7677     if ((ret == 0) && (version == PKCS5v2)) {
7678         ret = BAD_FUNC_ARG;
7679     }
7680 
7681     CALLOC_ASNSETDATA(dataASN, p8EncPbes1ASN_Length, ret, heap);
7682 
7683     if (ret == 0) {
7684         /* Setup data to go into encoding including PBE algorithm, salt,
7685          * iteration count, and padded key length. */
7686         SetASN_OID(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_OID], id, oidPBEType);
7687         if (salt == NULL || saltSz == 0) {
7688             salt = NULL;
7689             saltSz = PKCS5_SALT_SZ;
7690             /* Salt generated into encoding below. */
7691         }
7692         SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT],
7693                 salt, saltSz);
7694         SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER], itt);
7695         pkcs8Sz = Pkcs8Pad(NULL, inputSz, blockSz);
7696         SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
7697 
7698         /* Calculate size of encoding. */
7699         ret = SizeASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
7700                 dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
7701                 (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
7702                 &sz);
7703     }
7704     /* Return size when no output buffer. */
7705     if ((ret == 0) && (out == NULL)) {
7706         *outSz = sz;
7707         ret = LENGTH_ONLY_E;
7708     }
7709     /* Check output buffer is big enough for encoded data. */
7710     if ((ret == 0) && (sz > (int)*outSz)) {
7711         ret = BAD_FUNC_ARG;
7712     }
7713     if (ret == 0) {
7714         /* Encode PKCS#8 key. */
7715         SetASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
7716                  dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
7717                  (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
7718                  out);
7719 
7720         if (salt == NULL) {
7721             /* Generate salt into encoding. */
7722             salt = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT].data.buffer.data;
7723             ret = wc_RNG_GenerateBlock(rng, salt, saltSz);
7724         }
7725     }
7726     if (ret == 0) {
7727         /* Store PKCS#8 key in output buffer. */
7728         pkcs8 = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
7729         XMEMCPY(pkcs8, input, inputSz);
7730         Pkcs8Pad(pkcs8, inputSz, blockSz);
7731 
7732         /* Encrypt PKCS#8 key inline. */
7733         ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id, pkcs8,
7734                           pkcs8Sz, version, cbcIv, 1, 0);
7735     }
7736     if (ret == 0) {
7737         /* Returning size on success. */
7738         ret = sz;
7739     }
7740 
7741     FREE_ASNSETDATA(dataASN, heap);
7742     return ret;
7743 #endif /* WOLFSSL_ASN_TEMPLATE */
7744 }
7745 
7746 
7747 #endif /* HAVE_PKCS12 */
7748 #endif /* NO_PWDBASED */
7749 
7750 #ifndef NO_RSA
7751 
7752 #ifndef HAVE_USER_RSA
7753 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
7754 /* This function is to retrieve key position information in a cert.*
7755  * The information will be used to call TSIP TLS-linked API for    *
7756  * certificate verification.                                       */
7757 static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
7758                                       word32 inSz, word32* key_n,
7759                                       word32* key_n_len, word32* key_e,
7760                                       word32* key_e_len)
7761 {
7762 
7763     int ret = 0;
7764     int length = 0;
7765 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
7766     byte b;
7767 #endif
7768 
7769     if (input == NULL || inOutIdx == NULL)
7770         return BAD_FUNC_ARG;
7771 
7772     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7773         return ASN_PARSE_E;
7774 
7775 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
7776     if ((*inOutIdx + 1) > inSz)
7777         return BUFFER_E;
7778 
7779     b = input[*inOutIdx];
7780     if (b != ASN_INTEGER) {
7781         /* not from decoded cert, will have algo id, skip past */
7782         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7783             return ASN_PARSE_E;
7784 
7785         if (SkipObjectId(input, inOutIdx, inSz) < 0)
7786             return ASN_PARSE_E;
7787 
7788         /* Option NULL ASN.1 tag */
7789         if (*inOutIdx  >= inSz) {
7790             return BUFFER_E;
7791         }
7792         if (input[*inOutIdx] == ASN_TAG_NULL) {
7793             ret = GetASNNull(input, inOutIdx, inSz);
7794             if (ret != 0)
7795                 return ret;
7796         }
7797 
7798         /* should have bit tag length and seq next */
7799         ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
7800         if (ret != 0)
7801             return ret;
7802 
7803         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7804             return ASN_PARSE_E;
7805     }
7806 #endif /* OPENSSL_EXTRA */
7807 
7808     /* Get modulus */
7809     ret = GetASNInt(input, inOutIdx, &length, inSz);
7810     *key_n += *inOutIdx;
7811     if (ret < 0) {
7812         return ASN_RSA_KEY_E;
7813     }
7814     if (key_n_len)
7815         *key_n_len = length;
7816     *inOutIdx += length;
7817 
7818     /* Get exponent */
7819     ret = GetASNInt(input, inOutIdx, &length, inSz);
7820     *key_e += *inOutIdx;
7821     if (ret < 0) {
7822         return ASN_RSA_KEY_E;
7823     }
7824     if (key_e_len)
7825         *key_e_len = length;
7826 
7827     return ret;
7828 }
7829 #endif /* WOLFSSL_RENESAS_TSIP */
7830 
7831 #ifdef WOLFSSL_ASN_TEMPLATE
7832 /* ASN.1 template for an RSA public key.
7833  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
7834  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
7835  */
7836 static const ASNItem rsaPublicKeyASN[] = {
7837 /*  SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
7838 /*  ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
7839 /*  ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
7840 /*  ALGOID_NULL    */         { 2, ASN_TAG_NULL, 0, 0, 1 },
7841 /*  PUBKEY         */     { 1, ASN_BIT_STRING, 0, 1, 0 },
7842                                                   /* RSAPublicKey */
7843 /*  PUBKEY_RSA_SEQ */         { 2, ASN_SEQUENCE, 1, 1, 0 },
7844 /*  PUBKEY_RSA_N   */             { 3, ASN_INTEGER, 0, 0, 0 },
7845 /*  PUBKEY_RSA_E   */             { 3, ASN_INTEGER, 0, 0, 0 },
7846 };
7847 enum {
7848     RSAPUBLICKEYASN_IDX_SEQ = 0,
7849     RSAPUBLICKEYASN_IDX_ALGOID_SEQ,
7850     RSAPUBLICKEYASN_IDX_ALGOID_OID,
7851     RSAPUBLICKEYASN_IDX_ALGOID_NULL,
7852     RSAPUBLICKEYASN_IDX_PUBKEY,
7853     RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ,
7854     RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N,
7855     RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E,
7856 };
7857 
7858 /* Number of items in ASN.1 template for an RSA public key. */
7859 #define rsaPublicKeyASN_Length (sizeof(rsaPublicKeyASN) / sizeof(ASNItem))
7860 #endif
7861 
7862 /* Decode RSA public key.
7863  *
7864  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
7865  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
7866  *
7867  * @param [in]      input     Buffer holding BER encoded data.
7868  * @param [in, out] inOutIdx  On in, start of RSA public key.
7869  *                            On out, start of ASN.1 item after RSA public key.
7870  * @param [in]      inSz      Number of bytes in buffer.
7871  * @param [out]     n         Pointer to modulus in buffer.
7872  * @param [out]     nSz       Size of modulus in bytes.
7873  * @param [out]     e         Pointer to exponent in buffer.
7874  * @param [out]     eSz       Size of exponent in bytes.
7875  * @return  0 on success.
7876  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7877  *          is invalid.
7878  * @return  BUFFER_E when data in buffer is too small.
7879  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
7880  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
7881  *          non-zero length.
7882  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
7883  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
7884  */
7885 int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
7886     const byte** n, word32* nSz, const byte** e, word32* eSz)
7887 {
7888 #ifndef WOLFSSL_ASN_TEMPLATE
7889     int ret = 0;
7890     int length = 0;
7891 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
7892     word32 localIdx;
7893     byte   tag;
7894 #endif
7895 
7896     if (input == NULL || inOutIdx == NULL)
7897         return BAD_FUNC_ARG;
7898 
7899     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7900         return ASN_PARSE_E;
7901 
7902 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
7903     localIdx = *inOutIdx;
7904     if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
7905         return BUFFER_E;
7906 
7907     if (tag != ASN_INTEGER) {
7908         /* not from decoded cert, will have algo id, skip past */
7909         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7910             return ASN_PARSE_E;
7911 
7912         if (SkipObjectId(input, inOutIdx, inSz) < 0)
7913             return ASN_PARSE_E;
7914 
7915         /* Option NULL ASN.1 tag */
7916         if (*inOutIdx  >= inSz) {
7917             return BUFFER_E;
7918         }
7919 
7920         localIdx = *inOutIdx;
7921         if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
7922             return ASN_PARSE_E;
7923 
7924         if (tag == ASN_TAG_NULL) {
7925             ret = GetASNNull(input, inOutIdx, inSz);
7926             if (ret != 0)
7927                 return ret;
7928         }
7929 
7930         /* should have bit tag length and seq next */
7931         ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
7932         if (ret != 0)
7933             return ret;
7934 
7935         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7936             return ASN_PARSE_E;
7937     }
7938 #endif /* OPENSSL_EXTRA */
7939 
7940     /* Get modulus */
7941     ret = GetASNInt(input, inOutIdx, &length, inSz);
7942     if (ret < 0) {
7943         return ASN_RSA_KEY_E;
7944     }
7945     if (nSz)
7946         *nSz = length;
7947     if (n)
7948         *n = &input[*inOutIdx];
7949     *inOutIdx += length;
7950 
7951     /* Get exponent */
7952     ret = GetASNInt(input, inOutIdx, &length, inSz);
7953     if (ret < 0) {
7954         return ASN_RSA_KEY_E;
7955     }
7956     if (eSz)
7957         *eSz = length;
7958     if (e)
7959         *e = &input[*inOutIdx];
7960     *inOutIdx += length;
7961 
7962     return ret;
7963 #else
7964     DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
7965     int ret = 0;
7966 
7967     /* Check validity of parameters. */
7968     if (input == NULL || inOutIdx == NULL) {
7969         ret = BAD_FUNC_ARG;
7970     }
7971 
7972     CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
7973 
7974     if (ret == 0) {
7975         /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
7976         ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
7977            &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
7978            (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
7979            0, input, inOutIdx, inSz);
7980         if (ret != 0) {
7981             /* Didn't work - try whole SubjectKeyInfo instead. */
7982             /* Set the OID to expect. */
7983             GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
7984                     keyRsaOid, sizeof(keyRsaOid));
7985             /* Decode SubjectKeyInfo. */
7986             ret = GetASN_Items(rsaPublicKeyASN, dataASN,
7987                                rsaPublicKeyASN_Length, 1, input, inOutIdx,
7988                                inSz);
7989         }
7990     }
7991     if (ret == 0) {
7992         /* Return the buffers and lengths asked for. */
7993         if (n != NULL) {
7994             *n   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.data;
7995         }
7996         if (nSz != NULL) {
7997             *nSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.length;
7998         }
7999         if (e != NULL) {
8000             *e   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.data;
8001         }
8002         if (eSz != NULL) {
8003             *eSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.length;
8004         }
8005     }
8006 
8007     FREE_ASNGETDATA(dataASN, NULL);
8008     return ret;
8009 #endif /* WOLFSSL_ASN_TEMPLATE */
8010 }
8011 
8012 /* Decode RSA public key.
8013  *
8014  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8015  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
8016  *
8017  * @param [in]      input     Buffer holding BER encoded data.
8018  * @param [in, out] inOutIdx  On in, start of RSA public key.
8019  *                            On out, start of ASN.1 item after RSA public key.
8020  * @param [in, out] key       RSA key object.
8021  * @param [in]      inSz      Number of bytes in buffer.
8022  * @return  0 on success.
8023  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8024  *          is invalid.
8025  * @return  BUFFER_E when data in buffer is too small.
8026  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8027  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
8028  *          non-zero length.
8029  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
8030  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
8031  */
8032 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
8033                        word32 inSz)
8034 {
8035 #ifndef WOLFSSL_ASN_TEMPLATE
8036     int ret;
8037     const byte *n = NULL, *e = NULL;
8038     word32 nSz = 0, eSz = 0;
8039 
8040     if (key == NULL)
8041         return BAD_FUNC_ARG;
8042 
8043     ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
8044     if (ret == 0) {
8045         ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
8046     }
8047 
8048     return ret;
8049 #else
8050     DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
8051     int ret = 0;
8052 
8053     /* Check validity of parameters. */
8054     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
8055         ret = BAD_FUNC_ARG;
8056     }
8057 
8058     CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
8059 
8060     if (ret == 0) {
8061         /* Set mp_ints to fill with modulus and exponent data. */
8062         GetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
8063         GetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
8064         /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
8065         ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
8066                &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
8067                (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
8068                0, input, inOutIdx, inSz);
8069         if (ret != 0) {
8070             /* Didn't work - try whole SubjectKeyInfo instead. */
8071             /* Set the OID to expect. */
8072             GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
8073                     keyRsaOid, sizeof(keyRsaOid));
8074             /* Decode SubjectKeyInfo. */
8075             ret = GetASN_Items(rsaPublicKeyASN, dataASN,
8076                                rsaPublicKeyASN_Length, 1, input, inOutIdx,
8077                                inSz);
8078         }
8079     }
8080 
8081     FREE_ASNGETDATA(dataASN, NULL);
8082     return ret;
8083 #endif
8084 }
8085 
8086 /* import RSA public key elements (n, e) into RsaKey structure (key) */
8087 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
8088                              word32 eSz, RsaKey* key)
8089 {
8090     if (n == NULL || e == NULL || key == NULL)
8091         return BAD_FUNC_ARG;
8092 
8093     key->type = RSA_PUBLIC;
8094 
8095     if (mp_init(&key->n) != MP_OKAY)
8096         return MP_INIT_E;
8097 
8098     if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
8099         mp_clear(&key->n);
8100         return ASN_GETINT_E;
8101     }
8102 #ifdef HAVE_WOLF_BIGINT
8103     if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
8104         mp_clear(&key->n);
8105         return ASN_GETINT_E;
8106     }
8107 #endif /* HAVE_WOLF_BIGINT */
8108 
8109     if (mp_init(&key->e) != MP_OKAY) {
8110         mp_clear(&key->n);
8111         return MP_INIT_E;
8112     }
8113 
8114     if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
8115         mp_clear(&key->n);
8116         mp_clear(&key->e);
8117         return ASN_GETINT_E;
8118     }
8119 #ifdef HAVE_WOLF_BIGINT
8120     if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
8121         mp_clear(&key->n);
8122         mp_clear(&key->e);
8123         return ASN_GETINT_E;
8124     }
8125 #endif /* HAVE_WOLF_BIGINT */
8126 
8127 #ifdef WOLFSSL_XILINX_CRYPT
8128     if (wc_InitRsaHw(key) != 0) {
8129         return BAD_STATE_E;
8130     }
8131 #endif
8132 
8133     return 0;
8134 }
8135 #endif /* HAVE_USER_RSA */
8136 #endif /* !NO_RSA */
8137 
8138 #ifndef NO_DH
8139 #if defined(WOLFSSL_DH_EXTRA)
8140 /*
8141  * Decodes DH public key to fill specified DhKey.
8142  *
8143  * return 0 on success, negative on failure
8144  */
8145 int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx,
8146                 DhKey* key, word32 inSz)
8147 {
8148     int ret = 0;
8149     int length;
8150     word32 oid = 0;
8151 
8152     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
8153         return BAD_FUNC_ARG;
8154 
8155     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8156         return ASN_PARSE_E;
8157 
8158     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8159         return ASN_PARSE_E;
8160 
8161     ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
8162     if (oid != DHk || ret < 0)
8163         return ASN_DH_KEY_E;
8164 
8165     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8166         return ASN_PARSE_E;
8167 
8168     if (GetInt(&key->p, input, inOutIdx, inSz) < 0)
8169         return ASN_DH_KEY_E;
8170 
8171     if (GetInt(&key->g, input, inOutIdx, inSz) < 0) {
8172         mp_clear(&key->p);
8173         return ASN_DH_KEY_E;
8174     }
8175     ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
8176     if (ret > 0) {
8177         /* Found Bit String WOLFSSL_DH_EXTRA is required to access DhKey.pub */
8178         if (GetInt(&key->pub, input, inOutIdx, inSz) < 0) {
8179             mp_clear(&key->p);
8180             mp_clear(&key->g);
8181             return ASN_DH_KEY_E;
8182         }
8183     }
8184     else {
8185         mp_clear(&key->p);
8186         mp_clear(&key->g);
8187         return ASN_DH_KEY_E;
8188     }
8189     return 0;
8190 }
8191 #endif /* WOLFSSL_DH_EXTRA */
8192 
8193 #ifdef WOLFSSL_ASN_TEMPLATE
8194 /* ASN.1 template for DH key.
8195  * PKCS #3, 9 - DHParameter.
8196  * (Also in: RFC 2786, 3)
8197  */
8198 static const ASNItem dhParamASN[] = {
8199 /* SEQ     */    { 0, ASN_SEQUENCE, 1, 1, 0 },
8200                 /* prime */
8201 /* PRIME   */        { 1, ASN_INTEGER, 0, 0, 0 },
8202                 /* base */
8203 /* BASE    */        { 1, ASN_INTEGER, 0, 0, 0 },
8204                 /* privateValueLength */
8205 /* PRIVLEN */        { 1, ASN_INTEGER, 0, 0, 1 },
8206 };
8207 enum {
8208     DHPARAMASN_IDX_SEQ = 0,
8209     DHPARAMASN_IDX_PRIME,
8210     DHPARAMASN_IDX_BASE,
8211     DHPARAMASN_IDX_PRIVLEN,
8212 };
8213 
8214 /* Number of items in ASN.1 template for DH key. */
8215 #define dhParamASN_Length (sizeof(dhParamASN) / sizeof(ASNItem))
8216 
8217 #ifdef WOLFSSL_DH_EXTRA
8218 /* ASN.1 template for DH key wrapped in PKCS #8 or SubjectPublicKeyInfo.
8219  * PKCS #8: RFC 5208, 5 - PrivateKeyInfo
8220  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8221  * RFC 3279, 2.3.3 - DH in SubjectPublicKeyInfo
8222  */
8223 static const ASNItem dhKeyPkcs8ASN[] = {
8224 /* SEQ                  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8225 /* VER                  */     { 1, ASN_INTEGER, 0, 0, 1 },
8226 /* PKEYALGO_SEQ         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8227 /* PKEYALGO_OID         */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
8228                                                      /* DHParameter */
8229 /* PKEYALGO_PARAM_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
8230                                                          /* p */
8231 /* PKEYALGO_PARAM_P     */             { 3, ASN_INTEGER, 0, 0, 0 },
8232                                                          /* g */
8233 /* PKEYALGO_PARAM_G     */             { 3, ASN_INTEGER, 0, 0, 0 },
8234                                                          /* q - factor of p-1 */
8235 /* PKEYALGO_PARAM_Q     */             { 3, ASN_INTEGER, 0, 0, 1 },
8236                                                          /* j - subgroup factor */
8237 /* PKEYALGO_PARAM_J     */             { 3, ASN_INTEGER, 0, 0, 1 },
8238                                                          /* ValidationParms */
8239 /* PKEYALGO_PARAM_VALID */             { 3, ASN_SEQUENCE, 0, 0, 1 },
8240                                                  /* PrivateKey - PKCS #8 */
8241 /* PKEY_STR             */     { 1, ASN_OCTET_STRING, 0, 1, 2 },
8242 /* PKEY_INT             */         { 2, ASN_INTEGER, 0, 0, 0 },
8243                                                  /* PublicKey - SubjectPublicKeyInfo. */
8244 /* PUBKEY_STR           */     { 1, ASN_BIT_STRING, 0, 1, 2 },
8245 /* PUBKEY_INT           */         { 2, ASN_INTEGER, 0, 0, 0 },
8246 };
8247 enum {
8248     DHKEYPKCS8ASN_IDX_SEQ = 0,
8249     DHKEYPKCS8ASN_IDX_VER,
8250     DHKEYPKCS8ASN_IDX_PKEYALGO_SEQ,
8251     DHKEYPKCS8ASN_IDX_PKEYALGO_OID,
8252     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_SEQ,
8253     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P,
8254     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G,
8255     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q,
8256     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J,
8257     DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID,
8258     DHKEYPKCS8ASN_IDX_PKEY_STR,
8259     DHKEYPKCS8ASN_IDX_PKEY_INT,
8260     DHKEYPKCS8ASN_IDX_PUBKEY_STR,
8261     DHKEYPKCS8ASN_IDX_PUBKEY_INT,
8262 };
8263 
8264 #define dhKeyPkcs8ASN_Length (sizeof(dhKeyPkcs8ASN) / sizeof(ASNItem))
8265 #endif
8266 #endif
8267 
8268 /* Decodes either PKCS#3 DH parameters or PKCS#8 DH key file (WOLFSSL_DH_EXTRA).
8269  *
8270  * See also wc_DhParamsLoad(). Loads directly into buffers rather than key
8271  * object.
8272  *
8273  * @param [in]      input     BER/DER encoded data.
8274  * @param [in, out] inOutIdx  On in, start of DH key data.
8275  *                            On out, end of DH key data.
8276  * @param [in, out] key       DH key object.
8277  * @param [in]      inSz      Size of data in bytes.
8278  * @return  0 on success.
8279  * @return  BAD_FUNC_ARG when input, inOutIDx or key is NULL.
8280  * @return  MEMORY_E when dynamic memory allocation fails.
8281  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8282  *          is invalid.
8283  * @return  BUFFER_E when data in buffer is too small.
8284  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8285  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
8286  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
8287  *          non-zero length.
8288  * @return  MP_INIT_E when the unable to initialize an mp_int.
8289  * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
8290  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
8291  */
8292 int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
8293 {
8294 #ifndef WOLFSSL_ASN_TEMPLATE
8295     int ret = 0;
8296     int length;
8297 #ifdef WOLFSSL_DH_EXTRA
8298     #if !defined(HAVE_FIPS) || \
8299         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
8300     word32 oid = 0, temp = 0;
8301     #endif
8302 #endif
8303 
8304     WOLFSSL_ENTER("wc_DhKeyDecode");
8305 
8306     if (inOutIdx == NULL)
8307         return BAD_FUNC_ARG;
8308 
8309     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8310         return ASN_PARSE_E;
8311 
8312 #ifdef WOLFSSL_DH_EXTRA
8313     #if !defined(HAVE_FIPS) || \
8314         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
8315     temp = *inOutIdx;
8316     #endif
8317 #endif
8318     /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
8319     if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
8320         ret = ASN_DH_KEY_E;
8321     }
8322     if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
8323         mp_clear(&key->p);
8324         ret = ASN_DH_KEY_E;
8325     }
8326 
8327 #ifdef WOLFSSL_DH_EXTRA
8328     #if !defined(HAVE_FIPS) || \
8329         (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
8330     /* If ASN_DH_KEY_E: Check if input started at beginning of key */
8331     if (ret == ASN_DH_KEY_E) {
8332         *inOutIdx = temp;
8333 
8334         /* the version (0) - private only (for public skip) */
8335         if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
8336             *inOutIdx += length;
8337         }
8338 
8339         /* Size of dhKeyAgreement section */
8340         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8341             return ASN_PARSE_E;
8342 
8343         /* Check for dhKeyAgreement */
8344         ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
8345         if (oid != DHk || ret < 0)
8346             return ASN_DH_KEY_E;
8347 
8348         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8349             return ASN_PARSE_E;
8350 
8351         if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
8352             return ASN_DH_KEY_E;
8353         }
8354         if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
8355             mp_clear(&key->p);
8356             return ASN_DH_KEY_E;
8357         }
8358     }
8359 
8360     temp = *inOutIdx;
8361     ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
8362     if (ret > 0) {
8363         /* Found Bit String */
8364         if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
8365             WOLFSSL_MSG("Found Public Key");
8366             ret = 0;
8367         }
8368     } else {
8369         *inOutIdx = temp;
8370         ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
8371         if (ret > 0) {
8372             /* Found Octet String */
8373             if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
8374                 WOLFSSL_MSG("Found Private Key");
8375 
8376                 /* Compute public */
8377                 ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
8378             }
8379         } else {
8380             /* Don't use length from failed CheckBitString/GetOctetString */
8381             *inOutIdx = temp;
8382             ret = 0;
8383         }
8384     }
8385     #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
8386 #endif /* WOLFSSL_DH_EXTRA */
8387 
8388     WOLFSSL_LEAVE("wc_DhKeyDecode", ret);
8389 
8390     return ret;
8391 #else
8392 #ifdef WOLFSSL_DH_EXTRA
8393     DECL_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length);
8394 #else
8395     DECL_ASNGETDATA(dataASN, dhParamASN_Length);
8396 #endif
8397     int ret = 0;
8398 
8399     /* Check input parameters are valid. */
8400     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
8401         ret = BAD_FUNC_ARG;
8402     }
8403 
8404 #ifdef WOLFSSL_DH_EXTRA
8405     ALLOC_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length, ret, key->heap);
8406 #else
8407     ALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, key->heap);
8408 #endif
8409 
8410     if (ret == 0) {
8411         /* Initialize data and set mp_ints to hold p and g. */
8412         XMEMSET(dataASN, 0, sizeof(*dataASN) * dhParamASN_Length);
8413         GetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
8414         GetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
8415         /* Try simple PKCS #3 template. */
8416         ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
8417                            inOutIdx, inSz);
8418 #ifdef WOLFSSL_DH_EXTRA
8419         if (ret != 0) {
8420             /* Initialize data and set mp_ints to hold p, g, q, priv and pub. */
8421             XMEMSET(dataASN, 0, sizeof(*dataASN) * dhKeyPkcs8ASN_Length);
8422             GetASN_ExpBuffer(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID],
8423                     keyDhOid, sizeof(keyDhOid));
8424             GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
8425             GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
8426             GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q], &key->q);
8427             GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
8428             GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
8429             /* Try PKCS #8 wrapped template. */
8430             ret = GetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, 1,
8431                                input, inOutIdx, inSz);
8432             if (ret == 0) {
8433                 /* VERSION only present in PKCS #8 private key structure */
8434                 if ((dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].length != 0) &&
8435                         (dataASN[DHKEYPKCS8ASN_IDX_VER].length == 0)) {
8436                     ret = ASN_PARSE_E;
8437                 }
8438                 else if ((dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].length != 0) &&
8439                         (dataASN[DHKEYPKCS8ASN_IDX_VER].length != 0)) {
8440                     ret = ASN_PARSE_E;
8441                 }
8442             }
8443         }
8444 #endif
8445     }
8446 
8447     FREE_ASNGETDATA(dataASN, key->heap);
8448     return ret;
8449 #endif /* WOLFSSL_ASN_TEMPLATE */
8450 }
8451 
8452 #ifdef WOLFSSL_DH_EXTRA
8453 
8454 /* Export DH Key (private or public) */
8455 int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
8456 {
8457 #ifndef WOLFSSL_ASN_TEMPLATE
8458     int ret, privSz = 0, pubSz = 0, keySz;
8459     word32 idx, len, total;
8460 
8461     if (key == NULL || outSz == NULL) {
8462         return BAD_FUNC_ARG;
8463     }
8464 
8465     /* determine size */
8466     if (exportPriv) {
8467         /* octect string: priv */
8468         privSz = SetASNIntMP(&key->priv, -1, NULL);
8469         idx = 1 + SetLength(privSz, NULL) + privSz; /* +1 for ASN_OCTET_STRING */
8470     }
8471     else {
8472         /* bit string: public */
8473         pubSz = SetASNIntMP(&key->pub, -1, NULL);
8474         idx = SetBitString(pubSz, 0, NULL) + pubSz;
8475     }
8476     keySz = idx;
8477 
8478     /* DH Parameters sequence with P and G */
8479     total = 0;
8480     ret = wc_DhParamsToDer(key, NULL, &total);
8481     if (ret != LENGTH_ONLY_E)
8482         return ret;
8483     idx += total;
8484 
8485     /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
8486     idx += SetObjectId(sizeof(keyDhOid), NULL);
8487     idx += sizeof(keyDhOid);
8488     len = idx - keySz;
8489     /* sequence - all but pub/priv */
8490     idx += SetSequence(len, NULL);
8491     if (exportPriv) {
8492         /* version: 0 (ASN_INTEGER, 0x01, 0x00) */
8493         idx += 3;
8494     }
8495     /* sequence */
8496     total = idx + SetSequence(idx, NULL);
8497 
8498     /* if no output, then just getting size */
8499     if (output == NULL) {
8500         *outSz = total;
8501         return LENGTH_ONLY_E;
8502     }
8503 
8504     /* make sure output fits in buffer */
8505     if (total > *outSz) {
8506         return BUFFER_E;
8507     }
8508     total = idx;
8509 
8510     /* sequence */
8511     idx = SetSequence(total, output);
8512     if (exportPriv) {
8513         /* version: 0 */
8514         idx += SetMyVersion(0, output + idx, 0);
8515     }
8516     /* sequence - all but pub/priv */
8517     idx += SetSequence(len, output + idx);
8518     /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
8519     idx += SetObjectId(sizeof(keyDhOid), output + idx);
8520     XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
8521     idx += sizeof(keyDhOid);
8522 
8523     /* DH Parameters sequence with P and G */
8524     total = *outSz - idx;
8525     ret = wc_DhParamsToDer(key, output + idx, &total);
8526     if (ret < 0)
8527         return ret;
8528     idx += total;
8529 
8530     /* octect string: priv */
8531     if (exportPriv) {
8532         idx += SetOctetString(privSz, output + idx);
8533         idx += SetASNIntMP(&key->priv, -1, output + idx);
8534     }
8535     else {
8536         /* bit string: public */
8537         idx += SetBitString(pubSz, 0, output + idx);
8538         idx += SetASNIntMP(&key->pub, -1, output + idx);
8539     }
8540     *outSz = idx;
8541 
8542     return idx;
8543 #else
8544     ASNSetData dataASN[dhKeyPkcs8ASN_Length];
8545     int ret = 0;
8546     int sz;
8547 
8548     WOLFSSL_ENTER("wc_DhKeyToDer");
8549 
8550     XMEMSET(dataASN, 0, sizeof(dataASN));
8551     SetASN_Int8Bit(&dataASN[DHKEYPKCS8ASN_IDX_VER], 0);
8552     SetASN_OID(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID], DHk, oidKeyType);
8553     /* Set mp_int containing p and g. */
8554     SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
8555     SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
8556     dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q].noOut = 1;
8557     dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J].noOut = 1;
8558     dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID].noOut = 1;
8559 
8560     if (exportPriv) {
8561         SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
8562         dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_STR].noOut = 1;
8563         dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].noOut = 1;
8564     }
8565     else {
8566         dataASN[DHKEYPKCS8ASN_IDX_VER].noOut = 1;
8567         dataASN[DHKEYPKCS8ASN_IDX_PKEY_STR].noOut = 1;
8568         dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].noOut = 1;
8569         SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
8570     }
8571 
8572     /* Calculate the size of the DH parameters. */
8573     ret = SizeASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, &sz);
8574     if (output == NULL) {
8575         *outSz = sz;
8576         ret = LENGTH_ONLY_E;
8577     }
8578     /* Check buffer is big enough for encoding. */
8579     if ((ret == 0) && ((int)*outSz < sz)) {
8580         ret = BUFFER_E;
8581     }
8582     if (ret == 0) {
8583         /* Encode the DH parameters into buffer. */
8584         SetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, output);
8585         /* Set the actual encoding size. */
8586         *outSz = sz;
8587         /* Return the actual encoding size. */
8588         ret = sz;
8589     }
8590 
8591     return ret;
8592 #endif
8593 }
8594 
8595 int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz)
8596 {
8597     return wc_DhKeyToDer(key, out, outSz, 0);
8598 }
8599 int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
8600 {
8601     return wc_DhKeyToDer(key, out, outSz, 1);
8602 }
8603 
8604 
8605 /* Convert DH key parameters to DER format, write to output (outSz)
8606  * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
8607  * returned.
8608  *
8609  * Note : static function due to redefinition complications with DhKey and FIPS
8610  * version 2 build.
8611  *
8612  * return bytes written on success */
8613 int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
8614 {
8615 #ifndef WOLFSSL_ASN_TEMPLATE
8616     word32 idx, total;
8617 
8618     if (key == NULL || outSz == NULL) {
8619         return BAD_FUNC_ARG;
8620     }
8621 
8622     /* determine size */
8623     /* integer - g */
8624     idx = SetASNIntMP(&key->g, -1, NULL);
8625     /* integer - p */
8626     idx += SetASNIntMP(&key->p, -1, NULL);
8627     total = idx;
8628      /* sequence */
8629     idx += SetSequence(idx, NULL);
8630 
8631     if (output == NULL) {
8632         *outSz = idx;
8633         return LENGTH_ONLY_E;
8634     }
8635     /* make sure output fits in buffer */
8636     if (idx > *outSz) {
8637         return BUFFER_E;
8638     }
8639 
8640 
8641     /* write DH parameters */
8642     /* sequence - for P and G only */
8643     idx = SetSequence(total, output);
8644     /* integer - p */
8645     idx += SetASNIntMP(&key->p, -1, output + idx);
8646     /* integer - g */
8647     idx += SetASNIntMP(&key->g, -1, output + idx);
8648     *outSz = idx;
8649 
8650     return idx;
8651 #else
8652     ASNSetData dataASN[dhParamASN_Length];
8653     int ret = 0;
8654     int sz;
8655 
8656     WOLFSSL_ENTER("wc_DhParamsToDer");
8657 
8658     if (key == NULL || outSz == NULL) {
8659         ret = BAD_FUNC_ARG;
8660     }
8661 
8662     if (ret == 0) {
8663         XMEMSET(dataASN, 0, sizeof(dataASN));
8664         /* Set mp_int containing p and g. */
8665         SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
8666         SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
8667         /* privateValueLength not encoded. */
8668         dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
8669 
8670         /* Calculate the size of the DH parameters. */
8671         ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
8672     }
8673     if ((ret == 0) && (output == NULL)) {
8674         *outSz = sz;
8675         ret = LENGTH_ONLY_E;
8676     }
8677     /* Check buffer is big enough for encoding. */
8678     if ((ret == 0) && ((int)*outSz < sz)) {
8679         ret = BUFFER_E;
8680     }
8681     if (ret == 0) {
8682         /* Encode the DH parameters into buffer. */
8683         SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, output);
8684         /* Set the actual encoding size. */
8685         *outSz = sz;
8686         /* Return count of bytes written. */
8687         ret = sz;
8688     }
8689 
8690     return ret;
8691 #endif
8692 }
8693 
8694 #endif /* WOLFSSL_DH_EXTRA */
8695 
8696 /* Decode DH parameters.
8697  *
8698  * PKCS #3, 9 - DHParameter.
8699  * (Also in: RFC 2786, 3)
8700  *
8701  * @param [in]      input     Buffer holding BER encoded data.
8702  * @param [in, out] inOutIdx  On in, start of RSA public key.
8703  *                            On out, start of ASN.1 item after RSA public key.
8704  * @param [in]      inSz      Number of bytes in buffer.
8705  * @param [in, out] p         Buffer to hold prime.
8706  * @param [out]     pInOutSz  On in, size of buffer to hold prime in bytes.
8707  *                            On out, size of prime in bytes.
8708  * @param [in, out] g         Buffer to hold base.
8709  * @param [out]     gInOutSz  On in, size of buffer to hold base in bytes.
8710  *                            On out, size of base in bytes.
8711  * @return  0 on success.
8712  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8713  *          is invalid.
8714  * @return  BUFFER_E when data in buffer is too small.
8715  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
8716  */
8717 int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
8718                  byte* g, word32* gInOutSz)
8719 {
8720 #ifndef WOLFSSL_ASN_TEMPLATE
8721     word32 idx = 0;
8722     int    ret;
8723     int    length;
8724 
8725     if (GetSequence(input, &idx, &length, inSz) <= 0)
8726         return ASN_PARSE_E;
8727 
8728     ret = GetASNInt(input, &idx, &length, inSz);
8729     if (ret != 0)
8730         return ret;
8731 
8732     if (length <= (int)*pInOutSz) {
8733         XMEMCPY(p, &input[idx], length);
8734         *pInOutSz = length;
8735     }
8736     else {
8737         return BUFFER_E;
8738     }
8739     idx += length;
8740 
8741     ret = GetASNInt(input, &idx, &length, inSz);
8742     if (ret != 0)
8743         return ret;
8744 
8745     if (length <= (int)*gInOutSz) {
8746         XMEMCPY(g, &input[idx], length);
8747         *gInOutSz = length;
8748     }
8749     else {
8750         return BUFFER_E;
8751     }
8752 
8753     return 0;
8754 #else
8755     DECL_ASNGETDATA(dataASN, dhParamASN_Length);
8756     word32 idx = 0;
8757     int ret = 0;
8758 
8759     /* Make sure pointers are valid before use. */
8760     if ((input == NULL) || (p == NULL) || (pInOutSz == NULL) || (g == NULL) ||
8761             (gInOutSz == NULL)) {
8762         ret = BAD_FUNC_ARG;
8763     }
8764 
8765     CALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, NULL);
8766 
8767     if (ret == 0) {
8768         /* Set the buffers to copy p and g into. */
8769         GetASN_Buffer(&dataASN[DHPARAMASN_IDX_PRIME], p, pInOutSz);
8770         GetASN_Buffer(&dataASN[DHPARAMASN_IDX_BASE], g, gInOutSz);
8771         /* Decode the DH Parameters. */
8772         ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
8773                            &idx, inSz);
8774     }
8775 
8776     FREE_ASNGETDATA(dataASN, NULL);
8777     return ret;
8778 #endif /* WOLFSSL_ASN_TEMPLATE */
8779 }
8780 #endif /* !NO_DH */
8781 
8782 
8783 #ifndef NO_DSA
8784 
8785 static mp_int* GetDsaInt(DsaKey* key, int idx)
8786 {
8787     if (idx == 0)
8788         return &key->p;
8789     if (idx == 1)
8790         return &key->q;
8791     if (idx == 2)
8792         return &key->g;
8793     if (idx == 3)
8794         return &key->y;
8795     if (idx == 4)
8796         return &key->x;
8797 
8798     return NULL;
8799 }
8800 
8801 #ifdef WOLFSSL_ASN_TEMPLATE
8802 /* ASN.1 template for DSA public and private keys.
8803  * Public key: seq, p, q, g, y
8804  * Private key: seq, version, p, q, g, y, x
8805  * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
8806  */
8807 static const ASNItem dsaKeyASN[] = {
8808 /* SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
8809 /* VER */        { 1, ASN_INTEGER, 0, 0, 0 },
8810 /* P   */        { 1, ASN_INTEGER, 0, 0, 0 },
8811 /* Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
8812 /* G   */        { 1, ASN_INTEGER, 0, 0, 0 },
8813 /* Y   */        { 1, ASN_INTEGER, 0, 0, 0 },
8814 /* X   */        { 1, ASN_INTEGER, 0, 0, 0 },
8815 };
8816 enum {
8817     DSAKEYASN_IDX_SEQ = 0,
8818     DSAKEYASN_IDX_VER,
8819     DSAKEYASN_IDX_P,
8820     DSAKEYASN_IDX_Q,
8821     DSAKEYASN_IDX_G,
8822     DSAKEYASN_IDX_Y,
8823     DSAKEYASN_IDX_X,
8824 };
8825 
8826 /* Number of items in ASN.1 template for DSA private key. */
8827 #define dsaKeyASN_Length (sizeof(dsaKeyASN) / sizeof(ASNItem))
8828 /* Number of items in ASN.1 template for DSA public key. */
8829 #define dsaPublicKeyASN_Length ((sizeof(dsaKeyASN) / sizeof(ASNItem)) - 2)
8830 
8831 /* ASN.1 template for PublicKeyInfo with DSA.
8832  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8833  * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
8834  */
8835 static const ASNItem dsaPubKeyASN[] = {
8836 /* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8837 /* ALGOID_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8838 /* ALGOID_OID      */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
8839 /* ALGOID_PARAMS   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
8840                                                    /* p */
8841 /* ALGOID_PARAMS_P */             { 3, ASN_INTEGER, 0, 0, 0 },
8842                                                    /* q */
8843 /* ALGOID_PARAMS_Q */             { 3, ASN_INTEGER, 0, 0, 0 },
8844                                                    /* g */
8845 /* ALGOID_PARAMS_G */             { 3, ASN_INTEGER, 0, 0, 0 },
8846 /* PUBKEY_STR      */     { 1, ASN_BIT_STRING, 0, 1, 1 },
8847                                                /* y */
8848 /* PUBKEY_Y        */         { 2, ASN_INTEGER, 0, 0, 0 },
8849 };
8850 enum {
8851     DSAPUBKEYASN_IDX_SEQ = 0,
8852     DSAPUBKEYASN_IDX_ALGOID_SEQ,
8853     DSAPUBKEYASN_IDX_ALGOID_OID,
8854     DSAPUBKEYASN_IDX_ALGOID_PARAMS,
8855     DSAPUBKEYASN_IDX_ALGOID_PARAMS_P,
8856     DSAPUBKEYASN_IDX_ALGOID_PARAMS_Q,
8857     DSAPUBKEYASN_IDX_ALGOID_PARAMS_G,
8858     DSAPUBKEYASN_IDX_PUBKEY_STR,
8859     DSAPUBKEYASN_IDX_PUBKEY_Y,
8860 };
8861 
8862 /* Number of items in ASN.1 template for PublicKeyInfo with DSA. */
8863 #define dsaPubKeyASN_Length (sizeof(dsaPubKeyASN) / sizeof(ASNItem))
8864 #endif /* WOLFSSL_ASN_TEMPLATE */
8865 
8866 /* Decode DSA public key.
8867  *
8868  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8869  * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
8870  *
8871  * @param [in]      input     Buffer holding BER encoded data.
8872  * @param [in, out] inOutIdx  On in, start of DSA public key.
8873  *                            On out, start of ASN.1 item after DSA public key.
8874  * @param [in, out] key       DSA key object.
8875  * @param [in]      inSz      Number of bytes in buffer.
8876  * @return  0 on success.
8877  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8878  *          is invalid.
8879  * @return  BUFFER_E when data in buffer is too small.
8880  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8881  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
8882  *          non-zero length.
8883  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
8884  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
8885  */
8886 int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
8887                           word32 inSz)
8888 {
8889 #ifndef WOLFSSL_ASN_TEMPLATE
8890     int    length;
8891     int    ret = 0;
8892     word32 oid;
8893     word32 maxIdx;
8894 
8895     if (input == NULL || inOutIdx == NULL || key == NULL)
8896         return BAD_FUNC_ARG;
8897 
8898     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8899         return ASN_PARSE_E;
8900 
8901     maxIdx = (word32)(*inOutIdx + length);
8902     if (GetInt(&key->p,  input, inOutIdx, maxIdx) < 0 ||
8903         GetInt(&key->q,  input, inOutIdx, maxIdx) < 0 ||
8904         GetInt(&key->g,  input, inOutIdx, maxIdx) < 0 ||
8905         GetInt(&key->y,  input, inOutIdx, maxIdx) < 0 )
8906         ret = ASN_DH_KEY_E;
8907 
8908     if (ret != 0) {
8909         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8910             return ASN_PARSE_E;
8911 
8912         ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
8913         if (ret != 0)
8914             return ret;
8915 
8916         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8917             return ASN_PARSE_E;
8918 
8919         if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
8920             GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
8921             GetInt(&key->g,  input, inOutIdx, inSz) < 0)
8922             return ASN_DH_KEY_E;
8923 
8924         if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
8925             return ASN_PARSE_E;
8926 
8927         if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
8928             return ASN_DH_KEY_E;
8929 
8930         ret = 0;
8931     }
8932 
8933     key->type = DSA_PUBLIC;
8934     return ret;
8935 #else
8936     /* dsaPubKeyASN is longer than dsaPublicKeyASN. */
8937     DECL_ASNGETDATA(dataASN, dsaPubKeyASN_Length);
8938     int ret = 0;
8939     int i;
8940 
8941     /* Validated parameters. */
8942     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
8943         ret = BAD_FUNC_ARG;
8944     }
8945 
8946     ALLOC_ASNGETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
8947 
8948     if (ret == 0) {
8949         /* Clear dynamic data items. */
8950         XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPublicKeyASN_Length);
8951         /* seq
8952          *   p, q, g, y
8953          * Start DSA ints from DSAKEYASN_IDX_VER instead of DSAKEYASN_IDX_P */
8954         for (i = 0; i < DSA_INTS - 1; i++)
8955             GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i], GetDsaInt(key, i));
8956         /* Parse as simple form. */
8957         ret = GetASN_Items(dsaKeyASN, dataASN, dsaPublicKeyASN_Length, 1, input,
8958                            inOutIdx, inSz);
8959         if (ret != 0) {
8960             /* Clear dynamic data items. */
8961             XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPubKeyASN_Length);
8962             /* Set DSA OID to expect. */
8963             GetASN_ExpBuffer(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID],
8964                     keyDsaOid, sizeof(keyDsaOid));
8965             /* p, q, g */
8966             for (i = 0; i < DSA_INTS - 2; i++)
8967                 GetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
8968                         GetDsaInt(key, i));
8969             /* y */
8970             GetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
8971             /* Parse as SubjectPublicKeyInfo. */
8972             ret = GetASN_Items(dsaPubKeyASN, dataASN, dsaPubKeyASN_Length, 1,
8973                 input, inOutIdx, inSz);
8974         }
8975     }
8976 
8977     if (ret == 0) {
8978         /* Data parsed - set type of key parsed. */
8979         key->type = DSA_PUBLIC;
8980     }
8981 
8982     FREE_ASNGETDATA(dataASN, key->heap);
8983     return ret;
8984 #endif
8985 }
8986 
8987 int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
8988                         word32 inSz)
8989 {
8990     int    length;
8991     word32 maxIdx;
8992 
8993     if (input == NULL || inOutIdx == NULL || key == NULL)
8994         return BAD_FUNC_ARG;
8995 
8996     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8997         return ASN_PARSE_E;
8998 
8999     maxIdx = (word32)(*inOutIdx + length);
9000     if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
9001         GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
9002         GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
9003         return ASN_DH_KEY_E;
9004 
9005     return 0;
9006 }
9007 
9008 
9009 #ifdef WOLFSSL_ASN_TEMPLATE
9010 /* ASN.1 template for a DSA key holding private key in an OCTET_STRING. */
9011 static const ASNItem dsaKeyOctASN[] = {
9012 /*  SEQ      */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9013                 /* p */
9014 /*  P        */     { 1, ASN_INTEGER, 0, 0, 0 },
9015                 /* q */
9016 /*  Q        */     { 1, ASN_INTEGER, 0, 0, 0 },
9017                 /* g */
9018 /*  G        */     { 1, ASN_INTEGER, 0, 0, 0 },
9019                 /* Private key */
9020 /*  PKEY_STR */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
9021                     /* x */
9022 /*  X        */         { 2, ASN_INTEGER, 0, 0, 0 },
9023 };
9024 enum {
9025     DSAKEYOCTASN_IDX_SEQ = 0,
9026     DSAKEYOCTASN_IDX_P,
9027     DSAKEYOCTASN_IDX_Q,
9028     DSAKEYOCTASN_IDX_G,
9029     DSAKEYOCTASN_IDX_PKEY_STR,
9030     DSAKEYOCTASN_IDX_X,
9031 };
9032 
9033 /* Number of items in ASN.1 template for a DSA key (OCTET_STRING version). */
9034 #define dsaKeyOctASN_Length (sizeof(dsaKeyOctASN) / sizeof(ASNItem))
9035 #endif
9036 
9037 /* Decode DSA private key.
9038  *
9039  * @param [in]      input     Buffer holding BER encoded data.
9040  * @param [in, out] inOutIdx  On in, start of DSA public key.
9041  *                            On out, start of ASN.1 item after DSA public key.
9042  * @param [in, out] key       DSA key object.
9043  * @param [in]      inSz      Number of bytes in buffer.
9044  * @return  0 on success.
9045  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9046  *          is invalid.
9047  * @return  BUFFER_E when data in buffer is too small.
9048  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9049  *          non-zero length.
9050  */
9051 int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
9052                            word32 inSz)
9053 {
9054 #ifndef WOLFSSL_ASN_TEMPLATE
9055     int length, version, ret = 0, temp = 0;
9056     word32 algId = 0;
9057 
9058     /* Sanity checks on input */
9059     if (input == NULL || inOutIdx == NULL || key == NULL) {
9060         return BAD_FUNC_ARG;
9061     }
9062 
9063     /* if has pkcs8 header skip it */
9064     if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
9065         /* ignore error, did not have pkcs8 header */
9066     }
9067 
9068     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9069         return ASN_PARSE_E;
9070 
9071     temp = (int)*inOutIdx;
9072 
9073     /* Default case expects a certificate with OctetString but no version ID */
9074     ret = GetInt(&key->p, input, inOutIdx, inSz);
9075     if (ret < 0) {
9076         mp_clear(&key->p);
9077         ret = ASN_PARSE_E;
9078     }
9079     else {
9080         ret = GetInt(&key->q, input, inOutIdx, inSz);
9081         if (ret < 0) {
9082             mp_clear(&key->p);
9083             mp_clear(&key->q);
9084             ret = ASN_PARSE_E;
9085         }
9086         else {
9087             ret = GetInt(&key->g, input, inOutIdx, inSz);
9088             if (ret < 0) {
9089                 mp_clear(&key->p);
9090                 mp_clear(&key->q);
9091                 mp_clear(&key->g);
9092                 ret = ASN_PARSE_E;
9093             }
9094             else {
9095                 ret = GetOctetString(input, inOutIdx, &length, inSz);
9096                 if (ret < 0) {
9097                     mp_clear(&key->p);
9098                     mp_clear(&key->q);
9099                     mp_clear(&key->g);
9100                     ret = ASN_PARSE_E;
9101                 }
9102                 else {
9103                     ret = GetInt(&key->y, input, inOutIdx, inSz);
9104                     if (ret < 0) {
9105                         mp_clear(&key->p);
9106                         mp_clear(&key->q);
9107                         mp_clear(&key->g);
9108                         mp_clear(&key->y);
9109                         ret = ASN_PARSE_E;
9110                     }
9111                 }
9112             }
9113         }
9114     }
9115     /* An alternate pass if default certificate fails parsing */
9116     if (ret == ASN_PARSE_E) {
9117         *inOutIdx = temp;
9118         if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
9119             return ASN_PARSE_E;
9120 
9121         if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
9122             GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
9123             GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
9124             GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
9125             GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
9126             return ASN_DH_KEY_E;
9127     }
9128 
9129     key->type = DSA_PRIVATE;
9130     return 0;
9131 #else
9132     /* dsaKeyASN is longer than dsaKeyOctASN. */
9133     DECL_ASNGETDATA(dataASN, dsaKeyASN_Length);
9134     int ret = 0;
9135     int i;
9136     byte version = 0;
9137 
9138     /* Sanity checks on input */
9139     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
9140         ret = BAD_FUNC_ARG;
9141     }
9142 
9143     CALLOC_ASNGETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
9144 
9145     if (ret == 0) {
9146         /* Try dsaKeyOctASN */
9147         /* Initialize key data and set mp_ints for params */
9148         for (i = 0; i < DSA_INTS - 2; i++) {
9149             GetASN_MP(&dataASN[(int)DSAKEYOCTASN_IDX_P + i], GetDsaInt(key, i));
9150         }
9151         /* and priv */
9152         GetASN_MP(&dataASN[DSAKEYOCTASN_IDX_X], GetDsaInt(key, i));
9153         /* Try simple form. */
9154         ret = GetASN_Items(dsaKeyOctASN, dataASN, dsaKeyOctASN_Length, 1, input,
9155                            inOutIdx, inSz);
9156 
9157         if (ret != 0) {
9158             /* Try dsaKeyASN */
9159             XMEMSET(dataASN, 0, sizeof(*dataASN) * dsaKeyASN_Length);
9160             GetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], &version);
9161             for (i = 0; i < DSA_INTS; i++) {
9162                 GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
9163             }
9164 
9165             /* Try simple OCTET_STRING form. */
9166             ret = GetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, 1, input,
9167                                inOutIdx, inSz);
9168         }
9169     }
9170 
9171     if (ret == 0) {
9172         /* Set the contents to be a private key. */
9173         key->type = DSA_PRIVATE;
9174     }
9175 
9176     FREE_ASNGETDATA(dataASN, key->heap);
9177     return ret;
9178 #endif
9179 }
9180 
9181 #ifndef WOLFSSL_ASN_TEMPLATE
9182 /* Release Tmp DSA resources */
9183 static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
9184 {
9185     int i;
9186 
9187     for (i = 0; i < ints; i++)
9188         XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
9189 
9190     (void)heap;
9191 }
9192 #endif /* !WOLFSSL_ASN_TEMPLATE */
9193 
9194 #if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
9195         defined(WOLFSSL_CERT_GEN))
9196 /* Encode a DSA public key into buffer.
9197  *
9198  * @param [out] output       Buffer to hold encoded data.
9199  * @param [in]  key          DSA key object.
9200  * @param [out] outLen       Length of buffer.
9201  * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
9202  * @return  Size of encoded data in bytes on success.
9203  * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
9204  *          than a minimal size (5 bytes), or buffer size is smaller than
9205  *          encoding size.
9206  * @return  MEMORY_E when dynamic memory allocation fails.
9207  */
9208 int wc_SetDsaPublicKey(byte* output, DsaKey* key, int outLen, int with_header)
9209 {
9210 #ifndef WOLFSSL_ASN_TEMPLATE
9211     /* p, g, q = DSA params, y = public exponent */
9212 #ifdef WOLFSSL_SMALL_STACK
9213     byte* p = NULL;
9214     byte* g = NULL;
9215     byte* q = NULL;
9216     byte* y = NULL;
9217 #else
9218     byte p[MAX_DSA_INT_SZ];
9219     byte g[MAX_DSA_INT_SZ];
9220     byte q[MAX_DSA_INT_SZ];
9221     byte y[MAX_DSA_INT_SZ];
9222 #endif
9223     byte innerSeq[MAX_SEQ_SZ];
9224     byte outerSeq[MAX_SEQ_SZ];
9225     byte bitString[1 + MAX_LENGTH_SZ + 1];
9226     int  idx, pSz, gSz, qSz, ySz, innerSeqSz, outerSeqSz, bitStringSz = 0;
9227 
9228     WOLFSSL_ENTER("wc_SetDsaPublicKey");
9229 
9230     if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
9231         return BAD_FUNC_ARG;
9232     }
9233 
9234     /* p */
9235 #ifdef WOLFSSL_SMALL_STACK
9236     p = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9237     if (p == NULL)
9238         return MEMORY_E;
9239 #endif
9240     if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
9241         WOLFSSL_MSG("SetASNIntMP Error with p");
9242 #ifdef WOLFSSL_SMALL_STACK
9243         XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9244 #endif
9245         return pSz;
9246     }
9247 
9248     /* q */
9249 #ifdef WOLFSSL_SMALL_STACK
9250     q = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9251     if (q == NULL)
9252         return MEMORY_E;
9253 #endif
9254     if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
9255         WOLFSSL_MSG("SetASNIntMP Error with q");
9256 #ifdef WOLFSSL_SMALL_STACK
9257         XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9258         XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9259 #endif
9260         return qSz;
9261     }
9262 
9263     /* g */
9264 #ifdef WOLFSSL_SMALL_STACK
9265     g = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9266     if (g == NULL)
9267         return MEMORY_E;
9268 #endif
9269     if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
9270         WOLFSSL_MSG("SetASNIntMP Error with g");
9271 #ifdef WOLFSSL_SMALL_STACK
9272         XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9273         XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9274         XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9275 #endif
9276         return gSz;
9277     }
9278 
9279     /* y */
9280 #ifdef WOLFSSL_SMALL_STACK
9281     y = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9282     if (y == NULL)
9283         return MEMORY_E;
9284 #endif
9285     if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
9286         WOLFSSL_MSG("SetASNIntMP Error with y");
9287 #ifdef WOLFSSL_SMALL_STACK
9288         XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9289         XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9290         XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9291         XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9292 #endif
9293         return ySz;
9294     }
9295 
9296     if (with_header) {
9297         int algoSz;
9298 #ifdef WOLFSSL_SMALL_STACK
9299         byte* algo = NULL;
9300 
9301         algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9302         if (algo == NULL) {
9303             XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9304             XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9305             XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9306             XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9307             return MEMORY_E;
9308         }
9309 #else
9310         byte algo[MAX_ALGO_SZ];
9311 #endif
9312         innerSeqSz  = SetSequence(pSz + qSz + gSz, innerSeq);
9313         algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
9314         bitStringSz  = SetBitString(ySz, 0, bitString);
9315         outerSeqSz = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz,
9316                                                                       outerSeq);
9317 
9318         idx = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz + bitStringSz +
9319                                                       ySz + outerSeqSz, output);
9320 
9321         /* check output size */
9322         if ((idx + algoSz + bitStringSz + innerSeqSz + pSz + qSz + gSz + ySz) >
9323                                                                        outLen) {
9324             #ifdef WOLFSSL_SMALL_STACK
9325                 XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9326                 XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9327                 XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9328                 XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9329                 XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9330             #endif
9331             WOLFSSL_MSG("Error, output size smaller than outlen");
9332             return BUFFER_E;
9333         }
9334 
9335         /* outerSeq */
9336         XMEMCPY(output + idx, outerSeq, outerSeqSz);
9337         idx += outerSeqSz;
9338         /* algo */
9339         XMEMCPY(output + idx, algo, algoSz);
9340         idx += algoSz;
9341 #ifdef WOLFSSL_SMALL_STACK
9342         XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9343 #endif
9344     } else {
9345         innerSeqSz  = SetSequence(pSz + qSz + gSz + ySz, innerSeq);
9346 
9347         /* check output size */
9348         if ((innerSeqSz + pSz + qSz + gSz + ySz) > outLen) {
9349     #ifdef WOLFSSL_SMALL_STACK
9350             XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9351             XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9352             XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9353             XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9354     #endif
9355             WOLFSSL_MSG("Error, output size smaller than outlen");
9356             return BUFFER_E;
9357         }
9358 
9359         idx = 0;
9360     }
9361 
9362     /* innerSeq */
9363     XMEMCPY(output + idx, innerSeq, innerSeqSz);
9364     idx += innerSeqSz;
9365     /* p */
9366     XMEMCPY(output + idx, p, pSz);
9367     idx += pSz;
9368     /* q */
9369     XMEMCPY(output + idx, q, qSz);
9370     idx += qSz;
9371     /* g */
9372     XMEMCPY(output + idx, g, gSz);
9373     idx += gSz;
9374     /* bit string */
9375     if (bitStringSz > 0) {
9376         XMEMCPY(output + idx, bitString, bitStringSz);
9377         idx += bitStringSz;
9378     }
9379     /* y */
9380     XMEMCPY(output + idx, y, ySz);
9381     idx += ySz;
9382 
9383 #ifdef WOLFSSL_SMALL_STACK
9384     XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9385     XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9386     XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9387     XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
9388 #endif
9389     return idx;
9390 #else
9391     DECL_ASNSETDATA(dataASN, dsaPubKeyASN_Length);
9392     int ret = 0;
9393     int i;
9394     int sz;
9395     const ASNItem *data = NULL;
9396     int count = 0;
9397 
9398     WOLFSSL_ENTER("wc_SetDsaPublicKey");
9399 
9400     if ((output == NULL) || (key == NULL) || (outLen < MAX_SEQ_SZ)) {
9401         ret = BAD_FUNC_ARG;
9402     }
9403 
9404     CALLOC_ASNSETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
9405 
9406     if (ret == 0) {
9407         if (with_header) {
9408             /* Using dsaPubKeyASN */
9409             data = dsaPubKeyASN;
9410             count = dsaPubKeyASN_Length;
9411             /* Set the algorithm OID to write out. */
9412             SetASN_OID(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID], DSAk, oidKeyType);
9413             /* Set the mp_ints to encode - parameters and public value. */
9414             for (i = 0; i < DSA_INTS - 2; i++) {
9415                 SetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
9416                         GetDsaInt(key, i));
9417             }
9418             SetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
9419         }
9420         else {
9421             /* Using dsaKeyASN */
9422             data = dsaKeyASN;
9423             count = dsaPublicKeyASN_Length;
9424             /* Set the mp_ints to encode - parameters and public value. */
9425             for (i = 0; i < DSA_INTS - 1; i++) {
9426                 /* Move all DSA ints up one slot (ignore VERSION so now
9427                  * it means P) */
9428                 SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i],
9429                         GetDsaInt(key, i));
9430             }
9431         }
9432         ret = SizeASN_Items(data, dataASN, count, &sz);
9433     }
9434     /* Check buffer is big enough for encoding. */
9435     if ((ret == 0) && (sz > (int)outLen)) {
9436         ret = BAD_FUNC_ARG;
9437     }
9438     /* Encode the DSA public key into output buffer. */
9439     if (ret == 0) {
9440         ret = SetASN_Items(data, dataASN, count, output);
9441     }
9442 
9443     FREE_ASNSETDATA(dataASN, key->heap);
9444     return ret;
9445 #endif /* WOLFSSL_ASN_TEMPLATE */
9446 }
9447 
9448 /* Encode a DSA public key into buffer.
9449  *
9450  * @param [out] output       Buffer to hold encoded data.
9451  * @param [in]  key          DSA key object.
9452  * @param [out] outLen       Length of buffer.
9453  * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
9454  * @return  Size of encoded data in bytes on success.
9455  * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
9456  *          than a minimal size (5 bytes), or buffer size is smaller than
9457  *          encoding size.
9458  * @return  MEMORY_E when dynamic memory allocation fails.
9459  */
9460 int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
9461 {
9462     return wc_SetDsaPublicKey(output, key, inLen, 1);
9463 }
9464 #endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
9465 
9466 static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen,
9467                            int ints, int includeVersion)
9468 {
9469 #ifndef WOLFSSL_ASN_TEMPLATE
9470     word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
9471     word32 sizes[DSA_INTS];
9472     int    i, j, outLen, ret = 0, mpSz;
9473 
9474     byte  seq[MAX_SEQ_SZ];
9475     byte  ver[MAX_VERSION_SZ];
9476     byte* tmps[DSA_INTS];
9477 
9478     if (ints > DSA_INTS || inLen == NULL)
9479         return BAD_FUNC_ARG;
9480 
9481     XMEMSET(sizes, 0, sizeof(sizes));
9482     for (i = 0; i < ints; i++)
9483         tmps[i] = NULL;
9484 
9485     /* write all big ints from key to DER tmps */
9486     for (i = 0; i < ints; i++) {
9487         mp_int* keyInt = GetDsaInt(key, i);
9488 
9489         rawLen = mp_unsigned_bin_size(keyInt) + 1;
9490         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
9491                                                               DYNAMIC_TYPE_DSA);
9492         if (tmps[i] == NULL) {
9493             ret = MEMORY_E;
9494             break;
9495         }
9496 
9497         mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
9498         if (mpSz < 0) {
9499             ret = mpSz;
9500             break;
9501         }
9502         intTotalLen += (sizes[i] = mpSz);
9503     }
9504 
9505     if (ret != 0) {
9506         FreeTmpDsas(tmps, key->heap, ints);
9507         return ret;
9508     }
9509 
9510     /* make headers */
9511     if (includeVersion)
9512         verSz = SetMyVersion(0, ver, FALSE);
9513     seqSz = SetSequence(verSz + intTotalLen, seq);
9514 
9515     outLen = seqSz + verSz + intTotalLen;
9516     *inLen = outLen;
9517     if (output == NULL) {
9518         FreeTmpDsas(tmps, key->heap, ints);
9519         return LENGTH_ONLY_E;
9520     }
9521     if (outLen > (int)*inLen) {
9522         FreeTmpDsas(tmps, key->heap, ints);
9523         return BAD_FUNC_ARG;
9524     }
9525 
9526     /* write to output */
9527     XMEMCPY(output, seq, seqSz);
9528     j = seqSz;
9529     if (includeVersion) {
9530         XMEMCPY(output + j, ver, verSz);
9531         j += verSz;
9532     }
9533 
9534     for (i = 0; i < ints; i++) {
9535         XMEMCPY(output + j, tmps[i], sizes[i]);
9536         j += sizes[i];
9537     }
9538     FreeTmpDsas(tmps, key->heap, ints);
9539 
9540     return outLen;
9541 #else
9542     DECL_ASNSETDATA(dataASN, dsaKeyASN_Length);
9543     int ret = 0;
9544     int i;
9545     int sz;
9546 
9547     (void)ints;
9548 
9549     if ((key == NULL) || (inLen == NULL)) {
9550         ret = BAD_FUNC_ARG;
9551     }
9552     if ((ret == 0) && (ints > DSA_INTS)) {
9553         ret = BAD_FUNC_ARG;
9554     }
9555 
9556     CALLOC_ASNSETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
9557 
9558     if (ret == 0) {
9559         if (includeVersion) {
9560             /* Set the version. */
9561             SetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], 0);
9562         }
9563         else {
9564             dataASN[DSAKEYASN_IDX_VER].noOut = 1;
9565         }
9566         dataASN[DSAKEYASN_IDX_Y].noOut = mp_iszero(&key->y);
9567         dataASN[DSAKEYASN_IDX_X].noOut = mp_iszero(&key->x);
9568         /* Set the mp_ints to encode - params, public and private value. */
9569         for (i = 0; i < DSA_INTS; i++) {
9570             if (i < ints)
9571                 SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
9572             else
9573                 dataASN[(int)DSAKEYASN_IDX_P + i].noOut = 1;
9574         }
9575         /* Calculate size of the encoding. */
9576         ret = SizeASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, &sz);
9577     }
9578     if ((ret == 0) && (output == NULL)) {
9579         *inLen = sz;
9580         ret = LENGTH_ONLY_E;
9581     }
9582     /* Check buffer is big enough for encoding. */
9583     if ((ret == 0) && (sz > (int)*inLen)) {
9584         ret = BAD_FUNC_ARG;
9585     }
9586     if (ret == 0) {
9587         /* Encode the DSA private key into output buffer. */
9588         SetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, output);
9589         /* Return the size of the encoding. */
9590         ret = sz;
9591     }
9592 
9593     FREE_ASNSETDATA(dataASN, key->heap);
9594     return ret;
9595 #endif /* WOLFSSL_ASN_TEMPLATE */
9596 }
9597 
9598 /* Encode a DSA private key into buffer.
9599  *
9600  * @param [in]  key          DSA key object.
9601  * @param [out] output       Buffer to hold encoded data.
9602  * @param [out] inLen        Length of buffer.
9603  * @return  Size of encoded data in bytes on success.
9604  * @return  BAD_FUNC_ARG when key or output is NULL, or key is not a private key
9605  *          or, buffer size is smaller than encoding size.
9606  * @return  MEMORY_E when dynamic memory allocation fails.
9607  */
9608 int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
9609 {
9610     if (!key || !output)
9611         return BAD_FUNC_ARG;
9612 
9613     if (key->type != DSA_PRIVATE)
9614         return BAD_FUNC_ARG;
9615 
9616     return DsaKeyIntsToDer(key, output, &inLen, DSA_INTS, 1);
9617 }
9618 
9619 /* Convert DsaKey parameters to DER format, write to output (inLen),
9620    return bytes written. Version is excluded to be compatible with
9621    OpenSSL d2i_DSAparams */
9622 int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
9623 {
9624     if (!key || !output)
9625         return BAD_FUNC_ARG;
9626 
9627     return DsaKeyIntsToDer(key, output, &inLen, DSA_PARAM_INTS, 0);
9628 }
9629 
9630 /* This version of the function allows output to be NULL. In that case, the
9631    DsaKeyIntsToDer will return LENGTH_ONLY_E and the required output buffer
9632    size will be pointed to by inLen. */
9633 int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen)
9634 {
9635     if (!key || !inLen)
9636         return BAD_FUNC_ARG;
9637 
9638     return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
9639 }
9640 
9641 #endif /* NO_DSA */
9642 
9643 /* Initialize decoded certificate object with buffer of DER encoding.
9644  *
9645  * @param [in, out] cert    Decoded certificate object.
9646  * @param [in]      source  Buffer containing DER encoded certificate.
9647  * @param [in]      inSz    Size of DER data in buffer in bytes.
9648  * @param [in]      heap    Dynamic memory hint.
9649  */
9650 void InitDecodedCert(DecodedCert* cert,
9651                      const byte* source, word32 inSz, void* heap)
9652 {
9653     if (cert != NULL) {
9654         XMEMSET(cert, 0, sizeof(DecodedCert));
9655 
9656         cert->subjectCNEnc    = CTC_UTF8;
9657         cert->issuer[0]       = '\0';
9658         cert->subject[0]      = '\0';
9659         cert->source          = source;  /* don't own */
9660         cert->maxIdx          = inSz;    /* can't go over this index */
9661         cert->heap            = heap;
9662         cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;
9663     #ifdef WOLFSSL_CERT_GEN
9664         cert->subjectSNEnc    = CTC_UTF8;
9665         cert->subjectCEnc     = CTC_PRINTABLE;
9666         cert->subjectLEnc     = CTC_UTF8;
9667         cert->subjectSTEnc    = CTC_UTF8;
9668         cert->subjectOEnc     = CTC_UTF8;
9669         cert->subjectOUEnc    = CTC_UTF8;
9670     #endif /* WOLFSSL_CERT_GEN */
9671 
9672     #ifndef NO_CERTS
9673         InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
9674     #endif
9675     }
9676 }
9677 
9678 void wc_InitDecodedCert(DecodedCert* cert, const byte* source, word32 inSz,
9679                         void* heap)
9680 {
9681     InitDecodedCert(cert, source, inSz, heap);
9682 }
9683 
9684 /* Free the alternative names object.
9685  *
9686  * Frees each linked list items and its name.
9687  *
9688  * @param [in, out] altNames  Alternative names.
9689  * @param [in]      heap      Dynamic memory hint.
9690  */
9691 void FreeAltNames(DNS_entry* altNames, void* heap)
9692 {
9693     (void)heap;
9694 
9695     while (altNames) {
9696         DNS_entry* tmp = altNames->next;
9697 
9698         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
9699     #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
9700         XFREE(altNames->ipString, heap, DYNAMIC_TYPE_ALTNAME);
9701     #endif
9702         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
9703         altNames = tmp;
9704     }
9705 }
9706 
9707 /* malloc and initialize a new alt name structure */
9708 DNS_entry* AltNameNew(void* heap)
9709 {
9710     DNS_entry* ret;
9711     ret = (DNS_entry*)XMALLOC(sizeof(DNS_entry), heap, DYNAMIC_TYPE_ALTNAME);
9712     if (ret != NULL) {
9713         XMEMSET(ret, 0, sizeof(DNS_entry));
9714     }
9715     (void)heap;
9716     return ret;
9717 }
9718 
9719 
9720 #ifndef IGNORE_NAME_CONSTRAINTS
9721 
9722 /* Free the subtree names object.
9723  *
9724  * Frees each linked list items and its name.
9725  *
9726  * @param [in, out] names  Subtree names.
9727  * @param [in]      heap   Dynamic memory hint.
9728  */
9729 void FreeNameSubtrees(Base_entry* names, void* heap)
9730 {
9731     (void)heap;
9732 
9733     while (names) {
9734         Base_entry* tmp = names->next;
9735 
9736         XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
9737         XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
9738         names = tmp;
9739     }
9740 }
9741 
9742 #endif /* IGNORE_NAME_CONSTRAINTS */
9743 
9744 /* Free the decoded cert object's dynamic data.
9745  *
9746  * @param [in, out] cert  Decoded certificate object.
9747  */
9748 void FreeDecodedCert(DecodedCert* cert)
9749 {
9750     if (cert == NULL)
9751         return;
9752     if (cert->subjectCNStored == 1)
9753         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
9754     if (cert->pubKeyStored == 1)
9755         XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9756     if (cert->weOwnAltNames && cert->altNames)
9757         FreeAltNames(cert->altNames, cert->heap);
9758 #ifndef IGNORE_NAME_CONSTRAINTS
9759     if (cert->altEmailNames)
9760         FreeAltNames(cert->altEmailNames, cert->heap);
9761     if (cert->altDirNames)
9762         FreeAltNames(cert->altDirNames, cert->heap);
9763     if (cert->permittedNames)
9764         FreeNameSubtrees(cert->permittedNames, cert->heap);
9765     if (cert->excludedNames)
9766         FreeNameSubtrees(cert->excludedNames, cert->heap);
9767 #endif /* IGNORE_NAME_CONSTRAINTS */
9768 #ifdef WOLFSSL_SEP
9769     XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
9770     XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
9771     XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
9772 #endif /* WOLFSSL_SEP */
9773 #ifdef WOLFSSL_X509_NAME_AVAILABLE
9774     if (cert->issuerName != NULL)
9775         wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->issuerName);
9776     if (cert->subjectName != NULL)
9777         wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->subjectName);
9778 #endif /* WOLFSSL_X509_NAME_AVAILABLE */
9779 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
9780     if (cert->sce_tsip_encRsaKeyIdx != NULL)
9781         XFREE(cert->sce_tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);
9782 #endif
9783 #ifndef NO_CERTS
9784     FreeSignatureCtx(&cert->sigCtx);
9785 #endif
9786 }
9787 
9788 void wc_FreeDecodedCert(DecodedCert* cert)
9789 {
9790     FreeDecodedCert(cert);
9791 }
9792 
9793 #ifndef WOLFSSL_ASN_TEMPLATE
9794 static int GetCertHeader(DecodedCert* cert)
9795 {
9796     int ret = 0, len;
9797 
9798     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
9799         return ASN_PARSE_E;
9800 
9801     /* Reset the max index for the size indicated in the outer wrapper. */
9802     cert->maxIdx = len + cert->srcIdx;
9803     cert->certBegin = cert->srcIdx;
9804 
9805     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
9806         return ASN_PARSE_E;
9807 
9808     cert->sigIndex = len + cert->srcIdx;
9809     if (cert->sigIndex > cert->maxIdx)
9810         return ASN_PARSE_E;
9811 
9812     if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
9813                                                             cert->sigIndex) < 0)
9814         return ASN_PARSE_E;
9815 
9816     if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
9817                                            &cert->serialSz, cert->sigIndex) < 0)
9818         return ASN_PARSE_E;
9819 
9820     return ret;
9821 }
9822 #endif
9823 
9824 #if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_PQC)
9825 /* Store the key data under the BIT_STRING in dynamicly allocated data.
9826  *
9827  * @param [in, out] cert    Certificate object.
9828  * @param [in]      source  Buffer containing encoded key.
9829  * @param [in, out] srcIdx  On in, start of key data.
9830  *                          On out, start of element after key data.
9831  * @param [in]      maxIdx  Maximum index of certificate data.
9832  */
9833 static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx,
9834                     word32 maxIdx)
9835 {
9836     int ret;
9837     int length;
9838     byte* publicKey;
9839 
9840     ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
9841     if (ret == 0) {
9842     #ifdef HAVE_OCSP
9843         ret = CalcHashId(source + *srcIdx, length, cert->subjectKeyHash);
9844     }
9845     if (ret == 0) {
9846     #endif
9847         publicKey = (byte*)XMALLOC(length, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9848         if (publicKey == NULL) {
9849             ret = MEMORY_E;
9850         }
9851         else {
9852             XMEMCPY(publicKey, &source[*srcIdx], length);
9853             cert->publicKey = publicKey;
9854             cert->pubKeyStored = 1;
9855             cert->pubKeySize   = length;
9856 
9857             *srcIdx += length;
9858         }
9859     }
9860 
9861     return ret;
9862 }
9863 #endif /* HAVE_ED25519 || HAVE_ED448 */
9864 
9865 #if !defined(NO_RSA)
9866 #ifdef WOLFSSL_ASN_TEMPLATE
9867 /* ASN.1 template for header before RSA key in certificate. */
9868 static const ASNItem rsaCertKeyASN[] = {
9869 /* STR */ { 0, ASN_BIT_STRING, 0, 1, 0 },
9870 /* SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
9871 };
9872 enum {
9873     RSACERTKEYASN_IDX_STR = 0,
9874     RSACERTKEYASN_IDX_SEQ,
9875 };
9876 
9877 /* Number of items in ASN.1 template for header before RSA key in cert. */
9878 #define rsaCertKeyASN_Length (sizeof(rsaCertKeyASN) / sizeof(ASNItem))
9879 #endif
9880 
9881 /* Store RSA key pointer and length in certificate object.
9882  *
9883  * @param [in, out] cert    Certificate object.
9884  * @param [in]      source  Buffer containing encoded key.
9885  * @param [in, out] srcIdx  On in, start of RSA key data.
9886  *                          On out, start of element after RSA key data.
9887  * @param [in]      maxIdx  Maximum index of key data.
9888  * @return  0 on success.
9889  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9890  *          is invalid.
9891  * @return  BUFFER_E when data in buffer is too small.
9892  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9893  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9894  *          non-zero length.
9895  */
9896 static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
9897                        word32 maxIdx)
9898 {
9899 #ifndef WOLFSSL_ASN_TEMPLATE
9900     int    length;
9901     int    pubLen;
9902     word32 pubIdx;
9903 
9904     if (CheckBitString(source, srcIdx, &pubLen, maxIdx, 1, NULL) != 0)
9905         return ASN_PARSE_E;
9906     pubIdx = *srcIdx;
9907 
9908     if (GetSequence(source, srcIdx, &length, pubIdx + pubLen) < 0)
9909         return ASN_PARSE_E;
9910 
9911 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
9912     cert->sigCtx.CertAtt.pubkey_n_start =
9913             cert->sigCtx.CertAtt.pubkey_e_start = pubIdx;
9914 #endif
9915     cert->pubKeySize = pubLen;
9916     cert->publicKey = source + pubIdx;
9917     *srcIdx += length;
9918 
9919 #ifdef HAVE_OCSP
9920     return CalcHashId(cert->publicKey, cert->pubKeySize, cert->subjectKeyHash);
9921 #else
9922     return 0;
9923 #endif
9924 #else
9925     ASNGetData dataASN[rsaCertKeyASN_Length];
9926     int ret;
9927 
9928     /* No dynamic data. */
9929     XMEMSET(dataASN, 0, sizeof(dataASN));
9930     /* Decode the header before the key data. */
9931     ret = GetASN_Items(rsaCertKeyASN, dataASN, rsaCertKeyASN_Length, 1, source,
9932                        srcIdx, maxIdx);
9933     if (ret == 0) {
9934         /* Store the pointer and length in certificate object starting at
9935          * SEQUENCE. */
9936         GetASN_GetConstRef(&dataASN[RSACERTKEYASN_IDX_STR],
9937                 &cert->publicKey, &cert->pubKeySize);
9938 
9939     #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
9940         /* Start of SEQUENCE. */
9941         cert->sigCtx.CertAtt.pubkey_n_start =
9942             cert->sigCtx.CertAtt.pubkey_e_start = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
9943     #endif
9944     #ifdef HAVE_OCSP
9945         /* Calculate the hash of the public key for OCSP. */
9946         ret = CalcHashId(cert->publicKey, cert->pubKeySize,
9947                          cert->subjectKeyHash);
9948     #endif
9949     }
9950 
9951     return ret;
9952 #endif /* WOLFSSL_ASN_TEMPLATE */
9953 }
9954 #endif /* !NO_RSA */
9955 
9956 #ifdef HAVE_ECC
9957 
9958 #ifdef WOLFSSL_ASN_TEMPLATE
9959 /* ASN.1 template for header before ECC key in certificate. */
9960 static const ASNItem eccCertKeyASN[] = {
9961 /* OID        */     { 1, ASN_OBJECT_ID, 0, 0, 2 },
9962                             /* Algo parameters */
9963 /* PARAMS     */     { 1, ASN_SEQUENCE, 1, 0, 2 },
9964                             /* Subject public key */
9965 /* SUBJPUBKEY */ { 0, ASN_BIT_STRING, 0, 0, 0 },
9966 };
9967 enum {
9968     ECCCERTKEYASN_IDX_OID = 0,
9969     ECCCERTKEYASN_IDX_PARAMS,
9970     ECCCERTKEYASN_IDX_SUBJPUBKEY,
9971 };
9972 
9973 /* Number of items in ASN.1 template for header before ECC key in cert. */
9974 #define eccCertKeyASN_Length (sizeof(eccCertKeyASN) / sizeof(ASNItem))
9975 #endif /* WOLFSSL_ASN_TEMPLATE */
9976 
9977 /* Store public ECC key in certificate object.
9978  *
9979  * Parse parameters and store public key data.
9980  *
9981  * @param [in, out] cert       Certificate object.
9982  * @param [in]      source     Buffer containing encoded key.
9983  * @param [in, out] srcIdx     On in, start of ECC key data.
9984  *                             On out, start of element after ECC key data.
9985  * @param [in]      maxIdx     Maximum index of key data.
9986  * @param [in]      pubKey     Buffer holding encoded public key.
9987  * @param [in]      pubKeyLen  Length of encoded public key in bytes.
9988  * @return  0 on success.
9989  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9990  *          is invalid.
9991  * @return  BUFFER_E when data in buffer is too small.
9992  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9993  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9994  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9995  *          non-zero length.
9996  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9997  */
9998 static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
9999                        word32 maxIdx, const byte* pubKey, word32 pubKeyLen)
10000 {
10001 #ifndef WOLFSSL_ASN_TEMPLATE
10002     int ret;
10003     word32 localIdx;
10004     byte* publicKey;
10005     byte  tag;
10006     int length;
10007 
10008     localIdx = *srcIdx;
10009     if (GetASNTag(source, &localIdx, &tag, maxIdx) < 0)
10010         return ASN_PARSE_E;
10011 
10012     if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
10013         if (GetObjectId(source, srcIdx, &cert->pkCurveOID, oidCurveType,
10014                                                                     maxIdx) < 0)
10015             return ASN_PARSE_E;
10016 
10017         if ((ret = CheckCurve(cert->pkCurveOID)) < 0)
10018             return ECC_CURVE_OID_E;
10019 
10020     #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
10021         cert->sigCtx.CertAtt.curve_id = ret;
10022     #else
10023         (void)ret;
10024     #endif
10025         /* key header */
10026         ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
10027         if (ret != 0)
10028             return ret;
10029     #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
10030         cert->sigCtx.CertAtt.pubkey_n_start =
10031                 cert->sigCtx.CertAtt.pubkey_e_start = (*srcIdx + 1);
10032         cert->sigCtx.CertAtt.pubkey_n_len = ((length - 1) >> 1);
10033         cert->sigCtx.CertAtt.pubkey_e_start +=
10034                 cert->sigCtx.CertAtt.pubkey_n_len;
10035         cert->sigCtx.CertAtt.pubkey_e_len   =
10036                 cert->sigCtx.CertAtt.pubkey_n_len;
10037     #endif
10038     #ifdef HAVE_OCSP
10039         ret = CalcHashId(source + *srcIdx, length, cert->subjectKeyHash);
10040         if (ret != 0)
10041             return ret;
10042     #endif
10043         *srcIdx += length;
10044     }
10045 
10046     publicKey = (byte*)XMALLOC(pubKeyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10047     if (publicKey == NULL)
10048         return MEMORY_E;
10049     XMEMCPY(publicKey, pubKey, pubKeyLen);
10050     cert->publicKey = publicKey;
10051     cert->pubKeyStored = 1;
10052     cert->pubKeySize   = pubKeyLen;
10053 
10054     return 0;
10055 #else
10056     int ret = 0;
10057     DECL_ASNGETDATA(dataASN, eccCertKeyASN_Length);
10058     byte* publicKey;
10059 
10060     /* Clear dynamic data and check OID is a curve. */
10061     CALLOC_ASNGETDATA(dataASN, eccCertKeyASN_Length, ret, cert->heap);
10062     if (ret == 0) {
10063         GetASN_OID(&dataASN[ECCCERTKEYASN_IDX_OID], oidCurveType);
10064         /* Parse ECC public key header. */
10065         ret = GetASN_Items(eccCertKeyASN, dataASN, eccCertKeyASN_Length, 1,
10066                 source, srcIdx, maxIdx);
10067     }
10068     if (ret == 0) {
10069         if (dataASN[ECCCERTKEYASN_IDX_OID].tag != 0) {
10070             /* Store curve OID. */
10071             cert->pkCurveOID = dataASN[ECCCERTKEYASN_IDX_OID].data.oid.sum;
10072         }
10073         /* Ignore explicit parameters. */
10074 
10075     #ifdef HAVE_OCSP
10076         /* Calculate the hash of the subject public key for OCSP. */
10077         ret = CalcHashId(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data,
10078                          dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length,
10079                          cert->subjectKeyHash);
10080     }
10081     if (ret == 0) {
10082     #endif
10083         /* Store public key data length. */
10084         cert->pubKeySize = pubKeyLen;
10085         /* Must allocated space for key.
10086          * Don't memcpy into constant pointer so use temp. */
10087         publicKey = (byte*)XMALLOC(cert->pubKeySize, cert->heap,
10088                                    DYNAMIC_TYPE_PUBLIC_KEY);
10089         if (publicKey == NULL) {
10090             ret = MEMORY_E;
10091         }
10092         else {
10093             /* Copy in whole public key and store pointer. */
10094             XMEMCPY(publicKey, pubKey, cert->pubKeySize);
10095             cert->publicKey = publicKey;
10096             /* Indicate publicKey needs to be freed. */
10097             cert->pubKeyStored = 1;
10098         }
10099     }
10100     FREE_ASNGETDATA(dataASN, cert->heap);
10101 
10102     return ret;
10103 #endif /* WOLFSSL_ASN_TEMPLATE */
10104 }
10105 #endif /* HAVE_ECC */
10106 
10107 #if !defined(NO_DSA)
10108 #ifdef WOLFSSL_ASN_TEMPLATE
10109 /* ASN.1 template for DSA key in certificate.
10110  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10111  * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10112  */
10113 static const ASNItem dsaCertKeyASN[] = {
10114 /*  0 */        { 1, ASN_SEQUENCE, 1, 1, 0 },
10115 /*  1 */            { 2, ASN_INTEGER, 0, 0, 0 },
10116 /*  2 */            { 2, ASN_INTEGER, 0, 0, 0 },
10117 /*  3 */            { 2, ASN_INTEGER, 0, 0, 0 },
10118 /*  4 */    { 0, ASN_BIT_STRING, 0, 1, 0 },
10119 /*  5 */        { 1, ASN_INTEGER, 0, 0, 0 },
10120 };
10121 
10122 /* Number of items in ASN.1 template for DSA key in certificate. */
10123 #define dsaCertKeyASN_Length (sizeof(dsaCertKeyASN) / sizeof(ASNItem))
10124 #endif /* WOLFSSL_ASN_TEMPLATE */
10125 
10126 /* Parse DSA parameters to ensure valid.
10127  *
10128  * @param [in]      source  Buffer containing encoded key.
10129  * @param [in, out] srcIdx  On in, start of DSA key data.
10130  *                          On out, start of element after DSA key data.
10131  * @param [in]      maxIdx  Maximum index of key data.
10132  * @param [in]      heap    Dynamic memory hint.
10133  * @return  0 on success.
10134  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10135  *          is invalid.
10136  * @return  BUFFER_E when data in buffer is too small.
10137  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
10138  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
10139  *          non-zero length.
10140  */
10141 static int ParseDsaKey(const byte* source, word32* srcIdx, word32 maxIdx,
10142                        void* heap)
10143 {
10144 #ifndef WOLFSSL_ASN_TEMPLATE
10145     int ret;
10146     int length;
10147 
10148     (void)heap;
10149 
10150     ret = GetSequence(source, srcIdx, &length, maxIdx);
10151     if (ret < 0)
10152         return ret;
10153 
10154     ret = SkipInt(source, srcIdx, maxIdx);
10155     if (ret != 0)
10156         return ret;
10157     ret = SkipInt(source, srcIdx, maxIdx);
10158     if (ret != 0)
10159         return ret;
10160     ret = SkipInt(source, srcIdx, maxIdx);
10161     if (ret != 0)
10162         return ret;
10163 
10164     ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
10165     if (ret != 0)
10166         return ret;
10167 
10168     ret = GetASNInt(source, srcIdx, &length, maxIdx);
10169     if (ret != 0)
10170         return ASN_PARSE_E;
10171 
10172     *srcIdx += length;
10173 
10174     return 0;
10175 #else
10176     DECL_ASNGETDATA(dataASN, dsaCertKeyASN_Length);
10177     int ret = 0;
10178 
10179     (void)heap;
10180 
10181     CALLOC_ASNGETDATA(dataASN, dsaCertKeyASN_Length, ret, heap);
10182     if (ret == 0) {
10183         /* Parse the DSA key data to ensure valid. */
10184         ret = GetASN_Items(dsaCertKeyASN, dataASN, dsaCertKeyASN_Length, 1,
10185                            source, srcIdx, maxIdx);
10186     }
10187 
10188     FREE_ASNGETDATA(dataASN, heap);
10189     return ret;
10190 #endif /* WOLFSSL_ASN_TEMPLATE */
10191 }
10192 #endif /* !NO_DSA */
10193 
10194 /* Decode the SubjectPublicKeyInfo block in a certificate.
10195  *
10196  * Stores the public key in fields of the certificate object.
10197  * Validates the BER/DER items and does not store in a key object.
10198  *
10199  * @param [in, out] cert      Decoded certificate oject.
10200  * @param [in]      source    BER/DER encoded SubjectPublicKeyInfo block.
10201  * @param [in, out] inOutIdx  On in, start of public key.
10202  *                            On out, start of ASN.1 item after public key.
10203  * @param [in]      maxIdx    Maximum index of key data.
10204  * @return  0 on success.
10205  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10206  *          is invalid.
10207  * @return  BUFFER_E when data in buffer is too small.
10208  */
10209 static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
10210                       word32 maxIdx)
10211 {
10212     word32 srcIdx = *inOutIdx;
10213 #if defined(HAVE_ECC) || !defined(NO_DSA)
10214     int pubLen;
10215 #endif
10216 #if defined(HAVE_ECC) || !defined(NO_DSA)
10217     int pubIdx = srcIdx;
10218 #endif
10219     int ret = 0;
10220     int length;
10221 
10222 #ifndef WOLFSSL_ASN_TEMPLATE
10223     if (GetSequence(source, &srcIdx, &length, maxIdx) < 0)
10224 #else
10225     /* Get SEQUENCE and expect all data to be accounted for. */
10226     if (GetASN_Sequence(source, &srcIdx, &length, maxIdx, 1) != 0)
10227 #endif
10228     {
10229         return ASN_PARSE_E;
10230     }
10231 
10232 #if defined(HAVE_ECC) || !defined(NO_DSA)
10233     pubLen = srcIdx - pubIdx + length;
10234 #endif
10235     maxIdx = srcIdx + length;
10236 
10237     /* Decode the algorithm identifier for the key. */
10238     if (GetAlgoId(source, &srcIdx, &cert->keyOID, oidKeyType, maxIdx) < 0) {
10239         return ASN_PARSE_E;
10240     }
10241 
10242     (void)length;
10243 
10244     /* Parse each type of public key. */
10245     switch (cert->keyOID) {
10246     #ifndef NO_RSA
10247         case RSAk:
10248             ret = StoreRsaKey(cert, source, &srcIdx, maxIdx);
10249             break;
10250 
10251     #endif /* NO_RSA */
10252     #ifdef HAVE_ECC
10253         case ECDSAk:
10254             ret = StoreEccKey(cert, source, &srcIdx, maxIdx, source + pubIdx,
10255                               pubLen);
10256             break;
10257     #endif /* HAVE_ECC */
10258     #ifdef HAVE_ED25519
10259         case ED25519k:
10260             cert->pkCurveOID = ED25519k;
10261             ret = StoreKey(cert, source, &srcIdx, maxIdx);
10262             break;
10263     #endif /* HAVE_ED25519 */
10264     #ifdef HAVE_ED448
10265         case ED448k:
10266             cert->pkCurveOID = ED448k;
10267             ret = StoreKey(cert, source, &srcIdx, maxIdx);
10268             break;
10269     #endif /* HAVE_ED448 */
10270     #ifdef HAVE_PQC
10271         case FALCON_LEVEL1k:
10272             cert->pkCurveOID = FALCON_LEVEL1k;
10273             ret = StoreKey(cert, source, &srcIdx, maxIdx);
10274             break;
10275         case FALCON_LEVEL5k:
10276             cert->pkCurveOID = FALCON_LEVEL5k;
10277             ret = StoreKey(cert, source, &srcIdx, maxIdx);
10278             break;
10279     #endif /* HAVE_PQC */
10280     #ifndef NO_DSA
10281         case DSAk:
10282             cert->publicKey = source + pubIdx;
10283             cert->pubKeySize = pubLen;
10284             ret = ParseDsaKey(source, &srcIdx, maxIdx, cert->heap);
10285             break;
10286     #endif /* NO_DSA */
10287         default:
10288             WOLFSSL_MSG("Unknown or not compiled in key OID");
10289             ret = ASN_UNKNOWN_OID_E;
10290     }
10291 
10292     /* Return index after public key. */
10293     *inOutIdx = srcIdx;
10294 
10295     /* Return error code. */
10296     return ret;
10297 }
10298 
10299 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
10300 #if defined(HAVE_ECC)
10301 /* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
10302  * value.
10303  *
10304  * @param [in] n  ECC curve id.
10305  * @return  ECC curve NID (OpenSSL compatable value).
10306  */
10307 WOLFSSL_API int EccEnumToNID(int n)
10308 {
10309     WOLFSSL_ENTER("EccEnumToNID()");
10310 
10311     switch(n) {
10312         case ECC_SECP192R1:
10313             return NID_X9_62_prime192v1;
10314         case ECC_PRIME192V2:
10315             return NID_X9_62_prime192v2;
10316         case ECC_PRIME192V3:
10317             return NID_X9_62_prime192v3;
10318         case ECC_PRIME239V1:
10319             return NID_X9_62_prime239v1;
10320         case ECC_PRIME239V2:
10321             return NID_X9_62_prime239v2;
10322         case ECC_PRIME239V3:
10323             return NID_X9_62_prime239v3;
10324         case ECC_SECP256R1:
10325             return NID_X9_62_prime256v1;
10326         case ECC_SECP112R1:
10327             return NID_secp112r1;
10328         case ECC_SECP112R2:
10329             return NID_secp112r2;
10330         case ECC_SECP128R1:
10331             return NID_secp128r1;
10332         case ECC_SECP128R2:
10333             return NID_secp128r2;
10334         case ECC_SECP160R1:
10335             return NID_secp160r1;
10336         case ECC_SECP160R2:
10337             return NID_secp160r2;
10338         case ECC_SECP224R1:
10339             return NID_secp224r1;
10340         case ECC_SECP384R1:
10341             return NID_secp384r1;
10342         case ECC_SECP521R1:
10343             return NID_secp521r1;
10344         case ECC_SECP160K1:
10345             return NID_secp160k1;
10346         case ECC_SECP192K1:
10347             return NID_secp192k1;
10348         case ECC_SECP224K1:
10349             return NID_secp224k1;
10350         case ECC_SECP256K1:
10351             return NID_secp256k1;
10352         case ECC_BRAINPOOLP160R1:
10353             return NID_brainpoolP160r1;
10354         case ECC_BRAINPOOLP192R1:
10355             return NID_brainpoolP192r1;
10356         case ECC_BRAINPOOLP224R1:
10357             return NID_brainpoolP224r1;
10358         case ECC_BRAINPOOLP256R1:
10359             return NID_brainpoolP256r1;
10360         case ECC_BRAINPOOLP320R1:
10361             return NID_brainpoolP320r1;
10362         case ECC_BRAINPOOLP384R1:
10363             return NID_brainpoolP384r1;
10364         case ECC_BRAINPOOLP512R1:
10365             return NID_brainpoolP512r1;
10366         default:
10367             WOLFSSL_MSG("NID not found");
10368             return -1;
10369     }
10370 }
10371 #endif /* HAVE_ECC */
10372 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
10373 
10374 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
10375     && !defined(WOLFCRYPT_ONLY)
10376 /* Convert shortname to NID.
10377  *
10378  * For OpenSSL compatability.
10379  *
10380  * @param [in] sn  Short name of OID.
10381  * @return  NID corresponding to shortname on success.
10382  * @return  NID_undef when not recognized.
10383  */
10384 int wc_OBJ_sn2nid(const char *sn)
10385 {
10386     const struct {
10387         const char *sn;
10388         int  nid;
10389     } sn2nid[] = {
10390         {WOLFSSL_COMMON_NAME, NID_commonName},
10391         {WOLFSSL_COUNTRY_NAME, NID_countryName},
10392         {WOLFSSL_LOCALITY_NAME, NID_localityName},
10393         {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
10394         {WOLFSSL_ORG_NAME, NID_organizationName},
10395         {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
10396         {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
10397         {"SHA1", NID_sha1},
10398         {NULL, -1}};
10399     int i;
10400     #ifdef HAVE_ECC
10401     char curveName[16]; /* Same as MAX_CURVE_NAME_SZ but can't include that
10402                          * symbol in this file */
10403     int eccEnum;
10404     #endif
10405     WOLFSSL_ENTER("OBJ_sn2nid");
10406     for(i=0; sn2nid[i].sn != NULL; i++) {
10407         if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {
10408             return sn2nid[i].nid;
10409         }
10410     }
10411     #ifdef HAVE_ECC
10412     /* Nginx uses this OpenSSL string. */
10413     if (XSTRNCMP(sn, "prime256v1", 10) == 0)
10414         sn = "SECP256R1";
10415     /* OpenSSL allows lowercase curve names */
10416     for (i = 0; i < (int)(sizeof(curveName) - 1) && *sn; i++) {
10417         curveName[i] = (char)XTOUPPER((unsigned char) *sn++);
10418     }
10419     curveName[i] = '\0';
10420     /* find based on name and return NID */
10421     for (i = 0;
10422 #ifndef WOLFSSL_ECC_CURVE_STATIC
10423          ecc_sets[i].size != 0 && ecc_sets[i].name != NULL;
10424 #else
10425          ecc_sets[i].size != 0;
10426 #endif
10427          i++) {
10428         if (XSTRNCMP(curveName, ecc_sets[i].name, ECC_MAXNAME) == 0) {
10429             eccEnum = ecc_sets[i].id;
10430             /* Convert enum value in ecc_curve_id to OpenSSL NID */
10431             return EccEnumToNID(eccEnum);
10432         }
10433     }
10434     #endif
10435 
10436     return NID_undef;
10437 }
10438 #endif
10439 
10440 /* Calculate hash of the id using the SHA-1 or SHA-256.
10441  *
10442  * @param [in]  data  Data to hash.
10443  * @param [in]  len   Length of data to hash.
10444  * @param [out] hash  Buffer to hold hash.
10445  * @return  0 on success.
10446  * @return  MEMORY_E when dynamic memory allocation fails.
10447  */
10448 int CalcHashId(const byte* data, word32 len, byte* hash)
10449 {
10450     int ret;
10451 
10452 #if defined(NO_SHA) && !defined(NO_SHA256)
10453     ret = wc_Sha256Hash(data, len, hash);
10454 #elif !defined(NO_SHA)
10455     ret = wc_ShaHash(data, len, hash);
10456 #else
10457     ret = NOT_COMPILED_IN;
10458     (void)data;
10459     (void)len;
10460     (void)hash;
10461 #endif
10462 
10463     return ret;
10464 }
10465 
10466 #ifndef NO_CERTS
10467 /* Get the hash of the id using the SHA-1 or SHA-256.
10468  *
10469  * If the id is not the length of the hash, then hash it.
10470  *
10471  * @param [in]  id    Id to get hash for.
10472  * @param [in]  len   Length of id in bytes.
10473  * @param [out] hash  Buffer to hold hash.
10474  * @return  0 on success.
10475  * @return  MEMORY_E when dynamic memory allocation fails.
10476  */
10477 static int GetHashId(const byte* id, int length, byte* hash)
10478 {
10479     int ret;
10480 
10481     if (length == KEYID_SIZE) {
10482         XMEMCPY(hash, id, length);
10483         ret = 0;
10484     }
10485     else {
10486         ret = CalcHashId(id, length, hash);
10487     }
10488 
10489     return ret;
10490 }
10491 #endif /* !NO_CERTS */
10492 
10493 #ifdef WOLFSSL_ASN_TEMPLATE
10494 /* Id for email address. */
10495 #define ASN_EMAIL     0x100
10496 /* Id for user id. */
10497 #define ASN_UID       0x101
10498 /* Id for domain component. */
10499 #define ASN_DC        0x102
10500 /* Id for jurisdiction country. */
10501 #define ASN_JURIS_C   0x203
10502 /* Id for jurisdiction state. */
10503 #define ASN_JURIS_ST  0x203
10504 
10505 /* Set the string for a name component into the subject name. */
10506 #define SetCertNameSubject(cert, id, val) \
10507     *((char**)(((byte *)cert) + certNameSubject[(id) - 3].data)) = val
10508 /* Set the string length for a name component into the subject name. */
10509 #define SetCertNameSubjectLen(cert, id, val) \
10510     *((int*)(((byte *)cert) + certNameSubject[(id) - 3].len)) = val
10511 /* Set the encoding for a name component into the subject name. */
10512 #define SetCertNameSubjectEnc(cert, id, val) \
10513     *((byte*)(((byte *)cert) + certNameSubject[(id) - 3].enc)) = val
10514 
10515 /* Get the string of a name component from the subject name. */
10516 #define GetCertNameSubjectStr(id) \
10517     (certNameSubject[(id) - 3].str)
10518 /* Get the string length of a name component from the subject name. */
10519 #define GetCertNameSubjectStrLen(id) \
10520     (certNameSubject[(id) - 3].strLen)
10521 /* Get the NID of a name component from the subject name. */
10522 #define GetCertNameSubjectNID(id) \
10523     (certNameSubject[(id) - 3].nid)
10524 
10525 #define ValidCertNameSubject(id) \
10526     ((id - 3) >= 0 && (id - 3) < certNameSubjectSz && \
10527             (certNameSubject[(id) - 3].strLen > 0))
10528 
10529 /* Mapping of certificate name component to useful information. */
10530 typedef struct CertNameData {
10531     /* Type string of name component. */
10532     const char* str;
10533     /* Length of type string of name component. */
10534     byte        strLen;
10535 #ifdef WOLFSSL_CERT_GEN
10536     /* Offset of data in subject name component. */
10537     size_t      data;
10538     /* Offset of length in subject name component. */
10539     size_t      len;
10540     /* Offset of encoding in subject name component. */
10541     size_t      enc;
10542 #endif
10543 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10544     /* NID of type for subject name component. */
10545     int         nid;
10546 #endif
10547 } CertNameData;
10548 
10549 /* List of data for common name components. */
10550 static const CertNameData certNameSubject[] = {
10551     /* Common Name */
10552     {
10553         "/CN=", 4,
10554 #ifdef WOLFSSL_CERT_GEN
10555         OFFSETOF(DecodedCert, subjectCN),
10556         OFFSETOF(DecodedCert, subjectCNLen),
10557         OFFSETOF(DecodedCert, subjectCNEnc),
10558 #endif
10559 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10560         NID_commonName
10561 #endif
10562     },
10563     /* Surname */
10564     {
10565         "/SN=", 4,
10566 #ifdef WOLFSSL_CERT_GEN
10567         OFFSETOF(DecodedCert, subjectSN),
10568         OFFSETOF(DecodedCert, subjectSNLen),
10569         OFFSETOF(DecodedCert, subjectSNEnc),
10570 #endif
10571 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10572         NID_surname
10573 #endif
10574     },
10575     /* Serial Number */
10576     {
10577         "/serialNumber=", 14,
10578 #ifdef WOLFSSL_CERT_GEN
10579         OFFSETOF(DecodedCert, subjectSND),
10580         OFFSETOF(DecodedCert, subjectSNDLen),
10581         OFFSETOF(DecodedCert, subjectSNDEnc),
10582 #endif
10583 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10584         NID_serialNumber
10585 #endif
10586     },
10587     /* Country Name */
10588     {
10589         "/C=", 3,
10590 #ifdef WOLFSSL_CERT_GEN
10591         OFFSETOF(DecodedCert, subjectC),
10592         OFFSETOF(DecodedCert, subjectCLen),
10593         OFFSETOF(DecodedCert, subjectCEnc),
10594 #endif
10595 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10596         NID_countryName
10597 #endif
10598     },
10599     /* Locality Name */
10600     {
10601         "/L=", 3,
10602 #ifdef WOLFSSL_CERT_GEN
10603         OFFSETOF(DecodedCert, subjectL),
10604         OFFSETOF(DecodedCert, subjectLLen),
10605         OFFSETOF(DecodedCert, subjectLEnc),
10606 #endif
10607 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10608         NID_localityName
10609 #endif
10610     },
10611     /* State Name */
10612     {
10613         "/ST=", 4,
10614 #ifdef WOLFSSL_CERT_GEN
10615         OFFSETOF(DecodedCert, subjectST),
10616         OFFSETOF(DecodedCert, subjectSTLen),
10617         OFFSETOF(DecodedCert, subjectSTEnc),
10618 #endif
10619 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10620         NID_stateOrProvinceName
10621 #endif
10622     },
10623     /* Street Address */
10624     {
10625         "/street=", 8,
10626 #ifdef WOLFSSL_CERT_EXT
10627         OFFSETOF(DecodedCert, subjectStreet),
10628         OFFSETOF(DecodedCert, subjectStreetLen),
10629         OFFSETOF(DecodedCert, subjectStreetEnc),
10630 #endif
10631 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10632         NID_streetAddress
10633 #endif
10634     },
10635     /* Organization Name */
10636     {
10637         "/O=", 3,
10638 #ifdef WOLFSSL_CERT_GEN
10639         OFFSETOF(DecodedCert, subjectO),
10640         OFFSETOF(DecodedCert, subjectOLen),
10641         OFFSETOF(DecodedCert, subjectOEnc),
10642 #endif
10643 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10644         NID_organizationName
10645 #endif
10646     },
10647     /* Organization Unit Name */
10648     {
10649         "/OU=", 4,
10650 #ifdef WOLFSSL_CERT_GEN
10651         OFFSETOF(DecodedCert, subjectOU),
10652         OFFSETOF(DecodedCert, subjectOULen),
10653         OFFSETOF(DecodedCert, subjectOUEnc),
10654 #endif
10655 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10656         NID_organizationalUnitName
10657 #endif
10658     },
10659     /* Title */
10660     {
10661         NULL, 0,
10662 #ifdef WOLFSSL_CERT_GEN
10663         0,
10664         0,
10665         0,
10666 #endif
10667 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10668         0,
10669 #endif
10670     },
10671     /* Undefined */
10672     {
10673         NULL, 0,
10674 #ifdef WOLFSSL_CERT_GEN
10675         0,
10676         0,
10677         0,
10678 #endif
10679 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10680         0,
10681 #endif
10682     },
10683     /* Undefined */
10684     {
10685         NULL, 0,
10686 #ifdef WOLFSSL_CERT_GEN
10687         0,
10688         0,
10689         0,
10690 #endif
10691 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10692         0,
10693 #endif
10694     },
10695     /* Business Category */
10696     {
10697         "/businessCategory=", 18,
10698 #ifdef WOLFSSL_CERT_GEN
10699 #ifdef WOLFSSL_CERT_EXT
10700         OFFSETOF(DecodedCert, subjectBC),
10701         OFFSETOF(DecodedCert, subjectBCLen),
10702         OFFSETOF(DecodedCert, subjectBCEnc),
10703 #else
10704         0,
10705         0,
10706         0,
10707 #endif
10708 #endif
10709 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10710         NID_businessCategory
10711 #endif
10712     },
10713     /* Undefined */
10714     {
10715         NULL, 0,
10716 #ifdef WOLFSSL_CERT_GEN
10717         0,
10718         0,
10719         0,
10720 #endif
10721 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10722         0,
10723 #endif
10724     },
10725     /* Postal Code */
10726     {
10727         "/postalCode=", 12,
10728 #ifdef WOLFSSL_CERT_GEN
10729 #ifdef WOLFSSL_CERT_EXT
10730         OFFSETOF(DecodedCert, subjectPC),
10731         OFFSETOF(DecodedCert, subjectPCLen),
10732         OFFSETOF(DecodedCert, subjectPCEnc),
10733 #else
10734         0,
10735         0,
10736         0,
10737 #endif
10738 #endif
10739 #ifdef WOLFSSL_X509_NAME_AVAILABLE
10740         NID_postalCode
10741 #endif
10742     },
10743 };
10744 
10745 static const int certNameSubjectSz =
10746         (int) (sizeof(certNameSubject) / sizeof(CertNameData));
10747 
10748 /* ASN.1 template for an RDN.
10749  * X.509: RFC 5280, 4.1.2.4 - RelativeDistinguishedName
10750  */
10751 static const ASNItem rdnASN[] = {
10752 /* SET       */ { 1, ASN_SET, 1, 1, 0 },
10753                            /* AttributeTypeAndValue */
10754 /* ATTR_SEQ  */     { 2, ASN_SEQUENCE, 1, 1, 0 },
10755                                    /* AttributeType */
10756 /* ATTR_TYPE */         { 3, ASN_OBJECT_ID, 0, 0, 0 },
10757                            /* AttributeValue: Choice of tags - rdnChoice. */
10758 /* ATTR_VAL  */         { 3, 0, 0, 0, 0 },
10759 };
10760 enum {
10761     RDNASN_IDX_SET = 0,
10762     RDNASN_IDX_ATTR_SEQ,
10763     RDNASN_IDX_ATTR_TYPE,
10764     RDNASN_IDX_ATTR_VAL,
10765 };
10766 
10767 /* Number of items in ASN.1 template for an RDN. */
10768 #define rdnASN_Length (sizeof(rdnASN) / sizeof(ASNItem))
10769 
10770 /* Supported types of encodings (tags) for RDN strings.
10771  * X.509: RFC 5280, 4.1.2.4 - DirectoryString
10772  * (IA5 String not listed in RFC but required for alternative types)
10773  */
10774 static const byte rdnChoice[] = {
10775     ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, ASN_T61STRING,
10776     ASN_UNIVERSALSTRING, ASN_BMPSTRING, 0
10777 };
10778 #endif
10779 
10780 #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
10781 /* used to set the human readable string for the IP address with a ASN_IP_TYPE
10782  * DNS entry
10783  * return 0 on success
10784  */
10785 static int GenerateDNSEntryIPString(DNS_entry* entry, void* heap)
10786 {
10787     int ret = 0;
10788     int nameSz;
10789     char tmpName[WOLFSSL_MAX_IPSTR] = {0};
10790     char* ip;
10791 
10792     if (entry == NULL || entry->type != ASN_IP_TYPE) {
10793         return BAD_FUNC_ARG;
10794     }
10795 
10796     if (entry->len != WOLFSSL_IP4_ADDR_LEN &&
10797             entry->len != WOLFSSL_IP6_ADDR_LEN) {
10798         WOLFSSL_MSG("Unexpected IP size");
10799         return BAD_FUNC_ARG;
10800     }
10801     ip = entry->name;
10802 
10803     /* store IP addresses as a string */
10804     if (entry->len == WOLFSSL_IP4_ADDR_LEN) {
10805         XSNPRINTF(tmpName, sizeof(tmpName), "%u.%u.%u.%u", 0xFF & ip[0],
10806                 0xFF & ip[1], 0xFF & ip[2], 0xFF & ip[3]);
10807     }
10808 
10809     if (entry->len == WOLFSSL_IP6_ADDR_LEN) {
10810         int i;
10811         for (i = 0; i < 8; i++) {
10812             XSNPRINTF(tmpName + i * 5, sizeof(tmpName) - i * 5,
10813                     "%02X%02X%s", 0xFF & ip[2 * i], 0xFF & ip[2 * i + 1],
10814                     (i < 7) ? ":" : "");
10815         }
10816     }
10817 
10818     nameSz = (int)XSTRLEN(tmpName);
10819     entry->ipString = (char*)XMALLOC(nameSz + 1, heap, DYNAMIC_TYPE_ALTNAME);
10820     if (entry->ipString == NULL) {
10821         ret = MEMORY_E;
10822     }
10823 
10824     if (ret == 0) {
10825         XMEMCPY(entry->ipString, tmpName, nameSz);
10826         entry->ipString[nameSz] = '\0';
10827     }
10828 
10829     return ret;
10830 }
10831 #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
10832 
10833 #ifdef WOLFSSL_ASN_TEMPLATE
10834 #if defined(WOLFSSL_CERT_GEN) || \
10835     (!defined(NO_CERTS) && !defined(IGNORE_NAME_CONSTRAINTS))
10836 /* Allocate a DNS entry and set the fields.
10837  *
10838  * @param [in]      cert     Certificate object.
10839  * @param [in]      str      DNS name string.
10840  * @param [in]      strLen   Length of DNS name string.
10841  * @param [in]      type     Type of DNS name string.
10842  * @param [in, out] entries  Linked list of DNS name entries.
10843  * @return  0 on success.
10844  * @return  MEMORY_E when dynamic memory allocation fails.
10845  */
10846 static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen,
10847                        int type, DNS_entry** entries)
10848 {
10849     DNS_entry* dnsEntry;
10850     int ret = 0;
10851 
10852     /* Only used for heap. */
10853     (void)cert;
10854 
10855     /* TODO: consider one malloc. */
10856     /* Allocate DNS Entry object. */
10857     dnsEntry = AltNameNew(cert->heap);
10858     if (dnsEntry == NULL) {
10859         ret = MEMORY_E;
10860     }
10861     if (ret == 0) {
10862         /* Allocate DNS Entry name - length of string plus 1 for NUL. */
10863         dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
10864                                                           DYNAMIC_TYPE_ALTNAME);
10865         if (dnsEntry->name == NULL) {
10866             XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
10867             ret = MEMORY_E;
10868         }
10869     }
10870     if (ret == 0) {
10871         /* Set tag type, name length, name and NUL terminate name. */
10872         dnsEntry->type = type;
10873         dnsEntry->len = strLen;
10874         XMEMCPY(dnsEntry->name, str, strLen);
10875         dnsEntry->name[strLen] = '\0';
10876 
10877     #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
10878         /* store IP addresses as a string */
10879         if (type == ASN_IP_TYPE) {
10880             if ((ret = GenerateDNSEntryIPString(dnsEntry, cert->heap)) != 0) {
10881                 XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
10882                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
10883             }
10884         }
10885     #endif
10886     }
10887 
10888     if (ret == 0) {
10889     #if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
10890         dnsEntry->next = NULL;
10891         if (*entries == NULL) {
10892             /* First on list */
10893             *entries = dnsEntry;
10894         }
10895         else {
10896             DNS_entry* temp = *entries;
10897 
10898             /* Find end */
10899             for (; (temp->next != NULL); temp = temp->next);
10900 
10901             /* Add to end */
10902             temp->next = dnsEntry;
10903         }
10904     #else
10905         /* Prepend entry to linked list. */
10906         dnsEntry->next = *entries;
10907         *entries = dnsEntry;
10908     #endif
10909     }
10910 
10911     return ret;
10912 }
10913 #endif
10914 
10915 /* Set the details of a subject name component into a certificate.
10916  *
10917  * @param [in, out] cert    Certificate object.
10918  * @param [in]      id      Id of component.
10919  * @param [in]      str     String for component.
10920  * @param [in]      strLen  Length of string.
10921  * @param [in]      tag     BER tag representing encoding of string.
10922  * @return  0 on success.
10923  * @return  MEMORY_E when dynamic memory allocation fails.
10924  */
10925 static int SetSubject(DecodedCert* cert, int id, byte* str, word32 strLen,
10926                       byte tag)
10927 {
10928     int ret = 0;
10929 
10930     /* Put string and encoding into certificate. */
10931     if (id == ASN_COMMON_NAME) {
10932         cert->subjectCN = (char *)str;
10933         cert->subjectCNLen = strLen;
10934         cert->subjectCNEnc = tag;
10935     }
10936 #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
10937     else if (id > ASN_COMMON_NAME && id <= ASN_BUS_CAT) {
10938         /* Use table and offsets to put data into appropriate fields. */
10939         SetCertNameSubject(cert, id, (char*)str);
10940         SetCertNameSubjectLen(cert, id, strLen);
10941         SetCertNameSubjectEnc(cert, id, tag);
10942     }
10943     else if (id == ASN_EMAIL) {
10944         cert->subjectEmail = (char*)str;
10945         cert->subjectEmailLen = strLen;
10946     #if !defined(IGNORE_NAME_CONSTRAINTS)
10947         ret = SetDNSEntry(cert, cert->subjectEmail, strLen, 0,
10948                           &cert->altEmailNames);
10949     #endif
10950     }
10951 #ifdef WOLFSSL_CERT_EXT
10952     /* TODO: consider mapping id to an index and using SetCertNameSubect*(). */
10953     else if (id == ASN_JURIS_C) {
10954         cert->subjectJC = (char*)str;
10955         cert->subjectJCLen = strLen;
10956         cert->subjectJCEnc = tag;
10957     }
10958     else if (id == ASN_JURIS_ST) {
10959         cert->subjectJS = (char*)str;
10960         cert->subjectJSLen = strLen;
10961         cert->subjectJSEnc = tag;
10962     }
10963 #endif
10964 #endif
10965 
10966     return ret;
10967 }
10968 
10969 /* Get a RelativeDistinguishedName from the encoding and put in certificate.
10970  *
10971  * @param [in, out] cert       Certificate object.
10972  * @param [in, out] full       Full name string. ([/<type>=<value>]*)
10973  * @param [in, out] idx        Index int full name to place next component.
10974  * @param [in, out] nid        NID of component type.
10975  * @param [in]      isSubject  Whether this data is for a subject name.
10976  * @param [in]      dataASN    Decoded data of RDN. Expected rdnASN type.
10977  * @return  0 on success.
10978  * @return  MEMORY_E when dynamic memory allocation fails.
10979  * @return  ASN_PARSE_E when type not supported.
10980  */
10981 static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
10982                   int isSubject, ASNGetData* dataASN)
10983 {
10984     int         ret = 0;
10985     const char* typeStr = NULL;
10986     byte        typeStrLen = 0;
10987     byte*       oid;
10988     word32      oidSz;
10989     int         id = 0;
10990 
10991     (void)nid;
10992 
10993     /* Get name type OID from data items. */
10994     GetASN_OIDData(&dataASN[RDNASN_IDX_ATTR_TYPE], &oid, &oidSz);
10995 
10996     /* v1 name types */
10997     if ((oidSz == 3) && (oid[0] == 0x55) && (oid[1] == 0x04)) {
10998         id = oid[2];
10999         /* Check range of supported ids in table. */
11000         if (ValidCertNameSubject(id)) {
11001             /* Get the type string, length and NID from table. */
11002             typeStr = GetCertNameSubjectStr(id);
11003             typeStrLen = GetCertNameSubjectStrLen(id);
11004         #ifdef WOLFSSL_X509_NAME_AVAILABLE
11005             *nid = GetCertNameSubjectNID(id);
11006         #endif
11007         }
11008     }
11009     else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) {
11010         /* Set the email id, type string, length and NID. */
11011         id = ASN_EMAIL;
11012         typeStr =  WOLFSSL_EMAIL_ADDR;
11013         typeStrLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
11014     #ifdef WOLFSSL_X509_NAME_AVAILABLE
11015         *nid = NID_emailAddress;
11016     #endif
11017     }
11018     else if (oidSz == sizeof(uidOid) && XMEMCMP(oid, uidOid, oidSz) == 0) {
11019         /* Set the user id, type string, length and NID. */
11020         id = ASN_UID;
11021         typeStr = WOLFSSL_USER_ID;
11022         typeStrLen = sizeof(WOLFSSL_USER_ID) - 1;
11023     #ifdef WOLFSSL_X509_NAME_AVAILABLE
11024         *nid = NID_userId;
11025     #endif
11026     }
11027     else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz) == 0) {
11028         /* Set the domain component, type string, length and NID. */
11029         id = ASN_DC;
11030         typeStr = WOLFSSL_DOMAIN_COMPONENT;
11031         typeStrLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
11032     #ifdef WOLFSSL_X509_NAME_AVAILABLE
11033         *nid = NID_domainComponent;
11034     #endif
11035     }
11036     /* Other OIDs that start with the same values. */
11037     else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz-1) == 0) {
11038         WOLFSSL_MSG("Unknown pilot attribute type");
11039         ret = ASN_PARSE_E;
11040     }
11041     else if (oidSz == ASN_JOI_PREFIX_SZ + 1 &&
11042                          XMEMCMP(oid, ASN_JOI_PREFIX, ASN_JOI_PREFIX_SZ) == 0) {
11043         /* Set the jurisdiction id. */
11044         id = 0x200 + oid[ASN_JOI_PREFIX_SZ];
11045 
11046         /* Set the jurisdiction type string, length and NID if known. */
11047         if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_C) {
11048             typeStr = WOLFSSL_JOI_C;
11049             typeStrLen = sizeof(WOLFSSL_JOI_C) - 1;
11050         #ifdef WOLFSSL_X509_NAME_AVAILABLE
11051             *nid = NID_jurisdictionCountryName;
11052         #endif /* WOLFSSL_X509_NAME_AVAILABLE */
11053         }
11054         else if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_ST) {
11055             typeStr = WOLFSSL_JOI_ST;
11056             typeStrLen = sizeof(WOLFSSL_JOI_ST) - 1;
11057         #ifdef WOLFSSL_X509_NAME_AVAILABLE
11058             *nid = NID_jurisdictionStateOrProvinceName;
11059         #endif /* WOLFSSL_X509_NAME_AVAILABLE */
11060         }
11061         else {
11062             WOLFSSL_MSG("Unknown Jurisdiction, skipping");
11063         }
11064     }
11065 
11066     if ((ret == 0) && (typeStr != NULL)) {
11067         /* OID type to store for subject name and add to full string. */
11068         byte*  str;
11069         word32 strLen;
11070         byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
11071 
11072         /* Get the string reference and length. */
11073         GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
11074 
11075         if (isSubject) {
11076             /* Store subject field components. */
11077             ret = SetSubject(cert, id, str, strLen, tag);
11078         }
11079         if (ret == 0) {
11080             /* Check there is space for this in the full name string and
11081              * terminating NUL character. */
11082             if ((typeStrLen + strLen) < (word32)(ASN_NAME_MAX - *idx))
11083             {
11084                 /* Add RDN to full string. */
11085                 XMEMCPY(&full[*idx], typeStr, typeStrLen);
11086                 *idx += typeStrLen;
11087                 XMEMCPY(&full[*idx], str, strLen);
11088                 *idx += strLen;
11089             }
11090             else {
11091                 WOLFSSL_MSG("ASN Name too big, skipping");
11092             }
11093         }
11094     }
11095 
11096     return ret;
11097 }
11098 #endif /* WOLFSSL_ASN_TEMPLATE */
11099 
11100 /* Get a certificate name into the certificate object.
11101  *
11102  * @param [in, out] cert      Decoded certificate object.
11103  * @param [out]     full      Buffer to hold full name as a string.
11104  * @param [out]     hash      Buffer to hold hash of name.
11105  * @param [in]      nameType  ISSUER or SUBJECT.
11106  * @param [in]      input     Buffer holding certificate name.
11107  * @param [in, out] inOutIdx  On in, start of certificate name.
11108  *                            On out, start of ASN.1 item after cert name.
11109  * @param [in]      maxIdx    Index of next item after certificate name.
11110  * @return  0 on success.
11111  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11112  *          is invalid.
11113  * @return  BUFFER_E when data in buffer is too small.
11114  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11115  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11116  * @return  MEMORY_E when dynamic memory allocation fails.
11117  */
11118 static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
11119                        const byte* input, word32* inOutIdx, word32 maxIdx)
11120 {
11121 #ifndef WOLFSSL_ASN_TEMPLATE
11122     int    length;  /* length of all distinguished names */
11123     int    dummy;
11124     int    ret;
11125     word32 idx;
11126     word32 srcIdx = *inOutIdx;
11127 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11128     !defined(WOLFCRYPT_ONLY)
11129     WOLFSSL_X509_NAME* dName = NULL;
11130 #endif
11131 
11132     WOLFSSL_MSG("Getting Cert Name");
11133 
11134     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
11135      * calculated over the entire DER encoding of the Name field, including
11136      * the tag and length. */
11137     if (CalcHashId(input + *inOutIdx, maxIdx - *inOutIdx, hash) != 0)
11138         return ASN_PARSE_E;
11139 
11140 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11141     !defined(WOLFCRYPT_ONLY)
11142     dName = wolfSSL_X509_NAME_new();
11143     if (dName == NULL) {
11144         return MEMORY_E;
11145     }
11146 #endif /* OPENSSL_EXTRA */
11147 
11148     if (GetSequence(input, &srcIdx, &length, maxIdx) < 0) {
11149 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11150             !defined(WOLFCRYPT_ONLY)
11151         wolfSSL_X509_NAME_free(dName);
11152 #endif /* OPENSSL_EXTRA */
11153         return ASN_PARSE_E;
11154     }
11155 
11156 #if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
11157     /* store pointer to raw issuer */
11158     if (nameType == ISSUER) {
11159         cert->issuerRaw = &input[srcIdx];
11160         cert->issuerRawLen = length;
11161     }
11162 #endif
11163 #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
11164     if (nameType == SUBJECT) {
11165         cert->subjectRaw = &input[srcIdx];
11166         cert->subjectRawLen = length;
11167     }
11168 #endif
11169 
11170     length += srcIdx;
11171     idx = 0;
11172 
11173     while (srcIdx < (word32)length) {
11174         byte        b       = 0;
11175         byte        joint[3];
11176         byte        tooBig  = FALSE;
11177         int         oidSz;
11178         const char* copy    = NULL;
11179         int         copyLen = 0;
11180         int         strLen  = 0;
11181         byte        id      = 0;
11182     #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
11183                 && !defined(WOLFCRYPT_ONLY)
11184          int        nid = NID_undef;
11185          int        enc;
11186     #endif /* OPENSSL_EXTRA */
11187 
11188         if (GetSet(input, &srcIdx, &dummy, maxIdx) < 0) {
11189             WOLFSSL_MSG("Cert name lacks set header, trying sequence");
11190         }
11191 
11192         if (GetSequence(input, &srcIdx, &dummy, maxIdx) <= 0) {
11193         #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11194             !defined(WOLFCRYPT_ONLY)
11195             wolfSSL_X509_NAME_free(dName);
11196         #endif /* OPENSSL_EXTRA */
11197             return ASN_PARSE_E;
11198         }
11199 
11200         ret = GetASNObjectId(input, &srcIdx, &oidSz, maxIdx);
11201         if (ret != 0) {
11202         #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11203             !defined(WOLFCRYPT_ONLY)
11204             wolfSSL_X509_NAME_free(dName);
11205         #endif /* OPENSSL_EXTRA */
11206             return ret;
11207         }
11208 
11209         /* make sure there is room for joint */
11210         if ((srcIdx + sizeof(joint)) > (word32)maxIdx) {
11211         #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11212             !defined(WOLFCRYPT_ONLY)
11213             wolfSSL_X509_NAME_free(dName);
11214         #endif /* OPENSSL_EXTRA */
11215             return ASN_PARSE_E;
11216         }
11217 
11218         XMEMCPY(joint, &input[srcIdx], sizeof(joint));
11219 
11220         /* v1 name types */
11221         if (joint[0] == 0x55 && joint[1] == 0x04) {
11222             srcIdx += 3;
11223             id = joint[2];
11224             if (GetHeader(input, &b, &srcIdx, &strLen, maxIdx, 1) < 0) {
11225             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11226             !defined(WOLFCRYPT_ONLY)
11227                 wolfSSL_X509_NAME_free(dName);
11228             #endif /* OPENSSL_EXTRA */
11229                 return ASN_PARSE_E;
11230             }
11231 
11232             if (id == ASN_COMMON_NAME) {
11233                 if (nameType == SUBJECT) {
11234                     cert->subjectCN = (char *)&input[srcIdx];
11235                     cert->subjectCNLen = strLen;
11236                     cert->subjectCNEnc = b;
11237                 }
11238 
11239                 copy = WOLFSSL_COMMON_NAME;
11240                 copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
11241             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
11242                 && !defined(WOLFCRYPT_ONLY)
11243                 nid = NID_commonName;
11244             #endif /* OPENSSL_EXTRA */
11245             }
11246             else if (id == ASN_SUR_NAME) {
11247                 copy = WOLFSSL_SUR_NAME;
11248                 copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
11249                 #ifdef WOLFSSL_CERT_GEN
11250                     if (nameType == SUBJECT) {
11251                         cert->subjectSN = (char*)&input[srcIdx];
11252                         cert->subjectSNLen = strLen;
11253                         cert->subjectSNEnc = b;
11254                     }
11255                 #endif /* WOLFSSL_CERT_GEN */
11256                 #if (defined(OPENSSL_EXTRA) || \
11257                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11258                         && !defined(WOLFCRYPT_ONLY)
11259                     nid = NID_surname;
11260                 #endif /* OPENSSL_EXTRA */
11261             }
11262             else if (id == ASN_COUNTRY_NAME) {
11263                 copy = WOLFSSL_COUNTRY_NAME;
11264                 copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
11265                 #ifdef WOLFSSL_CERT_GEN
11266                     if (nameType == SUBJECT) {
11267                         cert->subjectC = (char*)&input[srcIdx];
11268                         cert->subjectCLen = strLen;
11269                         cert->subjectCEnc = b;
11270                     }
11271                 #endif /* WOLFSSL_CERT_GEN */
11272                 #if (defined(OPENSSL_EXTRA) || \
11273                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11274                         && !defined(WOLFCRYPT_ONLY)
11275                     nid = NID_countryName;
11276                 #endif /* OPENSSL_EXTRA */
11277             }
11278             else if (id == ASN_LOCALITY_NAME) {
11279                 copy = WOLFSSL_LOCALITY_NAME;
11280                 copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
11281                 #ifdef WOLFSSL_CERT_GEN
11282                     if (nameType == SUBJECT) {
11283                         cert->subjectL = (char*)&input[srcIdx];
11284                         cert->subjectLLen = strLen;
11285                         cert->subjectLEnc = b;
11286                     }
11287                 #endif /* WOLFSSL_CERT_GEN */
11288                 #if (defined(OPENSSL_EXTRA) || \
11289                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11290                         && !defined(WOLFCRYPT_ONLY)
11291                     nid = NID_localityName;
11292                 #endif /* OPENSSL_EXTRA */
11293             }
11294             else if (id == ASN_STATE_NAME) {
11295                 copy = WOLFSSL_STATE_NAME;
11296                 copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
11297                 #ifdef WOLFSSL_CERT_GEN
11298                     if (nameType == SUBJECT) {
11299                         cert->subjectST = (char*)&input[srcIdx];
11300                         cert->subjectSTLen = strLen;
11301                         cert->subjectSTEnc = b;
11302                     }
11303                 #endif /* WOLFSSL_CERT_GEN */
11304                 #if (defined(OPENSSL_EXTRA) || \
11305                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11306                         && !defined(WOLFCRYPT_ONLY)
11307                     nid = NID_stateOrProvinceName;
11308                 #endif /* OPENSSL_EXTRA */
11309             }
11310             else if (id == ASN_ORG_NAME) {
11311                 copy = WOLFSSL_ORG_NAME;
11312                 copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
11313                 #ifdef WOLFSSL_CERT_GEN
11314                     if (nameType == SUBJECT) {
11315                         cert->subjectO = (char*)&input[srcIdx];
11316                         cert->subjectOLen = strLen;
11317                         cert->subjectOEnc = b;
11318                     }
11319                 #endif /* WOLFSSL_CERT_GEN */
11320                 #if (defined(OPENSSL_EXTRA) || \
11321                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11322                         && !defined(WOLFCRYPT_ONLY)
11323                     nid = NID_organizationName;
11324                 #endif /* OPENSSL_EXTRA */
11325             }
11326             else if (id == ASN_ORGUNIT_NAME) {
11327                 copy = WOLFSSL_ORGUNIT_NAME;
11328                 copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
11329                 #ifdef WOLFSSL_CERT_GEN
11330                     if (nameType == SUBJECT) {
11331                         cert->subjectOU = (char*)&input[srcIdx];
11332                         cert->subjectOULen = strLen;
11333                         cert->subjectOUEnc = b;
11334                     }
11335                 #endif /* WOLFSSL_CERT_GEN */
11336                 #if (defined(OPENSSL_EXTRA) || \
11337                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11338                         && !defined(WOLFCRYPT_ONLY)
11339                     nid = NID_organizationalUnitName;
11340                 #endif /* OPENSSL_EXTRA */
11341             }
11342             else if (id == ASN_SERIAL_NUMBER) {
11343                 copy = WOLFSSL_SERIAL_NUMBER;
11344                 copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
11345                 #ifdef WOLFSSL_CERT_GEN
11346                     if (nameType == SUBJECT) {
11347                         cert->subjectSND = (char*)&input[srcIdx];
11348                         cert->subjectSNDLen = strLen;
11349                         cert->subjectSNDEnc = b;
11350                     }
11351                 #endif /* WOLFSSL_CERT_GEN */
11352                 #if (defined(OPENSSL_EXTRA) || \
11353                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11354                         && !defined(WOLFCRYPT_ONLY)
11355                     nid = NID_serialNumber;
11356                 #endif /* OPENSSL_EXTRA */
11357             }
11358         #ifdef WOLFSSL_CERT_EXT
11359             else if (id == ASN_STREET_ADDR) {
11360                 copy = WOLFSSL_STREET_ADDR_NAME;
11361                 copyLen = sizeof(WOLFSSL_STREET_ADDR_NAME) - 1;
11362                 #ifdef WOLFSSL_CERT_GEN
11363                     if (nameType == SUBJECT) {
11364                         cert->subjectStreet = (char*)&input[srcIdx];
11365                         cert->subjectStreetLen = strLen;
11366                         cert->subjectStreetEnc = b;
11367                     }
11368                 #endif /* WOLFSSL_CERT_GEN */
11369                 #if (defined(OPENSSL_EXTRA) || \
11370                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11371                         && !defined(WOLFCRYPT_ONLY)
11372                     nid = NID_streetAddress;
11373                 #endif /* OPENSSL_EXTRA */
11374             }
11375             else if (id == ASN_BUS_CAT) {
11376                 copy = WOLFSSL_BUS_CAT;
11377                 copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
11378             #ifdef WOLFSSL_CERT_GEN
11379                 if (nameType == SUBJECT) {
11380                     cert->subjectBC = (char*)&input[srcIdx];
11381                     cert->subjectBCLen = strLen;
11382                     cert->subjectBCEnc = b;
11383                 }
11384             #endif /* WOLFSSL_CERT_GEN */
11385             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
11386                         && !defined(WOLFCRYPT_ONLY)
11387                 nid = NID_businessCategory;
11388             #endif /* OPENSSL_EXTRA */
11389             }
11390             else if (id == ASN_POSTAL_CODE) {
11391                 copy = WOLFSSL_POSTAL_NAME;
11392                 copyLen = sizeof(WOLFSSL_POSTAL_NAME) - 1;
11393                 #ifdef WOLFSSL_CERT_GEN
11394                     if (nameType == SUBJECT) {
11395                         cert->subjectPC = (char*)&input[srcIdx];
11396                         cert->subjectPCLen = strLen;
11397                         cert->subjectPCEnc = b;
11398                     }
11399                 #endif /* WOLFSSL_CERT_GEN */
11400                 #if (defined(OPENSSL_EXTRA) || \
11401                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11402                         && !defined(WOLFCRYPT_ONLY)
11403                     nid = NID_postalCode;
11404                 #endif /* OPENSSL_EXTRA */
11405             }
11406         #endif /* WOLFSSL_CERT_EXT */
11407         }
11408     #ifdef WOLFSSL_CERT_EXT
11409         else if ((srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
11410                  (0 == XMEMCMP(&input[srcIdx], ASN_JOI_PREFIX,
11411                                ASN_JOI_PREFIX_SZ)) &&
11412                  ((input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
11413                   (input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
11414         {
11415             srcIdx += ASN_JOI_PREFIX_SZ;
11416             id = input[srcIdx++];
11417             b = input[srcIdx++]; /* encoding */
11418 
11419             if (GetLength(input, &srcIdx, &strLen,
11420                           maxIdx) < 0) {
11421             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11422             !defined(WOLFCRYPT_ONLY)
11423                 wolfSSL_X509_NAME_free(dName);
11424             #endif /* OPENSSL_EXTRA */
11425                 return ASN_PARSE_E;
11426             }
11427 
11428             /* Check for jurisdiction of incorporation country name */
11429             if (id == ASN_JOI_C) {
11430                 copy = WOLFSSL_JOI_C;
11431                 copyLen = sizeof(WOLFSSL_JOI_C) - 1;
11432                 #ifdef WOLFSSL_CERT_GEN
11433                     if (nameType == SUBJECT) {
11434                         cert->subjectJC = (char*)&input[srcIdx];
11435                         cert->subjectJCLen = strLen;
11436                         cert->subjectJCEnc = b;
11437                     }
11438                 #endif /* WOLFSSL_CERT_GEN */
11439                 #if (defined(OPENSSL_EXTRA) || \
11440                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11441                         && !defined(WOLFCRYPT_ONLY)
11442                     nid = NID_jurisdictionCountryName;
11443                 #endif /* OPENSSL_EXTRA */
11444             }
11445 
11446             /* Check for jurisdiction of incorporation state name */
11447             else if (id == ASN_JOI_ST) {
11448                 copy = WOLFSSL_JOI_ST;
11449                 copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
11450                 #ifdef WOLFSSL_CERT_GEN
11451                     if (nameType == SUBJECT) {
11452                         cert->subjectJS = (char*)&input[srcIdx];
11453                         cert->subjectJSLen = strLen;
11454                         cert->subjectJSEnc = b;
11455                     }
11456                 #endif /* WOLFSSL_CERT_GEN */
11457                 #if (defined(OPENSSL_EXTRA) || \
11458                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11459                         && !defined(WOLFCRYPT_ONLY)
11460                     nid = NID_jurisdictionStateOrProvinceName;
11461                 #endif /* OPENSSL_EXTRA */
11462             }
11463 
11464             if ((strLen + copyLen) > (int)(ASN_NAME_MAX - idx)) {
11465                 WOLFSSL_MSG("ASN Name too big, skipping");
11466                 tooBig = TRUE;
11467             }
11468         }
11469     #endif /* WOLFSSL_CERT_EXT */
11470         else {
11471             /* skip */
11472             byte email = FALSE;
11473             byte pilot = FALSE;
11474 
11475             if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr */
11476                 id = ASN_EMAIL_NAME;
11477                 email = TRUE;
11478             }
11479 
11480             if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
11481                 /* last value of OID is the type of pilot attribute */
11482                 id    = input[srcIdx + oidSz - 1];
11483                 pilot = TRUE;
11484             }
11485 
11486             srcIdx += oidSz + 1;
11487 
11488             if (GetLength(input, &srcIdx, &strLen, maxIdx) < 0) {
11489             #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11490             !defined(WOLFCRYPT_ONLY)
11491                 wolfSSL_X509_NAME_free(dName);
11492             #endif /* OPENSSL_EXTRA */
11493                 return ASN_PARSE_E;
11494             }
11495 
11496             if (strLen > (int)(ASN_NAME_MAX - idx)) {
11497                 WOLFSSL_MSG("ASN name too big, skipping");
11498                 tooBig = TRUE;
11499             }
11500 
11501             if (email) {
11502                 copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
11503                 if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx)) {
11504                     WOLFSSL_MSG("ASN name too big, skipping");
11505                     tooBig = TRUE;
11506                 }
11507                 else {
11508                     copy = WOLFSSL_EMAIL_ADDR;
11509                 }
11510 
11511                 #ifdef WOLFSSL_CERT_GEN
11512                     if (nameType == SUBJECT) {
11513                         cert->subjectEmail = (char*)&input[srcIdx];
11514                         cert->subjectEmailLen = strLen;
11515                     }
11516                 #endif /* WOLFSSL_CERT_GEN */
11517                 #if (defined(OPENSSL_EXTRA) || \
11518                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11519                         && !defined(WOLFCRYPT_ONLY)
11520                     nid = NID_emailAddress;
11521                 #endif /* OPENSSL_EXTRA */
11522                 #ifndef IGNORE_NAME_CONSTRAINTS
11523                     {
11524                         DNS_entry* emailName;
11525 
11526                         emailName = AltNameNew(cert->heap);
11527                         if (emailName == NULL) {
11528                             WOLFSSL_MSG("\tOut of Memory");
11529                         #if (defined(OPENSSL_EXTRA) || \
11530                                 defined(OPENSSL_EXTRA_X509_SMALL)) && \
11531                                 !defined(WOLFCRYPT_ONLY)
11532                             wolfSSL_X509_NAME_free(dName);
11533                         #endif /* OPENSSL_EXTRA */
11534                             return MEMORY_E;
11535                         }
11536                         emailName->type = 0;
11537                         emailName->name = (char*)XMALLOC(strLen + 1,
11538                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
11539                         if (emailName->name == NULL) {
11540                             WOLFSSL_MSG("\tOut of Memory");
11541                             XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
11542                         #if (defined(OPENSSL_EXTRA) || \
11543                                 defined(OPENSSL_EXTRA_X509_SMALL)) && \
11544                                 !defined(WOLFCRYPT_ONLY)
11545                             wolfSSL_X509_NAME_free(dName);
11546                         #endif /* OPENSSL_EXTRA */
11547                             return MEMORY_E;
11548                         }
11549                         emailName->len = strLen;
11550                         XMEMCPY(emailName->name, &input[srcIdx], strLen);
11551                         emailName->name[strLen] = '\0';
11552 
11553                         emailName->next = cert->altEmailNames;
11554                         cert->altEmailNames = emailName;
11555                     }
11556                 #endif /* IGNORE_NAME_CONSTRAINTS */
11557             }
11558 
11559             if (pilot) {
11560                 switch (id) {
11561                     case ASN_USER_ID:
11562                         copy = WOLFSSL_USER_ID;
11563                         copyLen = sizeof(WOLFSSL_USER_ID) - 1;
11564                     #if (defined(OPENSSL_EXTRA) || \
11565                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11566                         && !defined(WOLFCRYPT_ONLY)
11567                         nid = NID_userId;
11568                     #endif /* OPENSSL_EXTRA */
11569                         break;
11570 
11571                     case ASN_DOMAIN_COMPONENT:
11572                         copy = WOLFSSL_DOMAIN_COMPONENT;
11573                         copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
11574                     #if (defined(OPENSSL_EXTRA) || \
11575                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11576                         && !defined(WOLFCRYPT_ONLY)
11577                         nid = NID_domainComponent;
11578                     #endif /* OPENSSL_EXTRA */
11579                         break;
11580                     case ASN_FAVOURITE_DRINK:
11581                         copy = WOLFSSL_FAVOURITE_DRINK;
11582                         copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
11583                     #if (defined(OPENSSL_EXTRA) || \
11584                         defined(OPENSSL_EXTRA_X509_SMALL)) \
11585                         && !defined(WOLFCRYPT_ONLY)
11586                         nid = NID_favouriteDrink;
11587                     #endif /* OPENSSL_EXTRA */
11588                         break;
11589 
11590                     default:
11591                         WOLFSSL_MSG("Unknown pilot attribute type");
11592                     #if (defined(OPENSSL_EXTRA) || \
11593                                 defined(OPENSSL_EXTRA_X509_SMALL)) && \
11594                                 !defined(WOLFCRYPT_ONLY)
11595                         wolfSSL_X509_NAME_free(dName);
11596                     #endif /* OPENSSL_EXTRA */
11597                         return ASN_PARSE_E;
11598                 }
11599             }
11600         }
11601         if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx))
11602         {
11603             WOLFSSL_MSG("ASN Name too big, skipping");
11604             tooBig = TRUE;
11605         }
11606         if ((copy != NULL) && !tooBig) {
11607             XMEMCPY(&full[idx], copy, copyLen);
11608             idx += copyLen;
11609             XMEMCPY(&full[idx], &input[srcIdx], strLen);
11610             idx += strLen;
11611         }
11612         #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11613             !defined(WOLFCRYPT_ONLY)
11614         switch (b) {
11615             case CTC_UTF8:
11616                 enc = MBSTRING_UTF8;
11617                 break;
11618             case CTC_PRINTABLE:
11619                 enc = V_ASN1_PRINTABLESTRING;
11620                 break;
11621             default:
11622                 WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
11623                 enc = MBSTRING_UTF8;
11624         }
11625 
11626         if (nid != NID_undef) {
11627             if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
11628                             &input[srcIdx], strLen, -1, -1) !=
11629                             WOLFSSL_SUCCESS) {
11630                 wolfSSL_X509_NAME_free(dName);
11631                 return ASN_PARSE_E;
11632             }
11633         }
11634         #endif /* OPENSSL_EXTRA */
11635         srcIdx += strLen;
11636     }
11637     full[idx++] = 0;
11638 
11639 #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11640             !defined(WOLFCRYPT_ONLY)
11641     if (nameType == ISSUER) {
11642 #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) && \
11643     (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
11644         dName->rawLen = min(cert->issuerRawLen, ASN_NAME_MAX);
11645         XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
11646 #endif
11647         cert->issuerName = dName;
11648     }
11649     else {
11650 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
11651         dName->rawLen = min(cert->subjectRawLen, ASN_NAME_MAX);
11652         XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
11653 #endif
11654         cert->subjectName = dName;
11655     }
11656 #endif
11657 
11658     *inOutIdx = srcIdx;
11659 
11660     return 0;
11661 #else
11662     DECL_ASNGETDATA(dataASN, rdnASN_Length);
11663     int    ret = 0;
11664     word32 idx = 0;
11665     int    len;
11666     word32 srcIdx = *inOutIdx;
11667 #ifdef WOLFSSL_X509_NAME_AVAILABLE
11668     WOLFSSL_X509_NAME* dName = NULL;
11669 #endif /* WOLFSSL_X509_NAME_AVAILABLE */
11670 
11671     WOLFSSL_MSG("Getting Cert Name");
11672 
11673     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
11674      * calculated over the entire DER encoding of the Name field, including
11675      * the tag and length. */
11676     if (CalcHashId(input + srcIdx, maxIdx - srcIdx, hash) != 0) {
11677         ret = ASN_PARSE_E;
11678     }
11679 
11680     CALLOC_ASNGETDATA(dataASN, rdnASN_Length, ret, cert->heap);
11681 
11682 #ifdef WOLFSSL_X509_NAME_AVAILABLE
11683     if (ret == 0) {
11684         /* Create an X509_NAME to hold data for OpenSSL compatability APIs. */
11685         dName = wolfSSL_X509_NAME_new();
11686         if (dName == NULL) {
11687             ret = MEMORY_E;
11688         }
11689     }
11690 #endif /* WOLFSSL_X509_NAME_AVAILABLE */
11691 
11692     if (ret == 0) {
11693         /* Expecting a SEQUENCE using up all data. */
11694         ret = GetASN_Sequence(input, &srcIdx, &len, maxIdx, 1);
11695     }
11696     if (ret == 0) {
11697     #if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
11698         /* Store pointer and length to raw issuer. */
11699         if (nameType == ISSUER) {
11700             cert->issuerRaw = &input[srcIdx];
11701             cert->issuerRawLen = len;
11702         }
11703     #endif
11704     #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
11705         /* Store pointer and length to raw subject. */
11706         if (nameType == SUBJECT) {
11707             cert->subjectRaw = &input[srcIdx];
11708             cert->subjectRawLen = len;
11709         }
11710     #endif
11711 
11712         /* Process all RDNs in name. */
11713         while ((ret == 0) && (srcIdx < maxIdx)) {
11714             int nid = 0;
11715 
11716             /* Initialize for data and setup RDN choice. */
11717             GetASN_Choice(&dataASN[RDNASN_IDX_ATTR_VAL], rdnChoice);
11718             /* Ignore type OID as too many to store in table. */
11719             GetASN_OID(&dataASN[RDNASN_IDX_ATTR_TYPE], oidIgnoreType);
11720             /* Parse RDN. */
11721             ret = GetASN_Items(rdnASN, dataASN, rdnASN_Length, 1, input,
11722                                &srcIdx, maxIdx);
11723             if (ret == 0) {
11724                 /* Put RDN data into certificate. */
11725                 ret = GetRDN(cert, full, &idx, &nid, nameType == SUBJECT,
11726                              dataASN);
11727             }
11728         #ifdef WOLFSSL_X509_NAME_AVAILABLE
11729             /* TODO: push this back up to ssl.c
11730              * (do parsing for WOLFSSL_X509_NAME on demand) */
11731             if (ret == 0) {
11732                 int enc;
11733                 byte*  str;
11734                 word32 strLen;
11735                 byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
11736 
11737                 /* Get string reference. */
11738                 GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
11739 
11740                 /* Convert BER tag to a OpenSSL type. */
11741                 switch (tag) {
11742                     case CTC_UTF8:
11743                         enc = MBSTRING_UTF8;
11744                         break;
11745                     case CTC_PRINTABLE:
11746                         enc = V_ASN1_PRINTABLESTRING;
11747                         break;
11748                     default:
11749                         WOLFSSL_MSG("Unknown encoding type, default UTF8");
11750                         enc = MBSTRING_UTF8;
11751                 }
11752                 if (nid != 0) {
11753                     /* Add an entry to the X509_NAME. */
11754                     if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc, str,
11755                             strLen, -1, -1) != WOLFSSL_SUCCESS) {
11756                         ret = ASN_PARSE_E;
11757                     }
11758                 }
11759             }
11760         #endif
11761         }
11762     }
11763     if (ret == 0) {
11764         /* Terminate string. */
11765         full[idx] = 0;
11766         /* Return index into encoding after name. */
11767         *inOutIdx = srcIdx;
11768 
11769 #ifdef WOLFSSL_X509_NAME_AVAILABLE
11770         /* Store X509_NAME in certificate. */
11771         if (nameType == ISSUER) {
11772         #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
11773              defined(HAVE_LIGHTY)) && \
11774             (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
11775             dName->rawLen = min(cert->issuerRawLen, ASN_NAME_MAX);
11776             XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
11777         #endif
11778             cert->issuerName = dName;
11779         }
11780         else {
11781         #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
11782             dName->rawLen = min(cert->subjectRawLen, ASN_NAME_MAX);
11783             XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
11784         #endif
11785             cert->subjectName = dName;
11786         }
11787     }
11788     else {
11789         /* Dispose of unused X509_NAME. */
11790         wolfSSL_X509_NAME_free(dName);
11791 #endif
11792     }
11793 
11794     FREE_ASNGETDATA(dataASN, cert->heap);
11795     return ret;
11796 #endif /* WOLFSSL_ASN_TEMPLATE */
11797 }
11798 
11799 #ifdef WOLFSSL_ASN_TEMPLATE
11800 /* ASN.1 template for certificate name. */
11801 static const ASNItem certNameASN[] = {
11802 /* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
11803 /* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
11804 };
11805 enum {
11806     CERTNAMEASN_IDX_OID = 0,
11807     CERTNAMEASN_IDX_NAME,
11808 };
11809 
11810 /* Number of items in ASN.1 template for certificate name. */
11811 #define certNameASN_Length (sizeof(certNameASN) / sizeof(ASNItem))
11812 #endif
11813 
11814 /* Get a certificate name into the certificate object.
11815  *
11816  * Either the issuer or subject name.
11817  *
11818  * @param [in, out] cert      Decoded certificate object.
11819  * @param [in]      nameType  Type of name being decoded: ISSUER or SUBJECT.
11820  * @param [in]      maxIdx    Index of next item after certificate name.
11821  * @return  0 on success.
11822  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11823  *          is invalid.
11824  * @return  BUFFER_E when data in buffer is too small.
11825  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11826  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11827  * @return  MEMORY_E when dynamic memory allocation fails.
11828  */
11829 int GetName(DecodedCert* cert, int nameType, int maxIdx)
11830 {
11831 #ifndef WOLFSSL_ASN_TEMPLATE
11832     char*  full;
11833     byte*  hash;
11834     int    length;
11835     word32 localIdx;
11836     byte   tag;
11837 
11838     WOLFSSL_MSG("Getting Cert Name");
11839 
11840     if (nameType == ISSUER) {
11841         full = cert->issuer;
11842         hash = cert->issuerHash;
11843     }
11844     else {
11845         full = cert->subject;
11846         hash = cert->subjectHash;
11847     }
11848 
11849     if (cert->srcIdx >= (word32)maxIdx) {
11850         return BUFFER_E;
11851     }
11852 
11853     localIdx = cert->srcIdx;
11854     if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
11855         return ASN_PARSE_E;
11856     }
11857 
11858     if (tag == ASN_OBJECT_ID) {
11859         WOLFSSL_MSG("Trying optional prefix...");
11860 
11861         if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0)
11862             return ASN_PARSE_E;
11863         WOLFSSL_MSG("Got optional prefix");
11864     }
11865 
11866     localIdx = cert->srcIdx;
11867     if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
11868         return ASN_PARSE_E;
11869     }
11870     localIdx = cert->srcIdx + 1;
11871     if (GetLength(cert->source, &localIdx, &length, maxIdx) < 0) {
11872         return ASN_PARSE_E;
11873     }
11874     length += localIdx - cert->srcIdx;
11875 
11876     return GetCertName(cert, full, hash, nameType, cert->source, &cert->srcIdx,
11877                        cert->srcIdx + length);
11878 #else
11879     ASNGetData dataASN[certNameASN_Length];
11880     word32 idx = cert->srcIdx;
11881     int    ret = 0;
11882     char*  full;
11883     byte*  hash;
11884 
11885     WOLFSSL_MSG("Getting Cert Name");
11886 
11887     XMEMSET(dataASN, 0, sizeof(dataASN));
11888     /* Initialize for data and don't check optional prefix OID. */
11889     GetASN_OID(&dataASN[CERTNAMEASN_IDX_OID], oidIgnoreType);
11890     ret = GetASN_Items(certNameASN, dataASN, certNameASN_Length, 0,
11891                        cert->source, &idx, maxIdx);
11892     if (ret == 0) {
11893         /* Store offset of SEQUENCE that is start of name. */
11894         cert->srcIdx = dataASN[CERTNAMEASN_IDX_NAME].offset;
11895 
11896         /* Get fields to fill in based on name type. */
11897         if (nameType == ISSUER) {
11898             full = cert->issuer;
11899             hash = cert->issuerHash;
11900         }
11901         else {
11902             full = cert->subject;
11903             hash = cert->subjectHash;
11904         }
11905 
11906         /* Parse certificate name. */
11907         ret = GetCertName(cert, full, hash, nameType, cert->source,
11908                           &cert->srcIdx, idx);
11909     }
11910 
11911     return ret;
11912 #endif
11913 }
11914 
11915 #ifndef NO_ASN_TIME
11916 
11917 /* two byte date/time, add to value */
11918 static WC_INLINE int GetTime(int* value, const byte* date, int* idx)
11919 {
11920     int i = *idx;
11921 
11922     if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
11923                                                              date[i+1] > 0x39) {
11924         return ASN_PARSE_E;
11925     }
11926 
11927     *value += btoi(date[i++]) * 10;
11928     *value += btoi(date[i++]);
11929 
11930     *idx = i;
11931 
11932     return 0;
11933 }
11934 
11935 #ifdef WOLFSSL_LINUXKM
11936 static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx)
11937 {
11938     int i = *idx;
11939 
11940     if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
11941                                                              date[i+1] > 0x39) {
11942         return ASN_PARSE_E;
11943     }
11944 
11945     *value += (long)btoi(date[i++]) * 10;
11946     *value += (long)btoi(date[i++]);
11947 
11948     *idx = i;
11949 
11950     return 0;
11951 }
11952 #endif
11953 
11954 int ExtractDate(const unsigned char* date, unsigned char format,
11955                                                   struct tm* certTime, int* idx)
11956 {
11957     XMEMSET(certTime, 0, sizeof(struct tm));
11958 
11959     if (format == ASN_UTC_TIME) {
11960         if (btoi(date[*idx]) >= 5)
11961             certTime->tm_year = 1900;
11962         else
11963             certTime->tm_year = 2000;
11964     }
11965     else  { /* format == GENERALIZED_TIME */
11966 #ifdef WOLFSSL_LINUXKM
11967         if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
11968 #else
11969         if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
11970 #endif
11971         certTime->tm_year *= 100;
11972     }
11973 
11974 #ifdef AVR
11975     /* Extract the time from the struct tm and adjust tm_year, tm_mon */
11976     /* AVR libc stores these as uint8_t instead of int */
11977     /* AVR time_t also offsets from midnight 1 Jan 2000 */
11978     int tm_year = certTime->tm_year - 2000;
11979     int tm_mon  = certTime->tm_mon - 1;
11980     int tm_mday = certTime->tm_mday;
11981     int tm_hour = certTime->tm_hour;
11982     int tm_min  = certTime->tm_min;
11983     int tm_sec  = certTime->tm_sec;
11984 
11985 #ifdef WOLFSSL_LINUXKM
11986     if (GetTime_Long(&tm_year, date, idx) != 0) return 0;
11987 #else
11988     if (GetTime(&tm_year, date, idx) != 0) return 0;
11989 #endif
11990     if (GetTime(&tm_mon , date, idx) != 0) return 0;
11991     if (GetTime(&tm_mday, date, idx) != 0) return 0;
11992     if (GetTime(&tm_hour, date, idx) != 0) return 0;
11993     if (GetTime(&tm_min , date, idx) != 0) return 0;
11994     if (GetTime(&tm_sec , date, idx) != 0) return 0;
11995 
11996     /* Re-populate certTime with computed values */
11997     certTime->tm_year = tm_year;
11998     certTime->tm_mon  = tm_mon;
11999     certTime->tm_mday = tm_mday;
12000     certTime->tm_hour = tm_hour;
12001     certTime->tm_min  = tm_min;
12002     certTime->tm_sec  = tm_sec;
12003 #else
12004     /* adjust tm_year, tm_mon */
12005 #ifdef WOLFSSL_LINUXKM
12006     if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
12007 #else
12008     if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
12009 #endif
12010     certTime->tm_year -= 1900;
12011     if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;
12012     certTime->tm_mon  -= 1;
12013     if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;
12014     if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;
12015     if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;
12016     if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;
12017 #endif
12018 
12019     return 1;
12020 }
12021 
12022 
12023 #if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
12024     defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12025 int GetTimeString(byte* date, int format, char* buf, int len)
12026 {
12027     struct tm t;
12028     int idx = 0;
12029 
12030     if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
12031         return 0;
12032     }
12033 
12034     if (date[idx] != 'Z') {
12035         WOLFSSL_MSG("UTCtime, not Zulu") ;
12036         return 0;
12037     }
12038 
12039     /* place month in buffer */
12040     buf[0] = '\0';
12041     switch(t.tm_mon) {
12042         case 0:  XSTRNCAT(buf, "Jan ", 5); break;
12043         case 1:  XSTRNCAT(buf, "Feb ", 5); break;
12044         case 2:  XSTRNCAT(buf, "Mar ", 5); break;
12045         case 3:  XSTRNCAT(buf, "Apr ", 5); break;
12046         case 4:  XSTRNCAT(buf, "May ", 5); break;
12047         case 5:  XSTRNCAT(buf, "Jun ", 5); break;
12048         case 6:  XSTRNCAT(buf, "Jul ", 5); break;
12049         case 7:  XSTRNCAT(buf, "Aug ", 5); break;
12050         case 8:  XSTRNCAT(buf, "Sep ", 5); break;
12051         case 9:  XSTRNCAT(buf, "Oct ", 5); break;
12052         case 10: XSTRNCAT(buf, "Nov ", 5); break;
12053         case 11: XSTRNCAT(buf, "Dec ", 5); break;
12054         default:
12055             return 0;
12056 
12057     }
12058     idx = 4; /* use idx now for char buffer */
12059 
12060     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
12061               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, (int)t.tm_year + 1900);
12062 
12063     return 1;
12064 }
12065 #endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
12066 
12067 
12068 #if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
12069 
12070 /* Set current time string, either UTC or GeneralizedTime.
12071  * (void*) tm should be a pointer to time_t, output is placed in buf.
12072  *
12073  * Return time string length placed in buf on success, negative on error */
12074 int GetAsnTimeString(void* currTime, byte* buf, word32 len)
12075 {
12076     struct tm* ts      = NULL;
12077     struct tm* tmpTime = NULL;
12078     byte* data_ptr  = buf;
12079     word32 data_len = 0;
12080     int year, mon, day, hour, mini, sec;
12081 #if defined(NEED_TMP_TIME)
12082     struct tm tmpTimeStorage;
12083     tmpTime = &tmpTimeStorage;
12084 #else
12085     (void)tmpTime;
12086 #endif
12087 
12088     WOLFSSL_ENTER("SetAsnTimeString");
12089 
12090     if (buf == NULL || len == 0)
12091         return BAD_FUNC_ARG;
12092 
12093     ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
12094     if (ts == NULL){
12095         WOLFSSL_MSG("failed to get time data.");
12096         return ASN_TIME_E;
12097     }
12098 
12099     /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
12100      * the null terminator. ASN encoded values leave off the terminator. */
12101 
12102     if (ts->tm_year >= 50 && ts->tm_year < 150) {
12103         /* UTC Time */
12104         char utc_str[ASN_UTC_TIME_SIZE];
12105         data_len = ASN_UTC_TIME_SIZE - 1 + 2;
12106 
12107         if (len < data_len)
12108             return BUFFER_E;
12109 
12110         if (ts->tm_year >= 50 && ts->tm_year < 100) {
12111             year = ts->tm_year;
12112         } else if (ts->tm_year >= 100 && ts->tm_year < 150) {
12113             year = ts->tm_year - 100;
12114         }
12115         else {
12116             WOLFSSL_MSG("unsupported year range");
12117             return BAD_FUNC_ARG;
12118         }
12119         mon  = ts->tm_mon + 1;
12120         day  = ts->tm_mday;
12121         hour = ts->tm_hour;
12122         mini = ts->tm_min;
12123         sec  = ts->tm_sec;
12124         XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
12125                   "%02d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
12126         *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
12127         /* -1 below excludes null terminator */
12128         *data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;
12129         XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);
12130 
12131     } else {
12132         /* GeneralizedTime */
12133         char gt_str[ASN_GENERALIZED_TIME_SIZE];
12134         data_len = ASN_GENERALIZED_TIME_SIZE - 1 + 2;
12135 
12136         if (len < data_len)
12137             return BUFFER_E;
12138 
12139         year = ts->tm_year + 1900;
12140         mon  = ts->tm_mon + 1;
12141         day  = ts->tm_mday;
12142         hour = ts->tm_hour;
12143         mini = ts->tm_min;
12144         sec  = ts->tm_sec;
12145         XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
12146                   "%4d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
12147         *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
12148         /* -1 below excludes null terminator */
12149         *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;
12150         XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);
12151     }
12152 
12153     return data_len;
12154 }
12155 
12156 #endif /* !NO_ASN_TIME && HAVE_PKCS7 */
12157 
12158 
12159 #if defined(USE_WOLF_VALIDDATE)
12160 
12161 /* to the second */
12162 int DateGreaterThan(const struct tm* a, const struct tm* b)
12163 {
12164     if (a->tm_year > b->tm_year)
12165         return 1;
12166 
12167     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
12168         return 1;
12169 
12170     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
12171            a->tm_mday > b->tm_mday)
12172         return 1;
12173 
12174     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
12175         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
12176         return 1;
12177 
12178     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
12179         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
12180         a->tm_min > b->tm_min)
12181         return 1;
12182 
12183     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
12184         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
12185         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
12186         return 1;
12187 
12188     return 0; /* false */
12189 }
12190 
12191 
12192 static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
12193 {
12194     return DateGreaterThan(b,a);
12195 }
12196 
12197 /* like atoi but only use first byte */
12198 /* Make sure before and after dates are valid */
12199 int wc_ValidateDate(const byte* date, byte format, int dateType)
12200 {
12201     time_t ltime;
12202     struct tm  certTime;
12203     struct tm* localTime;
12204     struct tm* tmpTime;
12205     int    i = 0;
12206     int    timeDiff = 0 ;
12207     int    diffHH = 0 ; int diffMM = 0 ;
12208     int    diffSign = 0 ;
12209 
12210 #if defined(NEED_TMP_TIME)
12211     struct tm tmpTimeStorage;
12212     tmpTime = &tmpTimeStorage;
12213 #else
12214     tmpTime = NULL;
12215 #endif
12216     (void)tmpTime;
12217 
12218     ltime = XTIME(0);
12219 
12220 #ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
12221     if (dateType == BEFORE) {
12222         WOLFSSL_MSG("Skewing local time for before date check");
12223         ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
12224     }
12225 #endif
12226 
12227 #ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
12228     if (dateType == AFTER) {
12229         WOLFSSL_MSG("Skewing local time for after date check");
12230         ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
12231     }
12232 #endif
12233 
12234     if (!ExtractDate(date, format, &certTime, &i)) {
12235         WOLFSSL_MSG("Error extracting the date");
12236         return 0;
12237     }
12238 
12239     if ((date[i] == '+') || (date[i] == '-')) {
12240         WOLFSSL_MSG("Using time differential, not Zulu") ;
12241         diffSign = date[i++] == '+' ? 1 : -1 ;
12242         if (GetTime(&diffHH, date, &i) != 0)
12243             return 0;
12244         if (GetTime(&diffMM, date, &i) != 0)
12245             return 0;
12246         timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
12247     } else if (date[i] != 'Z') {
12248         WOLFSSL_MSG("UTCtime, neither Zulu or time differential") ;
12249         return 0;
12250     }
12251 
12252     ltime -= (time_t)timeDiff ;
12253     localTime = XGMTIME(&ltime, tmpTime);
12254 
12255     if (localTime == NULL) {
12256         WOLFSSL_MSG("XGMTIME failed");
12257         return 0;
12258     }
12259 
12260     if (dateType == BEFORE) {
12261         if (DateLessThan(localTime, &certTime)) {
12262             WOLFSSL_MSG("Date BEFORE check failed");
12263             return 0;
12264         }
12265     }
12266     else {  /* dateType == AFTER */
12267         if (DateGreaterThan(localTime, &certTime)) {
12268             WOLFSSL_MSG("Date AFTER check failed");
12269             return 0;
12270         }
12271     }
12272 
12273     return 1;
12274 }
12275 #endif /* USE_WOLF_VALIDDATE */
12276 
12277 int wc_GetTime(void* timePtr, word32 timeSize)
12278 {
12279     time_t* ltime = (time_t*)timePtr;
12280 
12281     if (timePtr == NULL) {
12282         return BAD_FUNC_ARG;
12283     }
12284 
12285     if ((word32)sizeof(time_t) > timeSize) {
12286         return BUFFER_E;
12287     }
12288 
12289     *ltime = XTIME(0);
12290 
12291     return 0;
12292 }
12293 
12294 #endif /* !NO_ASN_TIME */
12295 
12296 
12297 #ifdef WOLFSSL_ASN_TEMPLATE
12298 /* TODO: use a CHOICE instead of two items? */
12299 /* ASN.1 template for a date - either UTC or Generalized Time. */
12300 static const ASNItem dateASN[] = {
12301 /* UTC */ { 0, ASN_UTC_TIME, 0, 0, 2 },
12302 /* GT  */ { 0, ASN_GENERALIZED_TIME, 0, 0, 2 },
12303 };
12304 enum {
12305     DATEASN_IDX_UTC = 0,
12306     DATEASN_IDX_GT,
12307 };
12308 
12309 /* Number of items in ASN.1 template for a date. */
12310 #define dateASN_Length (sizeof(dateASN) / sizeof(ASNItem))
12311 #endif /* WOLFSSL_ASN_TEMPLATE */
12312 
12313 /* Get date buffer, format and length. Returns 0=success or error */
12314 /* Decode a DateInfo - choice of UTC TIME or GENERALIZED TIME.
12315  *
12316  * @param [in]      source   Buffer containing encoded date.
12317  * @param [in, out] idx      On in, the index of the date.
12318  *                           On out, index after date.
12319  * @param [out]     pDate    Pointer into buffer of data bytes.
12320  * @param [out]     pFormat  Format of date - BER/DER tag.
12321  * @param [out]     pLength  Length of date bytes.
12322  * @param [in]      maxIdx   Index of next item after date.
12323  * @return  0 on success.
12324  * @return  BAD_FUNC_ARG when source or idx is NULL.
12325  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12326  *          is invalid.
12327  * @return  BUFFER_E when data in buffer is too small.
12328  */
12329 static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
12330                         byte* pFormat, int* pLength, word32 maxIdx)
12331 {
12332 #ifndef WOLFSSL_ASN_TEMPLATE
12333     int length;
12334     byte format;
12335 
12336     if (source == NULL || idx == NULL)
12337         return BAD_FUNC_ARG;
12338 
12339     /* get ASN format header */
12340     if (*idx+1 > maxIdx)
12341         return BUFFER_E;
12342     format = source[*idx];
12343     *idx += 1;
12344     if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
12345         return ASN_TIME_E;
12346 
12347     /* get length */
12348     if (GetLength(source, idx, &length, maxIdx) < 0)
12349         return ASN_PARSE_E;
12350     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
12351         return ASN_DATE_SZ_E;
12352 
12353     /* return format, date and length */
12354     if (pFormat)
12355         *pFormat = format;
12356     if (pDate)
12357         *pDate = &source[*idx];
12358     if (pLength)
12359         *pLength = length;
12360 
12361     *idx += length;
12362 
12363     return 0;
12364 #else
12365     ASNGetData dataASN[dateASN_Length];
12366     int i;
12367     int ret = 0;
12368 
12369     if ((source == NULL) || (idx == NULL)) {
12370         ret = BAD_FUNC_ARG;
12371     }
12372     if (ret == 0) {
12373         /* Initialize data. */
12374         XMEMSET(dataASN, 0, sizeof(dataASN));
12375         /* Parse date. */
12376         ret = GetASN_Items(dateASN, dataASN, dateASN_Length, 0, source, idx,
12377                            maxIdx);
12378     }
12379     if (ret == 0) {
12380         /* Determine which tag was seen. */
12381         i = (dataASN[DATEASN_IDX_UTC].tag != 0) ? DATEASN_IDX_UTC
12382                                                 : DATEASN_IDX_GT;
12383         /* Return data from seen item. */
12384         if (pFormat != NULL) {
12385             *pFormat = dataASN[i].tag;
12386         }
12387         if (pDate != NULL) {
12388             *pDate = dataASN[i].data.ref.data;
12389         }
12390         if (pLength != NULL) {
12391             *pLength = dataASN[i].data.ref.length;
12392         }
12393     }
12394 
12395     return ret;
12396 #endif
12397 }
12398 
12399 #ifndef WOLFSSL_ASN_TEMPLATE
12400 static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
12401 {
12402     int    ret, length;
12403     const byte *datePtr = NULL;
12404     byte   date[MAX_DATE_SIZE];
12405     byte   format;
12406     word32 startIdx = 0;
12407 
12408     if (dateType == BEFORE)
12409         cert->beforeDate = &cert->source[cert->srcIdx];
12410     else
12411         cert->afterDate = &cert->source[cert->srcIdx];
12412     startIdx = cert->srcIdx;
12413 
12414     ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
12415                       &length, maxIdx);
12416     if (ret < 0)
12417         return ret;
12418 
12419     XMEMSET(date, 0, MAX_DATE_SIZE);
12420     XMEMCPY(date, datePtr, length);
12421 
12422     if (dateType == BEFORE)
12423         cert->beforeDateLen = cert->srcIdx - startIdx;
12424     else
12425         cert->afterDateLen  = cert->srcIdx - startIdx;
12426 
12427 #ifndef NO_ASN_TIME
12428     if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
12429             !XVALIDATE_DATE(date, format, dateType)) {
12430         if (dateType == BEFORE)
12431             return ASN_BEFORE_DATE_E;
12432         else
12433             return ASN_AFTER_DATE_E;
12434     }
12435 #else
12436     (void)verify;
12437 #endif
12438 
12439     return 0;
12440 }
12441 
12442 static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
12443 {
12444     int length;
12445     int badDate = 0;
12446 
12447     if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
12448         return ASN_PARSE_E;
12449 
12450     maxIdx = cert->srcIdx + length;
12451 
12452     if (GetDate(cert, BEFORE, verify, maxIdx) < 0)
12453         badDate = ASN_BEFORE_DATE_E; /* continue parsing */
12454 
12455     if (GetDate(cert, AFTER, verify, maxIdx) < 0)
12456         return ASN_AFTER_DATE_E;
12457 
12458     if (badDate != 0)
12459         return badDate;
12460 
12461     return 0;
12462 }
12463 #endif /* !WOLFSSL_ASN_TEMPLATE */
12464 
12465 
12466 int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
12467     byte* format, int* length)
12468 {
12469     int ret;
12470     word32 idx = 0;
12471 
12472     ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
12473     if (ret < 0)
12474         return ret;
12475 
12476     return 0;
12477 }
12478 
12479 #ifndef NO_ASN_TIME
12480 int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
12481     struct tm* timearg)
12482 {
12483     int idx = 0;
12484     (void)length;
12485     if (!ExtractDate(date, format, timearg, &idx))
12486         return ASN_TIME_E;
12487     return 0;
12488 }
12489 
12490 #if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
12491 int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
12492 {
12493     int ret = 0;
12494     const byte* date;
12495     byte format;
12496     int length;
12497 
12498     if (cert == NULL)
12499         return BAD_FUNC_ARG;
12500 
12501     if (before && cert->beforeDateSz > 0) {
12502         ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
12503                              &format, &length);
12504         if (ret == 0)
12505             ret = wc_GetDateAsCalendarTime(date, length, format, before);
12506     }
12507     if (after && cert->afterDateSz > 0) {
12508         ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
12509                              &format, &length);
12510         if (ret == 0)
12511             ret = wc_GetDateAsCalendarTime(date, length, format, after);
12512     }
12513 
12514     return ret;
12515 }
12516 #endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
12517 #endif /* !NO_ASN_TIME */
12518 
12519 #ifdef WOLFSSL_ASN_TEMPLATE
12520 /* TODO: move code around to not require this. */
12521 static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
12522                               int* badDateRet, int stopAtPubKey,
12523                               int stopAfterPubKey);
12524 #endif
12525 
12526 /* Parse the certificate up to the X.509 public key.
12527  *
12528  * If cert data is invalid then badDate get set to error value.
12529  *
12530  * @param [in, out] cert     Decoded certificate object.
12531  * @param [in]      verify   Whether to verify dates.
12532  * @param [out]     badDate  Error code when verify dates.
12533  * @return  0 on success.
12534  * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
12535  * @return  ASN_DATE_SZ_E when time data is not supported.
12536  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12537  *          is invalid.
12538  * @return  BUFFER_E when data in buffer is too small.
12539  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
12540  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
12541  */
12542 int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
12543 {
12544 #ifndef WOLFSSL_ASN_TEMPLATE
12545     int ret;
12546 
12547     if (cert == NULL || badDate == NULL)
12548         return BAD_FUNC_ARG;
12549 
12550     *badDate = 0;
12551     if ( (ret = GetCertHeader(cert)) < 0)
12552         return ret;
12553 
12554     WOLFSSL_MSG("Got Cert Header");
12555 
12556 #ifdef WOLFSSL_CERT_REQ
12557     if (!cert->isCSR) {
12558 #endif
12559         /* Using the sigIndex as the upper bound because that's where the
12560          * actual certificate data ends. */
12561         if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
12562                               oidSigType, cert->sigIndex)) < 0)
12563             return ret;
12564 
12565         WOLFSSL_MSG("Got Algo ID");
12566 
12567         if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)
12568             return ret;
12569 
12570         if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)
12571             *badDate = ret;
12572 #ifdef WOLFSSL_CERT_REQ
12573     }
12574 #endif
12575 
12576     if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0)
12577         return ret;
12578 
12579     WOLFSSL_MSG("Got Subject Name");
12580     return ret;
12581 #else
12582     /* Use common decode routine and stop at public key. */
12583     int ret;
12584 
12585     *badDate = 0;
12586 
12587     ret = DecodeCertInternal(cert, verify, NULL, badDate, 1, 0);
12588     if (ret >= 0) {
12589         /* Store current index: public key. */
12590         cert->srcIdx = ret;
12591     }
12592     return ret;
12593 #endif /* WOLFSSL_ASN_TEMPLATE */
12594 }
12595 
12596 /* Parse the certificate up to and including X.509 public key.
12597  *
12598  * @param [in, out] cert     Decoded certificate object.
12599  * @param [in]      verify   Whether to verify dates.
12600  * @return  0 on success.
12601  * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
12602  * @return  ASN_DATE_SZ_E when time data is not supported.
12603  * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
12604  * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
12605  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12606  *          is invalid.
12607  * @return  BUFFER_E when data in buffer is too small.
12608  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
12609  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
12610  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
12611  */
12612 int DecodeToKey(DecodedCert* cert, int verify)
12613 {
12614 #ifndef WOLFSSL_ASN_TEMPLATE
12615     int badDate = 0;
12616     int ret;
12617 
12618     if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
12619         return ret;
12620 
12621     /* Determine if self signed */
12622     cert->selfSigned = XMEMCMP(cert->issuerHash,
12623                                cert->subjectHash,
12624                                KEYID_SIZE) == 0 ? 1 : 0;
12625 
12626     ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
12627     if (ret != 0)
12628         return ret;
12629 
12630     WOLFSSL_MSG("Got Key");
12631 
12632     if (badDate != 0)
12633         return badDate;
12634 
12635     return ret;
12636 #else
12637     int ret;
12638     int badDate = 0;
12639 
12640     /* Call internal version and stop after public key. */
12641     ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1);
12642     /* Always return date errors. */
12643     if (ret == 0) {
12644         ret = badDate;
12645     }
12646     return ret;
12647 #endif /* WOLFSSL_ASN_TEMPLATE */
12648 }
12649 
12650 #if !defined(NO_CERTS) && !defined(WOLFSSL_ASN_TEMPLATE)
12651 static int GetSignature(DecodedCert* cert)
12652 {
12653     int length;
12654     int ret;
12655 
12656     ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
12657                          NULL);
12658     if (ret != 0)
12659         return ret;
12660 
12661     cert->sigLength = length;
12662     cert->signature = &cert->source[cert->srcIdx];
12663     cert->srcIdx += cert->sigLength;
12664 
12665     if (cert->srcIdx != cert->maxIdx)
12666         return ASN_PARSE_E;
12667 
12668     return 0;
12669 }
12670 #endif /* !NO_CERTS && !WOLFSSL_ASN_TEMPLATE */
12671 
12672 #ifndef WOLFSSL_ASN_TEMPLATE
12673 static word32 SetOctetString8Bit(word32 len, byte* output)
12674 {
12675     output[0] = ASN_OCTET_STRING;
12676     output[1] = (byte)len;
12677     return 2;
12678 }
12679 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
12680 {
12681     word32 idx = SetOctetString8Bit(digSz, output);
12682     XMEMCPY(&output[idx], digest, digSz);
12683 
12684     return idx + digSz;
12685 }
12686 #endif
12687 
12688 
12689 /* Encode a length for DER.
12690  *
12691  * @param [in]  length  Value to encode.
12692  * @param [out] output  Buffer to encode into.
12693  * @return  Number of bytes encoded.
12694  */
12695 word32 SetLength(word32 length, byte* output)
12696 {
12697     /* Start encoding at start of buffer. */
12698     word32 i = 0;
12699 
12700     if (length < ASN_LONG_LENGTH) {
12701         /* Only one byte needed to encode. */
12702         if (output) {
12703             /* Write out length value. */
12704             output[i] = (byte)length;
12705         }
12706         /* Skip over length. */
12707         i++;
12708     }
12709     else {
12710         /* Calculate the number of bytes required to encode value. */
12711         byte j = (byte)BytePrecision(length);
12712 
12713         if (output) {
12714             /* Encode count byte. */
12715             output[i] = j | ASN_LONG_LENGTH;
12716         }
12717         /* Skip over count byte. */
12718         i++;
12719 
12720         /* Encode value as a big-endian byte array. */
12721         for (; j > 0; --j) {
12722             if (output) {
12723                 /* Encode next most-significant byte. */
12724                 output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
12725             }
12726             /* Skip over byte. */
12727             i++;
12728         }
12729     }
12730 
12731     /* Return number of bytes in encoded length. */
12732     return i;
12733 }
12734 
12735 /* Encode a DER header - type/tag and length.
12736  *
12737  * @param [in]  tag     DER tag of ASN.1 item.
12738  * @param [in]  len     Length of data in ASN.1 item.
12739  * @param [out] output  Buffer to encode into.
12740  * @return  Number of bytes encoded.
12741  */
12742 static word32 SetHeader(byte tag, word32 len, byte* output)
12743 {
12744     if (output) {
12745         /* Encode tag first. */
12746         output[0] = tag;
12747     }
12748     /* Encode the length. */
12749     return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ;
12750 }
12751 
12752 /* Encode a SEQUENCE header in DER.
12753  *
12754  * @param [in]  len     Length of data in SEQUENCE.
12755  * @param [out] output  Buffer to encode into.
12756  * @return  Number of bytes encoded.
12757  */
12758 word32 SetSequence(word32 len, byte* output)
12759 {
12760     return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output);
12761 }
12762 
12763 /* Encode an OCTET STRING header in DER.
12764  *
12765  * @param [in]  len     Length of data in OCTET STRING.
12766  * @param [out] output  Buffer to encode into.
12767  * @return  Number of bytes encoded.
12768  */
12769 word32 SetOctetString(word32 len, byte* output)
12770 {
12771     return SetHeader(ASN_OCTET_STRING, len, output);
12772 }
12773 
12774 /* Encode a SET header in DER.
12775  *
12776  * @param [in]  len     Length of data in SET.
12777  * @param [out] output  Buffer to encode into.
12778  * @return  Number of bytes encoded.
12779  */
12780 word32 SetSet(word32 len, byte* output)
12781 {
12782     return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output);
12783 }
12784 
12785 /* Encode an implicit context specific header in DER.
12786  *
12787  * Implicit means that it is constructed only if the included ASN.1 item is.
12788  *
12789  * @param [in]  tag     Tag for the implicit ASN.1 item.
12790  * @param [in]  number  Context specific number.
12791  * @param [in]  len     Length of data in SET.
12792  * @param [out] output  Buffer to encode into.
12793  * @return  Number of bytes encoded.
12794  */
12795 word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
12796 {
12797     tag = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
12798                     | ASN_CONTEXT_SPECIFIC | number;
12799     return SetHeader(tag, len, output);
12800 }
12801 
12802 /* Encode an explicit context specific header in DER.
12803  *
12804  * Explicit means that there will be an ASN.1 item underneath.
12805  *
12806  * @param [in]  number  Context specific number.
12807  * @param [in]  len     Length of data in SET.
12808  * @param [out] output  Buffer to encode into.
12809  * @return  Number of bytes encoded.
12810  */
12811 word32 SetExplicit(byte number, word32 len, byte* output)
12812 {
12813     return SetHeader(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number, len,
12814                      output);
12815 }
12816 
12817 
12818 #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
12819 
12820 #ifndef WOLFSSL_ASN_TEMPLATE
12821 static int SetCurve(ecc_key* key, byte* output)
12822 {
12823 #ifdef HAVE_OID_ENCODING
12824     int ret;
12825 #endif
12826     int idx = 0;
12827     word32 oidSz = 0;
12828 
12829     /* validate key */
12830     if (key == NULL || key->dp == NULL) {
12831         return BAD_FUNC_ARG;
12832     }
12833 
12834 #ifdef HAVE_OID_ENCODING
12835     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
12836     if (ret != 0) {
12837         return ret;
12838     }
12839 #else
12840     oidSz = key->dp->oidSz;
12841 #endif
12842 
12843     idx += SetObjectId(oidSz, output);
12844 
12845 #ifdef HAVE_OID_ENCODING
12846     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
12847     if (ret != 0) {
12848         return ret;
12849     }
12850 #else
12851     XMEMCPY(output+idx, key->dp->oid, oidSz);
12852 #endif
12853     idx += oidSz;
12854 
12855     return idx;
12856 }
12857 #endif /* !WOLFSSL_ASN_TEMPLATE */
12858 
12859 #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
12860 
12861 
12862 #ifdef HAVE_ECC
12863 /* Determines whether the signature algorithm is using ECDSA.
12864  *
12865  * @param [in] algoOID  Signature algorithm identifier.
12866  * @return  1 when algorithm is using ECDSA.
12867  * @return  0 otherwise.
12868  */
12869 static WC_INLINE int IsSigAlgoECDSA(int algoOID)
12870 {
12871     /* ECDSA sigAlgo must not have ASN1 NULL parameters */
12872     if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
12873         algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
12874         return 1;
12875     }
12876 
12877     return 0;
12878 }
12879 #endif
12880 
12881 /* Determines if OID is for an EC signing algorithm including ECDSA and EdDSA.
12882  *
12883  * @param [in] algoOID  Algorithm OID.
12884  * @return  1 when is EC signing algorithm.
12885  * @return  0 otherwise.
12886  */
12887 static WC_INLINE int IsSigAlgoECC(int algoOID)
12888 {
12889     (void)algoOID;
12890 
12891     return (0
12892         #ifdef HAVE_ECC
12893               || IsSigAlgoECDSA(algoOID)
12894         #endif
12895         #ifdef HAVE_ED25519
12896               || (algoOID == ED25519k)
12897         #endif
12898         #ifdef HAVE_CURVE25519
12899               || (algoOID == X25519k)
12900         #endif
12901         #ifdef HAVE_ED448
12902               || (algoOID == ED448k)
12903         #endif
12904         #ifdef HAVE_CURVE448
12905               || (algoOID == X448k)
12906         #endif
12907         #ifdef HAVE_PQC
12908               || (algoOID == FALCON_LEVEL1k)
12909               || (algoOID == FALCON_LEVEL5k)
12910         #endif
12911     );
12912 }
12913 
12914 /* Encode an algorithm identifier.
12915  *
12916  * [algoOID, type] is unique.
12917  *
12918  * @param [in]  algoOID   Algorithm identifier.
12919  * @param [out] output    Buffer to hold encoding.
12920  * @param [in]  type      Type of OID being encoded.
12921  * @param [in]  curveSz   Add extra space for curve data.
12922  * @return  Encoded data size on success.
12923  * @return  0 when dynamic memory allocation fails.
12924  */
12925 word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
12926 {
12927 #ifndef WOLFSSL_ASN_TEMPLATE
12928     word32 tagSz, idSz, seqSz, algoSz = 0;
12929     const  byte* algoName = 0;
12930     byte   ID_Length[1 + MAX_LENGTH_SZ];
12931     byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
12932     int    length = 0;
12933 
12934     tagSz = (type == oidHashType ||
12935              (type == oidSigType && !IsSigAlgoECC(algoOID)) ||
12936              (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
12937 
12938     algoName = OidFromId(algoOID, type, &algoSz);
12939     if (algoName == NULL) {
12940         WOLFSSL_MSG("Unknown Algorithm");
12941         return 0;
12942     }
12943 
12944     idSz  = SetObjectId(algoSz, ID_Length);
12945     seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
12946 
12947     /* Copy only algo to output for DSA keys */
12948     if (algoOID == DSAk && output) {
12949         XMEMCPY(output, ID_Length, idSz);
12950         XMEMCPY(output + idSz, algoName, algoSz);
12951         if (tagSz == 2)
12952             SetASNNull(&output[seqSz + idSz + algoSz]);
12953     }
12954     else if (output) {
12955         XMEMCPY(output, seqArray, seqSz);
12956         XMEMCPY(output + seqSz, ID_Length, idSz);
12957         XMEMCPY(output + seqSz + idSz, algoName, algoSz);
12958         if (tagSz == 2)
12959             SetASNNull(&output[seqSz + idSz + algoSz]);
12960     }
12961 
12962     if (algoOID == DSAk)
12963         length = idSz + algoSz + tagSz;
12964     else
12965         length = seqSz + idSz + algoSz + tagSz;
12966 
12967     return length;
12968 #else
12969     DECL_ASNSETDATA(dataASN, algoIdASN_Length);
12970     int sz;
12971     int ret = 0;
12972     int o = 0;
12973 
12974     CALLOC_ASNSETDATA(dataASN, algoIdASN_Length, ret, NULL);
12975 
12976     /* Set the OID and OID type to encode. */
12977     SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], algoOID, type);
12978     /* Hashes, signatures not ECC and keys not RSA put put NULL tag. */
12979     if (!(type == oidHashType ||
12980              (type == oidSigType && !IsSigAlgoECC(algoOID)) ||
12981              (type == oidKeyType && algoOID == RSAk))) {
12982         /* Don't put out NULL DER item. */
12983         dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
12984     }
12985     if (algoOID == DSAk) {
12986         /* Don't include SEQUENCE for DSA keys. */
12987         o = 1;
12988     }
12989     else if (curveSz > 0) {
12990         /* Don't put out NULL DER item. */
12991         dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
12992         /* Include space for extra data of length curveSz.
12993          * Subtract 1 for sequence and 1 for length encoding. */
12994         SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL, curveSz - 2);
12995     }
12996 
12997     /* Calculate size of encoding. */
12998     ret = SizeASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, &sz);
12999     if (ret == 0 && output != NULL) {
13000         /* Encode into buffer. */
13001         SetASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, output);
13002         if (curveSz > 0) {
13003             /* Return size excluding curve data. */
13004             sz = dataASN[o].offset - dataASN[ALGOIDASN_IDX_NULL].offset;
13005         }
13006     }
13007 
13008     if (ret == 0) {
13009         /* Return encoded size. */
13010         ret = sz;
13011     }
13012     else {
13013         /* Unsigned return type so 0 indicates error. */
13014         ret = 0;
13015     }
13016 
13017     FREE_ASNSETDATA(dataASN, NULL);
13018     return ret;
13019 #endif /* WOLFSSL_ASN_TEMPLATE */
13020 }
13021 
13022 #ifdef WOLFSSL_ASN_TEMPLATE
13023 /* Always encode PKCS#1 v1.5 RSA signature and compare to encoded data. */
13024 /* ASN.1 template for DigestInfo for a PKCS#1 v1.5 RSA signature.
13025  * PKCS#1 v2.2: RFC 8017, A.2.4 - DigestInfo
13026  */
13027 static const ASNItem digestInfoASN[] = {
13028 /* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
13029                                          /* digestAlgorithm */
13030 /* DIGALGO_SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
13031 /* DIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
13032 /* DIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 0 },
13033                                          /* digest */
13034 /* DIGEST       */     { 1, ASN_OCTET_STRING, 0, 0, 0 }
13035 };
13036 enum {
13037     DIGESTINFOASN_IDX_SEQ = 0,
13038     DIGESTINFOASN_IDX_DIGALGO_SEQ,
13039     DIGESTINFOASN_IDX_DIGALGO_OID,
13040     DIGESTINFOASN_IDX_DIGALGO_NULL,
13041     DIGESTINFOASN_IDX_DIGEST,
13042 };
13043 
13044 /* Number of items in ASN.1 template for DigestInfo for RSA. */
13045 #define digestInfoASN_Length (sizeof(digestInfoASN) / sizeof(ASNItem))
13046 #endif
13047 
13048 /* Encode signature.
13049  *
13050  * @param [out] out     Buffer to hold encoding.
13051  * @param [in]  digest  Buffer holding digest.
13052  * @param [in]  digSz   Length of digest in bytes.
13053  * @return  Encoded data size on success.
13054  * @return  0 when dynamic memory allocation fails.
13055  */
13056 word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
13057                           int hashOID)
13058 {
13059 #ifndef WOLFSSL_ASN_TEMPLATE
13060     byte digArray[MAX_ENCODED_DIG_SZ];
13061     byte algoArray[MAX_ALGO_SZ];
13062     byte seqArray[MAX_SEQ_SZ];
13063     word32 encDigSz, algoSz, seqSz;
13064 
13065     encDigSz = SetDigest(digest, digSz, digArray);
13066     algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
13067     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
13068 
13069     XMEMCPY(out, seqArray, seqSz);
13070     XMEMCPY(out + seqSz, algoArray, algoSz);
13071     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
13072 
13073     return encDigSz + algoSz + seqSz;
13074 #else
13075     DECL_ASNSETDATA(dataASN, digestInfoASN_Length);
13076     int ret = 0;
13077     int sz;
13078 
13079     CALLOC_ASNSETDATA(dataASN, digestInfoASN_Length, ret, NULL);
13080 
13081     if (ret == 0) {
13082         /* Set hash OID and type. */
13083         SetASN_OID(&dataASN[DIGESTINFOASN_IDX_DIGALGO_OID], hashOID, oidHashType);
13084         /* Set digest. */
13085         SetASN_Buffer(&dataASN[DIGESTINFOASN_IDX_DIGEST], digest, digSz);
13086 
13087         /* Calculate size of encoding. */
13088         ret = SizeASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, &sz);
13089     }
13090     if (ret == 0) {
13091         /* Encode PKCS#1 v1.5 RSA signature. */
13092         SetASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, out);
13093         ret = sz;
13094     }
13095     else {
13096         /* Unsigned return type so 0 indicates error. */
13097         ret = 0;
13098     }
13099 
13100     FREE_ASNSETDATA(dataASN, NULL);
13101     return ret;
13102 #endif
13103 }
13104 
13105 
13106 #ifndef NO_CERTS
13107 
13108 int wc_GetCTC_HashOID(int type)
13109 {
13110     int ret;
13111     enum wc_HashType hType;
13112 
13113     hType = wc_HashTypeConvert(type);
13114     ret = wc_HashGetOID(hType);
13115     if (ret < 0) {
13116         ret = 0; /* backwards compatibility */
13117     }
13118 
13119     return ret;
13120 }
13121 
13122 /* Initialize a signature context object.
13123  *
13124  * Object used for signing and verifying a certificate signature.
13125  *
13126  * @param [in, out] sigCtx  Signature context object.
13127  * @param [in]      heap    Dynamic memory hint.
13128  * @param [in]      devId   Hardware device identifier.
13129  */
13130 void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
13131 {
13132     if (sigCtx) {
13133         XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
13134         sigCtx->devId = devId;
13135         sigCtx->heap = heap;
13136     }
13137 }
13138 
13139 /* Free dynamic data in a signature context object.
13140  *
13141  * @param [in, out] sigCtx  Signature context object.
13142  */
13143 void FreeSignatureCtx(SignatureCtx* sigCtx)
13144 {
13145     if (sigCtx == NULL)
13146         return;
13147 
13148     if (sigCtx->digest) {
13149         XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
13150         sigCtx->digest = NULL;
13151     }
13152 #if !(defined(NO_RSA) && defined(NO_DSA))
13153     if (sigCtx->sigCpy) {
13154         XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
13155         sigCtx->sigCpy = NULL;
13156     }
13157 #endif
13158 #ifndef NO_ASN_CRYPT
13159     if (sigCtx->key.ptr) {
13160         switch (sigCtx->keyOID) {
13161         #ifndef NO_RSA
13162             case RSAk:
13163                 wc_FreeRsaKey(sigCtx->key.rsa);
13164                 XFREE(sigCtx->key.rsa, sigCtx->heap, DYNAMIC_TYPE_RSA);
13165                 sigCtx->key.rsa = NULL;
13166                 break;
13167         #endif /* !NO_RSA */
13168         #ifndef NO_DSA
13169             case DSAk:
13170                 wc_FreeDsaKey(sigCtx->key.dsa);
13171                 XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA);
13172                 sigCtx->key.dsa = NULL;
13173                 break;
13174         #endif
13175         #ifdef HAVE_ECC
13176             case ECDSAk:
13177                 wc_ecc_free(sigCtx->key.ecc);
13178                 XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
13179                 sigCtx->key.ecc = NULL;
13180                 break;
13181         #endif /* HAVE_ECC */
13182         #ifdef HAVE_ED25519
13183             case ED25519k:
13184                 wc_ed25519_free(sigCtx->key.ed25519);
13185                 XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
13186                 sigCtx->key.ed25519 = NULL;
13187                 break;
13188         #endif /* HAVE_ED25519 */
13189         #ifdef HAVE_ED448
13190             case ED448k:
13191                 wc_ed448_free(sigCtx->key.ed448);
13192                 XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
13193                 sigCtx->key.ed448 = NULL;
13194                 break;
13195         #endif /* HAVE_ED448 */
13196         #ifdef HAVE_PQC
13197             case FALCON_LEVEL1k:
13198             case FALCON_LEVEL5k:
13199                 wc_falcon_free(sigCtx->key.falcon);
13200                 XFREE(sigCtx->key.falcon, sigCtx->heap,
13201                       DYNAMIC_TYPE_FALCON);
13202                 sigCtx->key.falcon = NULL;
13203                 break;
13204         #endif /* HAVE_PQC */
13205             default:
13206                 break;
13207         } /* switch (keyOID) */
13208         sigCtx->key.ptr = NULL;
13209     }
13210 #endif
13211 
13212     /* reset state, we are done */
13213     sigCtx->state = SIG_STATE_BEGIN;
13214 }
13215 
13216 #ifndef NO_ASN_CRYPT
13217 static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
13218                             byte* digest, int* typeH, int* digestSz, int verify)
13219 {
13220     int ret = 0;
13221 
13222     switch (sigOID) {
13223     #if defined(WOLFSSL_MD2)
13224         case CTC_MD2wRSA:
13225             if (!verify) {
13226                 ret = HASH_TYPE_E;
13227                 WOLFSSL_MSG("MD2 not supported for signing");
13228             }
13229             else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
13230                 *typeH    = MD2h;
13231                 *digestSz = MD2_DIGEST_SIZE;
13232             }
13233         break;
13234     #endif
13235     #ifndef NO_MD5
13236         case CTC_MD5wRSA:
13237             if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
13238                 *typeH    = MD5h;
13239                 *digestSz = WC_MD5_DIGEST_SIZE;
13240             }
13241             break;
13242     #endif
13243     #ifndef NO_SHA
13244         case CTC_SHAwRSA:
13245         case CTC_SHAwDSA:
13246         case CTC_SHAwECDSA:
13247             if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
13248                 *typeH    = SHAh;
13249                 *digestSz = WC_SHA_DIGEST_SIZE;
13250             }
13251             break;
13252     #endif
13253     #ifdef WOLFSSL_SHA224
13254         case CTC_SHA224wRSA:
13255         case CTC_SHA224wECDSA:
13256             if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
13257                 *typeH    = SHA224h;
13258                 *digestSz = WC_SHA224_DIGEST_SIZE;
13259             }
13260             break;
13261     #endif
13262     #ifndef NO_SHA256
13263         case CTC_SHA256wRSA:
13264         case CTC_SHA256wECDSA:
13265         case CTC_SHA256wDSA:
13266             if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
13267                 *typeH    = SHA256h;
13268                 *digestSz = WC_SHA256_DIGEST_SIZE;
13269             }
13270             break;
13271     #endif
13272     #ifdef WOLFSSL_SHA384
13273         case CTC_SHA384wRSA:
13274         case CTC_SHA384wECDSA:
13275             if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
13276                 *typeH    = SHA384h;
13277                 *digestSz = WC_SHA384_DIGEST_SIZE;
13278             }
13279             break;
13280     #endif
13281     #ifdef WOLFSSL_SHA512
13282         case CTC_SHA512wRSA:
13283         case CTC_SHA512wECDSA:
13284             if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
13285                 *typeH    = SHA512h;
13286                 *digestSz = WC_SHA512_DIGEST_SIZE;
13287             }
13288             break;
13289     #endif
13290     #ifdef WOLFSSL_SHA3
13291     #ifndef WOLFSSL_NOSHA3_224
13292         case CTC_SHA3_224wRSA:
13293         case CTC_SHA3_224wECDSA:
13294             if ((ret = wc_Sha3_224Hash(buf, bufSz, digest)) == 0) {
13295                 *typeH    = SHA3_224h;
13296                 *digestSz = WC_SHA3_224_DIGEST_SIZE;
13297             }
13298             break;
13299     #endif
13300     #ifndef WOLFSSL_NOSHA3_256
13301         case CTC_SHA3_256wRSA:
13302         case CTC_SHA3_256wECDSA:
13303             if ((ret = wc_Sha3_256Hash(buf, bufSz, digest)) == 0) {
13304                 *typeH    = SHA3_256h;
13305                 *digestSz = WC_SHA3_256_DIGEST_SIZE;
13306             }
13307             break;
13308     #endif
13309     #ifndef WOLFSSL_NOSHA3_384
13310         case CTC_SHA3_384wRSA:
13311         case CTC_SHA3_384wECDSA:
13312             if ((ret = wc_Sha3_384Hash(buf, bufSz, digest)) == 0) {
13313                 *typeH    = SHA3_384h;
13314                 *digestSz = WC_SHA3_384_DIGEST_SIZE;
13315             }
13316             break;
13317     #endif
13318     #ifndef WOLFSSL_NOSHA3_512
13319         case CTC_SHA3_512wRSA:
13320         case CTC_SHA3_512wECDSA:
13321             if ((ret = wc_Sha3_512Hash(buf, bufSz, digest)) == 0) {
13322                 *typeH    = SHA3_512h;
13323                 *digestSz = WC_SHA3_512_DIGEST_SIZE;
13324             }
13325             break;
13326     #endif
13327     #endif
13328     #ifdef HAVE_ED25519
13329         case CTC_ED25519:
13330             /* Hashes done in signing operation.
13331              * Two dependent hashes with prefixes performed.
13332              */
13333             break;
13334     #endif
13335     #ifdef HAVE_ED448
13336         case CTC_ED448:
13337             /* Hashes done in signing operation.
13338              * Two dependent hashes with prefixes performed.
13339              */
13340             break;
13341     #endif
13342     #ifdef HAVE_PQC
13343         case CTC_FALCON_LEVEL1:
13344         case CTC_FALCON_LEVEL5:
13345             /* Hashes done in signing operation. */
13346             break;
13347     #endif
13348 
13349         default:
13350             ret = HASH_TYPE_E;
13351             WOLFSSL_MSG("Hash for Signature has unsupported type");
13352     }
13353 
13354     (void)buf;
13355     (void)bufSz;
13356     (void)sigOID;
13357     (void)digest;
13358     (void)digestSz;
13359     (void)typeH;
13360     (void)verify;
13361 
13362     return ret;
13363 }
13364 #endif /* !NO_ASN_CRYPT */
13365 
13366 /* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
13367 static int ConfirmSignature(SignatureCtx* sigCtx,
13368     const byte* buf, word32 bufSz,
13369     const byte* key, word32 keySz, word32 keyOID,
13370     const byte* sig, word32 sigSz, word32 sigOID, byte* rsaKeyIdx)
13371 {
13372     int ret = 0;
13373 
13374     if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
13375         keySz == 0 || sig == NULL || sigSz == 0) {
13376         return BAD_FUNC_ARG;
13377     }
13378 
13379     (void)key;
13380     (void)keySz;
13381     (void)sig;
13382     (void)sigSz;
13383 
13384     WOLFSSL_ENTER("ConfirmSignature");
13385 
13386 #if !defined(WOLFSSL_RENESAS_TSIP_TLS) && !defined(WOLFSSL_RENESAS_SCEPROTECT)
13387     (void)rsaKeyIdx;
13388 #else
13389     CertAttribute* certatt = NULL;
13390 
13391     #if !defined(NO_RSA) || defined(HAVE_ECC)
13392     certatt = (CertAttribute*)&sigCtx->CertAtt;
13393     #endif
13394     if(certatt) {
13395         certatt->keyIndex = rsaKeyIdx;
13396         certatt->cert = buf;
13397         certatt->certSz = bufSz;
13398     }
13399 #endif
13400 
13401 #ifndef NO_ASN_CRYPT
13402     switch (sigCtx->state) {
13403         case SIG_STATE_BEGIN:
13404         {
13405             sigCtx->keyOID = keyOID; /* must set early for cleanup */
13406 
13407             sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
13408                                                     DYNAMIC_TYPE_DIGEST);
13409             if (sigCtx->digest == NULL) {
13410                 ERROR_OUT(MEMORY_E, exit_cs);
13411             }
13412 
13413             sigCtx->state = SIG_STATE_HASH;
13414         } /* SIG_STATE_BEGIN */
13415         FALL_THROUGH;
13416 
13417         case SIG_STATE_HASH:
13418         {
13419             ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
13420                                    &sigCtx->typeH, &sigCtx->digestSz, 1);
13421             if (ret != 0) {
13422                 goto exit_cs;
13423             }
13424 
13425             sigCtx->state = SIG_STATE_KEY;
13426         } /* SIG_STATE_HASH */
13427         FALL_THROUGH;
13428 
13429         case SIG_STATE_KEY:
13430         {
13431             switch (keyOID) {
13432             #ifndef NO_RSA
13433                 case RSAk:
13434                 {
13435                     word32 idx = 0;
13436 
13437                     sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
13438                                                 sigCtx->heap, DYNAMIC_TYPE_RSA);
13439                     sigCtx->sigCpy = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
13440                                          sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
13441                     if (sigCtx->key.rsa == NULL || sigCtx->sigCpy == NULL) {
13442                         ERROR_OUT(MEMORY_E, exit_cs);
13443                     }
13444                     if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
13445                                                         sigCtx->devId)) != 0) {
13446                         goto exit_cs;
13447                     }
13448                     if (sigSz > MAX_ENCODED_SIG_SZ) {
13449                         WOLFSSL_MSG("Verify Signature is too big");
13450                         ERROR_OUT(BUFFER_E, exit_cs);
13451                     }
13452                     if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
13453                                                                  keySz)) != 0) {
13454                         WOLFSSL_MSG("ASN Key decode error RSA");
13455                         goto exit_cs;
13456                     }
13457                     XMEMCPY(sigCtx->sigCpy, sig, sigSz);
13458                     sigCtx->out = NULL;
13459 
13460                 #ifdef WOLFSSL_ASYNC_CRYPT
13461                     sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
13462                 #endif
13463                     break;
13464                 }
13465             #endif /* !NO_RSA */
13466             #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
13467                 case DSAk:
13468                 {
13469                     word32 idx = 0;
13470 
13471                     if (sigSz < DSA_MIN_SIG_SIZE) {
13472                         WOLFSSL_MSG("Verify Signature is too small");
13473                         ERROR_OUT(BUFFER_E, exit_cs);
13474                     }
13475                     sigCtx->key.dsa = (DsaKey*)XMALLOC(sizeof(DsaKey),
13476                                                 sigCtx->heap, DYNAMIC_TYPE_DSA);
13477                     sigCtx->sigCpy = (byte*)XMALLOC(sigSz,
13478                                          sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
13479                     if (sigCtx->key.dsa == NULL || sigCtx->sigCpy == NULL) {
13480                         ERROR_OUT(MEMORY_E, exit_cs);
13481                     }
13482                     if ((ret = wc_InitDsaKey_h(sigCtx->key.dsa, sigCtx->heap)) != 0) {
13483                         WOLFSSL_MSG("wc_InitDsaKey_h error");
13484                         goto exit_cs;
13485                     }
13486                     if ((ret = wc_DsaPublicKeyDecode(key, &idx, sigCtx->key.dsa,
13487                                                                  keySz)) != 0) {
13488                         WOLFSSL_MSG("ASN Key decode error DSA");
13489                         goto exit_cs;
13490                     }
13491                     if (sigSz != DSA_160_SIG_SIZE &&
13492                             sigSz != DSA_256_SIG_SIZE) {
13493                         /* Try to parse it as the contents of a bitstring */
13494                     #ifdef WOLFSSL_SMALL_STACK
13495                         mp_int* r;
13496                         mp_int* s;
13497                     #else
13498                         mp_int r[1];
13499                         mp_int s[1];
13500                     #endif
13501                         int rSz;
13502                         int sSz;
13503 
13504                     #ifdef WOLFSSL_SMALL_STACK
13505                         r = (mp_int*)XMALLOC(sizeof(*r), sigCtx->heap,
13506                                                        DYNAMIC_TYPE_TMP_BUFFER);
13507                         if (r == NULL) {
13508                             ERROR_OUT(MEMORY_E, exit_cs);
13509                         }
13510                         s = (mp_int*)XMALLOC(sizeof(*s), sigCtx->heap,
13511                                                        DYNAMIC_TYPE_TMP_BUFFER);
13512                         if (s == NULL) {
13513                             XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13514                             ERROR_OUT(MEMORY_E, exit_cs);
13515                         }
13516                     #endif
13517                         mp_init(r);
13518                         mp_init(s);
13519 
13520                         idx = 0;
13521                         if (DecodeECC_DSA_Sig(sig + idx, sigSz - idx, r, s)
13522                                               != 0) {
13523                             WOLFSSL_MSG("DSA Sig is in unrecognized or "
13524                                         "incorrect format");
13525                             mp_free(r);
13526                             mp_free(s);
13527                     #ifdef WOLFSSL_SMALL_STACK
13528                             XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13529                             XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13530                     #endif
13531                             ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
13532                         }
13533                         rSz = mp_unsigned_bin_size(r);
13534                         sSz = mp_unsigned_bin_size(s);
13535                         if (rSz + sSz > (int)sigSz) {
13536                             WOLFSSL_MSG("DSA Sig is in unrecognized or "
13537                                         "incorrect format");
13538                             mp_free(r);
13539                             mp_free(s);
13540                     #ifdef WOLFSSL_SMALL_STACK
13541                             XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13542                             XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13543                     #endif
13544                             ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
13545                         }
13546                         if (mp_to_unsigned_bin(r, sigCtx->sigCpy) != MP_OKAY ||
13547                                 mp_to_unsigned_bin(s,
13548                                         sigCtx->sigCpy + rSz) != MP_OKAY) {
13549                             WOLFSSL_MSG("DSA Sig is in unrecognized or "
13550                                         "incorrect format");
13551                             mp_free(r);
13552                             mp_free(s);
13553                     #ifdef WOLFSSL_SMALL_STACK
13554                             XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13555                             XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13556                     #endif
13557                             ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
13558                         }
13559                         mp_free(r);
13560                         mp_free(s);
13561                     #ifdef WOLFSSL_SMALL_STACK
13562                         XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13563                         XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13564                     #endif
13565                     }
13566                     else {
13567                         XMEMCPY(sigCtx->sigCpy, sig, sigSz);
13568                     }
13569                     break;
13570                 }
13571             #endif /* !NO_DSA && !HAVE_SELFTEST */
13572             #ifdef HAVE_ECC
13573                 case ECDSAk:
13574                 {
13575                     word32 idx = 0;
13576 
13577                     sigCtx->verify = 0;
13578                     sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
13579                                                 sigCtx->heap, DYNAMIC_TYPE_ECC);
13580                     if (sigCtx->key.ecc == NULL) {
13581                         ERROR_OUT(MEMORY_E, exit_cs);
13582                     }
13583                     if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
13584                                                           sigCtx->devId)) < 0) {
13585                         goto exit_cs;
13586                     }
13587                     ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
13588                                                                          keySz);
13589                     if (ret < 0) {
13590                         WOLFSSL_MSG("ASN Key import error ECC");
13591                         goto exit_cs;
13592                     }
13593                 #ifdef WOLFSSL_ASYNC_CRYPT
13594                     sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
13595                 #endif
13596                     break;
13597                 }
13598             #endif /* HAVE_ECC */
13599             #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13600                 case ED25519k:
13601                 {
13602                     sigCtx->verify = 0;
13603                     sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
13604                                               sizeof(ed25519_key), sigCtx->heap,
13605                                               DYNAMIC_TYPE_ED25519);
13606                     if (sigCtx->key.ed25519 == NULL) {
13607                         ERROR_OUT(MEMORY_E, exit_cs);
13608                     }
13609                     if ((ret = wc_ed25519_init_ex(sigCtx->key.ed25519,
13610                                             sigCtx->heap, sigCtx->devId)) < 0) {
13611                         goto exit_cs;
13612                     }
13613                     if ((ret = wc_ed25519_import_public(key, keySz,
13614                                                     sigCtx->key.ed25519)) < 0) {
13615                         WOLFSSL_MSG("ASN Key import error ED25519");
13616                         goto exit_cs;
13617                     }
13618                 #ifdef WOLFSSL_ASYNC_CRYPT
13619                     sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
13620                 #endif
13621                     break;
13622                 }
13623             #endif
13624             #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
13625                 case ED448k:
13626                 {
13627                     sigCtx->verify = 0;
13628                     sigCtx->key.ed448 = (ed448_key*)XMALLOC(
13629                                                 sizeof(ed448_key), sigCtx->heap,
13630                                                 DYNAMIC_TYPE_ED448);
13631                     if (sigCtx->key.ed448 == NULL) {
13632                         ERROR_OUT(MEMORY_E, exit_cs);
13633                     }
13634                     if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) {
13635                         goto exit_cs;
13636                     }
13637                     if ((ret = wc_ed448_import_public(key, keySz,
13638                                                       sigCtx->key.ed448)) < 0) {
13639                         WOLFSSL_MSG("ASN Key import error ED448");
13640                         goto exit_cs;
13641                     }
13642                 #ifdef WOLFSSL_ASYNC_CRYPT
13643                     sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev;
13644                 #endif
13645                     break;
13646                 }
13647             #endif
13648             #if defined(HAVE_PQC)
13649                 case FALCON_LEVEL1k:
13650                 {
13651                     sigCtx->verify = 0;
13652                     sigCtx->key.falcon =
13653                         (falcon_key*)XMALLOC(sizeof(falcon_key),
13654                                              sigCtx->heap,
13655                                              DYNAMIC_TYPE_FALCON);
13656                     if (sigCtx->key.falcon == NULL) {
13657                         ERROR_OUT(MEMORY_E, exit_cs);
13658                     }
13659                     if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
13660                         goto exit_cs;
13661                     }
13662                     if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1))
13663                         < 0) {
13664                         goto exit_cs;
13665                     }
13666                     if ((ret = wc_falcon_import_public(key, keySz,
13667                         sigCtx->key.falcon)) < 0) {
13668                         WOLFSSL_MSG("ASN Key import error Falcon Level 1");
13669                         goto exit_cs;
13670                     }
13671                     break;
13672                 }
13673                 case FALCON_LEVEL5k:
13674                 {
13675                     sigCtx->verify = 0;
13676                     sigCtx->key.falcon =
13677                         (falcon_key*)XMALLOC(sizeof(falcon_key),
13678                                              sigCtx->heap,
13679                                              DYNAMIC_TYPE_FALCON);
13680                     if (sigCtx->key.falcon == NULL) {
13681                         ERROR_OUT(MEMORY_E, exit_cs);
13682                     }
13683                     if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
13684                         goto exit_cs;
13685                     }
13686                     if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5))
13687                         < 0) {
13688                         goto exit_cs;
13689                     }
13690                     if ((ret = wc_falcon_import_public(key, keySz,
13691                         sigCtx->key.falcon)) < 0) {
13692                         WOLFSSL_MSG("ASN Key import error Falcon Level 5");
13693                         goto exit_cs;
13694                     }
13695                     break;
13696                 }
13697             #endif
13698                 default:
13699                     WOLFSSL_MSG("Verify Key type unknown");
13700                     ret = ASN_UNKNOWN_OID_E;
13701                     break;
13702             } /* switch (keyOID) */
13703 
13704             if (ret != 0) {
13705                 goto exit_cs;
13706             }
13707 
13708             sigCtx->state = SIG_STATE_DO;
13709 
13710         #ifdef WOLFSSL_ASYNC_CRYPT
13711             if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
13712                 /* make sure event is initialized */
13713                 WOLF_EVENT* event = &sigCtx->asyncDev->event;
13714                 ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
13715                     sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
13716             }
13717         #endif
13718         } /* SIG_STATE_KEY */
13719         FALL_THROUGH;
13720 
13721         case SIG_STATE_DO:
13722         {
13723             switch (keyOID) {
13724             #ifndef NO_RSA
13725                 case RSAk:
13726                 {
13727                 #if defined(HAVE_PK_CALLBACKS)
13728                     if (sigCtx->pkCbRsa) {
13729                         ret = sigCtx->pkCbRsa(
13730                                 sigCtx->sigCpy, sigSz, &sigCtx->out,
13731                                 key, keySz,
13732                                 sigCtx->pkCtxRsa);
13733                     }
13734                 #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
13735                     !defined(WOLFSSL_RENESAS_TSIP_TLS)
13736                     else
13737                 #else
13738                     if (!sigCtx->pkCbRsa || ret == CRYPTOCB_UNAVAILABLE)
13739                 #endif /* WOLFSSL_RENESAS_SCEPROTECT */
13740                 #endif /* HAVE_PK_CALLBACKS */
13741                     {
13742                         ret = wc_RsaSSL_VerifyInline(sigCtx->sigCpy, sigSz,
13743                                                  &sigCtx->out, sigCtx->key.rsa);
13744                     }
13745                     break;
13746                 }
13747             #endif /* !NO_RSA */
13748             #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
13749                 case DSAk:
13750                 {
13751                     ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy,
13752                             sigCtx->key.dsa, &sigCtx->verify);
13753                     break;
13754                 }
13755             #endif /* !NO_DSA && !HAVE_SELFTEST */
13756             #if defined(HAVE_ECC)
13757                 case ECDSAk:
13758                 {
13759                 #if defined(HAVE_PK_CALLBACKS)
13760                     if (sigCtx->pkCbEcc) {
13761                         ret = sigCtx->pkCbEcc(
13762                                 sig, sigSz,
13763                                 sigCtx->digest, sigCtx->digestSz,
13764                                 key, keySz, &sigCtx->verify,
13765                                 sigCtx->pkCtxEcc);
13766                     }
13767                 #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
13768                     !defined(WOLFSSL_RENESAS_TSIP_TLS)
13769                     else
13770                 #else
13771                     if (!sigCtx->pkCbEcc || ret == CRYPTOCB_UNAVAILABLE)
13772                 #endif /* WOLFSSL_RENESAS_SCEPROTECT */
13773                 #endif /* HAVE_PK_CALLBACKS */
13774                     {
13775                         ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
13776                                             sigCtx->digestSz, &sigCtx->verify,
13777                                             sigCtx->key.ecc);
13778                     }
13779                     break;
13780                 }
13781             #endif /* HAVE_ECC */
13782             #if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY)
13783                 case ED25519k:
13784                 {
13785                     ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
13786                                           &sigCtx->verify, sigCtx->key.ed25519);
13787                     break;
13788                 }
13789             #endif
13790             #if defined(HAVE_ED448) && defined(HAVE_ED448_VERIFY)
13791                 case ED448k:
13792                 {
13793                     ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
13794                                              &sigCtx->verify, sigCtx->key.ed448,
13795                                              NULL, 0);
13796                     break;
13797                 }
13798             #endif
13799             #if defined(HAVE_PQC)
13800                 case FALCON_LEVEL1k:
13801                 case FALCON_LEVEL5k:
13802                 {
13803                     ret = wc_falcon_verify_msg(sig, sigSz, buf, bufSz,
13804                                                &sigCtx->verify,
13805                                                sigCtx->key.falcon);
13806                     break;
13807                 }
13808             #endif
13809                 default:
13810                     break;
13811             }  /* switch (keyOID) */
13812 
13813         #ifdef WOLFSSL_ASYNC_CRYPT
13814             if (ret == WC_PENDING_E) {
13815                 goto exit_cs;
13816             }
13817         #endif
13818 
13819             if (ret < 0) {
13820                 /* treat all RSA errors as ASN_SIG_CONFIRM_E */
13821                 ret = ASN_SIG_CONFIRM_E;
13822                 goto exit_cs;
13823             }
13824 
13825             sigCtx->state = SIG_STATE_CHECK;
13826         } /* SIG_STATE_DO */
13827         FALL_THROUGH;
13828 
13829         case SIG_STATE_CHECK:
13830         {
13831             switch (keyOID) {
13832             #ifndef NO_RSA
13833                 case RSAk:
13834                 {
13835                     int encodedSigSz, verifySz;
13836                 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || \
13837                                             defined(WOLFSSL_RENESAS_SCEPROTECT)
13838                     if (sigCtx->CertAtt.verifyByTSIP_SCE == 1) break;
13839                 #endif
13840                 #ifdef WOLFSSL_SMALL_STACK
13841                     byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
13842                                         sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13843                     if (encodedSig == NULL) {
13844                         ERROR_OUT(MEMORY_E, exit_cs);
13845                     }
13846                 #else
13847                     byte encodedSig[MAX_ENCODED_SIG_SZ];
13848                 #endif
13849 
13850                     verifySz = ret;
13851 
13852                     /* make sure we're right justified */
13853                     encodedSigSz = wc_EncodeSignature(encodedSig,
13854                             sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
13855                     if (encodedSigSz == verifySz && sigCtx->out != NULL &&
13856                         XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
13857                         ret = 0;
13858                     }
13859                     else {
13860                         WOLFSSL_MSG("RSA SSL verify match encode error");
13861                         ret = ASN_SIG_CONFIRM_E;
13862                     }
13863 
13864                 #ifdef WOLFSSL_SMALL_STACK
13865                     XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
13866                 #endif
13867                     break;
13868                 }
13869             #endif /* NO_RSA */
13870             #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
13871                 case DSAk:
13872                 {
13873                     if (sigCtx->verify == 1) {
13874                         ret = 0;
13875                     }
13876                     else {
13877                         WOLFSSL_MSG("DSA Verify didn't match");
13878                         ret = ASN_SIG_CONFIRM_E;
13879                     }
13880                     break;
13881                 }
13882             #endif /* !NO_DSA && !HAVE_SELFTEST */
13883             #ifdef HAVE_ECC
13884                 case ECDSAk:
13885                 {
13886                     if (sigCtx->verify == 1) {
13887                         ret = 0;
13888                     }
13889                     else {
13890                         WOLFSSL_MSG("ECC Verify didn't match");
13891                         ret = ASN_SIG_CONFIRM_E;
13892                     }
13893                     break;
13894                 }
13895             #endif /* HAVE_ECC */
13896             #ifdef HAVE_ED25519
13897                 case ED25519k:
13898                 {
13899                     if (sigCtx->verify == 1) {
13900                         ret = 0;
13901                     }
13902                     else {
13903                         WOLFSSL_MSG("ED25519 Verify didn't match");
13904                         ret = ASN_SIG_CONFIRM_E;
13905                     }
13906                     break;
13907                 }
13908             #endif /* HAVE_ED25519 */
13909             #ifdef HAVE_ED448
13910                 case ED448k:
13911                 {
13912                     if (sigCtx->verify == 1) {
13913                         ret = 0;
13914                     }
13915                     else {
13916                         WOLFSSL_MSG("ED448 Verify didn't match");
13917                         ret = ASN_SIG_CONFIRM_E;
13918                     }
13919                     break;
13920                 }
13921             #endif /* HAVE_ED448 */
13922             #ifdef HAVE_PQC
13923                 case FALCON_LEVEL1k:
13924                 {
13925                     if (sigCtx->verify == 1) {
13926                         ret = 0;
13927                     }
13928                     else {
13929                         WOLFSSL_MSG("FALCON_LEVEL1 Verify didn't match");
13930                         ret = ASN_SIG_CONFIRM_E;
13931                     }
13932                     break;
13933                 }
13934                 case FALCON_LEVEL5k:
13935                 {
13936                     if (sigCtx->verify == 1) {
13937                         ret = 0;
13938                     }
13939                     else {
13940                         WOLFSSL_MSG("FALCON_LEVEL5 Verify didn't match");
13941                         ret = ASN_SIG_CONFIRM_E;
13942                     }
13943                     break;
13944                 }
13945             #endif /* HAVE_PQC */
13946                 default:
13947                     break;
13948             }  /* switch (keyOID) */
13949 
13950             break;
13951         } /* SIG_STATE_CHECK */
13952 
13953         default:
13954             break;
13955     } /* switch (sigCtx->state) */
13956 
13957 exit_cs:
13958 
13959 #endif /* !NO_ASN_CRYPT */
13960 
13961     (void)keyOID;
13962     (void)sigOID;
13963 
13964     WOLFSSL_LEAVE("ConfirmSignature", ret);
13965 
13966 #ifdef WOLFSSL_ASYNC_CRYPT
13967     if (ret == WC_PENDING_E)
13968         return ret;
13969 #endif
13970 
13971     FreeSignatureCtx(sigCtx);
13972 
13973     return ret;
13974 }
13975 
13976 
13977 #ifndef IGNORE_NAME_CONSTRAINTS
13978 
13979 static int MatchBaseName(int type, const char* name, int nameSz,
13980                          const char* base, int baseSz)
13981 {
13982     if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
13983             name[0] == '.' || nameSz < baseSz ||
13984             (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE &&
13985              type != ASN_DIR_TYPE)) {
13986         return 0;
13987     }
13988 
13989     if (type == ASN_DIR_TYPE)
13990         return XMEMCMP(name, base, baseSz) == 0;
13991 
13992     /* If an email type, handle special cases where the base is only
13993      * a domain, or is an email address itself. */
13994     if (type == ASN_RFC822_TYPE) {
13995         const char* p = NULL;
13996         int count = 0;
13997 
13998         if (base[0] != '.') {
13999             p = base;
14000             count = 0;
14001 
14002             /* find the '@' in the base */
14003             while (*p != '@' && count < baseSz) {
14004                 count++;
14005                 p++;
14006             }
14007 
14008             /* No '@' in base, reset p to NULL */
14009             if (count >= baseSz)
14010                 p = NULL;
14011         }
14012 
14013         if (p == NULL) {
14014             /* Base isn't an email address, it is a domain name,
14015              * wind the name forward one character past its '@'. */
14016             p = name;
14017             count = 0;
14018             while (*p != '@' && count < baseSz) {
14019                 count++;
14020                 p++;
14021             }
14022 
14023             if (count < baseSz && *p == '@') {
14024                 name = p + 1;
14025                 nameSz -= count + 1;
14026             }
14027         }
14028     }
14029 
14030     /* RFC 5280 section 4.2.1.10
14031      * "...Any DNS name that can be constructed by simply adding zero or more
14032      *  labels to the left-hand side of the name satisfies the name constraint."
14033      * i.e www.host.example.com works for host.example.com name constraint and
14034      * host1.example.com does not. */
14035     if (type == ASN_DNS_TYPE || (type == ASN_RFC822_TYPE && base[0] == '.')) {
14036         int szAdjust = nameSz - baseSz;
14037         name += szAdjust;
14038         nameSz -= szAdjust;
14039     }
14040 
14041     while (nameSz > 0) {
14042         if (XTOLOWER((unsigned char)*name++) !=
14043                                                XTOLOWER((unsigned char)*base++))
14044             return 0;
14045         nameSz--;
14046     }
14047 
14048     return 1;
14049 }
14050 
14051 
14052 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
14053 {
14054     const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE};
14055     int i;
14056 
14057     if (signer == NULL || cert == NULL)
14058         return 0;
14059 
14060     if (signer->excludedNames == NULL && signer->permittedNames == NULL)
14061         return 1;
14062 
14063     for (i=0; i < (int)sizeof(nameTypes); i++) {
14064         byte nameType = nameTypes[i];
14065         DNS_entry* name = NULL;
14066         DNS_entry  subjectDnsName;
14067         Base_entry* base;
14068 
14069         switch (nameType) {
14070             case ASN_DNS_TYPE:
14071                 /* Should it also consider CN in subject? It could use
14072                  * subjectDnsName too */
14073                 name = cert->altNames;
14074                 break;
14075             case ASN_RFC822_TYPE:
14076                 /* Shouldn't it validade E= in subject as well? */
14077                 name = cert->altEmailNames;
14078                 break;
14079             case ASN_DIR_TYPE:
14080                 if (cert->subjectRaw != NULL) {
14081                     subjectDnsName.next = NULL;
14082                     subjectDnsName.type = ASN_DIR_TYPE;
14083                     subjectDnsName.len = cert->subjectRawLen;
14084                     subjectDnsName.name = (char *)cert->subjectRaw;
14085                     name = &subjectDnsName;
14086                 }
14087 
14088                 #ifndef WOLFSSL_NO_ASN_STRICT
14089                 /* RFC 5280 section 4.2.1.10
14090                     "Restrictions of the form directoryName MUST be
14091                     applied to the subject field .... and to any names
14092                     of type directoryName in the subjectAltName
14093                     extension"
14094                 */
14095                 if (name != NULL)
14096                     name->next = cert->altDirNames;
14097                 else
14098                     name = cert->altDirNames;
14099                 #endif
14100                 break;
14101             default:
14102                 /* Other types of names are ignored for now.
14103                  * Shouldn't it be rejected if it there is a altNamesByType[nameType]
14104                  * and signer->extNameConstraintCrit is set? */
14105                 return 0;
14106         }
14107 
14108         while (name != NULL) {
14109             int match = 0;
14110             int need = 0;
14111 
14112             base = signer->excludedNames;
14113             /* Check against the excluded list */
14114             while (base != NULL) {
14115                 if (base->type == nameType) {
14116                     if (name->len >= base->nameSz &&
14117                         MatchBaseName(nameType,
14118                                       name->name, name->len,
14119                                       base->name, base->nameSz)) {
14120                             return 0;
14121                     }
14122                 }
14123                 base = base->next;
14124             }
14125 
14126             /* Check against the permitted list */
14127             base = signer->permittedNames;
14128             while (base != NULL) {
14129                 if (base->type == nameType) {
14130                     need = 1;
14131                     if (name->len >= base->nameSz &&
14132                         MatchBaseName(nameType,
14133                                       name->name, name->len,
14134                                       base->name, base->nameSz)) {
14135                             match = 1;
14136                             break;
14137                     }
14138                 }
14139                 base = base->next;
14140             }
14141 
14142             if (need && !match)
14143                 return 0;
14144 
14145             name = name->next;
14146         }
14147     }
14148 
14149     return 1;
14150 }
14151 
14152 #endif /* IGNORE_NAME_CONSTRAINTS */
14153 
14154 #ifndef WOLFSSL_ASN_TEMPLATE
14155 static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry)
14156 {
14157 #if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
14158     dnsEntry->next = NULL;
14159     if (cert->altNames == NULL) {
14160         /* First on list */
14161         cert->altNames = dnsEntry;
14162     }
14163     else {
14164         DNS_entry* temp = cert->altNames;
14165 
14166         /* Find end */
14167         for (; (temp->next != NULL); temp = temp->next);
14168 
14169         /* Add to end */
14170         temp->next = dnsEntry;
14171     }
14172 #else
14173     dnsEntry->next = cert->altNames;
14174     cert->altNames = dnsEntry;
14175 #endif
14176 }
14177 #endif
14178 
14179 #ifdef WOLFSSL_ASN_TEMPLATE
14180 #ifdef WOLFSSL_SEP
14181 /* ASN.1 template for OtherName of an X.509 certificate.
14182  * X.509: RFC 5280, 4.2.1.6 - OtherName (without implicit outer SEQUENCE).
14183  * HW Name: RFC 4108, 5 - Hardware Module Name
14184  * Only support HW Name where the type is a HW serial number.
14185  */
14186 static const ASNItem otherNameASN[] = {
14187 /* TYPEID   */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
14188 /* VALUE    */ { 0, ASN_CONTEXT_SPECIFIC | ASN_OTHERNAME_VALUE, 1, 0, 0 },
14189 /* HWN_SEQ  */     { 1, ASN_SEQUENCE, 1, 0, 0 },
14190 /* HWN_TYPE */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
14191 /* HWN_NUM  */         { 2, ASN_OCTET_STRING, 0, 0, 0 }
14192 };
14193 enum {
14194     OTHERNAMEASN_IDX_TYPEID = 0,
14195     OTHERNAMEASN_IDX_VALUE,
14196     OTHERNAMEASN_IDX_HWN_SEQ,
14197     OTHERNAMEASN_IDX_HWN_TYPE,
14198     OTHERNAMEASN_IDX_HWN_NUM,
14199 };
14200 
14201 /* Number of items in ASN.1 template for OtherName of an X.509 certificate. */
14202 #define otherNameASN_Length (sizeof(otherNameASN) / sizeof(ASNItem))
14203 
14204 /* Decode data with OtherName format from after implicit SEQUENCE.
14205  *
14206  * @param [in, out] cert      Certificate object.
14207  * @param [in]      input     Buffer containing encoded OtherName.
14208  * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
14209  *                            On out, index after OtherName.
14210  * @param [in]      maxIdx    Maximum index of data in buffer.
14211  * @return  0 on success.
14212  * @return  MEMORY_E on dynamic memory allocation failure.
14213  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14214  *          is invalid.
14215  * @return  ASN_PARSE_E when OID does is not HW Name.
14216  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
14217  * @return  BUFFER_E when data in buffer is too small.
14218  */
14219 static int DecodeOtherName(DecodedCert* cert, const byte* input,
14220                            word32* inOutIdx, word32 maxIdx)
14221 {
14222     DECL_ASNGETDATA(dataASN, otherNameASN_Length);
14223     int ret = 0;
14224     word32 oidLen, serialLen;
14225 
14226     CALLOC_ASNGETDATA(dataASN, otherNameASN_Length, ret, cert->heap);
14227 
14228     if (ret == 0) {
14229         /* Check the first OID is a recognized Alt Cert Name type. */
14230         GetASN_OID(&dataASN[OTHERNAMEASN_IDX_TYPEID], oidCertAltNameType);
14231         /* Only support HW serial number. */
14232         GetASN_OID(&dataASN[OTHERNAMEASN_IDX_HWN_TYPE], oidIgnoreType);
14233         /* Parse OtherName. */
14234         ret = GetASN_Items(otherNameASN, dataASN, otherNameASN_Length, 1, input,
14235                            inOutIdx, maxIdx);
14236     }
14237     if (ret == 0) {
14238         /* Ensure expected OID. */
14239         if (dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum != HW_NAME_OID) {
14240             WOLFSSL_MSG("\tunsupported OID");
14241             ret = ASN_PARSE_E;
14242         }
14243     }
14244 
14245     if (ret == 0) {
14246         oidLen = dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.length;
14247         serialLen = dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.length;
14248 
14249         /* Allocate space for HW type OID. */
14250         cert->hwType = (byte*)XMALLOC(oidLen, cert->heap,
14251                                       DYNAMIC_TYPE_X509_EXT);
14252         if (cert->hwType == NULL)
14253             ret = MEMORY_E;
14254     }
14255     if (ret == 0) {
14256         /* Copy, into cert HW type OID */
14257         XMEMCPY(cert->hwType,
14258                 dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.data, oidLen);
14259         cert->hwTypeSz = oidLen;
14260         /* TODO: check this is the HW serial number OID - no test data. */
14261 
14262         /* Allocate space for HW serial number. */
14263         cert->hwSerialNum = (byte*)XMALLOC(serialLen, cert->heap,
14264                                            DYNAMIC_TYPE_X509_EXT);
14265         if (cert->hwSerialNum == NULL) {
14266             WOLFSSL_MSG("\tOut of Memory");
14267             ret = MEMORY_E;
14268         }
14269     }
14270     if (ret == 0) {
14271         /* Copy into cert HW serial number. */
14272         XMEMCPY(cert->hwSerialNum,
14273                 dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.data, serialLen);
14274         cert->hwSerialNum[serialLen] = '\0';
14275         cert->hwSerialNumSz = serialLen;
14276     }
14277 
14278     FREE_ASNGETDATA(dataASN, cert->heap);
14279     return ret;
14280 }
14281 #endif /* WOLFSSL_SEP */
14282 
14283 /* Decode a GeneralName.
14284  *
14285  * @param [in]      input     Buffer containing encoded OtherName.
14286  * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
14287  *                            On out, index after OtherName.
14288  * @param [in]      len       Length of data in buffer.
14289  * @param [in]      cert      Decoded certificate object.
14290  * @return  0 on success.
14291  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14292  *          is invalid.
14293  * @return  BUFFER_E when data in buffer is too small.
14294  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
14295  * @return  MEMORY_E when dynamic memory allocation fails.
14296  */
14297 static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
14298                              int len, DecodedCert* cert)
14299 {
14300     int ret = 0;
14301     word32 idx = *inOutIdx;
14302 
14303     /* GeneralName choice: dnsName */
14304     if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
14305         ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_DNS_TYPE,
14306                 &cert->altNames);
14307         if (ret == 0) {
14308             idx += len;
14309         }
14310     }
14311 #ifndef IGNORE_NAME_CONSTRAINTS
14312     /* GeneralName choice: directoryName */
14313     else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
14314         int strLen;
14315         word32 idxDir = idx;
14316 
14317         /* Expecting a SEQUENCE using up all data. */
14318         if (GetASN_Sequence(input, &idxDir, &strLen, idx + len, 1) < 0) {
14319             WOLFSSL_MSG("\tfail: seq length");
14320             return ASN_PARSE_E;
14321         }
14322 
14323         ret = SetDNSEntry(cert, (const char*)(input + idxDir), strLen,
14324                 ASN_DIR_TYPE, &cert->altDirNames);
14325         if (ret == 0) {
14326             idx += len;
14327         }
14328     }
14329     /* GeneralName choice: rfc822Name */
14330     else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
14331         ret = SetDNSEntry(cert, (const char*)(input + idx), len,
14332                 ASN_RFC822_TYPE, &cert->altEmailNames);
14333         if (ret == 0) {
14334             idx += len;
14335         }
14336     }
14337     /* GeneralName choice: uniformResourceIdentifier */
14338     else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
14339         WOLFSSL_MSG("\tPutting URI into list but not using");
14340 
14341     #ifndef WOLFSSL_NO_ASN_STRICT
14342         /* Verify RFC 5280 Sec 4.2.1.6 rule:
14343             "The name MUST NOT be a relative URI" */
14344         {
14345             int i;
14346 
14347             /* skip past scheme (i.e http,ftp,...) finding first ':' char */
14348             for (i = 0; i < len; i++) {
14349                 if (input[idx + i] == ':') {
14350                     break;
14351                 }
14352                 if (input[idx + i] == '/') {
14353                     i = len; /* error, found relative path since '/' was
14354                               * encountered before ':'. Returning error
14355                               * value in next if statement. */
14356                 }
14357             }
14358 
14359             /* test if no ':' char was found and test that the next two
14360              * chars are "//" to match the pattern "://" */
14361             if (i >= len - 2 || (input[idx + i + 1] != '/' ||
14362                                  input[idx + i + 2] != '/')) {
14363                 WOLFSSL_MSG("\tAlt Name must be absolute URI");
14364                 return ASN_ALT_NAME_E;
14365             }
14366         }
14367     #endif
14368 
14369         ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_URI_TYPE,
14370                 &cert->altNames);
14371         if (ret == 0) {
14372             idx += len;
14373         }
14374     }
14375     #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
14376                                             defined(WOLFSSL_IP_ALT_NAME)
14377     /* GeneralName choice: iPAddress */
14378     else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
14379         ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_IP_TYPE,
14380                 &cert->altNames);
14381         if (ret == 0) {
14382             idx += len;
14383         }
14384     }
14385     #endif /* WOLFSSL_QT || OPENSSL_ALL */
14386 #endif /* IGNORE_NAME_CONSTRAINTS */
14387 #ifdef WOLFSSL_SEP
14388     /* GeneralName choice: otherName */
14389     else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
14390         /* TODO: test data for code path */
14391         ret = DecodeOtherName(cert, input, &idx, idx + len);
14392     }
14393 #endif
14394     /* GeneralName choice: dNSName, x400Address, ediPartyName,
14395      *                     registeredID */
14396     else {
14397         WOLFSSL_MSG("\tUnsupported name type, skipping");
14398         idx += len;
14399     }
14400 
14401     if (ret == 0) {
14402         /* Return index of next encoded byte. */
14403         *inOutIdx = idx;
14404     }
14405     return ret;
14406 }
14407 
14408 /* ASN.1 choices for GeneralName.
14409  * X.509: RFC 5280, 4.2.1.6 - GeneralName.
14410  */
14411 static const byte generalNameChoice[] = {
14412     ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
14413     ASN_CONTEXT_SPECIFIC                   | 1,
14414     ASN_CONTEXT_SPECIFIC                   | 2,
14415     ASN_CONTEXT_SPECIFIC                   | 3,
14416     ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 4,
14417     ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 5,
14418     ASN_CONTEXT_SPECIFIC                   | 6,
14419     ASN_CONTEXT_SPECIFIC                   | 7,
14420     ASN_CONTEXT_SPECIFIC                   | 8,
14421     0
14422 };
14423 
14424 /* ASN.1 template for GeneralName.
14425  * X.509: RFC 5280, 4.2.1.6 - GeneralName.
14426  */
14427 static const ASNItem altNameASN[] = {
14428     { 0, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 0 }
14429 };
14430 enum {
14431     ALTNAMEASN_IDX_GN = 0,
14432 };
14433 
14434 /* Number of items in ASN.1 template for GeneralName. */
14435 #define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
14436 #endif /* WOLFSSL_ASN_TEMPLATE */
14437 
14438 /* Decode subject alternative names extension.
14439  *
14440  * RFC 5280 4.2.1.6.  Subject Alternative Name
14441  *
14442  * @param [in]      input  Buffer holding encoded data.
14443  * @param [in]      sz     Size of encoded data in bytes.
14444  * @param [in, out] cert   Decoded certificate object.
14445  * @return  0 on success.
14446  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14447  *          is invalid.
14448  * @return  BUFFER_E when data in buffer is too small.
14449  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
14450  * @return  MEMORY_E when dynamic memory allocation fails.
14451  */
14452 static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
14453 {
14454 #ifndef WOLFSSL_ASN_TEMPLATE
14455     word32 idx = 0;
14456     int length = 0;
14457 
14458     WOLFSSL_ENTER("DecodeAltNames");
14459 
14460     if (GetSequence(input, &idx, &length, sz) < 0) {
14461         WOLFSSL_MSG("\tBad Sequence");
14462         return ASN_PARSE_E;
14463     }
14464 
14465     if (length == 0) {
14466         /* RFC 5280 4.2.1.6.  Subject Alternative Name
14467            If the subjectAltName extension is present, the sequence MUST
14468            contain at least one entry. */
14469         return ASN_PARSE_E;
14470     }
14471 
14472 #ifdef OPENSSL_ALL
14473     cert->extSubjAltNameSrc = input;
14474     cert->extSubjAltNameSz = sz;
14475 #endif
14476 
14477     cert->weOwnAltNames = 1;
14478 
14479     while (length > 0) {
14480         byte b = input[idx++];
14481 
14482         length--;
14483 
14484         /* Save DNS Type names in the altNames list. */
14485         /* Save Other Type names in the cert's OidMap */
14486         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
14487             DNS_entry* dnsEntry;
14488             int strLen;
14489             word32 lenStartIdx = idx;
14490 
14491             if (GetLength(input, &idx, &strLen, sz) < 0) {
14492                 WOLFSSL_MSG("\tfail: str length");
14493                 return ASN_PARSE_E;
14494             }
14495             length -= (idx - lenStartIdx);
14496 
14497             dnsEntry = AltNameNew(cert->heap);
14498             if (dnsEntry == NULL) {
14499                 WOLFSSL_MSG("\tOut of Memory");
14500                 return MEMORY_E;
14501             }
14502 
14503             dnsEntry->type = ASN_DNS_TYPE;
14504             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
14505                                          DYNAMIC_TYPE_ALTNAME);
14506             if (dnsEntry->name == NULL) {
14507                 WOLFSSL_MSG("\tOut of Memory");
14508                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
14509                 return MEMORY_E;
14510             }
14511             dnsEntry->len = strLen;
14512             XMEMCPY(dnsEntry->name, &input[idx], strLen);
14513             dnsEntry->name[strLen] = '\0';
14514 
14515             AddAltName(cert, dnsEntry);
14516 
14517             length -= strLen;
14518             idx    += strLen;
14519         }
14520     #ifndef IGNORE_NAME_CONSTRAINTS
14521         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
14522             DNS_entry* dirEntry;
14523             int strLen;
14524             word32 lenStartIdx = idx;
14525 
14526             if (GetLength(input, &idx, &strLen, sz) < 0) {
14527                 WOLFSSL_MSG("\tfail: str length");
14528                 return ASN_PARSE_E;
14529             }
14530 
14531             if (GetSequence(input, &idx, &strLen, sz) < 0) {
14532                 WOLFSSL_MSG("\tfail: seq length");
14533                 return ASN_PARSE_E;
14534             }
14535             length -= (idx - lenStartIdx);
14536 
14537             dirEntry = AltNameNew(cert->heap);
14538             if (dirEntry == NULL) {
14539                 WOLFSSL_MSG("\tOut of Memory");
14540                 return MEMORY_E;
14541             }
14542 
14543             dirEntry->type = ASN_DIR_TYPE;
14544             dirEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
14545                                          DYNAMIC_TYPE_ALTNAME);
14546             if (dirEntry->name == NULL) {
14547                 WOLFSSL_MSG("\tOut of Memory");
14548                 XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
14549                 return MEMORY_E;
14550             }
14551             dirEntry->len = strLen;
14552             XMEMCPY(dirEntry->name, &input[idx], strLen);
14553             dirEntry->name[strLen] = '\0';
14554 
14555             dirEntry->next = cert->altDirNames;
14556             cert->altDirNames = dirEntry;
14557 
14558             length -= strLen;
14559             idx    += strLen;
14560         }
14561         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
14562             DNS_entry* emailEntry;
14563             int strLen;
14564             word32 lenStartIdx = idx;
14565 
14566             if (GetLength(input, &idx, &strLen, sz) < 0) {
14567                 WOLFSSL_MSG("\tfail: str length");
14568                 return ASN_PARSE_E;
14569             }
14570             length -= (idx - lenStartIdx);
14571 
14572             emailEntry = AltNameNew(cert->heap);
14573             if (emailEntry == NULL) {
14574                 WOLFSSL_MSG("\tOut of Memory");
14575                 return MEMORY_E;
14576             }
14577 
14578             emailEntry->type = ASN_RFC822_TYPE;
14579             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
14580                                          DYNAMIC_TYPE_ALTNAME);
14581             if (emailEntry->name == NULL) {
14582                 WOLFSSL_MSG("\tOut of Memory");
14583                 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
14584                 return MEMORY_E;
14585             }
14586             emailEntry->len = strLen;
14587             XMEMCPY(emailEntry->name, &input[idx], strLen);
14588             emailEntry->name[strLen] = '\0';
14589 
14590             emailEntry->next = cert->altEmailNames;
14591             cert->altEmailNames = emailEntry;
14592 
14593             length -= strLen;
14594             idx    += strLen;
14595         }
14596         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
14597             DNS_entry* uriEntry;
14598             int strLen;
14599             word32 lenStartIdx = idx;
14600 
14601             WOLFSSL_MSG("\tPutting URI into list but not using");
14602             if (GetLength(input, &idx, &strLen, sz) < 0) {
14603                 WOLFSSL_MSG("\tfail: str length");
14604                 return ASN_PARSE_E;
14605             }
14606             length -= (idx - lenStartIdx);
14607 
14608             /* check that strLen at index is not past input buffer */
14609             if (strLen + (int)idx > sz) {
14610                 return BUFFER_E;
14611             }
14612 
14613         #ifndef WOLFSSL_NO_ASN_STRICT
14614             /* Verify RFC 5280 Sec 4.2.1.6 rule:
14615                 "The name MUST NOT be a relative URI" */
14616 
14617             {
14618                 int i;
14619 
14620                 /* skip past scheme (i.e http,ftp,...) finding first ':' char */
14621                 for (i = 0; i < strLen; i++) {
14622                     if (input[idx + i] == ':') {
14623                         break;
14624                     }
14625                     if (input[idx + i] == '/') {
14626                         WOLFSSL_MSG("\tAlt Name must be absolute URI");
14627                         return ASN_ALT_NAME_E;
14628                     }
14629                 }
14630 
14631                 /* test if no ':' char was found and test that the next two
14632                  * chars are "//" to match the pattern "://" */
14633                 if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
14634                                         input[idx + i + 2] != '/')) {
14635                     WOLFSSL_MSG("\tAlt Name must be absolute URI");
14636                     return ASN_ALT_NAME_E;
14637                 }
14638             }
14639         #endif
14640 
14641             uriEntry = AltNameNew(cert->heap);
14642             if (uriEntry == NULL) {
14643                 WOLFSSL_MSG("\tOut of Memory");
14644                 return MEMORY_E;
14645             }
14646 
14647             uriEntry->type = ASN_URI_TYPE;
14648             uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
14649                                          DYNAMIC_TYPE_ALTNAME);
14650             if (uriEntry->name == NULL) {
14651                 WOLFSSL_MSG("\tOut of Memory");
14652                 XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
14653                 return MEMORY_E;
14654             }
14655             uriEntry->len = strLen;
14656             XMEMCPY(uriEntry->name, &input[idx], strLen);
14657             uriEntry->name[strLen] = '\0';
14658 
14659             AddAltName(cert, uriEntry);
14660 
14661             length -= strLen;
14662             idx    += strLen;
14663         }
14664 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
14665         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
14666             DNS_entry* ipAddr;
14667             int strLen;
14668             word32 lenStartIdx = idx;
14669             WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
14670 
14671             if (GetLength(input, &idx, &strLen, sz) < 0) {
14672                 WOLFSSL_MSG("\tfail: str length");
14673                 return ASN_PARSE_E;
14674             }
14675             length -= (idx - lenStartIdx);
14676             /* check that strLen at index is not past input buffer */
14677             if (strLen + (int)idx > sz) {
14678                 return BUFFER_E;
14679             }
14680 
14681             ipAddr = AltNameNew(cert->heap);
14682             if (ipAddr == NULL) {
14683                 WOLFSSL_MSG("\tOut of Memory");
14684                 return MEMORY_E;
14685             }
14686 
14687             ipAddr->type = ASN_IP_TYPE;
14688             ipAddr->name = (char*)XMALLOC(strLen + 1, cert->heap,
14689                                          DYNAMIC_TYPE_ALTNAME);
14690             if (ipAddr->name == NULL) {
14691                 WOLFSSL_MSG("\tOut of Memory");
14692                 XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
14693                 return MEMORY_E;
14694             }
14695             ipAddr->len = strLen;
14696             XMEMCPY(ipAddr->name, &input[idx], strLen);
14697             ipAddr->name[strLen] = '\0';
14698 
14699         #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
14700             if (GenerateDNSEntryIPString(ipAddr, cert->heap) != 0) {
14701                 WOLFSSL_MSG("\tOut of Memory for IP string");
14702                 XFREE(ipAddr->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
14703                 XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
14704                 return MEMORY_E;
14705             }
14706         #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
14707             AddAltName(cert, ipAddr);
14708 
14709             length -= strLen;
14710             idx    += strLen;
14711         }
14712 #endif /* WOLFSSL_QT || OPENSSL_ALL */
14713 #endif /* IGNORE_NAME_CONSTRAINTS */
14714 #ifdef WOLFSSL_SEP
14715         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
14716         {
14717             int strLen;
14718             word32 lenStartIdx = idx;
14719             word32 oid = 0;
14720             int    ret;
14721             byte   tag;
14722 
14723             if (GetLength(input, &idx, &strLen, sz) < 0) {
14724                 WOLFSSL_MSG("\tfail: other name length");
14725                 return ASN_PARSE_E;
14726             }
14727             /* Consume the rest of this sequence. */
14728             length -= (strLen + idx - lenStartIdx);
14729 
14730             if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
14731                 WOLFSSL_MSG("\tbad OID");
14732                 return ASN_PARSE_E;
14733             }
14734 
14735             if (oid != HW_NAME_OID) {
14736                 WOLFSSL_MSG("\tincorrect OID");
14737                 return ASN_PARSE_E;
14738             }
14739 
14740             /* Certificates issued with this OID in the subject alt name are for
14741              * verifying signatures created on a module.
14742              * RFC 4108 Section 5. */
14743             if (cert->hwType != NULL) {
14744                 WOLFSSL_MSG("\tAlready seen Hardware Module Name");
14745                 return ASN_PARSE_E;
14746             }
14747 
14748             if (GetASNTag(input, &idx, &tag, sz) < 0) {
14749                 return ASN_PARSE_E;
14750             }
14751 
14752             if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
14753                 WOLFSSL_MSG("\twrong type");
14754                 return ASN_PARSE_E;
14755             }
14756 
14757             if (GetLength(input, &idx, &strLen, sz) < 0) {
14758                 WOLFSSL_MSG("\tfail: str len");
14759                 return ASN_PARSE_E;
14760             }
14761 
14762             if (GetSequence(input, &idx, &strLen, sz) < 0) {
14763                 WOLFSSL_MSG("\tBad Sequence");
14764                 return ASN_PARSE_E;
14765             }
14766 
14767             ret = GetASNObjectId(input, &idx, &strLen, sz);
14768             if (ret != 0) {
14769                 WOLFSSL_MSG("\tbad OID");
14770                 return ret;
14771             }
14772 
14773             cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
14774                                           DYNAMIC_TYPE_X509_EXT);
14775             if (cert->hwType == NULL) {
14776                 WOLFSSL_MSG("\tOut of Memory");
14777                 return MEMORY_E;
14778             }
14779 
14780             XMEMCPY(cert->hwType, &input[idx], strLen);
14781             cert->hwTypeSz = strLen;
14782             idx += strLen;
14783 
14784             ret = GetOctetString(input, &idx, &strLen, sz);
14785             if (ret < 0)
14786                 return ret;
14787 
14788             cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
14789                                                DYNAMIC_TYPE_X509_EXT);
14790             if (cert->hwSerialNum == NULL) {
14791                 WOLFSSL_MSG("\tOut of Memory");
14792                 return MEMORY_E;
14793             }
14794 
14795             XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
14796             cert->hwSerialNum[strLen] = '\0';
14797             cert->hwSerialNumSz = strLen;
14798             idx += strLen;
14799         }
14800     #endif /* WOLFSSL_SEP */
14801         else {
14802             int strLen;
14803             word32 lenStartIdx = idx;
14804 
14805             WOLFSSL_MSG("\tUnsupported name type, skipping");
14806 
14807             if (GetLength(input, &idx, &strLen, sz) < 0) {
14808                 WOLFSSL_MSG("\tfail: unsupported name length");
14809                 return ASN_PARSE_E;
14810             }
14811             length -= (strLen + idx - lenStartIdx);
14812             idx += strLen;
14813         }
14814     }
14815 
14816     return 0;
14817 #else
14818     word32 idx = 0;
14819     int length = 0;
14820     int ret = 0;
14821 
14822     WOLFSSL_ENTER("DecodeAltNames");
14823 
14824     /* Get SEQUENCE and expect all data to be accounted for. */
14825     if (GetASN_Sequence(input, &idx, &length, sz, 1) != 0) {
14826         WOLFSSL_MSG("\tBad Sequence");
14827         ret = ASN_PARSE_E;
14828     }
14829 
14830     if ((ret == 0) && (length == 0)) {
14831         /* RFC 5280 4.2.1.6.  Subject Alternative Name
14832            If the subjectAltName extension is present, the sequence MUST
14833            contain at least one entry. */
14834         ret = ASN_PARSE_E;
14835     }
14836     if (ret == 0) {
14837     #ifdef OPENSSL_ALL
14838         cert->extSubjAltNameSrc = input;
14839         cert->extSubjAltNameSz = sz;
14840     #endif
14841 
14842         cert->weOwnAltNames = 1;
14843 
14844         if (length + (int)idx != sz) {
14845             ret = ASN_PARSE_E;
14846         }
14847     }
14848 
14849     while ((ret == 0) && ((int)idx < sz)) {
14850         ASNGetData dataASN[altNameASN_Length];
14851 
14852         /* Clear dynamic data items. */
14853         XMEMSET(dataASN, 0, sizeof(dataASN));
14854         /* Parse GeneralName with the choices supported. */
14855         GetASN_Choice(&dataASN[ALTNAMEASN_IDX_GN], generalNameChoice);
14856         /* Decode a GeneralName choice. */
14857         ret = GetASN_Items(altNameASN, dataASN, altNameASN_Length, 0, input,
14858                            &idx, sz);
14859         if (ret == 0) {
14860             ret = DecodeGeneralName(input, &idx, dataASN[ALTNAMEASN_IDX_GN].tag,
14861                 dataASN[ALTNAMEASN_IDX_GN].length, cert);
14862         }
14863     }
14864 
14865     return ret;
14866 #endif
14867 }
14868 
14869 #ifdef WOLFSSL_ASN_TEMPLATE
14870 /* ASN.1 template for BasicContraints.
14871  * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
14872  */
14873 static const ASNItem basicConsASN[] = {
14874 /* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
14875 /* CA   */     { 1, ASN_BOOLEAN, 0, 0, 1 },
14876 /* PLEN */     { 1, ASN_INTEGER, 0, 0, 1 }
14877 };
14878 enum {
14879     BASICCONSASN_IDX_SEQ = 0,
14880     BASICCONSASN_IDX_CA,
14881     BASICCONSASN_IDX_PLEN,
14882 };
14883 
14884 /* Number of items in ASN.1 template for BasicContraints. */
14885 #define basicConsASN_Length (sizeof(basicConsASN) / sizeof(ASNItem))
14886 #endif
14887 
14888 /* Decode basic constraints extension in a certificate.
14889  *
14890  * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
14891  *
14892  * @param [in]      input  Buffer holding data.
14893  * @param [in]      sz     Size of data in buffer.
14894  * @param [in, out] cert   Certificate object.
14895  * @return  0 on success.
14896  * @return  MEMORY_E on dynamic memory allocation failure.
14897  * @return  ASN_PARSE_E when CA boolean is present and false (default is false).
14898  * @return  ASN_PARSE_E when CA boolean is not present unless
14899  *          WOLFSSL_X509_BASICCONS_INT is defined. Only a CA extension.
14900  * @return  ASN_PARSE_E when path length more than 7 bits.
14901  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14902  *          is invalid.
14903  * @return  BUFFER_E when data in buffer is too small.
14904  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
14905  *          non-zero length.
14906  */
14907 static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
14908 {
14909 #ifndef WOLFSSL_ASN_TEMPLATE
14910     word32 idx = 0;
14911     int length = 0;
14912     int ret;
14913 
14914     WOLFSSL_ENTER("DecodeBasicCaConstraint");
14915 
14916     if (GetSequence(input, &idx, &length, sz) < 0) {
14917         WOLFSSL_MSG("\tfail: bad SEQUENCE");
14918         return ASN_PARSE_E;
14919     }
14920 
14921     if (length == 0)
14922         return 0;
14923 
14924     /* If the basic ca constraint is false, this extension may be named, but
14925      * left empty. So, if the length is 0, just return. */
14926 
14927     ret = GetBoolean(input, &idx, sz);
14928 
14929     /* Removed logic for WOLFSSL_X509_BASICCONS_INT which was mistreating the
14930      * pathlen value as if it were the CA Boolean value 7/2/2021 - KH.
14931      * When CA Boolean not asserted use the default value "False" */
14932     if (ret < 0) {
14933         WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN, set default FALSE");
14934         ret = 0;
14935     }
14936 
14937     cert->isCA = (byte)ret;
14938 
14939     /* If there isn't any more data, return. */
14940     if (idx >= (word32)sz) {
14941         return 0;
14942     }
14943 
14944     ret = GetInteger7Bit(input, &idx, sz);
14945     if (ret < 0)
14946         return ret;
14947     cert->pathLength = (byte)ret;
14948     cert->pathLengthSet = 1;
14949 
14950     return 0;
14951 #else
14952     DECL_ASNGETDATA(dataASN, basicConsASN_Length);
14953     int ret = 0;
14954     word32 idx = 0;
14955     byte isCA = 0;
14956 
14957     WOLFSSL_ENTER("DecodeBasicCaConstraints");
14958 
14959     CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, cert->heap);
14960 
14961     if (ret == 0) {
14962         /* Get the CA boolean and path length when present. */
14963         GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
14964         GetASN_Int8Bit(&dataASN[BASICCONSASN_IDX_PLEN], &cert->pathLength);
14965 
14966         ret = GetASN_Items(basicConsASN, dataASN, basicConsASN_Length, 1, input,
14967                            &idx, sz);
14968     }
14969 
14970     /* Empty SEQUENCE is OK - nothing to store. */
14971     if ((ret == 0) && (dataASN[BASICCONSASN_IDX_SEQ].length != 0)) {
14972         /* Bad encoding when CA Boolean is false
14973          * (default when not present). */
14974         if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
14975             ret = ASN_PARSE_E;
14976         }
14977         /* Path length must be a 7-bit value. */
14978         if ((ret == 0) && (cert->pathLength >= (1 << 7))) {
14979             ret = ASN_PARSE_E;
14980         }
14981         /* Store CA boolean and whether a path length was seen. */
14982         if (ret == 0) {
14983             /* isCA in certificate is a 1 bit of a byte. */
14984             cert->isCA = isCA;
14985             cert->pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
14986         }
14987     }
14988 
14989     FREE_ASNGETDATA(dataASN, cert->heap);
14990     return ret;
14991 #endif
14992 }
14993 
14994 
14995 static int DecodePolicyConstraints(const byte* input, int sz, DecodedCert* cert)
14996 {
14997     word32 idx = 0;
14998     int length = 0;
14999     int skipLength = 0;
15000     int ret;
15001     byte tag;
15002 
15003     WOLFSSL_ENTER("DecodePolicyConstraints");
15004 
15005     if (GetSequence(input, &idx, &length, sz) < 0) {
15006         WOLFSSL_MSG("\tfail: bad SEQUENCE");
15007         return ASN_PARSE_E;
15008     }
15009 
15010     if (length == 0)
15011         return ASN_PARSE_E;
15012 
15013     if (GetASNTag(input, &idx, &tag, sz) < 0) {
15014         WOLFSSL_MSG("\tfail: bad TAG");
15015         return ASN_PARSE_E;
15016     }
15017 
15018     if (tag == (ASN_CONTEXT_SPECIFIC | 0)) {
15019         /* requireExplicitPolicy */
15020         cert->extPolicyConstRxpSet = 1;
15021     }
15022     else if (tag == (ASN_CONTEXT_SPECIFIC | 1)) {
15023         /* inhibitPolicyMapping */
15024         cert->extPolicyConstIpmSet = 1;
15025     }
15026     else {
15027         WOLFSSL_MSG("\tfail: invalid TAG");
15028         return ASN_PARSE_E;
15029     }
15030 
15031     ret = GetLength(input, &idx, &skipLength, sz);
15032     if (ret < 0) {
15033         WOLFSSL_MSG("\tfail: invalid length");
15034         return ret;
15035     }
15036     if (skipLength > 1) {
15037         WOLFSSL_MSG("\tfail: skip value too big");
15038         return BUFFER_E;
15039     }
15040     if (idx >= (word32)sz) {
15041         WOLFSSL_MSG("\tfail: no policy const skip to read");
15042         return BUFFER_E;
15043     }
15044     cert->policyConstSkip = input[idx];
15045 
15046     return 0;
15047 }
15048 
15049 
15050 /* Context-Specific value for: DistributionPoint.distributionPoint
15051  * From RFC5280 SS4.2.1.13, Distribution Point */
15052 #define DISTRIBUTION_POINT  (ASN_CONTEXT_SPECIFIC | 0)
15053 /* Context-Specific value for: DistributionPoint.DistributionPointName.fullName
15054  *  From RFC3280 SS4.2.1.13, Distribution Point Name */
15055 #define CRLDP_FULL_NAME     (ASN_CONTEXT_SPECIFIC | 0)
15056 /* Context-Specific value for choice: GeneralName.uniformResourceIdentifier
15057  * From RFC3280 SS4.2.1.7, GeneralName */
15058 #define GENERALNAME_URI     (ASN_CONTEXT_SPECIFIC | 6)
15059 
15060 #ifdef WOLFSSL_ASN_TEMPLATE
15061 /* ASN.1 template for CRL distribution points.
15062  * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
15063  */
15064 static const ASNItem crlDistASN[] = {
15065 /* SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
15066 /* DP_SEQ             */     { 1, ASN_SEQUENCE, 1, 1, 0 },
15067                                                 /* Distribution point name */
15068 /* DP_DISTPOINT       */         { 2, DISTRIBUTION_POINT, 1, 1, 1 },
15069                                                     /* fullName */
15070 /* DP_DISTPOINT_FN    */             { 3, CRLDP_FULL_NAME, 1, 1, 2 },
15071 /* DP_DISTPOINT_FN_GN */                 { 4, GENERALNAME_URI, 0, 0, 0 },
15072                                                     /* nameRelativeToCRLIssuer */
15073 /* DP_DISTPOINT_RN    */             { 3, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
15074                                                 /* reasons: IMPLICIT BIT STRING */
15075 /* DP_REASONS         */         { 2, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
15076                                                 /* cRLIssuer */
15077 /* DP_CRLISSUER       */         { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 1 },
15078 };
15079 enum {
15080     CRLDISTASN_IDX_SEQ = 0,
15081     CRLDISTASN_IDX_DP_SEQ,
15082     CRLDISTASN_IDX_DP_DISTPOINT,
15083     CRLDISTASN_IDX_DP_DISTPOINT_FN,
15084     CRLDISTASN_IDX_DP_DISTPOINT_FN_GN,
15085     CRLDISTASN_IDX_DP_DISTPOINT_RN, /* Relative name */
15086     CRLDISTASN_IDX_DP_REASONS,
15087     CRLDISTASN_IDX_DP_CRLISSUER,
15088 };
15089 
15090 /* Number of items in ASN.1 template for CRL distribution points. */
15091 #define crlDistASN_Length (sizeof(crlDistASN) / sizeof(ASNItem))
15092 #endif
15093 
15094 /* Decode CRL distribution point extension in a certificate.
15095  *
15096  * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
15097  *
15098  * @param [in]      input  Buffer holding data.
15099  * @param [in]      sz     Size of data in buffer.
15100  * @param [in, out] cert   Certificate object.
15101  * @return  0 on success.
15102  * @return  MEMORY_E on dynamic memory allocation failure.
15103  * @return  ASN_PARSE_E when invalid bits of reason are set.
15104  * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
15105  * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
15106  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15107  *          is invalid.
15108  * @return  BUFFER_E when data in buffer is too small.
15109  */
15110 static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
15111 {
15112 #ifndef WOLFSSL_ASN_TEMPLATE
15113     word32 idx = 0, localIdx;
15114     int length = 0;
15115     byte tag   = 0;
15116 
15117     WOLFSSL_ENTER("DecodeCrlDist");
15118 
15119     cert->extCrlInfoRaw = input;
15120     cert->extCrlInfoRawSz = sz;
15121 
15122     /* Unwrap the list of Distribution Points*/
15123     if (GetSequence(input, &idx, &length, sz) < 0)
15124         return ASN_PARSE_E;
15125 
15126     /* Unwrap a single Distribution Point */
15127     if (GetSequence(input, &idx, &length, sz) < 0)
15128         return ASN_PARSE_E;
15129 
15130     /* The Distribution Point has three explicit optional members
15131      *  First check for a DistributionPointName
15132      */
15133     localIdx = idx;
15134     if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
15135             tag == (ASN_CONSTRUCTED | DISTRIBUTION_POINT))
15136     {
15137         idx++;
15138         if (GetLength(input, &idx, &length, sz) < 0)
15139             return ASN_PARSE_E;
15140 
15141         localIdx = idx;
15142         if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
15143                 tag == (ASN_CONSTRUCTED | CRLDP_FULL_NAME))
15144         {
15145             idx++;
15146             if (GetLength(input, &idx, &length, sz) < 0)
15147                 return ASN_PARSE_E;
15148 
15149             localIdx = idx;
15150             if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
15151                     tag == GENERALNAME_URI)
15152             {
15153                 idx++;
15154                 if (GetLength(input, &idx, &length, sz) < 0)
15155                     return ASN_PARSE_E;
15156 
15157                 cert->extCrlInfoSz = length;
15158                 cert->extCrlInfo = input + idx;
15159                 idx += length;
15160             }
15161             else
15162                 /* This isn't a URI, skip it. */
15163                 idx += length;
15164         }
15165         else {
15166             /* This isn't a FULLNAME, skip it. */
15167             idx += length;
15168         }
15169     }
15170 
15171     /* Check for reasonFlags */
15172     localIdx = idx;
15173     if (idx < (word32)sz &&
15174         GetASNTag(input, &localIdx, &tag, sz) == 0 &&
15175         tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
15176     {
15177         idx++;
15178         if (GetLength(input, &idx, &length, sz) < 0)
15179             return ASN_PARSE_E;
15180         idx += length;
15181     }
15182 
15183     /* Check for cRLIssuer */
15184     localIdx = idx;
15185     if (idx < (word32)sz &&
15186         GetASNTag(input, &localIdx, &tag, sz) == 0 &&
15187         tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
15188     {
15189         idx++;
15190         if (GetLength(input, &idx, &length, sz) < 0)
15191             return ASN_PARSE_E;
15192         idx += length;
15193     }
15194 
15195     if (idx < (word32)sz)
15196     {
15197         WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
15198                    "but we only use the first one.");
15199     }
15200 
15201     return 0;
15202 #else
15203     DECL_ASNGETDATA(dataASN, crlDistASN_Length);
15204     word32 idx = 0;
15205     int ret = 0;
15206 #ifdef CRLDP_VALIDATE_DATA
15207     word16 reason;
15208 #endif
15209 
15210     WOLFSSL_ENTER("DecodeCrlDist");
15211 
15212     CALLOC_ASNGETDATA(dataASN, crlDistASN_Length, ret, cert->heap);
15213 
15214     cert->extCrlInfoRaw = input;
15215     cert->extCrlInfoRawSz = sz;
15216 
15217     if  (ret == 0) {
15218         /* Get the GeneralName choice */
15219         GetASN_Choice(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN], generalNameChoice);
15220         /* Parse CRL distribtion point. */
15221         ret = GetASN_Items(crlDistASN, dataASN, crlDistASN_Length, 0, input,
15222                            &idx, sz);
15223     }
15224     if (ret == 0) {
15225         /* If the choice was a URI, store it in certificate. */
15226         if (dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN].tag == GENERALNAME_URI) {
15227             word32 sz32;
15228             GetASN_GetConstRef(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN],
15229                     &cert->extCrlInfo, &sz32);
15230             cert->extCrlInfoSz = sz32;
15231         }
15232 
15233     #ifdef CRLDP_VALIDATE_DATA
15234         if (dataASN[CRLDISTASN_IDX_DP_REASONS].data.ref.data != NULL) {
15235              /* TODO: test case */
15236              /* Validate ReasonFlags. */
15237              ret = GetASN_BitString_Int16Bit(&dataASN[CRLDISTASN_IDX_DP_REASONS],
15238                      &reason);
15239              /* First bit (LSB) unused and eight other bits defined. */
15240              if ((ret == 0) && ((reason >> 9) || (reason & 0x01))) {
15241                 ret = ASN_PARSE_E;
15242              }
15243         }
15244     #endif
15245     }
15246 
15247     /* Only parsing the first one. */
15248     if (ret == 0 && idx < (word32)sz) {
15249         WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
15250                     "but we only use the first one.");
15251     }
15252     /* TODO: validate other points. */
15253 
15254     FREE_ASNGETDATA(dataASN, cert->heap);
15255     return ret;
15256 #endif /* WOLFSSL_ASN_TEMPLATE */
15257 }
15258 
15259 #ifdef WOLFSSL_ASN_TEMPLATE
15260 /* ASN.1 template for the access description.
15261  * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
15262  */
15263 static const ASNItem accessDescASN[] = {
15264 /* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
15265                                  /* accessMethod */
15266 /* METH */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
15267                                  /* accessLocation: GeneralName */
15268 /* LOC  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
15269 };
15270 enum {
15271     ACCESSDESCASN_IDX_SEQ = 0,
15272     ACCESSDESCASN_IDX_METH,
15273     ACCESSDESCASN_IDX_LOC,
15274 };
15275 
15276 /* Number of items in ASN.1 template for the access description. */
15277 #define accessDescASN_Length (sizeof(accessDescASN) / sizeof(ASNItem))
15278 #endif
15279 
15280 /* Decode authority information access extension in a certificate.
15281  *
15282  * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
15283  *
15284  * @param [in]      input  Buffer holding data.
15285  * @param [in]      sz     Size of data in buffer.
15286  * @param [in, out] cert   Certificate object.
15287  * @return  0 on success.
15288  * @return  MEMORY_E on dynamic memory allocation failure.
15289  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15290  *          is invalid.
15291  * @return  BUFFER_E when data in buffer is too small.
15292  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
15293  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
15294  */
15295 static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
15296 {
15297 #ifndef WOLFSSL_ASN_TEMPLATE
15298     word32 idx = 0;
15299     int length = 0;
15300     int count  = 0;
15301     byte b = 0;
15302     word32 oid;
15303 
15304     WOLFSSL_ENTER("DecodeAuthInfo");
15305 
15306     /* Unwrap the list of AIAs */
15307     if (GetSequence(input, &idx, &length, sz) < 0)
15308         return ASN_PARSE_E;
15309 
15310     while ((idx < (word32)sz) && (count < MAX_AIA_SZ)) {
15311         /* Unwrap a single AIA */
15312         if (GetSequence(input, &idx, &length, sz) < 0)
15313             return ASN_PARSE_E;
15314 
15315         oid = 0;
15316         if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0) {
15317             return ASN_PARSE_E;
15318         }
15319 
15320         /* Only supporting URIs right now. */
15321         if (GetASNTag(input, &idx, &b, sz) < 0)
15322             return ASN_PARSE_E;
15323 
15324         if (GetLength(input, &idx, &length, sz) < 0)
15325             return ASN_PARSE_E;
15326 
15327         /* Set ocsp entry */
15328         if (b == GENERALNAME_URI && oid == AIA_OCSP_OID)
15329         {
15330             cert->extAuthInfoSz = length;
15331             cert->extAuthInfo = input + idx;
15332         #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
15333             count++;
15334         #else
15335             break;
15336         #endif
15337         }
15338         #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
15339         /* Set CaIssuers entry */
15340         else if ((b == GENERALNAME_URI) && oid == AIA_CA_ISSUER_OID)
15341         {
15342             cert->extAuthInfoCaIssuerSz = length;
15343             cert->extAuthInfoCaIssuer = input + idx;
15344             count++;
15345         }
15346         #endif
15347         idx += length;
15348     }
15349 
15350     return 0;
15351 #else
15352     word32 idx = 0;
15353     int length = 0;
15354     int count  = 0;
15355     int ret    = 0;
15356 
15357     WOLFSSL_ENTER("DecodeAuthInfo");
15358 
15359     /* Unwrap the list of AIAs */
15360     if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
15361         ret = ASN_PARSE_E;
15362     }
15363 
15364     while ((ret == 0) && (idx < (word32)sz) && (count < MAX_AIA_SZ)) {
15365         ASNGetData dataASN[accessDescASN_Length];
15366         word32 sz32;
15367 
15368         /* Clear dynamic data and retrieve OID and name. */
15369         XMEMSET(dataASN, 0, sizeof(dataASN));
15370         GetASN_OID(&dataASN[ACCESSDESCASN_IDX_METH], oidCertAuthInfoType);
15371         GetASN_Choice(&dataASN[ACCESSDESCASN_IDX_LOC], generalNameChoice);
15372         /* Parse AccessDescription. */
15373         ret = GetASN_Items(accessDescASN, dataASN, accessDescASN_Length, 0,
15374                            input, &idx, sz);
15375         if (ret == 0) {
15376             /* Check we have OCSP and URI. */
15377             if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum == AIA_OCSP_OID) &&
15378                     (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
15379                 /* Store URI for OCSP lookup. */
15380                 GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
15381                         &cert->extAuthInfo, &sz32);
15382                 cert->extAuthInfoSz = sz32;
15383                 count++;
15384             #if !defined(OPENSSL_ALL) || !defined(WOLFSSL_QT)
15385                 break;
15386             #endif
15387             }
15388             #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
15389             /* Check we have CA Issuer and URI. */
15390             else if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum ==
15391                         AIA_CA_ISSUER_OID) &&
15392                     (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
15393                 /* Set CaIssuers entry */
15394                 GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
15395                         &cert->extAuthInfoCaIssuer, &sz32);
15396                 cert->extAuthInfoCaIssuerSz = sz32;
15397                 count++;
15398             }
15399             #endif
15400             /* Otherwise skip. */
15401         }
15402     }
15403 
15404     return ret;
15405 #endif
15406 }
15407 
15408 
15409 #ifdef WOLFSSL_ASN_TEMPLATE
15410 /* ASN.1 template for AuthorityKeyIdentifier.
15411  * X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
15412  */
15413 static const ASNItem authKeyIdASN[] = {
15414 /* SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
15415                                      /* keyIdentifier */
15416 /* KEYID  */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_KEYID, 0, 0, 1 },
15417                                      /* authorityCertIssuer */
15418 /* ISSUER */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_ISSUER, 1, 0, 1 },
15419                                      /* authorityCertSerialNumber */
15420 /* SERIAL */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_SERIAL, 0, 0, 1 },
15421 };
15422 enum {
15423     AUTHKEYIDASN_IDX_SEQ = 0,
15424     AUTHKEYIDASN_IDX_KEYID,
15425     AUTHKEYIDASN_IDX_ISSUER,
15426     AUTHKEYIDASN_IDX_SERIAL,
15427 };
15428 
15429 /* Number of items in ASN.1 template for AuthorityKeyIdentifier. */
15430 #define authKeyIdASN_Length (sizeof(authKeyIdASN) / sizeof(ASNItem))
15431 #endif
15432 
15433 /* Decode authority information access extension in a certificate.
15434  *
15435  * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
15436  *
15437  * @param [in]      input  Buffer holding data.
15438  * @param [in]      sz     Size of data in buffer.
15439  * @param [in, out] cert   Certificate object.
15440  * @return  0 on success.
15441  * @return  MEMORY_E on dynamic memory allocation failure.
15442  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15443  *          is invalid.
15444  * @return  BUFFER_E when data in buffer is too small.
15445  */
15446 static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
15447 {
15448 #ifndef WOLFSSL_ASN_TEMPLATE
15449     word32 idx = 0;
15450     int length = 0;
15451     byte tag;
15452 
15453     WOLFSSL_ENTER("DecodeAuthKeyId");
15454 
15455     if (GetSequence(input, &idx, &length, sz) < 0) {
15456         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
15457         return ASN_PARSE_E;
15458     }
15459 
15460     if (GetASNTag(input, &idx, &tag, sz) < 0) {
15461         return ASN_PARSE_E;
15462     }
15463 
15464     if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
15465         WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
15466         cert->extAuthKeyIdSet = 0;
15467         return 0;
15468     }
15469 
15470     if (GetLength(input, &idx, &length, sz) <= 0) {
15471         WOLFSSL_MSG("\tfail: extension data length");
15472         return ASN_PARSE_E;
15473     }
15474 
15475 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15476 #ifdef WOLFSSL_AKID_NAME
15477     cert->extRawAuthKeyIdSrc = input;
15478     cert->extRawAuthKeyIdSz = sz;
15479 #endif
15480     cert->extAuthKeyIdSrc = &input[idx];
15481     cert->extAuthKeyIdSz = length;
15482 #endif /* OPENSSL_EXTRA */
15483 
15484     return GetHashId(input + idx, length, cert->extAuthKeyId);
15485 #else
15486     DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
15487     int ret = 0;
15488     word32 idx = 0;
15489 
15490     WOLFSSL_ENTER("DecodeAuthKeyId");
15491 
15492     CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, cert->heap);
15493 
15494     if (ret == 0) {
15495         /* Parse an authority key identifier. */
15496         ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
15497                            &idx, sz);
15498     }
15499     if (ret == 0) {
15500         /* Key id is optional. */
15501         if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
15502             WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
15503         }
15504         else {
15505 #ifdef OPENSSL_EXTRA
15506             /* Store the authority key id. */
15507 #ifdef WOLFSSL_AKID_NAME
15508             cert->extRawAuthKeyIdSrc = input;
15509             cert->extRawAuthKeyIdSz = sz;
15510 #endif
15511             GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID], &cert->extAuthKeyIdSrc,
15512                                &cert->extAuthKeyIdSz);
15513 #endif /* OPENSSL_EXTRA */
15514 
15515             /* Get the hash or hash of the hash if wrong size. */
15516             ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
15517                         dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
15518                         cert->extAuthKeyId);
15519         }
15520     }
15521 
15522     FREE_ASNGETDATA(dataASN, cert->heap);
15523     return ret;
15524 #endif /* WOLFSSL_ASN_TEMPLATE */
15525 }
15526 
15527 /* Decode subject key id extension in a certificate.
15528  *
15529  * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
15530  *
15531  * @param [in]      input  Buffer holding data.
15532  * @param [in]      sz     Size of data in buffer.
15533  * @param [in, out] cert   Certificate object.
15534  * @return  0 on success.
15535  * @return  ASN_PARSE_E when the OCTET_STRING tag is not found or length is
15536  *          invalid.
15537  * @return  MEMORY_E on dynamic memory allocation failure.
15538  */
15539 static int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)
15540 {
15541     word32 idx = 0;
15542     int length = 0;
15543     int ret = 0;
15544 
15545     WOLFSSL_ENTER("DecodeSubjKeyId");
15546 
15547     if (sz <= 0) {
15548         ret = ASN_PARSE_E;
15549     }
15550     if (ret == 0) {
15551         ret = GetOctetString(input, &idx, &length, sz);
15552     }
15553     if (ret > 0) {
15554     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15555         cert->extSubjKeyIdSrc = &input[idx];
15556         cert->extSubjKeyIdSz = length;
15557     #endif /* OPENSSL_EXTRA */
15558 
15559         /* Get the hash or hash of the hash if wrong size. */
15560         ret = GetHashId(input + idx, length, cert->extSubjKeyId);
15561     }
15562 
15563     return ret;
15564 }
15565 
15566 #ifdef WOLFSSL_ASN_TEMPLATE
15567 /* ASN.1 template for KeyUsage.
15568  * X.509: RFC 5280, 4.2.1.3 - Key Usage.
15569  */
15570 static const ASNItem keyUsageASN[] = {
15571 /* STR */ { 0, ASN_BIT_STRING, 0, 0, 0 },
15572 };
15573 enum {
15574     KEYUSAGEASN_IDX_STR = 0,
15575 };
15576 
15577 /* Number of items in ASN.1 template for KeyUsage. */
15578 #define keyUsageASN_Length (sizeof(keyUsageASN) / sizeof(ASNItem))
15579 #endif
15580 
15581 /* Decode key usage extension in a certificate.
15582  *
15583  * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
15584  *
15585  * @param [in]      input  Buffer holding data.
15586  * @param [in]      sz     Size of data in buffer.
15587  * @param [in, out] cert   Certificate object.
15588  * @return  0 on success.
15589  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
15590  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15591  *          is invalid.
15592  * @return  MEMORY_E on dynamic memory allocation failure.
15593  */
15594 static int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)
15595 {
15596 #ifndef WOLFSSL_ASN_TEMPLATE
15597     word32 idx = 0;
15598     int length;
15599     int ret;
15600     WOLFSSL_ENTER("DecodeKeyUsage");
15601 
15602     ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
15603     if (ret != 0)
15604         return ret;
15605 
15606     if (length == 0 || length > 2)
15607         return ASN_PARSE_E;
15608 
15609     cert->extKeyUsage = (word16)(input[idx]);
15610     if (length == 2)
15611         cert->extKeyUsage |= (word16)(input[idx+1] << 8);
15612 
15613     return 0;
15614 #else
15615     ASNGetData dataASN[keyUsageASN_Length];
15616     word32 idx = 0;
15617     WOLFSSL_ENTER("DecodeKeyUsage");
15618 
15619     /* Clear dynamic data and set where to store extended key usage. */
15620     XMEMSET(dataASN, 0, sizeof(dataASN));
15621     GetASN_Int16Bit(&dataASN[KEYUSAGEASN_IDX_STR], &cert->extKeyUsage);
15622     /* Parse key usage. */
15623     return GetASN_Items(keyUsageASN, dataASN, keyUsageASN_Length, 0, input,
15624                         &idx, sz);
15625 #endif /* WOLFSSL_ASN_TEMPLATE */
15626 }
15627 
15628 #ifdef WOLFSSL_ASN_TEMPLATE
15629 /* ASN.1 template for KeyPurposeId.
15630  * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
15631  */
15632 static const ASNItem keyPurposeIdASN[] = {
15633 /* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
15634 };
15635 enum {
15636     KEYPURPOSEIDASN_IDX_OID = 0,
15637 };
15638 
15639 /* Number of items in ASN.1 template for KeyPurposeId. */
15640 #define keyPurposeIdASN_Length (sizeof(keyPurposeIdASN) / sizeof(ASNItem))
15641 #endif
15642 
15643 /* Decode extended key usage extension in a certificate.
15644  *
15645  * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
15646  *
15647  * @param [in]      input  Buffer holding data.
15648  * @param [in]      sz     Size of data in buffer.
15649  * @param [in, out] cert   Certificate object.
15650  * @return  0 on success.
15651  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
15652  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15653  *          is invalid.
15654  * @return  MEMORY_E on dynamic memory allocation failure.
15655  */
15656 static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)
15657 {
15658 #ifndef WOLFSSL_ASN_TEMPLATE
15659     word32 idx = 0, oid;
15660     int length, ret;
15661 
15662     WOLFSSL_MSG("DecodeExtKeyUsage");
15663 
15664     if (GetSequence(input, &idx, &length, sz) < 0) {
15665         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
15666         return ASN_PARSE_E;
15667     }
15668 
15669 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15670     cert->extExtKeyUsageSrc = input + idx;
15671     cert->extExtKeyUsageSz = length;
15672 #endif
15673 
15674     while (idx < (word32)sz) {
15675         ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
15676         if (ret == ASN_UNKNOWN_OID_E)
15677             continue;
15678         else if (ret < 0)
15679             return ret;
15680 
15681         switch (oid) {
15682             case EKU_ANY_OID:
15683                 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
15684                 break;
15685             case EKU_SERVER_AUTH_OID:
15686                 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
15687                 break;
15688             case EKU_CLIENT_AUTH_OID:
15689                 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
15690                 break;
15691             case EKU_CODESIGNING_OID:
15692                 cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
15693                 break;
15694             case EKU_EMAILPROTECT_OID:
15695                 cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
15696                 break;
15697             case EKU_TIMESTAMP_OID:
15698                 cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
15699                 break;
15700             case EKU_OCSP_SIGN_OID:
15701                 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
15702                 break;
15703             default:
15704                 break;
15705         }
15706 
15707     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15708         cert->extExtKeyUsageCount++;
15709     #endif
15710     }
15711 
15712     return 0;
15713 #else
15714     word32 idx = 0;
15715     int length;
15716     int ret = 0;
15717 
15718     WOLFSSL_MSG("DecodeExtKeyUsage");
15719 
15720     /* Strip SEQUENCE OF and expect to account for all the data. */
15721     if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
15722         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
15723         ret = ASN_PARSE_E;
15724     }
15725 
15726     if (ret == 0) {
15727     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15728         /* Keep reference for WOLFSSL_X509. */
15729         cert->extExtKeyUsageSrc = input + idx;
15730         cert->extExtKeyUsageSz = length;
15731     #endif
15732     }
15733 
15734     /* Check all OIDs. */
15735     while ((ret == 0) && (idx < (word32)sz)) {
15736         ASNGetData dataASN[keyPurposeIdASN_Length];
15737 
15738         /* Clear dynamic data items and set OID type expected. */
15739         XMEMSET(dataASN, 0, sizeof(dataASN));
15740         GetASN_OID(&dataASN[KEYPURPOSEIDASN_IDX_OID], oidCertKeyUseType);
15741         /* Decode KeyPurposeId. */
15742         ret = GetASN_Items(keyPurposeIdASN, dataASN, keyPurposeIdASN_Length, 0,
15743                            input, &idx, sz);
15744         /* Skip unknown OIDs. */
15745         if (ret == ASN_UNKNOWN_OID_E) {
15746             ret = 0;
15747         }
15748         else if (ret == 0) {
15749             /* Store the bit for the OID. */
15750             switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
15751                 case EKU_ANY_OID:
15752                     cert->extExtKeyUsage |= EXTKEYUSE_ANY;
15753                     break;
15754                 case EKU_SERVER_AUTH_OID:
15755                     cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
15756                     break;
15757                 case EKU_CLIENT_AUTH_OID:
15758                     cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
15759                     break;
15760                 case EKU_CODESIGNING_OID:
15761                     cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
15762                     break;
15763                 case EKU_EMAILPROTECT_OID:
15764                     cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
15765                     break;
15766                 case EKU_TIMESTAMP_OID:
15767                     cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
15768                     break;
15769                 case EKU_OCSP_SIGN_OID:
15770                     cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
15771                     break;
15772             }
15773 
15774         #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15775             /* Keep count for WOLFSSL_X509. */
15776             cert->extExtKeyUsageCount++;
15777         #endif
15778         }
15779     }
15780 
15781     return ret;
15782 #endif /* WOLFSSL_ASN_TEMPLATE */
15783 }
15784 
15785 #ifndef IGNORE_NETSCAPE_CERT_TYPE
15786 
15787 static int DecodeNsCertType(const byte* input, int sz, DecodedCert* cert)
15788 {
15789     word32 idx = 0;
15790     int len = 0;
15791 
15792     WOLFSSL_ENTER("DecodeNsCertType");
15793     if (CheckBitString(input, &idx, &len, (word32)sz, 0, NULL) < 0) {
15794         return ASN_PARSE_E;
15795     }
15796 
15797     /* Don't need to worry about unused bits as CheckBitString makes sure
15798      * they're zero. */
15799     cert->nsCertType = input[idx];
15800 
15801     return 0;
15802 }
15803 #endif
15804 
15805 
15806 #ifndef IGNORE_NAME_CONSTRAINTS
15807 #ifdef WOLFSSL_ASN_TEMPLATE
15808 /* ASN.1 template for GeneralSubtree.
15809  * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
15810  */
15811 static const ASNItem subTreeASN[] = {
15812 /* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
15813                               /* base     GeneralName */
15814 /* BASE */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
15815                               /* minimum  BaseDistance DEFAULT 0*/
15816 /* MIN  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MIN, 0, 0, 1 },
15817                               /* maximum  BaseDistance OPTIONAL  */
15818 /* MAX  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MAX, 0, 0, 1 },
15819 };
15820 enum {
15821     SUBTREEASN_IDX_SEQ = 0,
15822     SUBTREEASN_IDX_BASE,
15823     SUBTREEASN_IDX_MIN,
15824     SUBTREEASN_IDX_MAX,
15825 };
15826 
15827 /* Number of items in ASN.1 template for GeneralSubtree. */
15828 #define subTreeASN_Length (sizeof(subTreeASN) / sizeof(ASNItem))
15829 #endif
15830 
15831 #ifdef WOLFSSL_ASN_TEMPLATE
15832 /* Decode the Subtree's GeneralName.
15833  *
15834  * @param [in]      input  Buffer holding data.
15835  * @param [in]      sz     Size of data in buffer.
15836  * @param [in]      tag    BER tag on GeneralName.
15837  * @param [in, out] head   Linked list of subtree names.
15838  * @param [in]      heap   Dynamic memory hint.
15839  * @return  0 on success.
15840  * @return  MEMORY_E when dynamic memory allocation fails.
15841  * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
15842  */
15843 static int DecodeSubtreeGeneralName(const byte* input, int sz, byte tag,
15844                                     Base_entry** head, void* heap)
15845 {
15846     Base_entry* entry;
15847     word32 nameIdx = 0;
15848     word32 len = sz;
15849     int strLen;
15850     int ret = 0;
15851 
15852     (void)heap;
15853 
15854     /* if constructed has leading sequence */
15855     if ((tag & ASN_CONSTRUCTED) == ASN_CONSTRUCTED) {
15856         ret = GetASN_Sequence(input, &nameIdx, &strLen, sz, 0);
15857         if (ret < 0) {
15858             ret = ASN_PARSE_E;
15859         }
15860         else {
15861             len = strLen;
15862             ret = 0;
15863         }
15864     }
15865     if (ret == 0) {
15866         /* TODO: consider one malloc. */
15867         /* Allocate Base Entry object. */
15868         entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
15869                                      DYNAMIC_TYPE_ALTNAME);
15870         if (entry == NULL) {
15871             ret = MEMORY_E;
15872         }
15873     }
15874     if (ret == 0) {
15875         /* Allocate name. */
15876         entry->name = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_ALTNAME);
15877         if (entry->name == NULL) {
15878             XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
15879             ret = MEMORY_E;
15880         }
15881     }
15882     if (ret == 0) {
15883         /* Store name, size and tag in object. */
15884         XMEMCPY(entry->name, &input[nameIdx], len);
15885         entry->name[len] = '\0';
15886         entry->nameSz = len;
15887         entry->type = tag & ASN_TYPE_MASK;
15888 
15889         /* Put entry at front of linked list. */
15890         entry->next = *head;
15891         *head = entry;
15892     }
15893 
15894     return ret;
15895 }
15896 #endif
15897 
15898 /* Decode a subtree of a name contraint in a certificate.
15899  *
15900  * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
15901  *
15902  * @param [in]      input  Buffer holding data.
15903  * @param [in]      sz     Size of data in buffer.
15904  * @param [in, out] head   Linked list of subtree names.
15905  * @param [in]      heap   Dynamic memory hint.
15906  * @return  0 on success.
15907  * @return  MEMORY_E when dynamic memory allocation fails.
15908  * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
15909  */
15910 static int DecodeSubtree(const byte* input, int sz, Base_entry** head,
15911                          void* heap)
15912 {
15913 #ifndef WOLFSSL_ASN_TEMPLATE
15914     word32 idx = 0;
15915     int ret = 0;
15916 
15917     (void)heap;
15918 
15919     while (idx < (word32)sz) {
15920         int seqLength, strLength;
15921         word32 nameIdx;
15922         byte b, bType;
15923 
15924         if (GetSequence(input, &idx, &seqLength, sz) < 0) {
15925             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
15926             return ASN_PARSE_E;
15927         }
15928         nameIdx = idx;
15929         b = input[nameIdx++];
15930 
15931         if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
15932             WOLFSSL_MSG("\tinvalid length");
15933             return ASN_PARSE_E;
15934         }
15935 
15936         /* Get type, LSB 4-bits */
15937         bType = (b & ASN_TYPE_MASK);
15938 
15939         if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
15940                                                         bType == ASN_DIR_TYPE) {
15941             Base_entry* entry;
15942 
15943             /* if constructed has leading sequence */
15944             if (b & ASN_CONSTRUCTED) {
15945                 if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
15946                     WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
15947                     return ASN_PARSE_E;
15948                 }
15949             }
15950 
15951             entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
15952                                                           DYNAMIC_TYPE_ALTNAME);
15953             if (entry == NULL) {
15954                 WOLFSSL_MSG("allocate error");
15955                 return MEMORY_E;
15956             }
15957 
15958             entry->name = (char*)XMALLOC(strLength+1, heap, DYNAMIC_TYPE_ALTNAME);
15959             if (entry->name == NULL) {
15960                 WOLFSSL_MSG("allocate error");
15961                 XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
15962                 return MEMORY_E;
15963             }
15964 
15965             XMEMCPY(entry->name, &input[nameIdx], strLength);
15966             entry->name[strLength] = '\0';
15967             entry->nameSz = strLength;
15968             entry->type = bType;
15969 
15970             entry->next = *head;
15971             *head = entry;
15972         }
15973 
15974         idx += seqLength;
15975     }
15976 
15977     return ret;
15978 #else
15979     DECL_ASNGETDATA(dataASN, subTreeASN_Length);
15980     word32 idx = 0;
15981     int ret = 0;
15982 
15983     (void)heap;
15984 
15985     ALLOC_ASNGETDATA(dataASN, subTreeASN_Length, ret, heap);
15986 
15987     /* Process all subtrees. */
15988     while ((ret == 0) && (idx < (word32)sz)) {
15989         byte minVal = 0;
15990         byte maxVal = 0;
15991 
15992         /* Clear dynamic data and set choice for GeneralName and location to
15993          * store minimum and maximum.
15994          */
15995         XMEMSET(dataASN, 0, sizeof(*dataASN) * subTreeASN_Length);
15996         GetASN_Choice(&dataASN[SUBTREEASN_IDX_BASE], generalNameChoice);
15997         GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MIN], &minVal);
15998         GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MAX], &maxVal);
15999         /* Parse GeneralSubtree. */
16000         ret = GetASN_Items(subTreeASN, dataASN, subTreeASN_Length, 0, input,
16001                            &idx, sz);
16002         if (ret == 0) {
16003             byte t = dataASN[SUBTREEASN_IDX_BASE].tag;
16004 
16005             /* Check GeneralName tag is one of the types we can handle. */
16006             if (t == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
16007                 t == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
16008                 t == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
16009                 /* Parse the general name and store a new entry. */
16010                 ret = DecodeSubtreeGeneralName(input +
16011                     GetASNItem_DataIdx(dataASN[SUBTREEASN_IDX_BASE], input),
16012                     dataASN[SUBTREEASN_IDX_BASE].length, t, head, heap);
16013             }
16014             /* Skip entry. */
16015         }
16016     }
16017 
16018     FREE_ASNGETDATA(dataASN, heap);
16019     return ret;
16020 #endif
16021 }
16022 
16023 #ifdef WOLFSSL_ASN_TEMPLATE
16024 /* ASN.1 template for NameConstraints.
16025  * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
16026  */
16027 static const ASNItem nameConstraintsASN[] = {
16028 /* SEQ     */ { 0, ASN_SEQUENCE, 1, 1, 0 },
16029                                          /* permittedSubtrees */
16030 /* PERMIT  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
16031                                          /* excludededSubtrees */
16032 /* EXCLUDE */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
16033 };
16034 enum {
16035     NAMECONSTRAINTSASN_IDX_SEQ = 0,
16036     NAMECONSTRAINTSASN_IDX_PERMIT,
16037     NAMECONSTRAINTSASN_IDX_EXCLUDE,
16038 };
16039 
16040 /* Number of items in ASN.1 template for NameConstraints. */
16041 #define nameConstraintsASN_Length (sizeof(nameConstraintsASN) / sizeof(ASNItem))
16042 #endif
16043 
16044 /* Decode name constraints extension in a certificate.
16045  *
16046  * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
16047  *
16048  * @param [in]      input  Buffer holding data.
16049  * @param [in]      sz     Size of data in buffer.
16050  * @param [in, out] cert   Certificate object.
16051  * @return  0 on success.
16052  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16053  *          is invalid.
16054  * @return  MEMORY_E on dynamic memory allocation failure.
16055  */
16056 static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)
16057 {
16058 #ifndef WOLFSSL_ASN_TEMPLATE
16059     word32 idx = 0;
16060     int length = 0;
16061 
16062     WOLFSSL_ENTER("DecodeNameConstraints");
16063 
16064     if (GetSequence(input, &idx, &length, sz) < 0) {
16065         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
16066         return ASN_PARSE_E;
16067     }
16068 
16069     while (idx < (word32)sz) {
16070         byte b = input[idx++];
16071         Base_entry** subtree = NULL;
16072 
16073         if (GetLength(input, &idx, &length, sz) <= 0) {
16074             WOLFSSL_MSG("\tinvalid length");
16075             return ASN_PARSE_E;
16076         }
16077 
16078         if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
16079             subtree = &cert->permittedNames;
16080         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
16081             subtree = &cert->excludedNames;
16082         else {
16083             WOLFSSL_MSG("\tinvalid subtree");
16084             return ASN_PARSE_E;
16085         }
16086 
16087         if (DecodeSubtree(input + idx, length, subtree, cert->heap) < 0) {
16088             WOLFSSL_MSG("\terror parsing subtree");
16089             return ASN_PARSE_E;
16090         }
16091 
16092         idx += length;
16093     }
16094 
16095     return 0;
16096 #else
16097     DECL_ASNGETDATA(dataASN, nameConstraintsASN_Length);
16098     word32 idx = 0;
16099     int    ret = 0;
16100 
16101     CALLOC_ASNGETDATA(dataASN, nameConstraintsASN_Length, ret, cert->heap);
16102 
16103     if (ret == 0) {
16104         /* Parse NameConstraints. */
16105         ret = GetASN_Items(nameConstraintsASN, dataASN, nameConstraintsASN_Length,
16106                            1, input, &idx, sz);
16107     }
16108     if (ret == 0) {
16109         /* If there was a permittedSubtrees then parse it. */
16110         if (dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data != NULL) {
16111             ret = DecodeSubtree(
16112                     dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data,
16113                     dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.length,
16114                     &cert->permittedNames, cert->heap);
16115         }
16116     }
16117     if (ret == 0) {
16118         /* If there was a excludedSubtrees then parse it. */
16119         if (dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data != NULL) {
16120             ret = DecodeSubtree(
16121                     dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data,
16122                     dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.length,
16123                     &cert->excludedNames, cert->heap);
16124         }
16125     }
16126 
16127     return ret;
16128 #endif /* WOLFSSL_ASN_TEMPLATE */
16129 }
16130 #endif /* IGNORE_NAME_CONSTRAINTS */
16131 
16132 #if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || \
16133     defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16134 
16135 /* Decode ITU-T X.690 OID format to a string representation
16136  * return string length */
16137 int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
16138 {
16139     word32 val, inIdx = 0, outIdx = 0;
16140     int w = 0;
16141 
16142     if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
16143         return BAD_FUNC_ARG;
16144 
16145     /* The first byte expands into b/40 dot b%40. */
16146     val = in[inIdx++];
16147 
16148     w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40);
16149     if (w < 0) {
16150         w = BUFFER_E;
16151         goto exit;
16152     }
16153     outIdx += w;
16154     val = 0;
16155 
16156     while (inIdx < inSz && outIdx < outSz) {
16157         /* extract the next OID digit from in to val */
16158         /* first bit is used to set if value is coded on 1 or multiple bytes */
16159         if (in[inIdx] & 0x80) {
16160             val += in[inIdx] & 0x7F;
16161             val *= 128;
16162         }
16163         else {
16164             /* write val as text into out */
16165             val += in[inIdx];
16166             w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val);
16167             if (w < 0 || (word32)w > outSz - outIdx) {
16168                 w = BUFFER_E;
16169                 goto exit;
16170             }
16171             outIdx += w;
16172             val = 0;
16173         }
16174         inIdx++;
16175     }
16176     if (outIdx == outSz)
16177         outIdx--;
16178     out[outIdx] = 0;
16179 
16180     w = (int)outIdx;
16181 
16182 exit:
16183     return w;
16184 }
16185 #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
16186 
16187 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_QT)
16188     #ifdef WOLFSSL_ASN_TEMPLATE
16189     /* ASN.1 template for PolicyInformation.
16190      * X.509: RFC 5280, 4.2.1.4 - Certificate Policies.
16191      */
16192     static const ASNItem policyInfoASN[] = {
16193     /* SEQ   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
16194                                       /* policyIdentifier */
16195     /* ID    */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
16196                                       /* policyQualifiers */
16197     /* QUALI */     { 1, ASN_SEQUENCE, 1, 0, 1 },
16198     };
16199     enum {
16200         POLICYINFOASN_IDX_SEQ = 0,
16201         POLICYINFOASN_IDX_ID,
16202         POLICYINFOASN_IDX_QUALI,
16203     };
16204 
16205     /* Number of items in ASN.1 template for PolicyInformation. */
16206     #define policyInfoASN_Length (sizeof(policyInfoASN) / sizeof(ASNItem))
16207     #endif
16208 
16209     /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
16210     static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)
16211     {
16212     #ifndef WOLFSSL_ASN_TEMPLATE
16213         word32 idx = 0;
16214         word32 oldIdx;
16215         int policy_length = 0;
16216         int ret;
16217         int total_length = 0;
16218     #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
16219         !defined(WOLFSSL_DUP_CERTPOL)
16220         int i;
16221     #endif
16222 
16223         WOLFSSL_ENTER("DecodeCertPolicy");
16224 
16225     #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
16226         /* Check if cert is null before dereferencing below */
16227         if (cert == NULL)
16228             return BAD_FUNC_ARG;
16229     #else
16230         (void)cert;
16231     #endif
16232 
16233     #if defined(WOLFSSL_CERT_EXT)
16234          cert->extCertPoliciesNb = 0;
16235     #endif
16236 
16237         if (GetSequence(input, &idx, &total_length, sz) < 0) {
16238             WOLFSSL_MSG("\tGet CertPolicy total seq failed");
16239             return ASN_PARSE_E;
16240         }
16241 
16242         /* Validate total length */
16243         if (total_length > (sz - (int)idx)) {
16244             WOLFSSL_MSG("\tCertPolicy length mismatch");
16245             return ASN_PARSE_E;
16246         }
16247 
16248         /* Unwrap certificatePolicies */
16249         do {
16250             int length = 0;
16251 
16252             if (GetSequence(input, &idx, &policy_length, sz) < 0) {
16253                 WOLFSSL_MSG("\tGet CertPolicy seq failed");
16254                 return ASN_PARSE_E;
16255             }
16256 
16257             oldIdx = idx;
16258             ret = GetASNObjectId(input, &idx, &length, sz);
16259             if (ret != 0)
16260                 return ret;
16261             policy_length -= idx - oldIdx;
16262 
16263             if (length > 0) {
16264                 /* Verify length won't overrun buffer */
16265                 if (length > (sz - (int)idx)) {
16266                     WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
16267                     return ASN_PARSE_E;
16268                 }
16269 
16270         #if defined(WOLFSSL_SEP)
16271                 cert->deviceType = (byte*)XMALLOC(length, cert->heap,
16272                                                          DYNAMIC_TYPE_X509_EXT);
16273                 if (cert->deviceType == NULL) {
16274                     WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
16275                     return MEMORY_E;
16276                 }
16277                 cert->deviceTypeSz = length;
16278                 XMEMCPY(cert->deviceType, input + idx, length);
16279                 break;
16280         #elif defined(WOLFSSL_CERT_EXT)
16281                 /* decode cert policy */
16282                 if (DecodePolicyOID(cert->extCertPolicies[
16283                                        cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
16284                                        input + idx, length) <= 0) {
16285                     WOLFSSL_MSG("\tCouldn't decode CertPolicy");
16286                     return ASN_PARSE_E;
16287                 }
16288             #ifndef WOLFSSL_DUP_CERTPOL
16289                 /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
16290                  * NOT appear more than once in a certificate policies
16291                  * extension". This is a sanity check for duplicates.
16292                  * extCertPolicies should only have OID values, additional
16293                  * qualifiers need to be stored in a separate array. */
16294                 for (i = 0; i < cert->extCertPoliciesNb; i++) {
16295                     if (XMEMCMP(cert->extCertPolicies[i],
16296                             cert->extCertPolicies[cert->extCertPoliciesNb],
16297                             MAX_CERTPOL_SZ) == 0) {
16298                             WOLFSSL_MSG("Duplicate policy OIDs not allowed");
16299                             WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
16300                             return CERTPOLICIES_E;
16301                     }
16302                 }
16303             #endif /* !WOLFSSL_DUP_CERTPOL */
16304                 cert->extCertPoliciesNb++;
16305         #else
16306                 WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
16307                 return 0;
16308         #endif
16309             }
16310             idx += policy_length;
16311         } while((int)idx < total_length
16312     #if defined(WOLFSSL_CERT_EXT)
16313             && cert->extCertPoliciesNb < MAX_CERTPOL_NB
16314     #endif
16315         );
16316 
16317         WOLFSSL_LEAVE("DecodeCertPolicy", 0);
16318         return 0;
16319     #else /* WOLFSSL_ASN_TEMPLATE */
16320         word32 idx = 0;
16321         int ret = 0;
16322         int total_length = 0;
16323     #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
16324         !defined(WOLFSSL_DUP_CERTPOL)
16325         int i;
16326     #endif
16327 
16328         WOLFSSL_ENTER("DecodeCertPolicy");
16329         #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
16330         /* Check if cert is null before dereferencing below */
16331         if (cert == NULL)
16332             ret = BAD_FUNC_ARG;
16333         #endif
16334 
16335         if (ret == 0) {
16336         #if defined(WOLFSSL_CERT_EXT)
16337              cert->extCertPoliciesNb = 0;
16338         #endif
16339 
16340             /* Strip SEQUENCE OF and check using all data. */
16341             if (GetASN_Sequence(input, &idx, &total_length, sz, 1) < 0) {
16342                 ret = ASN_PARSE_E;
16343             }
16344         }
16345 
16346         /* Unwrap certificatePolicies */
16347         while ((ret == 0) && ((int)idx < total_length)
16348         #if defined(WOLFSSL_CERT_EXT)
16349             && (cert->extCertPoliciesNb < MAX_CERTPOL_NB)
16350         #endif
16351                ) {
16352             ASNGetData dataASN[policyInfoASN_Length];
16353             byte* data;
16354             word32 length = 0;
16355 
16356             /* Clear dynamic data and check OID is a cert policy type. */
16357             XMEMSET(dataASN, 0, sizeof(dataASN));
16358             GetASN_OID(&dataASN[POLICYINFOASN_IDX_ID], oidCertPolicyType);
16359             ret = GetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length, 1,
16360                                input, &idx, sz);
16361             if (ret == 0) {
16362                 /* Get the OID. */
16363                 GetASN_OIDData(&dataASN[POLICYINFOASN_IDX_ID], &data, &length);
16364                 if (length == 0) {
16365                     ret = ASN_PARSE_E;
16366                 }
16367             }
16368             #if defined(WOLFSSL_SEP)
16369             /* Store OID in device type. */
16370             if (ret == 0) {
16371                 cert->deviceType = (byte*)XMALLOC(length, cert->heap,
16372                                                   DYNAMIC_TYPE_X509_EXT);
16373                 if (cert->deviceType == NULL) {
16374                     WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
16375                     ret = MEMORY_E;
16376                 }
16377             }
16378             if (ret == 0) {
16379                 /* Store device type data and length. */
16380                 cert->deviceTypeSz = length;
16381                 XMEMCPY(cert->deviceType, data, length);
16382                 break;
16383             }
16384             #elif defined(WOLFSSL_CERT_EXT)
16385             if (ret == 0) {
16386                 /* Decode cert policy. */
16387                 if (DecodePolicyOID(
16388                                  cert->extCertPolicies[cert->extCertPoliciesNb],
16389                                  MAX_CERTPOL_SZ, data, length) <= 0) {
16390                     WOLFSSL_MSG("\tCouldn't decode CertPolicy");
16391                     ret = ASN_PARSE_E;
16392                 }
16393             }
16394             #ifndef WOLFSSL_DUP_CERTPOL
16395             /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
16396              * NOT appear more than once in a certificate policies
16397              * extension". This is a sanity check for duplicates.
16398              * extCertPolicies should only have OID values, additional
16399              * qualifiers need to be stored in a seperate array. */
16400             for (i = 0; (ret == 0) && (i < cert->extCertPoliciesNb); i++) {
16401                 if (XMEMCMP(cert->extCertPolicies[i],
16402                             cert->extCertPolicies[cert->extCertPoliciesNb],
16403                             MAX_CERTPOL_SZ) == 0) {
16404                     WOLFSSL_MSG("Duplicate policy OIDs not allowed");
16405                     WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
16406                     ret = CERTPOLICIES_E;
16407                 }
16408             }
16409             #endif /* !defined(WOLFSSL_DUP_CERTPOL) */
16410             if (ret == 0) {
16411                 /* Keep count of policies seen. */
16412                 cert->extCertPoliciesNb++;
16413             }
16414             #else
16415                 (void)data;
16416                 WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
16417                 break;
16418             #endif
16419         }
16420 
16421         WOLFSSL_LEAVE("DecodeCertPolicy", 0);
16422         return ret;
16423     #endif /* WOLFSSL_ASN_TEMPLATE */
16424     }
16425 #endif /* WOLFSSL_SEP */
16426 
16427 /* Macro to check if bit is set, if not sets and return success.
16428     Otherwise returns failure */
16429 /* Macro required here because bit-field operation */
16430 #ifndef WOLFSSL_NO_ASN_STRICT
16431     #define VERIFY_AND_SET_OID(bit) \
16432         if (bit == 0) \
16433             bit = 1; \
16434         else \
16435             return ASN_OBJECT_ID_E;
16436 #else
16437     /* With no strict defined, the verify is skipped */
16438 #define VERIFY_AND_SET_OID(bit) bit = 1;
16439 #endif
16440 
16441 /* Parse extension type specific data based on OID sum.
16442  *
16443  * Supported extensions:
16444  *   Basic Constraints - BASIC_CA_OID
16445  *   CRL Distribution Points - CRL_DIST_OID
16446  *   Authority Information Access - AUTH_INFO_OID
16447  *   Subject Alternative Name - ALT_NAMES_OID
16448  *   Authority Key Identifier - AUTH_KEY_OID
16449  *   Subject Key Identifier - SUBJ_KEY_OID
16450  *   Certificate Policies - CERT_POLICY_OID (conditional parsing)
16451  *   Key Usage - KEY_USAGE_OID
16452  *   Extended Key Usage - EXT_KEY_USAGE_OID
16453  *   Name Constraints - NAME_CONS_OID
16454  *   Inhibit anyPolicy - INHIBIT_ANY_OID
16455  *   Netscape Certificate Type - NETSCAPE_CT_OID (able to be excluded)
16456  *   OCSP no check - OCSP_NOCHECK_OID (when compiling OCSP)
16457  * Unsupported extensions from RFC 580:
16458  *   4.2.1.5 - Policy mappings
16459  *   4.2.1.7 - Issuer Alternative Name
16460  *   4.2.1.8 - Subject Directory Attributes
16461  *   4.2.1.11 - Policy Constraints
16462  *   4.2.1.15 - Freshest CRL
16463  *   4.2.2.2 - Subject Information Access
16464  *
16465  * @param [in]      input     Buffer containing extension type specific data.
16466  * @param [in]      length    Length of data.
16467  * @param [in]      oid       OID sum for extension.
16468  * @param [in]      critical  Whether extension is critical.
16469  * @param [in, out] cert      Certificate object.
16470  * @return  0 on success.
16471  * @return  ASN_PARSE_E when BER encoding is invalid.
16472  * @return  MEMORY_E on dynamic memory allocation failure.
16473  * @return  Other -ve value on error.
16474  */
16475 static int DecodeExtensionType(const byte* input, int length, word32 oid,
16476                                byte critical, DecodedCert* cert)
16477 {
16478     int ret = 0;
16479     word32 idx = 0;
16480 
16481     switch (oid) {
16482         /* Basic Constraints. */
16483         case BASIC_CA_OID:
16484             VERIFY_AND_SET_OID(cert->extBasicConstSet);
16485             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16486                 cert->extBasicConstCrit = critical;
16487             #endif
16488             if (DecodeBasicCaConstraint(input, length, cert) < 0) {
16489                 ret = ASN_PARSE_E;
16490             }
16491             break;
16492 
16493         /* CRL Distribution point. */
16494         case CRL_DIST_OID:
16495             VERIFY_AND_SET_OID(cert->extCRLdistSet);
16496             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16497                 cert->extCRLdistCrit = critical;
16498             #endif
16499             if (DecodeCrlDist(input, length, cert) < 0) {
16500                 ret = ASN_PARSE_E;
16501             }
16502             break;
16503 
16504         /* Authority information access. */
16505         case AUTH_INFO_OID:
16506             VERIFY_AND_SET_OID(cert->extAuthInfoSet);
16507             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16508                 cert->extAuthInfoCrit = critical;
16509             #endif
16510             if (DecodeAuthInfo(input, length, cert) < 0) {
16511                 ret = ASN_PARSE_E;
16512             }
16513             break;
16514 
16515         /* Subject alternative name. */
16516         case ALT_NAMES_OID:
16517             VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
16518             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16519                 cert->extSubjAltNameCrit = critical;
16520             #endif
16521             ret = DecodeAltNames(input, length, cert);
16522             break;
16523 
16524         /* Authority Key Identifier. */
16525         case AUTH_KEY_OID:
16526             VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
16527             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16528                 cert->extAuthKeyIdCrit = critical;
16529             #endif
16530             #ifndef WOLFSSL_ALLOW_CRIT_SKID
16531                 /* This check is added due to RFC 5280 section 4.2.1.1
16532                  * stating that conforming CA's must mark this extension
16533                  * as non-critical. When parsing extensions check that
16534                  * certificate was made in compliance with this. */
16535                 if (critical) {
16536                     WOLFSSL_MSG("Critical Auth Key ID is not allowed");
16537                     WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
16538                     ret = ASN_CRIT_EXT_E;
16539                 }
16540             #endif
16541             if ((ret == 0) && (DecodeAuthKeyId(input, length, cert) < 0)) {
16542                 ret = ASN_PARSE_E;
16543             }
16544             break;
16545 
16546         /* Subject Key Identifier. */
16547         case SUBJ_KEY_OID:
16548             VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
16549             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16550                 cert->extSubjKeyIdCrit = critical;
16551             #endif
16552             #ifndef WOLFSSL_ALLOW_CRIT_SKID
16553                 /* This check is added due to RFC 5280 section 4.2.1.2
16554                  * stating that conforming CA's must mark this extension
16555                  * as non-critical. When parsing extensions check that
16556                  * certificate was made in compliance with this. */
16557                 if (critical) {
16558                     WOLFSSL_MSG("Critical Subject Key ID is not allowed");
16559                     WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
16560                     ret = ASN_CRIT_EXT_E;
16561                 }
16562             #endif
16563 
16564             if ((ret == 0) && (DecodeSubjKeyId(input, length, cert) < 0)) {
16565                 ret = ASN_PARSE_E;
16566             }
16567             break;
16568 
16569         /* Certificate policies. */
16570         case CERT_POLICY_OID:
16571             #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
16572                 VERIFY_AND_SET_OID(cert->extCertPolicySet);
16573                 #if defined(OPENSSL_EXTRA) || \
16574                     defined(OPENSSL_EXTRA_X509_SMALL)
16575                     cert->extCertPolicyCrit = critical;
16576                 #endif
16577             #endif
16578             #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || \
16579                 defined(WOLFSSL_QT)
16580                 if (DecodeCertPolicy(input, length, cert) < 0) {
16581                     ret = ASN_PARSE_E;
16582                 }
16583             #else
16584                 WOLFSSL_MSG("Certificate Policy extension not supported yet.");
16585             #endif
16586             break;
16587 
16588         /* Key usage. */
16589         case KEY_USAGE_OID:
16590             VERIFY_AND_SET_OID(cert->extKeyUsageSet);
16591             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16592                 cert->extKeyUsageCrit = critical;
16593             #endif
16594             if (DecodeKeyUsage(input, length, cert) < 0) {
16595                 ret = ASN_PARSE_E;
16596             }
16597             break;
16598 
16599         /* Extended key usage. */
16600         case EXT_KEY_USAGE_OID:
16601             VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
16602             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16603                 cert->extExtKeyUsageCrit = critical;
16604             #endif
16605             if (DecodeExtKeyUsage(input, length, cert) < 0) {
16606                 ret = ASN_PARSE_E;
16607             }
16608             break;
16609 
16610         #ifndef IGNORE_NAME_CONSTRAINTS
16611         /* Name constraints. */
16612         case NAME_CONS_OID:
16613         #ifndef WOLFSSL_NO_ASN_STRICT
16614             /* Verify RFC 5280 Sec 4.2.1.10 rule:
16615                 "The name constraints extension,
16616                 which MUST be used only in a CA certificate" */
16617             if (!cert->isCA) {
16618                 WOLFSSL_MSG("Name constraints allowed only for CA certs");
16619                 ret = ASN_NAME_INVALID_E;
16620             }
16621         #endif
16622             VERIFY_AND_SET_OID(cert->extNameConstraintSet);
16623             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16624                 cert->extNameConstraintCrit = critical;
16625             #endif
16626             if (DecodeNameConstraints(input, length, cert) < 0) {
16627                 ret = ASN_PARSE_E;
16628             }
16629             break;
16630         #endif /* IGNORE_NAME_CONSTRAINTS */
16631 
16632         /* Inhibit anyPolicy. */
16633         case INHIBIT_ANY_OID:
16634             VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
16635             WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
16636             break;
16637 
16638    #ifndef IGNORE_NETSCAPE_CERT_TYPE
16639         /* Netscape's certificate type. */
16640         case NETSCAPE_CT_OID:
16641             if (DecodeNsCertType(input, length, cert) < 0)
16642                 ret = ASN_PARSE_E;
16643             break;
16644     #endif
16645     #ifdef HAVE_OCSP
16646         /* OCSP no check. */
16647         case OCSP_NOCHECK_OID:
16648             VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
16649             ret = GetASNNull(input, &idx, length);
16650             if (ret != 0) {
16651                 ret = ASN_PARSE_E;
16652             }
16653             break;
16654     #endif
16655         case POLICY_CONST_OID:
16656             VERIFY_AND_SET_OID(cert->extPolicyConstSet);
16657             #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16658                 cert->extPolicyConstCrit = critical;
16659             #endif
16660             if (DecodePolicyConstraints(&input[idx], length, cert) < 0)
16661                 return ASN_PARSE_E;
16662             break;
16663         default:
16664         #ifndef WOLFSSL_NO_ASN_STRICT
16665             /* While it is a failure to not support critical extensions,
16666              * still parse the certificate ignoring the unsupported
16667              * extension to allow caller to accept it with the verify
16668              * callback. */
16669             if (critical)
16670                 ret = ASN_CRIT_EXT_E;
16671         #endif
16672             break;
16673     }
16674 
16675     return ret;
16676 }
16677 
16678 #ifdef WOLFSSL_ASN_TEMPLATE
16679 /* ASN.1 template for extensions.
16680  * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
16681  */
16682 static const ASNItem certExtHdrASN[] = {
16683 /* EXTTAG */ { 0, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 0 },
16684 /* EXTSEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
16685 };
16686 enum {
16687     CERTEXTHDRASN_IDX_EXTTAG = 0,
16688     CERTEXTHDRASN_IDX_EXTSEQ,
16689 };
16690 
16691 /* Number of itesm in ASN.1 template for extensions. */
16692 #define certExtHdrASN_Length (sizeof(certExtHdrASN) / sizeof(ASNItem))
16693 
16694 /* ASN.1 template for Extension.
16695  * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
16696  */
16697 static const ASNItem certExtASN[] = {
16698 /* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
16699                               /* Extension object id */
16700 /* OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
16701                               /* critical - when true, must be parseable. */
16702 /* CRIT */     { 1, ASN_BOOLEAN, 0, 0, 1 },
16703                               /* Data for extension - leave index at start of data. */
16704 /* VAL  */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
16705 };
16706 enum {
16707     CERTEXTASN_IDX_SEQ = 0,
16708     CERTEXTASN_IDX_OID,
16709     CERTEXTASN_IDX_CRIT,
16710     CERTEXTASN_IDX_VAL,
16711 };
16712 
16713 /* Number of items in ASN.1 template for Extension. */
16714 #define certExtASN_Length (sizeof(certExtASN) / sizeof(ASNItem))
16715 #endif
16716 
16717 /*
16718  *  Processing the Certificate Extensions. This does not modify the current
16719  *  index. It is works starting with the recorded extensions pointer.
16720  */
16721 static int DecodeCertExtensions(DecodedCert* cert)
16722 {
16723 #ifndef WOLFSSL_ASN_TEMPLATE
16724     int ret = 0;
16725     word32 idx = 0;
16726     int sz = cert->extensionsSz;
16727     const byte* input = cert->extensions;
16728     int length;
16729     word32 oid;
16730     byte critical = 0;
16731     byte criticalFail = 0;
16732     byte tag = 0;
16733 
16734     WOLFSSL_ENTER("DecodeCertExtensions");
16735 
16736     if (input == NULL || sz == 0)
16737         return BAD_FUNC_ARG;
16738 
16739 #ifdef WOLFSSL_CERT_REQ
16740     if (!cert->isCSR)
16741 #endif
16742     { /* Not included in CSR */
16743         if (GetASNTag(input, &idx, &tag, sz) < 0) {
16744             return ASN_PARSE_E;
16745         }
16746 
16747         if (tag != ASN_EXTENSIONS) {
16748             WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
16749             return ASN_PARSE_E;
16750         }
16751 
16752         if (GetLength(input, &idx, &length, sz) < 0) {
16753             WOLFSSL_MSG("\tfail: invalid length");
16754             return ASN_PARSE_E;
16755         }
16756     }
16757 
16758     if (GetSequence(input, &idx, &length, sz) < 0) {
16759         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
16760         return ASN_PARSE_E;
16761     }
16762 
16763     while (idx < (word32)sz) {
16764         word32 localIdx;
16765 
16766         if (GetSequence(input, &idx, &length, sz) < 0) {
16767             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
16768             return ASN_PARSE_E;
16769         }
16770 
16771         oid = 0;
16772         if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
16773             WOLFSSL_MSG("\tfail: OBJECT ID");
16774             return ret;
16775         }
16776 
16777         /* check for critical flag */
16778         critical = 0;
16779         if ((idx + 1) > (word32)sz) {
16780             WOLFSSL_MSG("\tfail: malformed buffer");
16781             return BUFFER_E;
16782         }
16783 
16784         localIdx = idx;
16785         if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
16786             if (tag == ASN_BOOLEAN) {
16787                 ret = GetBoolean(input, &idx, sz);
16788                 if (ret < 0) {
16789                     WOLFSSL_MSG("\tfail: critical boolean");
16790                     return ret;
16791                 }
16792 
16793                 critical = (byte)ret;
16794             }
16795         }
16796 
16797         /* process the extension based on the OID */
16798         ret = GetOctetString(input, &idx, &length, sz);
16799         if (ret < 0) {
16800             WOLFSSL_MSG("\tfail: bad OCTET STRING");
16801             return ret;
16802         }
16803 
16804         ret = DecodeExtensionType(input + idx, length, oid, critical, cert);
16805         if (ret == ASN_CRIT_EXT_E) {
16806             ret = 0;
16807             criticalFail = 1;
16808         }
16809         if (ret < 0)
16810             goto end;
16811         idx += length;
16812     }
16813 
16814     ret = criticalFail ? ASN_CRIT_EXT_E : 0;
16815 end:
16816     return ret;
16817 #else
16818     DECL_ASNGETDATA(dataASN, certExtASN_Length);
16819     ASNGetData dataExtsASN[certExtHdrASN_Length];
16820     int ret = 0;
16821     const byte* input = cert->extensions;
16822     int sz = cert->extensionsSz;
16823     word32 idx = 0;
16824     int criticalRet = 0;
16825     int offset = 0;
16826 
16827     WOLFSSL_ENTER("DecodeCertExtensions");
16828 
16829     if (input == NULL || sz == 0)
16830         ret = BAD_FUNC_ARG;
16831 
16832     ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, cert->heap);
16833 
16834 #ifdef WOLFSSL_CERT_REQ
16835     if (cert->isCSR) {
16836         offset = CERTEXTHDRASN_IDX_EXTSEQ;
16837     }
16838 #endif
16839     if (ret == 0) {
16840         /* Clear dynamic data. */
16841         XMEMSET(dataExtsASN, 0, sizeof(dataExtsASN));
16842         /* Parse extensions header. */
16843         ret = GetASN_Items(certExtHdrASN + offset, dataExtsASN + offset,
16844                            certExtHdrASN_Length - offset, 0, input, &idx, sz);
16845     }
16846     /* Parse each extension. */
16847     while ((ret == 0) && (idx < (word32)sz)) {
16848         byte critical = 0;
16849 
16850         /* Clear dynamic data. */
16851         XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
16852         /* Ensure OID is an extention type. */
16853         GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
16854         /* Set criticality variable. */
16855         GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
16856         /* Parse extension wrapper. */
16857         ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
16858                            &idx, sz);
16859         if (ret == 0) {
16860             word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
16861             int length = dataASN[CERTEXTASN_IDX_VAL].length;
16862 
16863             /* Decode the extension by type. */
16864             ret = DecodeExtensionType(input + idx, length, oid, critical, cert);
16865             /* Move index on to next extension. */
16866             idx += length;
16867         }
16868         /* Don't fail criticality until all other extensions have been checked.
16869          */
16870         if (ret == ASN_CRIT_EXT_E) {
16871             criticalRet = ASN_CRIT_EXT_E;
16872             ret = 0;
16873         }
16874     }
16875 
16876     if (ret == 0) {
16877         /* Use criticality return. */
16878         ret = criticalRet;
16879     }
16880 
16881     FREE_ASNGETDATA(dataASN, cert->heap);
16882     return ret;
16883 #endif
16884 }
16885 
16886 #ifdef WOLFSSL_ASN_TEMPLATE
16887 /* ASN template for an X509 certificate.
16888  * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
16889  */
16890 static const ASNItem x509CertASN[] = {
16891         /* Certificate ::= SEQUENCE */
16892 /* SEQ                           */    { 0, ASN_SEQUENCE, 1, 1, 0 },
16893                                                    /* tbsCertificate       TBSCertificate */
16894                                                    /* TBSCertificate ::= SEQUENCE */
16895 /* TBS_SEQ                       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
16896                                                    /* version         [0]  EXPLICT Version DEFAULT v1 */
16897 /* TBS_VER                       */            { 2, ASN_CONTEXT_SPECIFIC | ASN_X509_CERT_VERSION, 1, 1, 1 },
16898                                                    /* Version ::= INTEGER { v1(0), v2(1), v3(2) */
16899 /* TBS_VER_INT                   */                { 3, ASN_INTEGER, 0, 0, 0 },
16900                                                    /* serialNumber         CertificateSerialNumber */
16901                                                    /* CetificateSerialNumber ::= INTEGER */
16902 /* TBS_SERIAL                    */            { 2, ASN_INTEGER, 0, 0, 0 },
16903                                                    /* signature            AlgorithmIdentifier */
16904                                                    /* AlgorithmIdentifier ::= SEQUENCE */
16905 /* TBS_ALGOID_SEQ                */            { 2, ASN_SEQUENCE, 1, 1, 0 },
16906                                                    /* Algorithm    OBJECT IDENTIFIER */
16907 /* TBS_ALGOID_OID                */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
16908                                                    /* parameters   ANY defined by algorithm OPTIONAL */
16909 /* TBS_ALGOID_PARAMS             */                { 3, ASN_TAG_NULL, 0, 0, 1 },
16910                                                    /* issuer               Name */
16911 /* TBS_ISSUER_SEQ                */            { 2, ASN_SEQUENCE, 1, 0, 0 },
16912                                                    /* validity             Validity */
16913                                                    /* Validity ::= SEQUENCE */
16914 /* TBS_VALIDITY_SEQ              */            { 2, ASN_SEQUENCE, 1, 1, 0 },
16915                                                    /* notBefore   Time */
16916                                                    /* Time :: CHOICE { UTCTime, GeneralizedTime } */
16917 /* TBS_VALIDITY_NOTB_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 2 },
16918 /* TBS_VALIDITY_NOTB_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 2 },
16919                                                    /* notAfter   Time */
16920                                                    /* Time :: CHOICE { UTCTime, GeneralizedTime } */
16921 /* TBS_VALIDITY_NOTA_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 3 },
16922 /* TBS_VALIDITY_NOTA_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 3 },
16923                                                    /* subject              Name */
16924 /* TBS_SUBJECT_SEQ               */            { 2, ASN_SEQUENCE, 1, 0, 0 },
16925                                                    /* subjectPublicKeyInfo SubjectPublicKeyInfo */
16926 /* TBS_SPUBKEYINFO_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
16927                                                    /* algorithm          AlgorithmIdentifier */
16928                                                    /* AlgorithmIdentifier ::= SEQUENCE */
16929 /* TBS_SPUBKEYINFO_ALGO_SEQ      */                { 3, ASN_SEQUENCE, 1, 1, 0 },
16930                                                    /* Algorithm    OBJECT IDENTIFIER */
16931 /* TBS_SPUBKEYINFO_ALGO_OID      */                    { 4, ASN_OBJECT_ID, 0, 0, 0 },
16932                                                    /* parameters   ANY defined by algorithm OPTIONAL */
16933 /* TBS_SPUBKEYINFO_ALGO_NOPARAMS */                    { 4, ASN_TAG_NULL, 0, 0, 1 },
16934 /* TBS_SPUBKEYINFO_ALGO_CURVEID  */                    { 4, ASN_OBJECT_ID, 0, 0, 1 },
16935                                                    /* subjectPublicKey   BIT STRING */
16936 /* TBS_SPUBKEYINFO_PUBKEY        */                { 3, ASN_BIT_STRING, 0, 0, 0 },
16937                                                    /* issuerUniqueID       UniqueIdentfier OPTIONAL */
16938 /* TBS_ISSUERUID                 */            { 2, ASN_CONTEXT_SPECIFIC | 1, 0, 0, 1 },
16939                                                    /* subjectUniqueID      UniqueIdentfier OPTIONAL */
16940 /* TBS_SUBJECTUID                */            { 2, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 1 },
16941                                                    /* extensions           Extensions OPTIONAL */
16942 /* TBS_EXT                       */            { 2, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 1 },
16943 /* TBS_EXT_SEQ                   */                { 3, ASN_SEQUENCE, 1, 0, 0 },
16944                                                    /* signatureAlgorithm   AlgorithmIdentifier */
16945                                                    /* AlgorithmIdentifier ::= SEQUENCE */
16946 /* SIGALGO_SEQ                   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
16947                                                    /* Algorithm    OBJECT IDENTIFIER */
16948 /* SIGALGO_OID                   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
16949                                                    /* parameters   ANY defined by algorithm OPTIONAL */
16950 /* SIGALGO_PARAMS                */            { 2, ASN_TAG_NULL, 0, 0, 1 },
16951                                                    /* signature            BIT STRING */
16952 /* SIGNATURE                     */        { 1, ASN_BIT_STRING, 0, 0, 0 },
16953 };
16954 enum {
16955     X509CERTASN_IDX_SEQ = 0,
16956     X509CERTASN_IDX_TBS_SEQ,
16957     X509CERTASN_IDX_TBS_VER,
16958     X509CERTASN_IDX_TBS_VER_INT,
16959     X509CERTASN_IDX_TBS_SERIAL,
16960     X509CERTASN_IDX_TBS_ALGOID_SEQ,
16961     X509CERTASN_IDX_TBS_ALGOID_OID,
16962     X509CERTASN_IDX_TBS_ALGOID_PARAMS,
16963     X509CERTASN_IDX_TBS_ISSUER_SEQ,
16964     X509CERTASN_IDX_TBS_VALIDITY_SEQ,
16965     X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC,
16966     X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT,
16967     X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC,
16968     X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT,
16969     X509CERTASN_IDX_TBS_SUBJECT_SEQ,
16970     X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ,
16971     X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
16972     X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID,
16973     X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_NOPARAMS,
16974     X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID,
16975     X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY,
16976     X509CERTASN_IDX_TBS_ISSUERUID,
16977     X509CERTASN_IDX_TBS_SUBJECTUID,
16978     X509CERTASN_IDX_TBS_EXT,
16979     X509CERTASN_IDX_TBS_EXT_SEQ,
16980     X509CERTASN_IDX_SIGALGO_SEQ,
16981     X509CERTASN_IDX_SIGALGO_OID,
16982     X509CERTASN_IDX_SIGALGO_PARAMS,
16983     X509CERTASN_IDX_SIGNATURE,
16984 };
16985 
16986 /* Number of items in ASN template for an X509 certificate. */
16987 #define x509CertASN_Length (sizeof(x509CertASN) / sizeof(ASNItem))
16988 
16989 /* Check the data data.
16990  *
16991  * @param [in] dataASN   ASN template dynamic data item.
16992  * @param [in] dataType  BEFORE or AFTER date.
16993  * @return  0 on success.
16994  * @return  ASN_TIME_E when BER tag is nor UTC or GENERALIZED time.
16995  * @return  ASN_DATE_SZ_E when time data is not supported.
16996  * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
16997  * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
16998  */
16999 static int CheckDate(ASNGetData *dataASN, int dateType)
17000 {
17001     int ret = 0;
17002 
17003     /* Check BER tag is valid. */
17004     if ((dataASN->tag != ASN_UTC_TIME) &&
17005             (dataASN->tag != ASN_GENERALIZED_TIME)) {
17006         ret = ASN_TIME_E;
17007     }
17008     /* Check date length is valid. */
17009     if ((ret == 0) && ((dataASN->length > MAX_DATE_SIZE) ||
17010                        (dataASN->length < MIN_DATE_SIZE))) {
17011         ret = ASN_DATE_SZ_E;
17012     }
17013 
17014 #ifndef NO_ASN_TIME
17015     /* Check date is a valid string and BEFORE or AFTER now. */
17016     if ((ret == 0) &&
17017             (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType))) {
17018         if (dateType == BEFORE) {
17019             ret = ASN_BEFORE_DATE_E;
17020         }
17021         else {
17022             ret = ASN_AFTER_DATE_E;
17023         }
17024     }
17025 #endif
17026     (void)dateType;
17027 
17028     return ret;
17029 }
17030 
17031 /* Decode a certificate. Internal/non-public API.
17032  *
17033  * @param [in]  cert             Certificate object.
17034  * @param [in]  verify           Whether to verify dates before and after now.
17035  * @param [out] criticalExt      Critical extension return code.
17036  * @param [out] badDateRet       Bad date return code.
17037  * @param [in]  stopAtPubKey     Stop parsing before subkectPublicKeyInfo.
17038  * @param [in]  stopAfterPubKey  Stop parsing after subkectPublicKeyInfo.
17039  * @return  0 on success.
17040  * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
17041  * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
17042  * @return  ASN_DATE_SZ_E when time data is not supported.
17043  * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
17044  * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
17045  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17046  *          is invalid.
17047  * @return  BUFFER_E when data in buffer is too small.
17048  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17049  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
17050  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
17051  *          non-zero length.
17052  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17053  */
17054 static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
17055                               int* badDateRet, int stopAtPubKey,
17056                               int stopAfterPubKey)
17057 {
17058     DECL_ASNGETDATA(dataASN, x509CertASN_Length);
17059     int ret = 0;
17060     int badDate = 0;
17061     int i;
17062     byte version;
17063     word32 idx;
17064     word32 serialSz;
17065     int done = 0;
17066 
17067     CALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
17068 
17069     if (ret == 0) {
17070         version = 0;
17071         serialSz = EXTERNAL_SERIAL_SIZE;
17072 
17073         /* Get the version and put the serial number into the buffer. */
17074         GetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], &version);
17075         GetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
17076                 &serialSz);
17077         /* Check OID types for signature, algorithm, ECC curve and sigAlg. */
17078         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
17079         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
17080                 oidKeyType);
17081         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
17082                 oidCurveType);
17083         GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
17084         /* Parse the X509 certificate. */
17085         ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1,
17086                            cert->source, &cert->srcIdx, cert->maxIdx);
17087     }
17088     /* Check version is valid/supported - can't be negative. */
17089     if ((ret == 0) && (version > MAX_X509_VERSION)) {
17090         WOLFSSL_MSG("Unexpected certificate version");
17091         ret = ASN_PARSE_E;
17092     }
17093     if (ret == 0) {
17094         /* Set fields extracted from data. */
17095         cert->version = version;
17096         cert->serialSz = serialSz;
17097         cert->signatureOID = dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum;
17098         cert->keyOID = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID].data.oid.sum;
17099         cert->certBegin = dataASN[X509CERTASN_IDX_TBS_SEQ].offset;
17100 
17101         /* No bad date error - don't always care. */
17102         badDate = 0;
17103         /* Find the item with the BEFORE date and check it. */
17104         i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].tag != 0)
17105                 ? X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC
17106                 : X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT;
17107         if ((CheckDate(&dataASN[i], BEFORE) < 0) && verify) {
17108             badDate = ASN_BEFORE_DATE_E;
17109         }
17110         /* Store reference to BEFOREdate. */
17111         cert->beforeDate = GetASNItem_Addr(dataASN[i], cert->source);
17112         cert->beforeDateLen = GetASNItem_Length(dataASN[i], cert->source);
17113 
17114         /* Find the item with the AFTER date and check it. */
17115         i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].tag != 0)
17116                 ? X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC
17117                 : X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT;
17118         if ((CheckDate(&dataASN[i], AFTER) < 0) && verify) {
17119             badDate = ASN_AFTER_DATE_E;
17120         }
17121         /* Store reference to AFTER date. */
17122         cert->afterDate = GetASNItem_Addr(dataASN[i], cert->source);
17123         cert->afterDateLen = GetASNItem_Length(dataASN[i], cert->source);
17124 
17125         /* Get the issuer name and calculate hash. */
17126         idx = dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
17127         ret = GetCertName(cert, cert->issuer, cert->issuerHash, ISSUER,
17128                           cert->source, &idx,
17129                           dataASN[X509CERTASN_IDX_TBS_VALIDITY_SEQ].offset);
17130     }
17131     if (ret == 0) {
17132         /* Get the subject name and calculate hash. */
17133         idx = dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
17134         ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
17135                           cert->source, &idx,
17136                           dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset);
17137     }
17138     if (ret == 0) {
17139         /* Determine if self signed by comparing issuer and subject hashes. */
17140         cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash,
17141                                    KEYID_SIZE) == 0 ? 1 : 0;
17142 
17143         if (stopAtPubKey) {
17144             /* Return any bad date error through badDateRet and return offset of
17145              * subjectPublicKeyInfo.
17146              */
17147             if (badDateRet != NULL) {
17148                 *badDateRet = badDate;
17149             }
17150             ret = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
17151             done = 1;
17152         }
17153     }
17154 
17155     if ((ret == 0) && (!done)) {
17156         /* Parse the public key. */
17157         idx = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
17158         ret = GetCertKey(cert, cert->source, &idx,
17159                 dataASN[X509CERTASN_IDX_TBS_ISSUERUID].offset);
17160         if ((ret == 0) && stopAfterPubKey) {
17161             /* Return any bad date error through badDateRed and return offset
17162              * after subjectPublicKeyInfo.
17163              */
17164             if (badDateRet != NULL) {
17165                 *badDateRet = badDate;
17166             }
17167             done = 1;
17168         }
17169     }
17170     if ((ret == 0) && (!done) &&
17171             (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
17172     #ifndef ALLOW_V1_EXTENSIONS
17173         /* Certificate extensions were only defined in version 2. */
17174         if (cert->version < 2) {
17175             WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
17176             ret = ASN_VERSION_E;
17177         }
17178     #endif
17179         if (ret == 0) {
17180             /* Save references to extension data. */
17181             cert->extensions    = GetASNItem_Addr(
17182                     dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
17183             cert->extensionsSz  = GetASNItem_Length(
17184                     dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
17185             cert->extensionsIdx = dataASN[X509CERTASN_IDX_TBS_EXT].offset;
17186 
17187             /* Decode the extension data starting at [3]. */
17188             ret = DecodeCertExtensions(cert);
17189             if (criticalExt != NULL) {
17190                 if (ret == ASN_CRIT_EXT_E) {
17191                     /* Return critical extension not recognized. */
17192                     *criticalExt = ret;
17193                     ret = 0;
17194                 }
17195                 else {
17196                     /* No critical extension error. */
17197                     *criticalExt = 0;
17198                 }
17199             }
17200         }
17201         if (ret == 0) {
17202             /* Advance past extensions. */
17203             cert->srcIdx = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
17204         }
17205     }
17206 
17207     if ((ret == 0) && (!done)) {
17208         /* Store the signature information. */
17209         cert->sigIndex = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
17210         GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE],
17211                 &cert->signature, &cert->sigLength);
17212         /* Make sure 'signature' and 'signatureAlgorithm' are the same. */
17213         if (dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum
17214                 != cert->signatureOID) {
17215             ret = ASN_SIG_OID_E;
17216         }
17217         /* NULL tagged item not allowed after ECDSA or EdDSA algorithm OID. */
17218         if (IsSigAlgoECC(cert->signatureOID) &&
17219                 (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0)) {
17220             ret = ASN_PARSE_E;
17221         }
17222     }
17223     if ((ret == 0) && (!done) && (badDate != 0)) {
17224         /* Parsed whole certificate fine but return any date errors. */
17225         ret = badDate;
17226     }
17227 
17228     FREE_ASNGETDATA(dataASN, cert->heap);
17229     return ret;
17230 }
17231 
17232 /* Decode BER/DER data into certificate object.
17233  *
17234  * BER/DER data information held in source, srcIdx and maxIdx fields of
17235  * certificate object.
17236  *
17237  * @param [in] cert         Decoded certificate object.
17238  * @param [in] verify       Whether to find CA and verify certificate.
17239  * @param [in] criticalExt  Any error for critical extensions not recognized.
17240  * @return  0 on success.
17241  * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
17242  * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
17243  * @return  ASN_DATE_SZ_E when time data is not supported.
17244  * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
17245  * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
17246  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17247  *          is invalid.
17248  * @return  BUFFER_E when data in buffer is too small.
17249  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17250  * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
17251  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
17252  *          non-zero length.
17253  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17254  */
17255 int DecodeCert(DecodedCert* cert, int verify, int* criticalExt)
17256 {
17257     return DecodeCertInternal(cert, verify, criticalExt, NULL, 0, 0);
17258 }
17259 
17260 #ifdef WOLFSSL_CERT_REQ
17261 /* ASN.1 template for certificate request Attribute.
17262  * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
17263  */
17264 static const ASNItem reqAttrASN[] = {
17265 /* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17266                               /* type */
17267 /* TYPE */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
17268                               /* values */
17269 /* VALS */     { 1, ASN_SET, 1, 0, 0 },
17270 };
17271 enum {
17272     REQATTRASN_IDX_SEQ = 0,
17273     REQATTRASN_IDX_TYPE,
17274     REQATTRASN_IDX_VALS,
17275 };
17276 
17277 /* Number of items in ASN.1 template for certificate request Attribute. */
17278 #define reqAttrASN_Length (sizeof(reqAttrASN) / sizeof(ASNItem))
17279 
17280 /* ASN.1 template for a string choice. */
17281 static const ASNItem strAttrASN[] = {
17282     { 0, 0, 0, 0, 0 },
17283 };
17284 enum {
17285     STRATTRASN_IDX_STR = 0,
17286 };
17287 
17288 /* Number of items in ASN.1 template for a string choice. */
17289 #define strAttrASN_Length (sizeof(strAttrASN) / sizeof(ASNItem))
17290 
17291 /* ASN.1 choices for types for a string in an attribute. */
17292 static const byte strAttrChoice[] = {
17293     ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, 0
17294 };
17295 
17296 /* Decode a certificate request attribute's value.
17297  *
17298  * @param [in]  cert         Certificate request object.
17299  * @param [out] criticalExt  Critical extension return code.
17300  * @param [in]  oid          OID decribing which attribute was found.
17301  * @param [in]  aIdx         Index into certificate source to start parsing.
17302  * @param [in]  input        Attribute value data.
17303  * @param [in]  maxIdx       Maximum index to parse to.
17304  * @return  0 on success.
17305  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17306  *          is invalid.
17307  */
17308 static int DecodeCertReqAttrValue(DecodedCert* cert, int* criticalExt,
17309     word32 oid, word32 aIdx, const byte* input, word32 maxIdx)
17310 {
17311     int ret = 0;
17312     word32 idx = 0;
17313     ASNGetData strDataASN[strAttrASN_Length];
17314 
17315     switch (oid) {
17316         case PKCS9_CONTENT_TYPE_OID:
17317             /* Clear dynamic data and specify choices acceptable. */
17318             XMEMSET(strDataASN, 0, sizeof(strDataASN));
17319             GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
17320             /* Parse a string. */
17321             ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
17322                                1, input, &idx, maxIdx);
17323             if (ret == 0) {
17324                 /* Store references to password data. */
17325                 cert->contentType =
17326                         (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
17327                 cert->contentTypeLen =
17328                         strDataASN[STRATTRASN_IDX_STR].data.ref.length;
17329             }
17330             break;
17331 
17332         /* A password by which the entity may request certificate revocation.
17333          * PKCS#9: RFC 2985, 5.4.1 - Challenge password
17334          */
17335         case CHALLENGE_PASSWORD_OID:
17336             /* Clear dynamic data and specify choices acceptable. */
17337             XMEMSET(strDataASN, 0, sizeof(strDataASN));
17338             GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
17339             /* Parse a string. */
17340             ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
17341                                1, input, &idx, maxIdx);
17342             if (ret == 0) {
17343                 /* Store references to password data. */
17344                 cert->cPwd =
17345                         (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
17346                 cert->cPwdLen = strDataASN[STRATTRASN_IDX_STR].data.ref.length;
17347             }
17348             break;
17349 
17350         /* Requested serial number to issue with.
17351          * PKCS#9: RFC 2985, 5.2.10 - Serial Number
17352          * (References: ISO/IEC 9594-6:1997)
17353          */
17354         case SERIAL_NUMBER_OID:
17355             /* Clear dynamic data and specify choices acceptable. */
17356             XMEMSET(strDataASN, 0, sizeof(strDataASN));
17357             GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
17358             /* Parse a string. */
17359             ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
17360                                1, input, &idx, maxIdx);
17361             if (ret == 0) {
17362                 /* Store references to serial number. */
17363                 cert->sNum =
17364                         (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
17365                 cert->sNumLen = strDataASN[STRATTRASN_IDX_STR].data.ref.length;
17366                 /* Store serial number if small enough. */
17367                 if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
17368                     XMEMCPY(cert->serial, cert->sNum, cert->sNumLen);
17369                     cert->serialSz = cert->sNumLen;
17370                 }
17371             }
17372             break;
17373 
17374         /* Certificate extensions to be included in generated certificate.
17375          * PKCS#9: RFC 2985, 5.4.2 - Extension request
17376          */
17377         case EXTENSION_REQUEST_OID:
17378             /* Store references to all extensions. */
17379             cert->extensions    = input;
17380             cert->extensionsSz  = maxIdx;
17381             cert->extensionsIdx = aIdx;
17382 
17383             /* Decode and validate extensions. */
17384             ret = DecodeCertExtensions(cert);
17385             if (ret == ASN_CRIT_EXT_E) {
17386                 /* Return critical extension not recognized. */
17387                 *criticalExt = ret;
17388                 ret = 0;
17389             }
17390             else {
17391                 /* No critical extension error. */
17392                 *criticalExt = 0;
17393             }
17394             break;
17395 
17396         default:
17397             ret = ASN_PARSE_E;
17398             break;
17399     }
17400 
17401     return ret;
17402 }
17403 
17404 /* Decode attributes of a BER encoded certificate request.
17405  *
17406  * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
17407  *
17408  * Outer sequence has been removed.
17409  *
17410  * @param [in]  cert         Certificate request object.
17411  * @param [out] criticalExt  Critical extension return code.
17412  * @param [in]  idx          Index into certificate source to start parsing.
17413  * @param [in]  maxIdx       Maximum index to parse to.
17414  * @return  0 on success.
17415  * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
17416  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17417  *          is invalid.
17418  * @return  BUFFER_E when data in buffer is too small.
17419  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17420  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
17421  *          non-zero length.
17422  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17423  */
17424 static int DecodeCertReqAttributes(DecodedCert* cert, int* criticalExt,
17425                                    word32 idx, word32 maxIdx)
17426 {
17427     DECL_ASNGETDATA(dataASN, reqAttrASN_Length);
17428     int ret = 0;
17429 
17430     WOLFSSL_ENTER("DecodeCertReqAttributes");
17431 
17432     ALLOC_ASNGETDATA(dataASN, reqAttrASN_Length, ret, cert->heap);
17433 
17434     /* Parse each attribute until all data used up. */
17435     while ((ret == 0) && (idx < maxIdx)) {
17436         /* Clear dynamic data. */
17437         XMEMSET(dataASN, 0, sizeof(ASNGetData) * reqAttrASN_Length);
17438         GetASN_OID(&dataASN[REQATTRASN_IDX_TYPE], oidIgnoreType);
17439 
17440         /* Parse an attribute. */
17441         ret = GetASN_Items(reqAttrASN, dataASN, reqAttrASN_Length, 0,
17442                            cert->source, &idx, maxIdx);
17443         /* idx is now at end of attribute data. */
17444         if (ret == 0) {
17445             ret = DecodeCertReqAttrValue(cert, criticalExt,
17446                 dataASN[REQATTRASN_IDX_TYPE].data.oid.sum,
17447                 GetASNItem_DataIdx(dataASN[REQATTRASN_IDX_VALS], cert->source),
17448                 dataASN[REQATTRASN_IDX_VALS].data.ref.data,
17449                 dataASN[REQATTRASN_IDX_VALS].data.ref.length);
17450         }
17451     }
17452 
17453     FREE_ASNGETDATA(dataASN, cert->heap);
17454     return ret;
17455 }
17456 
17457 /* ASN.1 template for a certificate request.
17458  * PKCS#10: RFC 2986, 4.1 - CertificationRequestInfo
17459  * PKCS#10: RFC 2986, 4.2 - CertificationRequest
17460  */
17461 static const ASNItem certReqASN[] = {
17462             /* CertificationRequest */
17463 /* SEQ                              */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17464                                                           /* CertificationRequestInfo */
17465 /* INFO_SEQ                         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
17466                                                               /* version              INTEGER { v1(0), v2(1), v3(2) */
17467 /* INFO_VER                         */         { 2, ASN_INTEGER, 0, 0, 0 },
17468                                                               /* subject              Name */
17469 /* INFO_SUBJ_SEQ                    */         { 2, ASN_SEQUENCE, 1, 0, 0 },
17470                                                               /* subjectPublicKeyInfo SubjectPublicKeyInfo */
17471 /* INFO_SPUBKEYINFO_SEQ             */         { 2, ASN_SEQUENCE, 1, 1, 0 },
17472                                                                   /* algorithm          AlgorithmIdentifier */
17473 /* INFO_SPUBKEYINFO_ALGOID_SEQ      */             { 3, ASN_SEQUENCE, 1, 1, 0 },
17474                                                                       /* Algorithm    OBJECT IDENTIFIER */
17475 /* INFO_SPUBKEYINFO_ALGOID_OID      */                 { 4, ASN_OBJECT_ID, 0, 0, 0 },
17476                                                                       /* parameters   ANY defined by algorithm OPTIONAL */
17477 /* INFO_SPUBKEYINFO_ALGOID_NOPARAMS */                 { 4, ASN_TAG_NULL, 0, 0, 1 },
17478 /* INFO_SPUBKEYINFO_ALGOID_CURVEID  */                 { 4, ASN_OBJECT_ID, 0, 0, 1 },
17479 /* INFO_SPUBKEYINFO_ALGOID_PARAMS   */                 { 4, ASN_SEQUENCE, 1, 0, 1 },
17480                                                                   /* subjectPublicKey   BIT STRING */
17481 /* INFO_SPUBKEYINFO_PUBKEY          */             { 3, ASN_BIT_STRING, 0, 0, 0 },
17482                                                               /* attributes       [0] Attributes */
17483 /* INFO_ATTRS                       */         { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
17484                                                           /* signatureAlgorithm   AlgorithmIdentifier */
17485 /* INFO_SIGALGO_SEQ                 */     { 1, ASN_SEQUENCE, 1, 1, 0 },
17486                                                               /* Algorithm    OBJECT IDENTIFIER */
17487 /* INFO_SIGALGO_OID                 */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
17488                                                               /* parameters   ANY defined by algorithm OPTIONAL */
17489 /* INFO_SIGALGO_NOPARAMS            */         { 2, ASN_TAG_NULL, 0, 0, 1 },
17490                                                           /* signature            BIT STRING */
17491 /* INFO_SIGNATURE                   */     { 1, ASN_BIT_STRING, 0, 0, 0 },
17492 };
17493 enum {
17494     CERTREQASN_IDX_SEQ = 0,
17495     CERTREQASN_IDX_INFO_SEQ,
17496     CERTREQASN_IDX_INFO_VER,
17497     CERTREQASN_IDX_INFO_SUBJ_SEQ,
17498     CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ,
17499     CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_SEQ,
17500     CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID,
17501     CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_NOPARAMS,
17502     CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID,
17503     CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_PARAMS,
17504     CERTREQASN_IDX_INFO_SPUBKEYINFO_PUBKEY,
17505     CERTREQASN_IDX_INFO_ATTRS,
17506     CERTREQASN_IDX_INFO_SIGALGO_SEQ,
17507     CERTREQASN_IDX_INFO_SIGALGO_OID,
17508     CERTREQASN_IDX_INFO_SIGALGO_NOPARAMS,
17509     CERTREQASN_IDX_INFO_SIGNATURE,
17510 };
17511 
17512 /* Number of items in ASN.1 template for a certificate request. */
17513 #define certReqASN_Length (sizeof(certReqASN) / sizeof(ASNItem))
17514 
17515 /* Parse BER encoded certificate request.
17516  *
17517  * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
17518  *
17519  * @param [in]  cert         Certificate request object.
17520  * @param [out] criticalExt  Critical extension return code.
17521  * @return  0 on success.
17522  * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
17523  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17524  *          is invalid.
17525  * @return  BUFFER_E when data in buffer is too small.
17526  * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17527  * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
17528  *          non-zero length.
17529  * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17530  * @return  MEMORY_E on dynamic memory allocation failure.
17531  */
17532 static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
17533 {
17534     DECL_ASNGETDATA(dataASN, certReqASN_Length);
17535     int ret = 0;
17536     byte version;
17537     word32 idx;
17538 
17539     CALLOC_ASNGETDATA(dataASN, certReqASN_Length, ret, cert->heap);
17540 
17541     if (ret == 0) {
17542         /* Default version is 0. */
17543         version = 0;
17544 
17545         /* Set version var and OID types to expect. */
17546         GetASN_Int8Bit(&dataASN[CERTREQASN_IDX_INFO_VER], &version);
17547         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
17548                 oidKeyType);
17549         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
17550                 oidCurveType);
17551         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
17552         /* Parse a certificate request. */
17553         ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1,
17554                            cert->source, &cert->srcIdx, cert->maxIdx);
17555     }
17556     /* Check version is valid/supported - can't be negative. */
17557     if ((ret == 0) && (version > MAX_X509_VERSION)) {
17558         WOLFSSL_MSG("Unexpected certificate request version");
17559         ret = ASN_PARSE_E;
17560     }
17561     if (ret == 0) {
17562         /* Set fields of certificate request. */
17563         cert->version = version;
17564         cert->signatureOID =
17565               dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
17566         cert->keyOID =
17567               dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID].data.oid.sum;
17568         cert->certBegin = dataASN[CERTREQASN_IDX_INFO_SEQ].offset;
17569 
17570         /* Parse the subject name. */
17571         idx = dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ].offset;
17572         ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
17573                           cert->source, &idx,
17574                           dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset);
17575     }
17576     if (ret == 0) {
17577         /* Parse the certificate request Attributes. */
17578         ret = DecodeCertReqAttributes(cert, criticalExt,
17579                 GetASNItem_DataIdx(dataASN[CERTREQASN_IDX_INFO_ATTRS],
17580                         cert->source),
17581                 dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset);
17582     }
17583     if (ret == 0) {
17584         /* Parse the certificate request's key. */
17585         idx = dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset;
17586         ret = GetCertKey(cert, cert->source, &idx,
17587                 dataASN[CERTREQASN_IDX_INFO_ATTRS].offset);
17588     }
17589     if (ret == 0) {
17590         /* Store references to signature. */
17591         cert->sigIndex = dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset;
17592         GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE],
17593                 &cert->signature, &cert->sigLength);
17594     }
17595 
17596     FREE_ASNGETDATA(dataASN, cert->heap);
17597     return ret;
17598 }
17599 
17600 #endif /* WOLFSSL_CERT_REQ */
17601 
17602 #endif
17603 
17604 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
17605 {
17606     int   ret;
17607 #ifndef WOLFSSL_NO_MALLOC
17608     char* ptr;
17609 #endif
17610 
17611     ret = ParseCertRelative(cert, type, verify, cm);
17612     if (ret < 0)
17613         return ret;
17614 
17615 #ifndef WOLFSSL_NO_MALLOC
17616     /* cert->subjectCN not stored as copy of WOLFSSL_NO_MALLOC defind */
17617     if (cert->subjectCNLen > 0) {
17618         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
17619                               DYNAMIC_TYPE_SUBJECT_CN);
17620         if (ptr == NULL)
17621             return MEMORY_E;
17622         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
17623         ptr[cert->subjectCNLen] = '\0';
17624         cert->subjectCN = ptr;
17625         cert->subjectCNStored = 1;
17626     }
17627 #endif
17628 
17629 #ifndef WOLFSSL_NO_MALLOC
17630     /* cert->publicKey not stored as copy if WOLFSSL_NO_MALLOC defined */
17631     if (cert->keyOID == RSAk &&
17632                           cert->publicKey != NULL  && cert->pubKeySize > 0) {
17633         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
17634                               DYNAMIC_TYPE_PUBLIC_KEY);
17635         if (ptr == NULL)
17636             return MEMORY_E;
17637         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
17638         cert->publicKey = (byte *)ptr;
17639         cert->pubKeyStored = 1;
17640     }
17641 #endif
17642 
17643     return ret;
17644 }
17645 
17646 int wc_ParseCert(DecodedCert* cert, int type, int verify, void* cm)
17647 {
17648     return ParseCert(cert, type, verify, cm);
17649 }
17650 
17651 #if !defined(OPENSSL_EXTRA) && !defined(OPENSSL_EXTRA_X509_SMALL) && \
17652     !defined(GetCA)
17653 /* from SSL proper, for locking can't do find here anymore.
17654  * brought in from internal.h if built with compat layer.
17655  * if defined(GetCA), it's a predefined macro and these prototypes
17656  * would conflict.
17657  */
17658 #ifdef __cplusplus
17659     extern "C" {
17660 #endif
17661     Signer* GetCA(void* signers, byte* hash);
17662     #ifndef NO_SKID
17663         Signer* GetCAByName(void* signers, byte* hash);
17664     #endif
17665 #ifdef __cplusplus
17666     }
17667 #endif
17668 
17669 #endif /* !OPENSSL_EXTRA && !OPENSSL_EXTRA_X509_SMALL && !GetCA */
17670 
17671 #if defined(WOLFCRYPT_ONLY)
17672 
17673 /* dummy functions, not using wolfSSL so don't need actual ones */
17674 Signer* GetCA(void* signers, byte* hash)
17675 {
17676     (void)hash;
17677 
17678     return (Signer*)signers;
17679 }
17680 
17681 #ifndef NO_SKID
17682 Signer* GetCAByName(void* signers, byte* hash)
17683 {
17684     (void)hash;
17685 
17686     return (Signer*)signers;
17687 }
17688 #endif /* NO_SKID */
17689 
17690 #endif /* WOLFCRYPT_ONLY */
17691 
17692 #if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
17693 static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
17694 {
17695     Signer* ca = NULL;
17696     if (cert->extSubjKeyIdSet)
17697         ca = GetCA(cm, cert->extSubjKeyId);
17698     if (ca == NULL)
17699         ca = GetCAByName(cm, cert->subjectHash);
17700     if (ca) {
17701         if ((ca->pubKeySize == cert->pubKeySize) &&
17702                (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
17703             return ca;
17704         }
17705     }
17706     return NULL;
17707 }
17708 #endif
17709 
17710 #if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
17711 #ifdef WOLFSSL_ASN_TEMPLATE
17712 /* Get the Hash of the Authority Key Identifier from the list of extensions.
17713  *
17714  * @param [in]  input   Input data.
17715  * @param [in]  maxIdx  Maximum index for data.
17716  * @param [out] hash    Hash of AKI.
17717  * @param [out] set     Whether the hash buffer was set.
17718  * @param [in]  heap    Dynamic memory allocation hint.
17719  * @return  0 on success.
17720  * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17721  *          is invalid.
17722  * @return  MEMORY_E on dynamic memory allocation failure.
17723  */
17724 static int GetAKIHash(const byte* input, word32 maxIdx, byte* hash, int* set,
17725                       void* heap)
17726 {
17727     /* AKI and Certificate Extenion ASN.1 templates are the same length. */
17728     DECL_ASNGETDATA(dataASN, certExtASN_Length);
17729     int ret = 0;
17730     word32 idx = 0;
17731     word32 extEndIdx;
17732     byte* extData;
17733     word32 extDataSz;
17734     byte critical;
17735 
17736     ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, heap);
17737     (void)heap;
17738 
17739     extEndIdx = idx + maxIdx;
17740 
17741     /* Step through each extension looking for AKI. */
17742     while ((ret == 0) && (idx < extEndIdx)) {
17743         /* Clear dynamic data and check for certificate extension type OIDs. */
17744         XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
17745         GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
17746         /* Set criticality variable. */
17747         GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
17748         /* Parse an extension. */
17749         ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
17750                 &idx, extEndIdx);
17751         if (ret == 0) {
17752             /* Get reference to extension data and move index on past this
17753              * extension. */
17754             GetASN_GetRef(&dataASN[CERTEXTASN_IDX_VAL], &extData, &extDataSz);
17755             idx += extDataSz;
17756 
17757             /* Check whether we have the AKI extension. */
17758             if (dataASN[CERTEXTASN_IDX_OID].data.oid.sum == AUTH_KEY_OID) {
17759                 /* Clear dynamic data. */
17760                 XMEMSET(dataASN, 0, sizeof(*dataASN) * authKeyIdASN_Length);
17761                 /* Start parsing extension data from the start. */
17762                 idx = 0;
17763                 /* Parse AKI extension data. */
17764                 ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length,
17765                         1, extData, &idx, extDataSz);
17766                 if ((ret == 0) &&
17767                         (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data
17768                                 != NULL)) {
17769                     /* We parsed successfully and have data. */
17770                     *set = 1;
17771                     /* Get the hash or hash of the hash if wrong size. */
17772                     ret = GetHashId(
17773                             dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
17774                             dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
17775                             hash);
17776                 }
17777                 break;
17778             }
17779         }
17780     }
17781 
17782     FREE_ASNGETDATA(dataASN, heap);
17783     return ret;
17784 }
17785 #endif
17786 
17787 /* Only quick step through the certificate to find fields that are then used
17788  * in certificate signature verification.
17789  * Must use the signature OID from the signed part of the certificate.
17790  * Works also on certificate signing requests.
17791  *
17792  * This is only for minimizing dynamic memory usage during TLS certificate
17793  * chain processing.
17794  * Doesn't support:
17795  *   OCSP Only: alt lookup using subject and pub key w/o sig check
17796  */
17797 static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
17798         void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req)
17799 {
17800 #ifndef WOLFSSL_ASN_TEMPLATE
17801 #ifndef WOLFSSL_SMALL_STACK
17802     SignatureCtx  sigCtx[1];
17803 #else
17804     SignatureCtx* sigCtx;
17805 #endif
17806     byte          hash[KEYID_SIZE];
17807     Signer*       ca = NULL;
17808     word32        idx = 0;
17809     int           len;
17810     word32        tbsCertIdx = 0;
17811     word32        sigIndex   = 0;
17812     word32        signatureOID = 0;
17813     word32        oid = 0;
17814     word32        issuerIdx = 0;
17815     word32        issuerSz  = 0;
17816 #ifndef NO_SKID
17817     int           extLen = 0;
17818     word32        extIdx = 0;
17819     word32        extEndIdx = 0;
17820     int           extAuthKeyIdSet = 0;
17821 #endif
17822     int           ret = 0;
17823     word32        localIdx;
17824     byte          tag;
17825 
17826 
17827     if (cert == NULL) {
17828         return BAD_FUNC_ARG;
17829     }
17830 
17831 #ifdef WOLFSSL_SMALL_STACK
17832     sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
17833     if (sigCtx == NULL)
17834         return MEMORY_E;
17835 #endif
17836     InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
17837 
17838     /* Certificate SEQUENCE */
17839     if (GetSequence(cert, &idx, &len, certSz) < 0)
17840         ret = ASN_PARSE_E;
17841     if (ret == 0) {
17842         tbsCertIdx = idx;
17843 
17844         /* TBSCertificate SEQUENCE */
17845         if (GetSequence(cert, &idx, &len, certSz) < 0)
17846             ret = ASN_PARSE_E;
17847     }
17848     if (ret == 0) {
17849         sigIndex = len + idx;
17850 
17851         if ((idx + 1) > certSz)
17852             ret = BUFFER_E;
17853     }
17854     if (ret == 0) {
17855         /* version - optional */
17856         localIdx = idx;
17857         if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
17858             if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
17859                 idx++;
17860                 if (GetLength(cert, &idx, &len, certSz) < 0)
17861                     ret = ASN_PARSE_E;
17862                 idx += len;
17863             }
17864         }
17865     }
17866 
17867     if (ret == 0) {
17868         /* serialNumber */
17869         if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
17870             ret = ASN_PARSE_E;
17871     }
17872     if (ret == 0) {
17873         idx += len;
17874 
17875         /* signature */
17876         if (!req &&
17877                 GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
17878             ret = ASN_PARSE_E;
17879     }
17880 
17881     if (ret == 0) {
17882         issuerIdx = idx;
17883         /* issuer for cert or subject for csr */
17884         if (GetSequence(cert, &idx, &len, certSz) < 0)
17885             ret = ASN_PARSE_E;
17886     }
17887     if (ret == 0) {
17888         issuerSz = len + idx - issuerIdx;
17889     }
17890 #ifndef NO_SKID
17891     if (!req && ret == 0) {
17892         idx += len;
17893 
17894         /* validity */
17895         if (GetSequence(cert, &idx, &len, certSz) < 0)
17896             ret = ASN_PARSE_E;
17897     }
17898     if (!req && ret == 0) {
17899         idx += len;
17900 
17901         /* subject */
17902         if (GetSequence(cert, &idx, &len, certSz) < 0)
17903             ret = ASN_PARSE_E;
17904     }
17905     if (ret == 0) {
17906         idx += len;
17907 
17908         /* subjectPublicKeyInfo */
17909         if (GetSequence(cert, &idx, &len, certSz) < 0)
17910             ret = ASN_PARSE_E;
17911     }
17912     if (req && ret == 0) {
17913         idx += len;
17914 
17915         /* attributes */
17916         if (GetASNHeader_ex(cert,
17917                 ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
17918                 &len, certSz, 1) < 0)
17919             ret = ASN_PARSE_E;
17920     }
17921     if (!req) {
17922         if (ret == 0) {
17923             idx += len;
17924 
17925             if ((idx + 1) > certSz)
17926                 ret = BUFFER_E;
17927         }
17928         if (ret == 0) {
17929             /* issuerUniqueID - optional */
17930             localIdx = idx;
17931             if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
17932                 if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
17933                     idx++;
17934                     if (GetLength(cert, &idx, &len, certSz) < 0)
17935                         ret = ASN_PARSE_E;
17936                     idx += len;
17937                 }
17938             }
17939         }
17940         if (ret == 0) {
17941             if ((idx + 1) > certSz)
17942                 ret = BUFFER_E;
17943         }
17944         if (ret == 0) {
17945             /* subjectUniqueID - optional */
17946             localIdx = idx;
17947             if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
17948                 if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
17949                     idx++;
17950                     if (GetLength(cert, &idx, &len, certSz) < 0)
17951                         ret = ASN_PARSE_E;
17952                     idx += len;
17953                 }
17954             }
17955         }
17956 
17957         if (ret == 0) {
17958             if ((idx + 1) > certSz)
17959                 ret = BUFFER_E;
17960         }
17961         /* extensions - optional */
17962         localIdx = idx;
17963         if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
17964                 tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
17965             idx++;
17966             if (GetLength(cert, &idx, &extLen, certSz) < 0)
17967                 ret = ASN_PARSE_E;
17968             if (ret == 0) {
17969                 if (GetSequence(cert, &idx, &extLen, certSz) < 0)
17970                     ret = ASN_PARSE_E;
17971             }
17972             if (ret == 0) {
17973                 extEndIdx = idx + extLen;
17974 
17975                 /* Check each extension for the ones we want. */
17976                 while (ret == 0 && idx < extEndIdx) {
17977                     if (GetSequence(cert, &idx, &len, certSz) < 0)
17978                         ret = ASN_PARSE_E;
17979                     if (ret == 0) {
17980                         extIdx = idx;
17981                         if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
17982                                                                   certSz) < 0) {
17983                             ret = ASN_PARSE_E;
17984                         }
17985 
17986                         if (ret == 0) {
17987                             if ((extIdx + 1) > certSz)
17988                                 ret = BUFFER_E;
17989                         }
17990                     }
17991 
17992                     if (ret == 0) {
17993                         localIdx = extIdx;
17994                         if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
17995                                 tag == ASN_BOOLEAN) {
17996                             if (GetBoolean(cert, &extIdx, certSz) < 0)
17997                                 ret = ASN_PARSE_E;
17998                         }
17999                     }
18000                     if (ret == 0) {
18001                         if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
18002                             ret = ASN_PARSE_E;
18003                     }
18004 
18005                     if (ret == 0) {
18006                         switch (oid) {
18007                         case AUTH_KEY_OID:
18008                             if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
18009                                 ret = ASN_PARSE_E;
18010 
18011                             if (ret == 0 && (extIdx + 1) >= certSz)
18012                                 ret = BUFFER_E;
18013 
18014                             if (ret == 0 &&
18015                                     GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
18016                                     tag == (ASN_CONTEXT_SPECIFIC | 0)) {
18017                                 if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
18018                                     ret = ASN_PARSE_E;
18019                                 if (ret == 0) {
18020                                     extAuthKeyIdSet = 1;
18021                                     /* Get the hash or hash of the hash if wrong
18022                                      * size. */
18023                                     ret = GetHashId(cert + extIdx, extLen,
18024                                                     hash);
18025                                 }
18026                             }
18027                             break;
18028 
18029                         default:
18030                             break;
18031                         }
18032                     }
18033                     idx += len;
18034                 }
18035             }
18036         }
18037     }
18038     else if (ret == 0) {
18039         idx += len;
18040     }
18041 
18042     if (ret == 0 && pubKey == NULL) {
18043         if (extAuthKeyIdSet)
18044             ca = GetCA(cm, hash);
18045         if (ca == NULL) {
18046             ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
18047             if (ret == 0)
18048                 ca = GetCAByName(cm, hash);
18049         }
18050     }
18051 #else
18052     if (ret == 0 && pubKey == NULL) {
18053         ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
18054         if (ret == 0)
18055             ca = GetCA(cm, hash);
18056     }
18057 #endif /* !NO_SKID */
18058     if (ca == NULL && pubKey == NULL)
18059         ret = ASN_NO_SIGNER_E;
18060 
18061     if (ret == 0) {
18062         idx = sigIndex;
18063         /* signatureAlgorithm */
18064         if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
18065             ret = ASN_PARSE_E;
18066         /* In CSR signature data is not present in body */
18067         if (req)
18068             signatureOID = oid;
18069     }
18070     if (ret == 0) {
18071         if (oid != signatureOID)
18072             ret = ASN_SIG_OID_E;
18073     }
18074     if (ret == 0) {
18075         /* signatureValue */
18076         if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
18077             ret = ASN_PARSE_E;
18078     }
18079 
18080     if (ret == 0) {
18081         if (pubKey != NULL) {
18082             ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
18083                                sigIndex - tbsCertIdx,
18084                                pubKey, pubKeySz, pubKeyOID,
18085                                cert + idx, len, signatureOID, NULL);
18086         }
18087         else {
18088             ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
18089                                sigIndex - tbsCertIdx,
18090                                ca->publicKey, ca->pubKeySize, ca->keyOID,
18091                                cert + idx, len, signatureOID, NULL);
18092         }
18093         if (ret != 0) {
18094             WOLFSSL_MSG("Confirm signature failed");
18095         }
18096     }
18097 
18098     FreeSignatureCtx(sigCtx);
18099 #ifdef WOLFSSL_SMALL_STACK
18100     if (sigCtx != NULL)
18101         XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
18102 #endif
18103     return ret;
18104 #else /* WOLFSSL_ASN_TEMPLATE */
18105     /* X509 ASN.1 template longer than Certificate Request template. */
18106     DECL_ASNGETDATA(dataASN, x509CertASN_Length);
18107 #ifndef WOLFSSL_SMALL_STACK
18108     SignatureCtx  sigCtx[1];
18109 #else
18110     SignatureCtx* sigCtx = NULL;
18111 #endif
18112     byte hash[KEYID_SIZE];
18113     Signer* ca = NULL;
18114     int ret = 0;
18115     word32 idx = 0;
18116 #ifndef NO_SKID
18117     int extAuthKeyIdSet = 0;
18118 #endif
18119     const byte* tbs = NULL;
18120     word32 tbsSz = 0;
18121     const byte* sig = NULL;
18122     word32 sigSz = 0;
18123     word32 sigOID = 0;
18124     const byte* caName = NULL;
18125     word32 caNameLen = 0;
18126 
18127     (void)req;
18128     (void)heap;
18129 
18130     if (cert == NULL) {
18131         ret = BAD_FUNC_ARG;
18132     }
18133 
18134     ALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, heap);
18135 #ifdef WOLFSSL_SMALL_STACK
18136     if (ret == 0) {
18137         sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap,
18138                                                         DYNAMIC_TYPE_SIGNATURE);
18139         if (sigCtx == NULL) {
18140             ret = MEMORY_E;
18141         }
18142     }
18143 #endif
18144 
18145     InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
18146 
18147     if ((ret == 0) && (!req)) {
18148         /* Clear dynamic data for certificate items. */
18149         XMEMSET(dataASN, 0, sizeof(ASNGetData) * x509CertASN_Length);
18150         /* Set OID types expected for signature and public key. */
18151         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
18152         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
18153                 oidKeyType);
18154         GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
18155                 oidCurveType);
18156         GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
18157         /* Parse certificate. */
18158         ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1, cert,
18159                            &idx, certSz);
18160 
18161         /* Check signature OIDs match. */
18162         if ((ret == 0) && dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum
18163                 != dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum) {
18164             ret = ASN_SIG_OID_E;
18165         }
18166         /* Store the data for verification in the certificate. */
18167         if (ret == 0) {
18168             tbs = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
18169             tbsSz = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
18170             caName = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
18171                     cert);
18172             caNameLen = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
18173                     cert);
18174             sigOID = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
18175             GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE], &sig, &sigSz);
18176         }
18177     }
18178     else if (ret == 0) {
18179 #ifndef WOLFSSL_CERT_REQ
18180         ret = NOT_COMPILED_IN;
18181 #else
18182         /* Clear dynamic data for certificate request items. */
18183         XMEMSET(dataASN, 0, sizeof(ASNGetData) * certReqASN_Length);
18184         /* Set OID types expected for signature and public key. */
18185         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
18186                 oidKeyType);
18187         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
18188                 oidCurveType);
18189         GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
18190         /* Parse certificate request. */
18191         ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1, cert,
18192                            &idx, certSz);
18193         if (ret == 0) {
18194             /* Store the data for verification in the certificate. */
18195             tbs = GetASNItem_Addr(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
18196             tbsSz = GetASNItem_Length(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
18197             caName = GetASNItem_Addr(
18198                     dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
18199             caNameLen = GetASNItem_Length(
18200                     dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
18201             sigOID = dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
18202             GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE], &sig,
18203                     &sigSz);
18204         }
18205 #endif
18206     }
18207 
18208     /* If no public passed, then find the CA. */
18209     if ((ret == 0) && (pubKey == NULL)) {
18210 #ifndef NO_SKID
18211         /* Find the AKI extension in list of extensions and get hash. */
18212         if ((!req) &&
18213                 (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
18214             /* TODO: test case */
18215             ret = GetAKIHash(dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data,
18216                              dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.length,
18217                              hash, &extAuthKeyIdSet, heap);
18218         }
18219 
18220         /* Get the CA by hash one was found. */
18221         if (extAuthKeyIdSet) {
18222             ca = GetCA(cm, hash);
18223         }
18224         if (ca == NULL)
18225 #endif
18226         {
18227             /* Try hash of issuer name. */
18228             ret = CalcHashId(caName, caNameLen, hash);
18229             if (ret == 0) {
18230                 ca = GetCAByName(cm, hash);
18231             }
18232         }
18233 
18234         if (ca != NULL) {
18235             /* Extract public key information. */
18236             pubKey = ca->publicKey;
18237             pubKeySz = ca->pubKeySize;
18238             pubKeyOID = ca->keyOID;
18239         }
18240         else {
18241             /* No public key to verify with. */
18242             ret = ASN_NO_SIGNER_E;
18243         }
18244     }
18245 
18246     if (ret == 0) {
18247         /* Check signature. */
18248         ret = ConfirmSignature(sigCtx, tbs, tbsSz, pubKey, pubKeySz, pubKeyOID,
18249                 sig, sigSz, sigOID, NULL);
18250         if (ret != 0) {
18251             WOLFSSL_MSG("Confirm signature failed");
18252         }
18253     }
18254 
18255     FreeSignatureCtx(sigCtx);
18256 #ifdef WOLFSSL_SMALL_STACK
18257     if (sigCtx != NULL)
18258         XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
18259 #endif
18260     FREE_ASNGETDATA(dataASN, heap);
18261     return ret;
18262 #endif /* WOLFSSL_ASN_TEMPLATE */
18263 }
18264 
18265 #ifdef OPENSSL_EXTRA
18266 /* Call CheckCertSignature_ex using a public key buffer for verification
18267  */
18268 int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
18269         const byte* pubKey, word32 pubKeySz, int pubKeyOID)
18270 {
18271     return CheckCertSignature_ex(cert, certSz, heap, NULL,
18272             pubKey, pubKeySz, pubKeyOID, 0);
18273 }
18274 #ifdef WOLFSSL_CERT_REQ
18275 int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap,
18276         const byte* pubKey, word32 pubKeySz, int pubKeyOID)
18277 {
18278     return CheckCertSignature_ex(cert, certSz, heap, NULL,
18279             pubKey, pubKeySz, pubKeyOID, 1);
18280 }
18281 #endif /* WOLFSSL_CERT_REQ */
18282 #endif /* OPENSSL_EXTRA */
18283 #ifdef WOLFSSL_SMALL_CERT_VERIFY
18284 /* Call CheckCertSignature_ex using a certificate manager (cm)
18285  */
18286 int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
18287 {
18288     return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0, 0);
18289 }
18290 #endif /* WOLFSSL_SMALL_CERT_VERIFY */
18291 #endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
18292 
18293 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
18294 {
18295     int    ret = 0;
18296     int    checkPathLen = 0;
18297     int    decrementMaxPathLen = 0;
18298 #ifndef WOLFSSL_ASN_TEMPLATE
18299     word32 confirmOID = 0;
18300 #ifdef WOLFSSL_CERT_REQ
18301     int    len = 0;
18302 #endif
18303 #endif
18304 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
18305     int    idx = 0;
18306 #endif
18307     byte*  sce_tsip_encRsaKeyIdx;
18308 
18309     if (cert == NULL) {
18310         return BAD_FUNC_ARG;
18311     }
18312 
18313 #ifdef WOLFSSL_CERT_REQ
18314     if (type == CERTREQ_TYPE)
18315         cert->isCSR = 1;
18316 #endif
18317 
18318     if (cert->sigCtx.state == SIG_STATE_BEGIN) {
18319 #ifndef WOLFSSL_ASN_TEMPLATE
18320         cert->badDate = 0;
18321         cert->criticalExt = 0;
18322         if ((ret = DecodeToKey(cert, verify)) < 0) {
18323             if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
18324                 cert->badDate = ret;
18325             else
18326                 return ret;
18327         }
18328 
18329         WOLFSSL_MSG("Parsed Past Key");
18330 
18331 
18332 #ifdef WOLFSSL_CERT_REQ
18333         /* Read attributes */
18334         if (cert->isCSR) {
18335             if (GetASNHeader_ex(cert->source,
18336                     ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx,
18337                     &len, cert->maxIdx, 1) < 0) {
18338                 WOLFSSL_MSG("GetASNHeader_ex error");
18339                 return ASN_PARSE_E;
18340             }
18341 
18342             if (len) {
18343                 word32 attrMaxIdx = cert->srcIdx + len;
18344                 word32 oid;
18345                 byte   tag;
18346 
18347                 if (attrMaxIdx > cert->maxIdx) {
18348                     WOLFSSL_MSG("Attribute length greater than CSR length");
18349                     return ASN_PARSE_E;
18350                 }
18351 
18352                 while (cert->srcIdx < attrMaxIdx) {
18353                     /* Attributes have the structure:
18354                      * SEQ -> OID -> SET -> ATTRIBUTE */
18355                     if (GetSequence(cert->source, &cert->srcIdx, &len,
18356                             attrMaxIdx) < 0) {
18357                         WOLFSSL_MSG("attr GetSequence error");
18358                         return ASN_PARSE_E;
18359                     }
18360                     if (GetObjectId(cert->source, &cert->srcIdx, &oid,
18361                             oidCsrAttrType, attrMaxIdx) < 0) {
18362                         WOLFSSL_MSG("attr GetObjectId error");
18363                         return ASN_PARSE_E;
18364                     }
18365                     if (GetSet(cert->source, &cert->srcIdx, &len,
18366                             attrMaxIdx) < 0) {
18367                         WOLFSSL_MSG("attr GetSet error");
18368                         return ASN_PARSE_E;
18369                     }
18370                     switch (oid) {
18371                     case PKCS9_CONTENT_TYPE_OID:
18372                         if (GetHeader(cert->source, &tag,
18373                                 &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
18374                             WOLFSSL_MSG("attr GetHeader error");
18375                             return ASN_PARSE_E;
18376                         }
18377                         if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
18378                                 tag != ASN_IA5_STRING) {
18379                             WOLFSSL_MSG("Unsupported attribute value format");
18380                             return ASN_PARSE_E;
18381                         }
18382                         cert->contentType = (char*)cert->source + cert->srcIdx;
18383                         cert->contentTypeLen = len;
18384                         cert->srcIdx += len;
18385                         break;
18386                     case CHALLENGE_PASSWORD_OID:
18387                         if (GetHeader(cert->source, &tag,
18388                                 &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
18389                             WOLFSSL_MSG("attr GetHeader error");
18390                             return ASN_PARSE_E;
18391                         }
18392                         if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
18393                                 tag != ASN_IA5_STRING) {
18394                             WOLFSSL_MSG("Unsupported attribute value format");
18395                             return ASN_PARSE_E;
18396                         }
18397                         cert->cPwd = (char*)cert->source + cert->srcIdx;
18398                         cert->cPwdLen = len;
18399                         cert->srcIdx += len;
18400                         break;
18401                     case SERIAL_NUMBER_OID:
18402                         if (GetHeader(cert->source, &tag,
18403                                 &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
18404                             WOLFSSL_MSG("attr GetHeader error");
18405                             return ASN_PARSE_E;
18406                         }
18407                         if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
18408                                 tag != ASN_IA5_STRING) {
18409                             WOLFSSL_MSG("Unsupported attribute value format");
18410                             return ASN_PARSE_E;
18411                         }
18412                         cert->sNum = (char*)cert->source + cert->srcIdx;
18413                         cert->sNumLen = len;
18414                         cert->srcIdx += len;
18415                         if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
18416                             XMEMCPY(cert->serial, cert->sNum, cert->sNumLen);
18417                             cert->serialSz = cert->sNumLen;
18418                         }
18419                         break;
18420                     case EXTENSION_REQUEST_OID:
18421                         /* save extensions */
18422                         cert->extensions    = &cert->source[cert->srcIdx];
18423                         cert->extensionsSz  = len;
18424                         cert->extensionsIdx = cert->srcIdx; /* for potential later use */
18425 
18426                         if ((ret = DecodeCertExtensions(cert)) < 0) {
18427                             if (ret == ASN_CRIT_EXT_E)
18428                                 cert->criticalExt = ret;
18429                             else
18430                                 return ret;
18431                         }
18432                         cert->srcIdx += len;
18433                         break;
18434                     default:
18435                         WOLFSSL_MSG("Unsupported attribute type");
18436                         return ASN_PARSE_E;
18437                     }
18438                 }
18439             }
18440         }
18441 #endif
18442 
18443         if (cert->srcIdx < cert->sigIndex) {
18444         #ifndef ALLOW_V1_EXTENSIONS
18445             if (cert->version < 2) {
18446                 WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
18447                 return ASN_VERSION_E;
18448             }
18449         #endif
18450 
18451             /* save extensions */
18452             cert->extensions    = &cert->source[cert->srcIdx];
18453             cert->extensionsSz  = cert->sigIndex - cert->srcIdx;
18454             cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
18455 
18456             if ((ret = DecodeCertExtensions(cert)) < 0) {
18457                 if (ret == ASN_CRIT_EXT_E)
18458                     cert->criticalExt = ret;
18459                 else
18460                     return ret;
18461             }
18462 
18463         #ifdef HAVE_OCSP
18464             if (verify == VERIFY_OCSP_CERT) {
18465                 /* trust for the lifetime of the responder's cert*/
18466                 if (cert->ocspNoCheckSet)
18467                     verify = VERIFY;
18468                 else
18469                     verify = VERIFY_OCSP;
18470             }
18471         #endif
18472             /* advance past extensions */
18473             cert->srcIdx = cert->sigIndex;
18474         }
18475 
18476         if ((ret = GetAlgoId(cert->source, &cert->srcIdx,
18477 #ifdef WOLFSSL_CERT_REQ
18478                 !cert->isCSR ? &confirmOID : &cert->signatureOID,
18479 #else
18480                 &confirmOID,
18481 #endif
18482                 oidSigType, cert->maxIdx)) < 0)
18483             return ret;
18484 
18485         if ((ret = GetSignature(cert)) < 0)
18486             return ret;
18487 
18488         if (confirmOID != cert->signatureOID
18489 #ifdef WOLFSSL_CERT_REQ
18490                 && !cert->isCSR
18491 #endif
18492                 )
18493             return ASN_SIG_OID_E;
18494 #else
18495 #ifdef WOLFSSL_CERT_REQ
18496         if (cert->isCSR) {
18497             ret = DecodeCertReq(cert, &cert->criticalExt);
18498             if (ret < 0) {
18499                 return ret;
18500             }
18501         }
18502         else
18503 #endif
18504         {
18505             ret = DecodeCert(cert, verify, &cert->criticalExt);
18506             if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
18507                 cert->badDate = ret;
18508             else if (ret < 0)
18509                 return ret;
18510         }
18511 #endif
18512 
18513     #ifndef NO_SKID
18514         if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
18515                                                          cert->pubKeySize > 0) {
18516             ret = CalcHashId(cert->publicKey, cert->pubKeySize,
18517                                                             cert->extSubjKeyId);
18518             if (ret != 0)
18519                 return ret;
18520         }
18521     #endif /* !NO_SKID */
18522 
18523         if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&
18524                                                    type != TRUSTED_PEER_TYPE)) {
18525             cert->ca = NULL;
18526     #ifndef NO_SKID
18527             if (cert->extAuthKeyIdSet) {
18528                 cert->ca = GetCA(cm, cert->extAuthKeyId);
18529             }
18530             if (cert->ca == NULL && cert->extSubjKeyIdSet
18531                                  && verify != VERIFY_OCSP) {
18532                 cert->ca = GetCA(cm, cert->extSubjKeyId);
18533             }
18534             if (cert->ca != NULL && XMEMCMP(cert->issuerHash,
18535                                   cert->ca->subjectNameHash, KEYID_SIZE) != 0) {
18536                 cert->ca = NULL;
18537             }
18538             if (cert->ca == NULL) {
18539                 cert->ca = GetCAByName(cm, cert->issuerHash);
18540                 /* If AKID is available then this CA doesn't have the public
18541                  * key required */
18542                 if (cert->ca && cert->extAuthKeyIdSet) {
18543                     WOLFSSL_MSG("CA SKID doesn't match AKID");
18544                     cert->ca = NULL;
18545                 }
18546             }
18547 
18548             /* OCSP Only: alt lookup using subject and pub key w/o sig check */
18549         #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
18550             if (cert->ca == NULL && verify == VERIFY_OCSP) {
18551                 cert->ca = GetCABySubjectAndPubKey(cert, cm);
18552                 if (cert->ca) {
18553                     ret = 0; /* success */
18554                     goto exit_pcr;
18555                 }
18556             }
18557         #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
18558     #else
18559             cert->ca = GetCA(cm, cert->issuerHash);
18560     #endif /* !NO_SKID */
18561 
18562             if (cert->ca) {
18563                 WOLFSSL_MSG("CA found");
18564             }
18565         }
18566 
18567         if (cert->selfSigned) {
18568             cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;
18569         } else {
18570             /* RFC 5280 Section 4.2.1.9:
18571              *
18572              * load/receive check
18573              *
18574              * 1) Is CA boolean set?
18575              *      No  - SKIP CHECK
18576              *      Yes - Check key usage
18577              * 2) Is Key usage extension present?
18578              *      No  - goto 3
18579              *      Yes - check keyCertSign assertion
18580              *     2.a) Is keyCertSign asserted?
18581              *          No  - goto 4
18582              *          Yes - goto 3
18583              * 3) Is pathLen set?
18584              *      No  - goto 4
18585              *      Yes - check pathLen against maxPathLen.
18586              *      3.a) Is pathLen less than maxPathLen?
18587              *           No - goto 4
18588              *           Yes - set maxPathLen to pathLen and EXIT
18589              * 4) Is maxPathLen > 0?
18590              *      Yes - Reduce by 1
18591              *      No  - ERROR
18592              */
18593 
18594             if (cert->ca && cert->pathLengthSet) {
18595                 cert->maxPathLen = cert->pathLength;
18596                 if (cert->isCA) {
18597                     WOLFSSL_MSG("\tCA boolean set");
18598                     if (cert->extKeyUsageSet) {
18599                          WOLFSSL_MSG("\tExtension Key Usage Set");
18600                          if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
18601                             checkPathLen = 1;
18602                          } else {
18603                             decrementMaxPathLen = 1;
18604                          }
18605                     } else {
18606                         checkPathLen = 1;
18607                     } /* !cert->ca check */
18608                 } /* cert is not a CA (assuming entity cert) */
18609 
18610                 if (checkPathLen && cert->pathLengthSet) {
18611                     if (cert->pathLength < cert->ca->maxPathLen) {
18612                         WOLFSSL_MSG("\tmaxPathLen status: set to pathLength");
18613                         cert->maxPathLen = cert->pathLength;
18614                     } else {
18615                         decrementMaxPathLen = 1;
18616                     }
18617                 }
18618 
18619                 if (decrementMaxPathLen && cert->ca->maxPathLen > 0) {
18620                     WOLFSSL_MSG("\tmaxPathLen status: reduce by 1");
18621                     cert->maxPathLen = cert->ca->maxPathLen - 1;
18622                     if (verify != NO_VERIFY && type != CA_TYPE &&
18623                                                     type != TRUSTED_PEER_TYPE) {
18624                         WOLFSSL_MSG("\tmaxPathLen status: OK");
18625                     }
18626                 } else if (decrementMaxPathLen && cert->ca->maxPathLen == 0) {
18627                     cert->maxPathLen = 0;
18628                     if (verify != NO_VERIFY && type != CA_TYPE &&
18629                                                     type != TRUSTED_PEER_TYPE) {
18630                         WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
18631                         WOLFSSL_MSG("\tmaxPathLen status: ERROR");
18632                         return ASN_PATHLEN_INV_E;
18633                     }
18634                 }
18635             } else if (cert->ca && cert->isCA) {
18636                 /* case where cert->pathLength extension is not set */
18637                 if (cert->ca->maxPathLen > 0) {
18638                     cert->maxPathLen = cert->ca->maxPathLen - 1;
18639                 } else {
18640                     cert->maxPathLen = 0;
18641                     if (verify != NO_VERIFY && type != CA_TYPE &&
18642                                                     type != TRUSTED_PEER_TYPE) {
18643                         WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
18644                         WOLFSSL_MSG("\tmaxPathLen status: ERROR");
18645                         return ASN_PATHLEN_INV_E;
18646                     }
18647                 }
18648             }
18649         }
18650 
18651         #ifdef HAVE_OCSP
18652         if (verify != NO_VERIFY && type != CA_TYPE &&
18653                                                 type != TRUSTED_PEER_TYPE) {
18654             if (cert->ca) {
18655                 /* Need the CA's public key hash for OCSP */
18656                 XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,
18657                                                                 KEYID_SIZE);
18658             }
18659         }
18660         #endif /* HAVE_OCSP */
18661     }
18662 #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
18663     /* prepare for TSIP TLS cert verification API use */
18664     if (cert->keyOID == RSAk) {
18665         /* to call TSIP API, it needs keys position info in bytes */
18666         if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,
18667                                    cert->pubKeySize,
18668                                    &cert->sigCtx.CertAtt.pubkey_n_start,
18669                                    &cert->sigCtx.CertAtt.pubkey_n_len,
18670                                    &cert->sigCtx.CertAtt.pubkey_e_start,
18671                                    &cert->sigCtx.CertAtt.pubkey_e_len)) != 0) {
18672             WOLFSSL_MSG("Decoding index from cert failed.");
18673             return ret;
18674         }
18675         cert->sigCtx.CertAtt.certBegin = cert->certBegin;
18676     } else if (cert->keyOID == ECDSAk) {
18677         cert->sigCtx.CertAtt.certBegin = cert->certBegin;
18678     }
18679     /* check if we can use TSIP for cert verification */
18680     /* if the ca is verified as tsip root ca.         */
18681     /* TSIP can only handle 2048 bits(256 byte) key.  */
18682     if (cert->ca && Renesas_cmn_checkCA(cert->ca->cm_idx) != 0 &&
18683         (cert->sigCtx.CertAtt.pubkey_n_len == 256 ||
18684          cert->sigCtx.CertAtt.curve_id == ECC_SECP256R1)) {
18685 
18686         /* assign memory to encrypted tsip Rsa key index */
18687         if (!cert->sce_tsip_encRsaKeyIdx)
18688             cert->sce_tsip_encRsaKeyIdx =
18689                             (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
18690                              cert->heap, DYNAMIC_TYPE_RSA);
18691         if (cert->sce_tsip_encRsaKeyIdx == NULL)
18692                 return MEMORY_E;
18693     } else {
18694         if (cert->ca) {
18695             /* TSIP isn't usable */
18696             if (Renesas_cmn_checkCA(cert->ca->cm_idx) == 0)
18697                 WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't verified "
18698                             "by TSIP.");
18699             else if (cert->sigCtx.CertAtt.pubkey_n_len != 256)
18700                 WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't signed by "
18701                             "RSA 2048.");
18702             else
18703                 WOLFSSL_MSG("SCE-TSIP isn't usable");
18704         }
18705         cert->sce_tsip_encRsaKeyIdx = NULL;
18706     }
18707 
18708     sce_tsip_encRsaKeyIdx = cert->sce_tsip_encRsaKeyIdx;
18709 
18710 #else
18711     sce_tsip_encRsaKeyIdx = NULL;
18712 #endif
18713 
18714     if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
18715         if (cert->ca) {
18716             if (verify == VERIFY || verify == VERIFY_OCSP ||
18717                                                  verify == VERIFY_SKIP_DATE) {
18718                 /* try to confirm/verify signature */
18719                 if ((ret = ConfirmSignature(&cert->sigCtx,
18720                         cert->source + cert->certBegin,
18721                         cert->sigIndex - cert->certBegin,
18722                         cert->ca->publicKey, cert->ca->pubKeySize,
18723                         cert->ca->keyOID, cert->signature,
18724                         cert->sigLength, cert->signatureOID,
18725                         sce_tsip_encRsaKeyIdx)) != 0) {
18726                     if (ret != WC_PENDING_E) {
18727                         WOLFSSL_MSG("Confirm signature failed");
18728                     }
18729                     return ret;
18730                 }
18731             }
18732         #ifndef IGNORE_NAME_CONSTRAINTS
18733             if (verify == VERIFY || verify == VERIFY_OCSP ||
18734                         verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
18735                 /* check that this cert's name is permitted by the signer's
18736                  * name constraints */
18737                 if (!ConfirmNameConstraints(cert->ca, cert)) {
18738                     WOLFSSL_MSG("Confirm name constraint failed");
18739                     return ASN_NAME_INVALID_E;
18740                 }
18741             }
18742         #endif /* IGNORE_NAME_CONSTRAINTS */
18743         }
18744         else {
18745             /* no signer */
18746             WOLFSSL_MSG("No CA signer to verify with");
18747             return ASN_NO_SIGNER_E;
18748         }
18749     }
18750 
18751 #if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
18752 exit_pcr:
18753 #endif
18754 
18755     if (cert->badDate != 0) {
18756         if (verify != VERIFY_SKIP_DATE) {
18757             return cert->badDate;
18758         }
18759         WOLFSSL_MSG("Date error: Verify option is skipping");
18760     }
18761 
18762     if (cert->criticalExt != 0)
18763         return cert->criticalExt;
18764 
18765     return ret;
18766 }
18767 
18768 /* Create and init an new signer */
18769 Signer* MakeSigner(void* heap)
18770 {
18771     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
18772                                        DYNAMIC_TYPE_SIGNER);
18773     if (signer) {
18774         XMEMSET(signer, 0, sizeof(Signer));
18775     }
18776     (void)heap;
18777 
18778     return signer;
18779 }
18780 
18781 
18782 /* Free an individual signer.
18783  *
18784  * Used by Certificate Manager.
18785  *
18786  * @param [in, out] signer  On in, signer object.
18787  *                          On out, pointer is no longer valid.
18788  * @param [in]      heap    Dynamic memory hint.
18789  */
18790 void FreeSigner(Signer* signer, void* heap)
18791 {
18792     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
18793     XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
18794 #ifndef IGNORE_NAME_CONSTRAINTS
18795     if (signer->permittedNames)
18796         FreeNameSubtrees(signer->permittedNames, heap);
18797     if (signer->excludedNames)
18798         FreeNameSubtrees(signer->excludedNames, heap);
18799 #endif
18800 #ifdef WOLFSSL_SIGNER_DER_CERT
18801     FreeDer(&signer->derCert);
18802 #endif
18803     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
18804 
18805     (void)heap;
18806 }
18807 
18808 
18809 /* Free the whole singer table with number of rows.
18810  *
18811  * Each table entry is a linked list of signers.
18812  * Used by Certificate Manager.
18813  *
18814  * @param [in, out] table   Array of signer objects.
18815  * @param [in]      rows    Number of entries in table.
18816  * @param [in]      heap    Dynamic memory hint.
18817  */
18818 void FreeSignerTable(Signer** table, int rows, void* heap)
18819 {
18820     int i;
18821 
18822     for (i = 0; i < rows; i++) {
18823         Signer* signer = table[i];
18824         while (signer) {
18825             Signer* next = signer->next;
18826             FreeSigner(signer, heap);
18827             signer = next;
18828         }
18829         table[i] = NULL;
18830     }
18831 }
18832 
18833 #ifdef WOLFSSL_TRUST_PEER_CERT
18834 /* Free an individual trusted peer cert.
18835  *
18836  * @param [in, out] tp    Trusted peer certificate object.
18837  * @param [in]      heap  Dynamic memory hint.
18838  */
18839 void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
18840 {
18841     if (tp == NULL) {
18842         return;
18843     }
18844 
18845     if (tp->name) {
18846         XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
18847     }
18848 
18849     if (tp->sig) {
18850         XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
18851     }
18852 #ifndef IGNORE_NAME_CONSTRAINTS
18853     if (tp->permittedNames)
18854         FreeNameSubtrees(tp->permittedNames, heap);
18855     if (tp->excludedNames)
18856         FreeNameSubtrees(tp->excludedNames, heap);
18857 #endif
18858     XFREE(tp, heap, DYNAMIC_TYPE_CERT);
18859 
18860     (void)heap;
18861 }
18862 
18863 /* Free the whole Trusted Peer linked list.
18864  *
18865  * Each table entry is a linked list of trusted peer certificates.
18866  * Used by Certificate Manager.
18867  *
18868  * @param [in, out] table   Array of trusted peer certificate objects.
18869  * @param [in]      rows    Number of entries in table.
18870  * @param [in]      heap    Dynamic memory hint.
18871  */
18872 void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
18873 {
18874     int i;
18875 
18876     for (i = 0; i < rows; i++) {
18877         TrustedPeerCert* tp = table[i];
18878         while (tp) {
18879             TrustedPeerCert* next = tp->next;
18880             FreeTrustedPeer(tp, heap);
18881             tp = next;
18882         }
18883         table[i] = NULL;
18884     }
18885 }
18886 #endif /* WOLFSSL_TRUST_PEER_CERT */
18887 
18888 int SetMyVersion(word32 version, byte* output, int header)
18889 {
18890     int i = 0;
18891 
18892     if (output == NULL)
18893         return BAD_FUNC_ARG;
18894 
18895     if (header) {
18896         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
18897         output[i++] = 3;
18898     }
18899     output[i++] = ASN_INTEGER;
18900     output[i++] = 0x01;
18901     output[i++] = (byte)version;
18902 
18903     return i;
18904 }
18905 
18906 #if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7)
18907 int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
18908     word32 outputSz, int maxSnSz)
18909 {
18910     int i;
18911     int snSzInt = (int)snSz;
18912 
18913     if (sn == NULL || output == NULL || snSzInt < 0)
18914         return BAD_FUNC_ARG;
18915 
18916     /* remove leading zeros */
18917     while (snSzInt > 0 && sn[0] == 0) {
18918         snSzInt--;
18919         sn++;
18920     }
18921     /* RFC 5280 - 4.1.2.2:
18922      *   Serial numbers must be a positive value (and not zero) */
18923     if (snSzInt == 0)
18924         return BAD_FUNC_ARG;
18925 
18926     if (sn[0] & 0x80)
18927         maxSnSz--;
18928     /* truncate if input is too long */
18929     if (snSzInt > maxSnSz)
18930         snSzInt = maxSnSz;
18931 
18932     i = SetASNInt(snSzInt, sn[0], NULL);
18933     /* truncate if input is too long */
18934     if (snSzInt > (int)outputSz - i)
18935         snSzInt = (int)outputSz - i;
18936     /* sanity check number of bytes to copy */
18937     if (snSzInt <= 0) {
18938         return BUFFER_E;
18939     }
18940 
18941     /* write out ASN.1 Integer */
18942     (void)SetASNInt(snSzInt, sn[0], output);
18943     XMEMCPY(output + i, sn, snSzInt);
18944 
18945     /* compute final length */
18946     i += snSzInt;
18947 
18948     return i;
18949 }
18950 #endif /* !WOLFSSL_ASN_TEMPLATE */
18951 
18952 #endif /* !NO_CERTS */
18953 
18954 #ifndef WOLFSSL_ASN_TEMPLATE
18955 int GetSerialNumber(const byte* input, word32* inOutIdx,
18956     byte* serial, int* serialSz, word32 maxIdx)
18957 {
18958     int result = 0;
18959     int ret;
18960 
18961     WOLFSSL_ENTER("GetSerialNumber");
18962 
18963     if (serial == NULL || input == NULL || serialSz == NULL) {
18964         return BAD_FUNC_ARG;
18965     }
18966 
18967     /* First byte is ASN type */
18968     if ((*inOutIdx+1) > maxIdx) {
18969         WOLFSSL_MSG("Bad idx first");
18970         return BUFFER_E;
18971     }
18972 
18973     ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
18974     if (ret != 0)
18975         return ret;
18976 
18977     if (*serialSz > EXTERNAL_SERIAL_SIZE || *serialSz <= 0) {
18978         WOLFSSL_MSG("Serial size bad");
18979         return ASN_PARSE_E;
18980     }
18981 
18982     /* return serial */
18983     XMEMCPY(serial, &input[*inOutIdx], (size_t)*serialSz);
18984     *inOutIdx += *serialSz;
18985 
18986     return result;
18987 }
18988 #endif
18989 
18990 #ifndef NO_CERTS
18991 
18992 /* TODO: consider moving PEM code out to a different file. */
18993 
18994 int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
18995 {
18996     int ret = BAD_FUNC_ARG;
18997     if (pDer) {
18998         int dynType = 0;
18999         DerBuffer* der;
19000 
19001         /* Determine dynamic type */
19002         switch (type) {
19003             case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
19004             case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
19005             case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
19006             case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
19007             case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
19008             case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
19009             default:        dynType = DYNAMIC_TYPE_KEY;  break;
19010         }
19011 
19012         /* Setup new buffer */
19013         *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
19014         if (*pDer == NULL) {
19015             return MEMORY_E;
19016         }
19017         XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
19018 
19019         der = *pDer;
19020         der->type = type;
19021         der->dynType = dynType; /* Cache this for FreeDer */
19022         der->heap = heap;
19023         der->buffer = (byte*)der + sizeof(DerBuffer);
19024         der->length = length;
19025         ret = 0; /* Success */
19026     }
19027     return ret;
19028 }
19029 
19030 void FreeDer(DerBuffer** pDer)
19031 {
19032     if (pDer && *pDer)
19033     {
19034         DerBuffer* der = (DerBuffer*)*pDer;
19035 
19036         /* ForceZero private keys */
19037         if (der->type == PRIVATEKEY_TYPE && der->buffer != NULL) {
19038             ForceZero(der->buffer, der->length);
19039         }
19040         der->buffer = NULL;
19041         der->length = 0;
19042         XFREE(der, der->heap, der->dynType);
19043 
19044         *pDer = NULL;
19045     }
19046 }
19047 
19048 int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
19049 {
19050     return AllocDer(pDer, length, type, heap);
19051 }
19052 void wc_FreeDer(DerBuffer** pDer)
19053 {
19054     FreeDer(pDer);
19055 }
19056 
19057 
19058 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
19059 
19060 /* Note: If items added make sure MAX_X509_HEADER_SZ is
19061     updated to reflect maximum length and pem_struct_min_sz
19062     to reflect minimum size */
19063 wcchar BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
19064 wcchar END_CERT             = "-----END CERTIFICATE-----";
19065 #ifdef WOLFSSL_CERT_REQ
19066     wcchar BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
19067     wcchar END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
19068 #endif
19069 #ifndef NO_DH
19070     wcchar BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
19071     wcchar END_DH_PARAM     = "-----END DH PARAMETERS-----";
19072     wcchar BEGIN_X942_PARAM = "-----BEGIN X9.42 DH PARAMETERS-----";
19073     wcchar END_X942_PARAM   = "-----END X9.42 DH PARAMETERS-----";
19074 #endif
19075 #ifndef NO_DSA
19076     wcchar BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
19077     wcchar END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
19078 #endif
19079 wcchar BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
19080 wcchar END_X509_CRL         = "-----END X509 CRL-----";
19081 wcchar BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
19082 wcchar END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
19083 wcchar BEGIN_RSA_PUB        = "-----BEGIN RSA PUBLIC KEY-----";
19084 wcchar END_RSA_PUB          = "-----END RSA PUBLIC KEY-----";
19085 wcchar BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
19086 wcchar END_PRIV_KEY         = "-----END PRIVATE KEY-----";
19087 wcchar BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
19088 wcchar END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
19089 #ifdef HAVE_ECC
19090     wcchar BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
19091     wcchar END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
19092 #endif
19093 #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
19094                                                                 !defined(NO_DSA)
19095     wcchar BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
19096     wcchar END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
19097 #endif
19098 #ifdef OPENSSL_EXTRA
19099     const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN";
19100     const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----";
19101     const char END_PRIV_KEY_PREFIX[]   = "-----END";
19102 #endif
19103 wcchar BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
19104 wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
19105 #if defined(HAVE_ED25519) || defined(HAVE_ED448)
19106     wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
19107     wcchar END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
19108 #endif
19109 #if defined(HAVE_PQC)
19110     wcchar BEGIN_FALCON_LEVEL1_PRIV  = "-----BEGIN FALCON_LEVEL1 PRIVATE KEY-----";
19111     wcchar END_FALCON_LEVEL1_PRIV    = "-----END FALCON_LEVEL1 PRIVATE KEY-----";
19112     wcchar BEGIN_FALCON_LEVEL5_PRIV = "-----BEGIN FALCON_LEVEL5 PRIVATE KEY-----";
19113     wcchar END_FALCON_LEVEL5_PRIV   = "-----END FALCON_LEVEL5 PRIVATE KEY-----";
19114 #endif
19115 
19116 const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
19117                                              "-----END X509 CRL-----");
19118 
19119 static WC_INLINE const char* SkipEndOfLineChars(const char* line,
19120                                                 const char* endOfLine)
19121 {
19122     /* eat end of line characters */
19123     while (line < endOfLine &&
19124               (line[0] == '\r' || line[0] == '\n')) {
19125         line++;
19126     }
19127     return line;
19128 }
19129 
19130 int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
19131 {
19132     int ret = BAD_FUNC_ARG;
19133 
19134     switch (type) {
19135         case CA_TYPE:       /* same as below */
19136         case TRUSTED_PEER_TYPE:
19137         case CERT_TYPE:
19138             if (header) *header = BEGIN_CERT;
19139             if (footer) *footer = END_CERT;
19140             ret = 0;
19141             break;
19142 
19143         case CRL_TYPE:
19144             if (header) *header = BEGIN_X509_CRL;
19145             if (footer) *footer = END_X509_CRL;
19146             ret = 0;
19147             break;
19148     #ifndef NO_DH
19149         case DH_PARAM_TYPE:
19150             if (header) *header = BEGIN_DH_PARAM;
19151             if (footer) *footer = END_DH_PARAM;
19152             ret = 0;
19153             break;
19154         case X942_PARAM_TYPE:
19155             if (header) *header = BEGIN_X942_PARAM;
19156             if (footer) *footer = END_X942_PARAM;
19157             ret = 0;
19158             break;
19159     #endif
19160     #ifndef NO_DSA
19161         case DSA_PARAM_TYPE:
19162             if (header) *header = BEGIN_DSA_PARAM;
19163             if (footer) *footer = END_DSA_PARAM;
19164             ret = 0;
19165             break;
19166     #endif
19167     #ifdef WOLFSSL_CERT_REQ
19168         case CERTREQ_TYPE:
19169             if (header) *header = BEGIN_CERT_REQ;
19170             if (footer) *footer = END_CERT_REQ;
19171             ret = 0;
19172             break;
19173     #endif
19174     #ifndef NO_DSA
19175         case DSA_TYPE:
19176         case DSA_PRIVATEKEY_TYPE:
19177             if (header) *header = BEGIN_DSA_PRIV;
19178             if (footer) *footer = END_DSA_PRIV;
19179             ret = 0;
19180             break;
19181     #endif
19182     #ifdef HAVE_ECC
19183         case ECC_TYPE:
19184         case ECC_PRIVATEKEY_TYPE:
19185             if (header) *header = BEGIN_EC_PRIV;
19186             if (footer) *footer = END_EC_PRIV;
19187             ret = 0;
19188             break;
19189     #endif
19190         case RSA_TYPE:
19191         case PRIVATEKEY_TYPE:
19192             if (header) *header = BEGIN_RSA_PRIV;
19193             if (footer) *footer = END_RSA_PRIV;
19194             ret = 0;
19195             break;
19196     #ifdef HAVE_ED25519
19197         case ED25519_TYPE:
19198     #endif
19199     #ifdef HAVE_ED448
19200         case ED448_TYPE:
19201     #endif
19202     #if defined(HAVE_ED25519) || defined(HAVE_ED448)
19203         case EDDSA_PRIVATEKEY_TYPE:
19204             if (header) *header = BEGIN_EDDSA_PRIV;
19205             if (footer) *footer = END_EDDSA_PRIV;
19206             ret = 0;
19207             break;
19208     #endif
19209 #ifdef HAVE_PQC
19210         case FALCON_LEVEL1_TYPE:
19211             if (header) *header = BEGIN_FALCON_LEVEL1_PRIV;
19212             if (footer) *footer = END_FALCON_LEVEL1_PRIV;
19213             ret = 0;
19214             break;
19215         case FALCON_LEVEL5_TYPE:
19216             if (header) *header = BEGIN_FALCON_LEVEL5_PRIV;
19217             if (footer) *footer = END_FALCON_LEVEL5_PRIV;
19218             ret = 0;
19219             break;
19220 #endif
19221         case PUBLICKEY_TYPE:
19222         case ECC_PUBLICKEY_TYPE:
19223             if (header) *header = BEGIN_PUB_KEY;
19224             if (footer) *footer = END_PUB_KEY;
19225             ret = 0;
19226             break;
19227     #ifndef NO_DH
19228         case DH_PRIVATEKEY_TYPE:
19229     #endif
19230         case PKCS8_PRIVATEKEY_TYPE:
19231             if (header) *header = BEGIN_PRIV_KEY;
19232             if (footer) *footer = END_PRIV_KEY;
19233             ret = 0;
19234             break;
19235         case PKCS8_ENC_PRIVATEKEY_TYPE:
19236             if (header) *header = BEGIN_ENC_PRIV_KEY;
19237             if (footer) *footer = END_ENC_PRIV_KEY;
19238             ret = 0;
19239             break;
19240         default:
19241             break;
19242     }
19243     return ret;
19244 }
19245 
19246 #ifdef WOLFSSL_ENCRYPTED_KEYS
19247 
19248 static wcchar kProcTypeHeader = "Proc-Type";
19249 static wcchar kDecInfoHeader = "DEK-Info";
19250 
19251 #ifdef WOLFSSL_PEM_TO_DER
19252 #ifndef NO_DES3
19253     static wcchar kEncTypeDes = "DES-CBC";
19254     static wcchar kEncTypeDes3 = "DES-EDE3-CBC";
19255 #endif
19256 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
19257     static wcchar kEncTypeAesCbc128 = "AES-128-CBC";
19258 #endif
19259 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
19260     static wcchar kEncTypeAesCbc192 = "AES-192-CBC";
19261 #endif
19262 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
19263     static wcchar kEncTypeAesCbc256 = "AES-256-CBC";
19264 #endif
19265 
19266 int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
19267 {
19268     int ret = 0;
19269 
19270     if (info == NULL || cipherInfo == NULL)
19271         return BAD_FUNC_ARG;
19272 
19273     /* determine cipher information */
19274 #ifndef NO_DES3
19275     if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
19276         info->cipherType = WC_CIPHER_DES;
19277         info->keySz = DES_KEY_SIZE;
19278 /* DES_IV_SIZE is incorrectly 16 in FIPS v2. It should be 8, same as the
19279  * block size. */
19280 #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
19281         if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
19282 #else
19283         if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
19284 #endif
19285     }
19286     else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
19287         info->cipherType = WC_CIPHER_DES3;
19288         info->keySz = DES3_KEY_SIZE;
19289 #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
19290         if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
19291 #else
19292         if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
19293 #endif
19294     }
19295     else
19296 #endif /* !NO_DES3 */
19297 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
19298     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
19299         info->cipherType = WC_CIPHER_AES_CBC;
19300         info->keySz = AES_128_KEY_SIZE;
19301         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
19302     }
19303     else
19304 #endif
19305 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
19306     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
19307         info->cipherType = WC_CIPHER_AES_CBC;
19308         info->keySz = AES_192_KEY_SIZE;
19309         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
19310     }
19311     else
19312 #endif
19313 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
19314     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
19315         info->cipherType = WC_CIPHER_AES_CBC;
19316         info->keySz = AES_256_KEY_SIZE;
19317         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
19318     }
19319     else
19320 #endif
19321     {
19322         ret = NOT_COMPILED_IN;
19323     }
19324     return ret;
19325 }
19326 
19327 int wc_EncryptedInfoParse(EncryptedInfo* info, const char** pBuffer,
19328                           size_t bufSz)
19329 {
19330     int         err = 0;
19331     const char* bufferStart;
19332     const char* bufferEnd;
19333     char*       line;
19334     word32      lineSz;
19335     char*       finish;
19336     word32      finishSz;
19337     char*       start = NULL;
19338     word32      startSz;
19339     const char* newline = NULL;
19340 
19341     if (info == NULL || pBuffer == NULL || bufSz == 0)
19342         return BAD_FUNC_ARG;
19343 
19344     bufferStart = *pBuffer;
19345     bufferEnd = bufferStart + bufSz;
19346 
19347     /* find encrypted info marker */
19348     line = XSTRNSTR(bufferStart, kProcTypeHeader,
19349                     min((word32)bufSz, PEM_LINE_LEN));
19350     if (line != NULL) {
19351         if (line >= bufferEnd) {
19352             return BUFFER_E;
19353         }
19354 
19355         lineSz = (word32)(bufferEnd - line);
19356 
19357         /* find DEC-Info marker */
19358         start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
19359 
19360         if (start == NULL)
19361             return BUFFER_E;
19362 
19363         /* skip dec-info and ": " */
19364         start += XSTRLEN(kDecInfoHeader);
19365         if (start >= bufferEnd)
19366             return BUFFER_E;
19367 
19368         if (start[0] == ':') {
19369             start++;
19370             if (start >= bufferEnd)
19371                 return BUFFER_E;
19372         }
19373         if (start[0] == ' ')
19374             start++;
19375 
19376         startSz = (word32)(bufferEnd - start);
19377         finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
19378 
19379         if ((start != NULL) && (finish != NULL) && (start < finish)) {
19380             if (finish >= bufferEnd) {
19381                 return BUFFER_E;
19382             }
19383 
19384             finishSz = (word32)(bufferEnd - finish);
19385             newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
19386 
19387             /* get cipher name */
19388             if (NAME_SZ < (finish - start)) /* buffer size of info->name */
19389                 return BUFFER_E;
19390             if (XMEMCPY(info->name, start, finish - start) == NULL)
19391                 return BUFFER_E;
19392             info->name[finish - start] = '\0'; /* null term */
19393 
19394             /* populate info */
19395             err = wc_EncryptedInfoGet(info, info->name);
19396             if (err != 0)
19397                 return err;
19398 
19399             /* get IV */
19400             if (finishSz < info->ivSz + 1)
19401                 return BUFFER_E;
19402 
19403             if (newline == NULL) {
19404                 newline = XSTRNSTR(finish, "\n", min(finishSz,
19405                                                      PEM_LINE_LEN));
19406             }
19407             if ((newline != NULL) && (newline > finish)) {
19408                 finish++;
19409                 info->ivSz = (word32)(newline - finish);
19410                 if (info->ivSz > IV_SZ)
19411                     return BUFFER_E;
19412                 if (XMEMCPY(info->iv, finish, info->ivSz) == NULL)
19413                     return BUFFER_E;
19414                 info->set = 1;
19415             }
19416             else
19417                 return BUFFER_E;
19418         }
19419         else
19420             return BUFFER_E;
19421 
19422         /* eat end of line characters */
19423         newline = SkipEndOfLineChars(newline, bufferEnd);
19424 
19425         /* return new headerEnd */
19426 
19427         *pBuffer = newline;
19428     }
19429 
19430     return err;
19431 }
19432 #endif /* WOLFSSL_PEM_TO_DER */
19433 
19434 #ifdef WOLFSSL_DER_TO_PEM
19435 static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
19436 {
19437     if (cipherInfo != NULL) {
19438         int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
19439 
19440         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
19441             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
19442 
19443         if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
19444             /* strncat's src length needs to include the NULL */
19445             XSTRNCAT(dest, kProcTypeHeader, 10);
19446             XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
19447             XSTRNCAT(dest, kDecInfoHeader, 9);
19448             XSTRNCAT(dest, ": ", 3);
19449             XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
19450             XSTRNCAT(dest, "\n\n", 4);
19451         }
19452     }
19453     return 0;
19454 }
19455 #endif /* WOLFSSL_DER_TO_PEM */
19456 #endif /* WOLFSSL_ENCRYPTED_KEYS */
19457 
19458 #ifdef WOLFSSL_DER_TO_PEM
19459 
19460 /* Used for compatibility API */
19461 int wc_DerToPem(const byte* der, word32 derSz,
19462                 byte* output, word32 outSz, int type)
19463 {
19464     return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
19465 }
19466 
19467 /* convert der buffer to pem into output, can't do inplace, der and output
19468    need to be different */
19469 int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
19470              byte *cipher_info, int type)
19471 {
19472     const char* headerStr = NULL;
19473     const char* footerStr = NULL;
19474 #ifdef WOLFSSL_SMALL_STACK
19475     char* header = NULL;
19476     char* footer = NULL;
19477 #else
19478     char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
19479     char footer[MAX_X509_HEADER_SZ];
19480 #endif
19481     int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
19482     int footerLen = MAX_X509_HEADER_SZ;
19483     int i;
19484     int err;
19485     int outLen;   /* return length or error */
19486 
19487     (void)cipher_info;
19488 
19489     if (der == output)      /* no in place conversion */
19490         return BAD_FUNC_ARG;
19491 
19492     err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
19493     if (err != 0)
19494         return err;
19495 
19496 #ifdef WOLFSSL_SMALL_STACK
19497     header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19498     if (header == NULL)
19499         return MEMORY_E;
19500 
19501     footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19502     if (footer == NULL) {
19503         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19504         return MEMORY_E;
19505     }
19506 #endif
19507 
19508     /* build header and footer based on type */
19509     XSTRNCPY(header, headerStr, headerLen - 1);
19510     header[headerLen - 2] = 0;
19511     XSTRNCPY(footer, footerStr, footerLen - 1);
19512     footer[footerLen - 2] = 0;
19513 
19514     /* add new line to end */
19515     XSTRNCAT(header, "\n", 2);
19516     XSTRNCAT(footer, "\n", 2);
19517 
19518 #ifdef WOLFSSL_ENCRYPTED_KEYS
19519     err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
19520     if (err != 0) {
19521     #ifdef WOLFSSL_SMALL_STACK
19522         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19523         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19524     #endif
19525         return err;
19526     }
19527 #endif
19528 
19529     headerLen = (int)XSTRLEN(header);
19530     footerLen = (int)XSTRLEN(footer);
19531 
19532     /* if null output and 0 size passed in then return size needed */
19533     if (!output && outSz == 0) {
19534 #ifdef WOLFSSL_SMALL_STACK
19535         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19536         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19537 #endif
19538         outLen = 0;
19539         if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
19540                 != LENGTH_ONLY_E) {
19541             return err;
19542         }
19543         return headerLen + footerLen + outLen;
19544     }
19545 
19546     if (!der || !output) {
19547 #ifdef WOLFSSL_SMALL_STACK
19548         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19549         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19550 #endif
19551         return BAD_FUNC_ARG;
19552     }
19553 
19554     /* don't even try if outSz too short */
19555     if (outSz < headerLen + footerLen + derSz) {
19556 #ifdef WOLFSSL_SMALL_STACK
19557         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19558         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19559 #endif
19560         return BAD_FUNC_ARG;
19561     }
19562 
19563     /* header */
19564     XMEMCPY(output, header, headerLen);
19565     i = headerLen;
19566 
19567 #ifdef WOLFSSL_SMALL_STACK
19568     XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19569 #endif
19570 
19571     /* body */
19572     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
19573     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
19574 #ifdef WOLFSSL_SMALL_STACK
19575         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19576 #endif
19577         return err;
19578     }
19579     i += outLen;
19580 
19581     /* footer */
19582     if ( (i + footerLen) > (int)outSz) {
19583 #ifdef WOLFSSL_SMALL_STACK
19584         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19585 #endif
19586         return BAD_FUNC_ARG;
19587     }
19588     XMEMCPY(output + i, footer, footerLen);
19589 
19590 #ifdef WOLFSSL_SMALL_STACK
19591     XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19592 #endif
19593 
19594     return outLen + headerLen + footerLen;
19595 }
19596 
19597 #endif /* WOLFSSL_DER_TO_PEM */
19598 
19599 #ifdef WOLFSSL_PEM_TO_DER
19600 
19601 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
19602    info->consumed tracks of PEM bytes consumed in case multiple parts */
19603 int PemToDer(const unsigned char* buff, long longSz, int type,
19604               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
19605 {
19606     const char* header      = NULL;
19607     const char* footer      = NULL;
19608     const char* headerEnd;
19609     const char* footerEnd;
19610     const char* consumedEnd;
19611     const char* bufferEnd   = (const char*)(buff + longSz);
19612     long        neededSz;
19613     int         ret         = 0;
19614     int         sz          = (int)longSz;
19615     int         encrypted_key = 0;
19616     DerBuffer*  der;
19617     word32      algId = 0;
19618     word32      idx;
19619 #if defined(WOLFSSL_ENCRYPTED_KEYS)
19620     #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && \
19621         !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
19622         int     padVal = 0;
19623     #endif
19624 #endif
19625 #ifdef OPENSSL_EXTRA
19626     char        beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */
19627     char        endBuf[PEM_LINE_LEN + 1];   /* add 1 for null terminator */
19628 #endif
19629 
19630     WOLFSSL_ENTER("PemToDer");
19631 
19632     /* get PEM header and footer based on type */
19633     ret = wc_PemGetHeaderFooter(type, &header, &footer);
19634     if (ret != 0)
19635         return ret;
19636 
19637     /* map header if not found for type */
19638     for (;;) {
19639         headerEnd = XSTRNSTR((char*)buff, header, sz);
19640         if (headerEnd) {
19641             break;
19642         }
19643 
19644         if (type == PRIVATEKEY_TYPE) {
19645             if (header == BEGIN_RSA_PRIV) {
19646                 header = BEGIN_PRIV_KEY;
19647                 footer = END_PRIV_KEY;
19648             }
19649             else if (header == BEGIN_PRIV_KEY) {
19650                 header = BEGIN_ENC_PRIV_KEY;
19651                 footer = END_ENC_PRIV_KEY;
19652             }
19653 #ifdef HAVE_ECC
19654             else if (header == BEGIN_ENC_PRIV_KEY) {
19655                 header = BEGIN_EC_PRIV;
19656                 footer = END_EC_PRIV;
19657             }
19658             else if (header == BEGIN_EC_PRIV) {
19659                 header = BEGIN_DSA_PRIV;
19660                 footer = END_DSA_PRIV;
19661             }
19662 #endif
19663 #if defined(HAVE_ED25519) || defined(HAVE_ED448)
19664     #ifdef HAVE_ECC
19665             else if (header == BEGIN_DSA_PRIV) {
19666     #else
19667             else if (header == BEGIN_ENC_PRIV_KEY) {
19668     #endif
19669                 header = BEGIN_EDDSA_PRIV;
19670                 footer = END_EDDSA_PRIV;
19671             }
19672 #endif
19673             else {
19674             #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)
19675                 /* allow loading a public key for use with crypto or PK callbacks */
19676                 type = PUBLICKEY_TYPE;
19677                 header = BEGIN_PUB_KEY;
19678                 footer = END_PUB_KEY;
19679             #else
19680                 break;
19681             #endif
19682             }
19683         }
19684         else if (type == PUBLICKEY_TYPE) {
19685             if (header == BEGIN_PUB_KEY) {
19686                 header = BEGIN_RSA_PUB;
19687                 footer = END_RSA_PUB;
19688             }
19689             else {
19690                 break;
19691             }
19692         }
19693 #ifdef HAVE_CRL
19694         else if ((type == CRL_TYPE) && (header != BEGIN_X509_CRL)) {
19695             header =  BEGIN_X509_CRL;
19696             footer = END_X509_CRL;
19697         }
19698 #endif
19699         else {
19700             break;
19701         }
19702     }
19703 
19704     if (!headerEnd) {
19705 #ifdef OPENSSL_EXTRA
19706         if (type == PRIVATEKEY_TYPE) {
19707             const char* beginEnd;
19708             int endLen;
19709             /* see if there is a -----BEGIN * PRIVATE KEY----- header */
19710             headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
19711             if (headerEnd) {
19712                 beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX);
19713                 if (beginEnd >= (char*)buff + sz) {
19714                     return BUFFER_E;
19715                 }
19716 
19717                 /* back up to BEGIN_PRIV_KEY_PREFIX */
19718                 while (headerEnd > (char*)buff &&
19719                         XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
19720                                 XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 &&
19721                         *headerEnd != '\n') {
19722                     headerEnd--;
19723                 }
19724                 if (headerEnd <= (char*)buff ||
19725                         XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
19726                         XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
19727                         beginEnd - headerEnd > PEM_LINE_LEN) {
19728                     WOLFSSL_MSG("Couldn't find PEM header");
19729                     WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
19730                     return ASN_NO_PEM_HEADER;
19731                 }
19732 
19733                 /* headerEnd now points to beginning of header */
19734                 XMEMCPY(beginBuf, headerEnd, beginEnd - headerEnd);
19735                 beginBuf[beginEnd - headerEnd] = '\0';
19736                 /* look for matching footer */
19737                 footer = XSTRNSTR(beginEnd,
19738                                 beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
19739                                 (unsigned int)((char*)buff + sz - beginEnd));
19740                 if (!footer) {
19741                     WOLFSSL_MSG("Couldn't find PEM footer");
19742                     WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
19743                     return ASN_NO_PEM_HEADER;
19744                 }
19745 
19746                 footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX);
19747                 if (footer > (char*)buff + sz - XSTR_SIZEOF(END_PRIV_KEY_PREFIX)
19748                         || XSTRNCMP(footer, END_PRIV_KEY_PREFIX,
19749                             XSTR_SIZEOF(END_PRIV_KEY_PREFIX)) != 0) {
19750                     WOLFSSL_MSG("Unexpected footer for PEM");
19751                     return BUFFER_E;
19752                 }
19753 
19754                 endLen = (unsigned int)(beginEnd - headerEnd -
19755                             (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
19756                                     XSTR_SIZEOF(END_PRIV_KEY_PREFIX)));
19757                 XMEMCPY(endBuf, footer, endLen);
19758                 endBuf[endLen] = '\0';
19759 
19760                 header = beginBuf;
19761                 footer = endBuf;
19762                 headerEnd = beginEnd;
19763             }
19764         }
19765 
19766         if (!headerEnd) {
19767             WOLFSSL_MSG("Couldn't find PEM header");
19768             WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
19769             return ASN_NO_PEM_HEADER;
19770         }
19771 #else
19772         WOLFSSL_MSG("Couldn't find PEM header");
19773         return ASN_NO_PEM_HEADER;
19774 #endif
19775     } else {
19776         headerEnd += XSTRLEN(header);
19777     }
19778 
19779     /* eat end of line characters */
19780     headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
19781 
19782     if (keyFormat) {
19783         /* keyFormat is Key_Sum enum */
19784         if (type == PRIVATEKEY_TYPE) {
19785         #ifndef NO_RSA
19786             if (header == BEGIN_RSA_PRIV)
19787                 *keyFormat = RSAk;
19788         #endif
19789         #ifdef HAVE_ECC
19790             if (header == BEGIN_EC_PRIV)
19791                 *keyFormat = ECDSAk;
19792         #endif
19793         #ifndef NO_DSA
19794             if (header == BEGIN_DSA_PRIV)
19795                 *keyFormat = DSAk;
19796         #endif
19797         }
19798     #if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS)
19799         else if (type == PUBLICKEY_TYPE) {
19800         #ifndef NO_RSA
19801             if (header == BEGIN_RSA_PUB)
19802                 *keyFormat = RSAk;
19803         #endif
19804         }
19805     #endif
19806     }
19807 
19808 #ifdef WOLFSSL_ENCRYPTED_KEYS
19809     if (info) {
19810         ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
19811         if (ret < 0)
19812             return ret;
19813         if (info->set)
19814             encrypted_key = 1;
19815     }
19816 #endif /* WOLFSSL_ENCRYPTED_KEYS */
19817 
19818     /* find footer */
19819     footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff +
19820         sz - headerEnd));
19821     if (!footerEnd) {
19822         if (info)
19823             info->consumed = longSz; /* No more certs if no footer */
19824         return BUFFER_E;
19825     }
19826 
19827     consumedEnd = footerEnd + XSTRLEN(footer);
19828 
19829     if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
19830         /* eat end of line characters */
19831         consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
19832         /* skip possible null term */
19833         if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
19834             consumedEnd++;
19835     }
19836 
19837     if (info)
19838         info->consumed = (long)(consumedEnd - (const char*)buff);
19839 
19840     /* set up der buffer */
19841     neededSz = (long)(footerEnd - headerEnd);
19842     if (neededSz > sz || neededSz <= 0)
19843         return BUFFER_E;
19844 
19845     ret = AllocDer(pDer, (word32)neededSz, type, heap);
19846     if (ret < 0) {
19847         return ret;
19848     }
19849     der = *pDer;
19850 
19851     if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
19852                       der->buffer, &der->length) < 0) {
19853         WOLFSSL_ERROR(BUFFER_E);
19854         return BUFFER_E;
19855     }
19856 
19857     if ((header == BEGIN_PRIV_KEY
19858 #ifdef OPENSSL_EXTRA
19859          || header == beginBuf
19860 #endif
19861 #ifdef HAVE_ECC
19862          || header == BEGIN_EC_PRIV
19863 #endif
19864         ) && !encrypted_key)
19865     {
19866         /* detect pkcs8 key and get alg type */
19867         /* keep PKCS8 header */
19868         idx = 0;
19869         ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
19870         if (ret > 0) {
19871             if (keyFormat)
19872                 *keyFormat = algId;
19873         }
19874         else {
19875             /* ignore failure here and assume key is not pkcs8 wrapped */
19876         }
19877         return 0;
19878     }
19879 
19880 #ifdef WOLFSSL_ENCRYPTED_KEYS
19881     if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
19882         int   passwordSz = NAME_SZ;
19883     #ifdef WOLFSSL_SMALL_STACK
19884         char* password = NULL;
19885     #else
19886         char  password[NAME_SZ];
19887     #endif
19888 
19889         if (!info || !info->passwd_cb) {
19890             WOLFSSL_MSG("No password callback set");
19891             return NO_PASSWORD;
19892         }
19893 
19894     #ifdef WOLFSSL_SMALL_STACK
19895         password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
19896         if (password == NULL)
19897             return MEMORY_E;
19898     #endif
19899 
19900         /* get password */
19901         ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
19902             info->passwd_userdata);
19903         if (ret >= 0) {
19904             passwordSz = ret;
19905 
19906             /* convert and adjust length */
19907             if (header == BEGIN_ENC_PRIV_KEY) {
19908             #ifndef NO_PWDBASED
19909                 ret = wc_DecryptPKCS8Key(der->buffer, der->length,
19910                     password, passwordSz);
19911                 if (ret > 0) {
19912                     /* update length by decrypted content */
19913                     der->length = ret;
19914                     idx = 0;
19915                     /* detect pkcs8 key and get alg type */
19916                     /* keep PKCS8 header */
19917                     ret = ToTraditionalInline_ex(der->buffer, &idx, der->length,
19918                         &algId);
19919                     if (ret >= 0) {
19920                         if (keyFormat)
19921                             *keyFormat = algId;
19922                         ret = 0;
19923                     }
19924                 }
19925             #else
19926                 ret = NOT_COMPILED_IN;
19927             #endif
19928             }
19929             /* decrypt the key */
19930             else {
19931                 if (passwordSz == 0) {
19932                     /* The key is encrypted but does not have a password */
19933                     WOLFSSL_MSG("No password for encrypted key");
19934                     ret = NO_PASSWORD;
19935                 }
19936                 else {
19937                     ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
19938                         (byte*)password, passwordSz, WC_MD5);
19939 
19940 #ifndef NO_WOLFSSL_SKIP_TRAILING_PAD
19941                 #ifndef NO_DES3
19942                     if (info->cipherType == WC_CIPHER_DES3) {
19943                         /* Assuming there is padding:
19944                          *      (der->length > 0 && der->length > DES_BLOCK_SIZE &&
19945                          *       (der->length % DES_BLOCK_SIZE) != 0)
19946                          * and assuming the last value signifies the number of
19947                          * padded bytes IE if last value is 0x08 then there are
19948                          * 8 bytes of padding:
19949                          *      padVal = der->buffer[der->length-1];
19950                          * then strip this padding before proceeding:
19951                          * der->length -= padVal;
19952                          */
19953                         if (der->length > DES_BLOCK_SIZE &&
19954                             (der->length % DES_BLOCK_SIZE) != 0) {
19955                             padVal = der->buffer[der->length-1];
19956                             if (padVal < DES_BLOCK_SIZE) {
19957                                 der->length -= padVal;
19958                             }
19959                         }
19960                     }
19961                 #endif /* !NO_DES3 */
19962 #endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */
19963                 }
19964             }
19965 #ifdef OPENSSL_EXTRA
19966             if (ret) {
19967                 PEMerr(0, PEM_R_BAD_DECRYPT);
19968             }
19969 #endif
19970             ForceZero(password, passwordSz);
19971         }
19972 #ifdef OPENSSL_EXTRA
19973         else {
19974             PEMerr(0, PEM_R_BAD_PASSWORD_READ);
19975         }
19976 #endif
19977 
19978     #ifdef WOLFSSL_SMALL_STACK
19979         XFREE(password, heap, DYNAMIC_TYPE_STRING);
19980     #endif
19981     }
19982 #endif /* WOLFSSL_ENCRYPTED_KEYS */
19983 
19984     return ret;
19985 }
19986 
19987 int wc_PemToDer(const unsigned char* buff, long longSz, int type,
19988               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
19989 {
19990     int ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
19991 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
19992     if (ret == 0 && type == PRIVATEKEY_TYPE) {
19993         DerBuffer* der = *pDer;
19994         /* if a PKCS8 key header exists remove it */
19995         ret = ToTraditional(der->buffer, der->length);
19996         if (ret > 0) {
19997             der->length = ret;
19998         }
19999         ret = 0; /* ignore error removing PKCS8 header */
20000     }
20001 #endif
20002     return ret;
20003 }
20004 
20005 
20006 /* our KeyPemToDer password callback, password in userData */
20007 static int KeyPemToDerPassCb(char* passwd, int sz, int rw, void* userdata)
20008 {
20009     (void)rw;
20010 
20011     if (userdata == NULL)
20012         return 0;
20013 
20014     XSTRNCPY(passwd, (char*)userdata, sz);
20015     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
20016 }
20017 
20018 /* Return bytes written to buff or < 0 for error */
20019 int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
20020                         unsigned char* buff, int buffSz, const char* pass)
20021 {
20022     int ret;
20023     DerBuffer* der = NULL;
20024 #ifdef WOLFSSL_SMALL_STACK
20025     EncryptedInfo* info = NULL;
20026 #else
20027     EncryptedInfo  info[1];
20028 #endif
20029 
20030     WOLFSSL_ENTER("wc_KeyPemToDer");
20031 
20032     if (pem == NULL || buff == NULL || buffSz <= 0) {
20033         WOLFSSL_MSG("Bad pem der args");
20034         return BAD_FUNC_ARG;
20035     }
20036 
20037 #ifdef WOLFSSL_SMALL_STACK
20038     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
20039                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
20040     if (info == NULL)
20041         return MEMORY_E;
20042 #endif
20043 
20044     XMEMSET(info, 0, sizeof(EncryptedInfo));
20045     info->passwd_cb = KeyPemToDerPassCb;
20046     info->passwd_userdata = (void*)pass;
20047 
20048     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, NULL);
20049 
20050 #ifdef WOLFSSL_SMALL_STACK
20051     XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
20052 #endif
20053 
20054     if (ret < 0 || der == NULL) {
20055         WOLFSSL_MSG("Bad Pem To Der");
20056     }
20057     else {
20058         if (der->length <= (word32)buffSz) {
20059             XMEMCPY(buff, der->buffer, der->length);
20060             ret = der->length;
20061         }
20062         else {
20063             WOLFSSL_MSG("Bad der length");
20064             ret = BAD_FUNC_ARG;
20065         }
20066     }
20067 
20068     FreeDer(&der);
20069     return ret;
20070 }
20071 
20072 
20073 /* Return bytes written to buff or < 0 for error */
20074 int wc_CertPemToDer(const unsigned char* pem, int pemSz,
20075                         unsigned char* buff, int buffSz, int type)
20076 {
20077     int ret;
20078     DerBuffer* der = NULL;
20079 
20080     WOLFSSL_ENTER("wc_CertPemToDer");
20081 
20082     if (pem == NULL || buff == NULL || buffSz <= 0) {
20083         WOLFSSL_MSG("Bad pem der args");
20084         return BAD_FUNC_ARG;
20085     }
20086 
20087     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
20088         WOLFSSL_MSG("Bad cert type");
20089         return BAD_FUNC_ARG;
20090     }
20091 
20092 
20093     ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, NULL);
20094     if (ret < 0 || der == NULL) {
20095         WOLFSSL_MSG("Bad Pem To Der");
20096     }
20097     else {
20098         if (der->length <= (word32)buffSz) {
20099             XMEMCPY(buff, der->buffer, der->length);
20100             ret = der->length;
20101         }
20102         else {
20103             WOLFSSL_MSG("Bad der length");
20104             ret = BAD_FUNC_ARG;
20105         }
20106     }
20107 
20108     FreeDer(&der);
20109     return ret;
20110 }
20111 
20112 #endif /* WOLFSSL_PEM_TO_DER */
20113 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
20114 
20115 
20116 #ifdef WOLFSSL_PEM_TO_DER
20117 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
20118 /* Return bytes written to buff or < 0 for error */
20119 int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
20120                            unsigned char* buff, int buffSz)
20121 {
20122     int ret;
20123     DerBuffer* der = NULL;
20124 
20125     WOLFSSL_ENTER("wc_PubKeyPemToDer");
20126 
20127     if (pem == NULL || buff == NULL || buffSz <= 0) {
20128         WOLFSSL_MSG("Bad pem der args");
20129         return BAD_FUNC_ARG;
20130     }
20131 
20132     ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
20133     if (ret < 0 || der == NULL) {
20134         WOLFSSL_MSG("Bad Pem To Der");
20135     }
20136     else {
20137         if (der->length <= (word32)buffSz) {
20138             XMEMCPY(buff, der->buffer, der->length);
20139             ret = der->length;
20140         }
20141         else {
20142             WOLFSSL_MSG("Bad der length");
20143             ret = BAD_FUNC_ARG;
20144         }
20145     }
20146 
20147     FreeDer(&der);
20148     return ret;
20149 }
20150 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
20151 #endif /* WOLFSSL_PEM_TO_DER */
20152 
20153 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_PEM_TO_DER)
20154 
20155 #ifdef WOLFSSL_CERT_GEN
20156 int wc_PemCertToDer_ex(const char* fileName, DerBuffer** der)
20157 {
20158 #ifdef WOLFSSL_SMALL_STACK
20159     byte   staticBuffer[1]; /* force XMALLOC */
20160 #else
20161     byte   staticBuffer[FILE_BUFFER_SIZE];
20162 #endif
20163     byte*  fileBuf = staticBuffer;
20164     int    dynamic = 0;
20165     int    ret     = 0;
20166     long   sz      = 0;
20167     XFILE  file    = NULL;
20168 
20169     WOLFSSL_ENTER("wc_PemCertToDer");
20170 
20171     if (fileName == NULL) {
20172         ret = BAD_FUNC_ARG;
20173     }
20174     else {
20175         file = XFOPEN(fileName, "rb");
20176         if (file == XBADFILE) {
20177             ret = BUFFER_E;
20178         }
20179     }
20180 
20181     if (ret == 0) {
20182         if (XFSEEK(file, 0, XSEEK_END) != 0) {
20183             ret = BUFFER_E;
20184         }
20185         sz = XFTELL(file);
20186         XREWIND(file);
20187 
20188         if (sz <= 0) {
20189             ret = BUFFER_E;
20190         }
20191         else if (sz > (long)sizeof(staticBuffer)) {
20192         #ifdef WOLFSSL_STATIC_MEMORY
20193             WOLFSSL_MSG("File was larger then static buffer");
20194             ret = MEMORY_E;
20195         #else
20196             fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
20197             if (fileBuf == NULL)
20198                 ret = MEMORY_E;
20199             else
20200                 dynamic = 1;
20201         #endif
20202         }
20203 
20204         if (ret == 0) {
20205             if ((size_t)XFREAD(fileBuf, 1, sz, file) != (size_t)sz) {
20206                 ret = BUFFER_E;
20207             }
20208             else {
20209                 ret = PemToDer(fileBuf, sz, CA_TYPE, der,  0, NULL,NULL);
20210             }
20211         }
20212 
20213         XFCLOSE(file);
20214         if (dynamic)
20215             XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
20216     }
20217 
20218     return ret;
20219 }
20220 /* load pem cert from file into der buffer, return der size or error */
20221 int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
20222 {
20223     int ret;
20224     DerBuffer* converted = NULL;
20225     ret = wc_PemCertToDer_ex(fileName, &converted);
20226     if (ret == 0) {
20227         if (converted->length < (word32)derSz) {
20228             XMEMCPY(derBuf, converted->buffer, converted->length);
20229             ret = converted->length;
20230         }
20231         else
20232             ret = BUFFER_E;
20233 
20234         FreeDer(&converted);
20235     }
20236     return ret;
20237 }
20238 #endif /* WOLFSSL_CERT_GEN */
20239 
20240 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
20241 /* load pem public key from file into der buffer, return der size or error */
20242 int wc_PemPubKeyToDer_ex(const char* fileName, DerBuffer** der)
20243 {
20244 #ifdef WOLFSSL_SMALL_STACK
20245     byte   staticBuffer[1]; /* force XMALLOC */
20246 #else
20247     byte   staticBuffer[FILE_BUFFER_SIZE];
20248 #endif
20249     byte*  fileBuf = staticBuffer;
20250     int    dynamic = 0;
20251     int    ret     = 0;
20252     long   sz      = 0;
20253     XFILE  file;
20254 
20255     WOLFSSL_ENTER("wc_PemPubKeyToDer");
20256 
20257     if (fileName == NULL) {
20258         ret = BAD_FUNC_ARG;
20259     }
20260     else {
20261         file = XFOPEN(fileName, "rb");
20262         if (file == XBADFILE) {
20263             ret = BUFFER_E;
20264         }
20265     }
20266 
20267     if (ret == 0) {
20268         if (XFSEEK(file, 0, XSEEK_END) != 0) {
20269             ret = BUFFER_E;
20270         }
20271         sz = XFTELL(file);
20272         XREWIND(file);
20273 
20274         if (sz <= 0) {
20275             ret = BUFFER_E;
20276         }
20277         else if (sz > (long)sizeof(staticBuffer)) {
20278         #ifdef WOLFSSL_STATIC_MEMORY
20279             WOLFSSL_MSG("File was larger then static buffer");
20280             ret = MEMORY_E;
20281         #else
20282             fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
20283             if (fileBuf == NULL)
20284                 ret = MEMORY_E;
20285             else
20286                 dynamic = 1;
20287         #endif
20288         }
20289         if (ret == 0) {
20290             if ((size_t)XFREAD(fileBuf, 1, sz, file) != (size_t)sz) {
20291                 ret = BUFFER_E;
20292             }
20293             else {
20294                 ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, der,
20295                                0, NULL, NULL);
20296             }
20297         }
20298 
20299         XFCLOSE(file);
20300         if (dynamic) {
20301             XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
20302         }
20303     }
20304 
20305     return ret;
20306 }
20307 /* load pem public key from file into der buffer, return der size or error */
20308 int wc_PemPubKeyToDer(const char* fileName,
20309                            unsigned char* derBuf, int derSz)
20310 {
20311     int ret;
20312     DerBuffer* converted = NULL;
20313     ret = wc_PemPubKeyToDer_ex(fileName, &converted);
20314     if (ret == 0) {
20315         if (converted->length < (word32)derSz) {
20316             XMEMCPY(derBuf, converted->buffer, converted->length);
20317             ret = converted->length;
20318         }
20319         else
20320             ret = BUFFER_E;
20321 
20322         FreeDer(&converted);
20323     }
20324     return ret;
20325 }
20326 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
20327 
20328 #endif /* !NO_FILESYSTEM && WOLFSSL_PEM_TO_DER */
20329 
20330 /* Get public key in DER format from a populated DecodedCert struct.
20331  *
20332  * Users must call wc_InitDecodedCert() and wc_ParseCert() before calling
20333  * this API. wc_InitDecodedCert() accepts a DER/ASN.1 encoded certificate.
20334  * To convert a PEM cert to DER first use wc_CertPemToDer() before calling
20335  * wc_InitDecodedCert().
20336  *
20337  * cert   - populated DecodedCert struct holding X.509 certificate
20338  * derKey - output buffer to place DER/ASN.1 encoded public key
20339  * derKeySz [IN/OUT] - size of derKey buffer on input, size of public key
20340  *                     on return. If derKey is passed in as NULL, derKeySz
20341  *                     will be set to required buffer size for public key
20342  *                     and LENGTH_ONLY_E will be returned from function.
20343  * Returns 0 on success, or negative error code on failure. LENGTH_ONLY_E
20344  * if derKey is NULL and returning length only.
20345  */
20346 int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
20347                             byte* derKey, word32* derKeySz)
20348 {
20349     int ret = 0;
20350 
20351     /* derKey may be NULL to return length only */
20352     if (cert == NULL || derKeySz == NULL ||
20353         (derKey != NULL && *derKeySz == 0)) {
20354         return BAD_FUNC_ARG;
20355     }
20356 
20357     if (cert->publicKey == NULL) {
20358         WOLFSSL_MSG("DecodedCert does not contain public key\n");
20359         return BAD_FUNC_ARG;
20360     }
20361 
20362     /* if derKey is NULL, return required output buffer size in derKeySz */
20363     if (derKey == NULL) {
20364         *derKeySz = cert->pubKeySize;
20365         ret = LENGTH_ONLY_E;
20366     }
20367 
20368     if (ret == 0) {
20369         if (cert->pubKeySize > *derKeySz) {
20370             WOLFSSL_MSG("Output buffer not large enough for public key DER");
20371             ret = BAD_FUNC_ARG;
20372         }
20373         else {
20374             XMEMCPY(derKey, cert->publicKey, cert->pubKeySize);
20375             *derKeySz = cert->pubKeySize;
20376         }
20377     }
20378 
20379     return ret;
20380 }
20381 
20382 #if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
20383     defined(WOLFSSL_KCAPI_RSA) || \
20384     ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
20385 /* USER RSA ifdef portions used instead of refactor in consideration for
20386    possible fips build */
20387 /* Encode a public RSA key to output.
20388  *
20389  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
20390  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
20391  *
20392  * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
20393  * (RSAPublicKey).
20394  *
20395  * @param [out] output       Buffer to put encoded data in.
20396  * @param [in]  key          RSA key object.
20397  * @param [in]  outLen       Size of the output buffer in bytes.
20398  * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
20399  * @return  Size of encoded data in bytes on success.
20400  * @return  BAD_FUNC_ARG when output or key is NULL, or outLen is less than
20401  *          minimum length (5 bytes).
20402  * @return  MEMORY_E when dynamic memory allocation failed.
20403  */
20404 static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen,
20405                            int with_header)
20406 {
20407 #ifndef WOLFSSL_ASN_TEMPLATE
20408     int  idx, nSz, eSz, seqSz, headSz = 0, bitStringSz = 0, algoSz = 0;
20409     byte seq[MAX_SEQ_SZ];
20410     byte headSeq[MAX_SEQ_SZ];
20411     byte bitString[1 + MAX_LENGTH_SZ + 1];
20412     byte algo[MAX_ALGO_SZ]; /* 20 bytes */
20413 
20414     if (key == NULL) {
20415         return BAD_FUNC_ARG;
20416     }
20417 
20418 #ifdef HAVE_USER_RSA
20419     nSz = SetASNIntRSA(key->n, NULL);
20420 #else
20421     nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
20422 #endif
20423     if (nSz < 0)
20424         return nSz;
20425 
20426 #ifdef HAVE_USER_RSA
20427     eSz = SetASNIntRSA(key->e, NULL);
20428 #else
20429     eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
20430 #endif
20431     if (eSz < 0)
20432         return eSz;
20433     seqSz = SetSequence(nSz + eSz, seq);
20434 
20435     /* headers */
20436     if (with_header) {
20437         algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
20438         bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
20439         headSz = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, headSeq);
20440     }
20441 
20442     /* if getting length only */
20443     if (output == NULL) {
20444         return headSz + algoSz + bitStringSz + seqSz + nSz + eSz;
20445     }
20446 
20447     /* check output size */
20448     if ((headSz + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
20449         return BUFFER_E;
20450     }
20451 
20452     /* write output */
20453     idx = 0;
20454     if (with_header) {
20455         /* header size */
20456         XMEMCPY(output + idx, headSeq, headSz);
20457         idx += headSz;
20458         /* algo */
20459         XMEMCPY(output + idx, algo, algoSz);
20460         idx += algoSz;
20461         /* bit string */
20462         XMEMCPY(output + idx, bitString, bitStringSz);
20463         idx += bitStringSz;
20464     }
20465 
20466     /* seq */
20467     XMEMCPY(output + idx, seq, seqSz);
20468     idx += seqSz;
20469     /* n */
20470 #ifdef HAVE_USER_RSA
20471     nSz = SetASNIntRSA(key->n, output + idx);
20472 #else
20473     nSz = SetASNIntMP(&key->n, nSz, output + idx);
20474 #endif
20475     idx += nSz;
20476     /* e */
20477 #ifdef HAVE_USER_RSA
20478     eSz = SetASNIntRSA(key->e, output + idx);
20479 #else
20480     eSz = SetASNIntMP(&key->e, eSz, output + idx);
20481 #endif
20482     idx += eSz;
20483 
20484     return idx;
20485 #else
20486     DECL_ASNSETDATA(dataASN, rsaPublicKeyASN_Length);
20487     int sz;
20488     int ret = 0;
20489     int o = 0;
20490 
20491     /* Check parameter validity. */
20492     if ((key == NULL) || ((output != NULL) && (outLen < MAX_SEQ_SZ))) {
20493         ret = BAD_FUNC_ARG;
20494     }
20495 
20496     CALLOC_ASNSETDATA(dataASN, rsaPublicKeyASN_Length, ret, key->heap);
20497 
20498     if (ret == 0) {
20499         if (!with_header) {
20500             /* Start encoding with items after header. */
20501             o = RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ;
20502         }
20503         /* Set OID for RSA key. */
20504         SetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], RSAk, oidKeyType);
20505         /* Set public key mp_ints. */
20506     #ifdef HAVE_USER_RSA
20507         SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], key->n);
20508         SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], key->e);
20509     #else
20510         SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
20511         SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
20512     #endif
20513         /* Calculate size of RSA public key. */
20514         ret = SizeASN_Items(rsaPublicKeyASN + o, dataASN + o,
20515                             rsaPublicKeyASN_Length - o, &sz);
20516     }
20517     /* Check output buffer is big enough for encoding. */
20518     if ((ret == 0) && (output != NULL) && (sz > outLen)) {
20519         ret = BUFFER_E;
20520     }
20521     if ((ret == 0) && (output != NULL)) {
20522         /* Encode RSA public key. */
20523         SetASN_Items(rsaPublicKeyASN + o, dataASN + o,
20524                      rsaPublicKeyASN_Length - o, output);
20525     }
20526     if (ret == 0) {
20527         /* Return size of encoding. */
20528         ret = sz;
20529     }
20530 
20531     FREE_ASNSETDATA(dataASN, key->heap);
20532     return ret;
20533 #endif /* WOLFSSL_ASN_TEMPLATE */
20534 }
20535 
20536 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
20537                                            !HAVE_USER_RSA))) */
20538 
20539 #if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
20540 /* Calculate size of encoded public RSA key in bytes.
20541  *
20542  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
20543  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
20544  *
20545  * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
20546  * (RSAPublicKey).
20547  *
20548  * @param [in]  key          RSA key object.
20549  * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
20550  * @return  Size of encoded data in bytes on success.
20551  * @return  BAD_FUNC_ARG when key is NULL.
20552  * @return  MEMORY_E when dynamic memory allocation failed.
20553  */
20554 int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
20555 {
20556     return SetRsaPublicKey(NULL, key, 0, with_header);
20557 }
20558 
20559 #endif /* !NO_RSA && WOLFSSL_CERT_GEN */
20560 
20561 #if ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && \
20562     !defined(NO_RSA) && !defined(HAVE_USER_RSA)) || defined(WOLFSSL_KCAPI_RSA)
20563 
20564 /* Encode private RSA key in DER format.
20565  *
20566  * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
20567  *
20568  * @param [in]  key     RSA key object.
20569  * @param [out] output  Buffer to put encoded data in.
20570  * @param [in]  inLen   Size of buffer in bytes.
20571  * @return  Size of encoded data in bytes on success.
20572  * @return  BAD_FUNC_ARG when key is NULL or not a private key.
20573  * @return  MEMORY_E when dynamic memory allocation failed.
20574  */
20575 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
20576 {
20577 #ifndef WOLFSSL_ASN_TEMPLATE
20578     int ret = 0, i, j, outLen = 0, mpSz;
20579     word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
20580     word32 sizes[RSA_INTS];
20581     byte  seq[MAX_SEQ_SZ];
20582     byte  ver[MAX_VERSION_SZ];
20583     byte* tmps[RSA_INTS];
20584 
20585     if (key == NULL)
20586         return BAD_FUNC_ARG;
20587 
20588     if (key->type != RSA_PRIVATE)
20589         return BAD_FUNC_ARG;
20590 
20591     for (i = 0; i < RSA_INTS; i++)
20592         tmps[i] = NULL;
20593 
20594     /* write all big ints from key to DER tmps */
20595     for (i = 0; i < RSA_INTS; i++) {
20596         mp_int* keyInt = GetRsaInt(key, (byte)i);
20597 
20598         rawLen = mp_unsigned_bin_size(keyInt) + 1;
20599         if (output != NULL) {
20600             tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
20601                                  DYNAMIC_TYPE_RSA);
20602             if (tmps[i] == NULL) {
20603                 ret = MEMORY_E;
20604                 break;
20605             }
20606         }
20607 
20608         mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
20609         if (mpSz < 0) {
20610             ret = mpSz;
20611             break;
20612         }
20613         intTotalLen += (sizes[i] = mpSz);
20614     }
20615 
20616     if (ret == 0) {
20617         /* make headers */
20618         verSz = SetMyVersion(0, ver, FALSE);
20619         seqSz = SetSequence(verSz + intTotalLen, seq);
20620 
20621         outLen = seqSz + verSz + intTotalLen;
20622         if (output != NULL && outLen > (int)inLen)
20623             ret = BUFFER_E;
20624     }
20625     if (ret == 0 && output != NULL) {
20626         /* write to output */
20627         XMEMCPY(output, seq, seqSz);
20628         j = seqSz;
20629         XMEMCPY(output + j, ver, verSz);
20630         j += verSz;
20631 
20632         for (i = 0; i < RSA_INTS; i++) {
20633             XMEMCPY(output + j, tmps[i], sizes[i]);
20634             j += sizes[i];
20635         }
20636     }
20637 
20638     for (i = 0; i < RSA_INTS; i++) {
20639         if (tmps[i])
20640             XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
20641     }
20642 
20643     if (ret == 0)
20644         ret = outLen;
20645     return ret;
20646 #else
20647     DECL_ASNSETDATA(dataASN, rsaKeyASN_Length);
20648     byte i;
20649     int sz;
20650     int ret = 0;
20651 
20652     if ((key == NULL) || (key->type != RSA_PRIVATE)) {
20653         ret = BAD_FUNC_ARG;
20654     }
20655 
20656     CALLOC_ASNSETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
20657 
20658     if (ret == 0) {
20659         /* Set the version. */
20660         SetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], 0);
20661         /* Set all the mp_ints in private key. */
20662         for (i = 0; i < RSA_INTS; i++) {
20663             SetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
20664         }
20665 
20666         /* Calculate size of RSA private key encoding. */
20667         ret = SizeASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, &sz);
20668     }
20669     /* Check output buffer has enough space for encoding. */
20670     if ((ret == 0) && (output != NULL) && (sz > (int)inLen)) {
20671         ret = BAD_FUNC_ARG;
20672     }
20673     if ((ret == 0) && (output != NULL)) {
20674         /* Encode RSA private key. */
20675         SetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, output);
20676     }
20677 
20678     if (ret == 0) {
20679         /* Return size of encoding. */
20680         ret = sz;
20681     }
20682 
20683     FREE_ASNSETDATA(dataASN, key->heap);
20684     return ret;
20685 #endif
20686 }
20687 
20688 
20689 /* Encode public RSA key in DER format.
20690  *
20691  * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
20692  * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
20693  *
20694  * @param [in]  key     RSA key object.
20695  * @param [out] output  Buffer to put encoded data in.
20696  * @param [in]  inLen   Size of buffer in bytes.
20697  * @return  Size of encoded data in bytes on success.
20698  * @return  BAD_FUNC_ARG when key or output is NULL.
20699  * @return  MEMORY_E when dynamic memory allocation failed.
20700  */
20701 int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
20702 {
20703     return SetRsaPublicKey(output, key, inLen, 1);
20704 }
20705 
20706 /* Returns public DER version of the RSA key. If with_header is 0 then only a
20707  * seq + n + e is returned in ASN.1 DER format */
20708 int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
20709     int with_header)
20710 {
20711     return SetRsaPublicKey(output, key, inLen, with_header);
20712 }
20713 #endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
20714 
20715 
20716 #ifdef WOLFSSL_CERT_GEN
20717 
20718 /* Initialize and Set Certificate defaults:
20719    version    = 3 (0x2)
20720    serial     = 0
20721    sigType    = SHA_WITH_RSA
20722    issuer     = blank
20723    daysValid  = 500
20724    selfSigned = 1 (true) use subject as issuer
20725    subject    = blank
20726 */
20727 int wc_InitCert_ex(Cert* cert, void* heap, int devId)
20728 {
20729 #ifdef WOLFSSL_MULTI_ATTRIB
20730     int i = 0;
20731 #endif
20732     if (cert == NULL) {
20733         return BAD_FUNC_ARG;
20734     }
20735 
20736     XMEMSET(cert, 0, sizeof(Cert));
20737 
20738     cert->version    = 2;   /* version 3 is hex 2 */
20739 #ifndef NO_SHA
20740     cert->sigType    = CTC_SHAwRSA;
20741 #elif !defined(NO_SHA256)
20742     cert->sigType    = CTC_SHA256wRSA;
20743 #else
20744     cert->sigType    = 0;
20745 #endif
20746     cert->daysValid  = 500;
20747     cert->selfSigned = 1;
20748     cert->keyType    = RSA_KEY;
20749 
20750     cert->issuer.countryEnc = CTC_PRINTABLE;
20751     cert->issuer.stateEnc = CTC_UTF8;
20752     cert->issuer.localityEnc = CTC_UTF8;
20753     cert->issuer.surEnc = CTC_UTF8;
20754     cert->issuer.orgEnc = CTC_UTF8;
20755     cert->issuer.unitEnc = CTC_UTF8;
20756     cert->issuer.commonNameEnc = CTC_UTF8;
20757 
20758     cert->subject.countryEnc = CTC_PRINTABLE;
20759     cert->subject.stateEnc = CTC_UTF8;
20760     cert->subject.localityEnc = CTC_UTF8;
20761     cert->subject.surEnc = CTC_UTF8;
20762     cert->subject.orgEnc = CTC_UTF8;
20763     cert->subject.unitEnc = CTC_UTF8;
20764     cert->subject.commonNameEnc = CTC_UTF8;
20765 
20766 #ifdef WOLFSSL_MULTI_ATTRIB
20767     for (i = 0; i < CTC_MAX_ATTRIB; i++) {
20768         cert->issuer.name[i].type   = CTC_UTF8;
20769         cert->subject.name[i].type  = CTC_UTF8;
20770     }
20771 #endif /* WOLFSSL_MULTI_ATTRIB */
20772 
20773     cert->heap = heap;
20774     (void)devId; /* future */
20775 
20776     return 0;
20777 }
20778 
20779 int wc_InitCert(Cert* cert)
20780 {
20781     return wc_InitCert_ex(cert, NULL, INVALID_DEVID);
20782 }
20783 
20784 /* DER encoded x509 Certificate */
20785 typedef struct DerCert {
20786     byte size[MAX_LENGTH_SZ];          /* length encoded */
20787     byte version[MAX_VERSION_SZ];      /* version encoded */
20788     byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
20789     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
20790     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
20791     byte subject[ASN_NAME_MAX];        /* subject encoded */
20792     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
20793     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa public key encoded */
20794     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
20795     byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
20796 #ifdef WOLFSSL_CERT_EXT
20797     byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
20798     byte akid[MAX_KID_SZ
20799 #ifdef WOLFSSL_AKID_NAME
20800               + sizeof(CertName) + CTC_SERIAL_SIZE
20801 #endif
20802               ]; /* Authority Key Identifier extension */
20803     byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
20804     byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
20805 #ifndef IGNORE_NETSCAPE_CERT_TYPE
20806     byte nsCertType[MAX_NSCERTTYPE_SZ]; /* Extended Key Usage extension */
20807 #endif
20808     byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
20809     byte crlInfo[CTC_MAX_CRLINFO_SZ];  /* CRL Distribution Points */
20810 #endif
20811 #ifdef WOLFSSL_CERT_REQ
20812     byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
20813     #ifdef WOLFSSL_CUSTOM_OID
20814     byte extCustom[MAX_ATTRIB_SZ];     /* Encoded user oid and value */
20815     #endif
20816 #endif
20817 #ifdef WOLFSSL_ALT_NAMES
20818     byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
20819 #endif
20820     int  sizeSz;                       /* encoded size length */
20821     int  versionSz;                    /* encoded version length */
20822     int  serialSz;                     /* encoded serial length */
20823     int  sigAlgoSz;                    /* encoded sig algo length */
20824     int  issuerSz;                     /* encoded issuer length */
20825     int  subjectSz;                    /* encoded subject length */
20826     int  validitySz;                   /* encoded validity length */
20827     int  publicKeySz;                  /* encoded public key length */
20828     int  caSz;                         /* encoded CA extension length */
20829 #ifdef WOLFSSL_CERT_EXT
20830     int  skidSz;                       /* encoded SKID extension length */
20831     int  akidSz;                       /* encoded SKID extension length */
20832     int  keyUsageSz;                   /* encoded KeyUsage extension length */
20833     int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
20834 #ifndef IGNORE_NETSCAPE_CERT_TYPE
20835     int  nsCertTypeSz;                 /* encoded Netscape Certifcate Type
20836                                         * extension length */
20837 #endif
20838     int  certPoliciesSz;               /* encoded CertPolicies extension length*/
20839     int  crlInfoSz;                    /* encoded CRL Dist Points length */
20840 #endif
20841 #ifdef WOLFSSL_ALT_NAMES
20842     int  altNamesSz;                   /* encoded AltNames extension length */
20843 #endif
20844     int  extensionsSz;                 /* encoded extensions total length */
20845     int  total;                        /* total encoded lengths */
20846 #ifdef WOLFSSL_CERT_REQ
20847     int  attribSz;
20848     #ifdef WOLFSSL_CUSTOM_OID
20849     int  extCustomSz;
20850     #endif
20851 #endif
20852 } DerCert;
20853 
20854 
20855 #ifdef WOLFSSL_CERT_REQ
20856 #ifndef WOLFSSL_ASN_TEMPLATE
20857 
20858 /* Write a set header to output */
20859 static word32 SetPrintableString(word32 len, byte* output)
20860 {
20861     output[0] = ASN_PRINTABLE_STRING;
20862     return SetLength(len, output + 1) + 1;
20863 }
20864 
20865 static word32 SetUTF8String(word32 len, byte* output)
20866 {
20867     output[0] = ASN_UTF8STRING;
20868     return SetLength(len, output + 1) + 1;
20869 }
20870 
20871 #endif
20872 #endif /* WOLFSSL_CERT_REQ */
20873 
20874 
20875 #ifndef WOLFSSL_CERT_GEN_CACHE
20876 /* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
20877 static
20878 #endif
20879 void wc_SetCert_Free(Cert* cert)
20880 {
20881     if (cert != NULL) {
20882         cert->der = NULL;
20883         if (cert->decodedCert) {
20884             FreeDecodedCert((DecodedCert*)cert->decodedCert);
20885 
20886             XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
20887             cert->decodedCert = NULL;
20888         }
20889     }
20890 }
20891 
20892 static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz)
20893 {
20894     int ret;
20895 
20896     if (cert == NULL) {
20897         ret = BAD_FUNC_ARG;
20898     }
20899     else {
20900         /* Allocate DecodedCert struct and Zero */
20901         cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
20902             DYNAMIC_TYPE_DCERT);
20903 
20904         if (cert->decodedCert == NULL) {
20905             ret = MEMORY_E;
20906         }
20907         else {
20908             XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
20909 
20910             InitDecodedCert((DecodedCert*)cert->decodedCert, der, derSz,
20911                     cert->heap);
20912             ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
20913                     CERT_TYPE, 0, NULL);
20914             if (ret >= 0) {
20915                 cert->der = (byte*)der;
20916             }
20917             else {
20918                 wc_SetCert_Free(cert);
20919             }
20920         }
20921     }
20922 
20923     return ret;
20924 }
20925 
20926 #endif /* WOLFSSL_CERT_GEN */
20927 
20928 #ifdef HAVE_ECC
20929 #ifdef WOLFSSL_ASN_TEMPLATE
20930 /* ASN.1 template for ECC public key (SubjectPublicKeyInfo).
20931  * RFC 5480, 2 - Subject Public Key Information Fields
20932  *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
20933  * X9.62 ECC point format.
20934  * See ASN.1 template 'eccSpecifiedASN' for specifiedCurve.
20935  */
20936 static const ASNItem eccPublicKeyASN[] = {
20937 /* SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20938                                              /* AlgorithmIdentifier */
20939 /* ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
20940                                                  /* algorithm */
20941 /* ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
20942                                                  /* namedCurve */
20943 /* ALGOID_CURVEID */         { 2, ASN_OBJECT_ID, 0, 0, 2 },
20944                                                  /* specifiedCurve - explicit parameters */
20945 /* ALGOID_PARAMS  */         { 2, ASN_SEQUENCE, 1, 0, 2 },
20946                                              /* Public Key */
20947 /* PUBKEY         */     { 1, ASN_BIT_STRING, 0, 0, 0 },
20948 };
20949 enum {
20950     ECCPUBLICKEYASN_IDX_SEQ = 0,
20951     ECCPUBLICKEYASN_IDX_ALGOID_SEQ,
20952     ECCPUBLICKEYASN_IDX_ALGOID_OID,
20953     ECCPUBLICKEYASN_IDX_ALGOID_CURVEID,
20954     ECCPUBLICKEYASN_IDX_ALGOID_PARAMS,
20955     ECCPUBLICKEYASN_IDX_PUBKEY,
20956 };
20957 
20958 /* Number of items in ASN.1 template for ECC public key. */
20959 #define eccPublicKeyASN_Length (sizeof(eccPublicKeyASN) / sizeof(ASNItem))
20960 #endif /* WOLFSSL_ASN_TEMPLATE */
20961 #endif /* HAVE_ECC */
20962 
20963 #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
20964 
20965 /* Encode public ECC key in DER format.
20966  *
20967  * RFC 5480, 2 - Subject Public Key Information Fields
20968  *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
20969  * X9.62 ECC point format.
20970  * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
20971  *
20972  * @param [out] output       Buffer to put encoded data in.
20973  * @param [in]  key          ECC key object.
20974  * @param [in]  outLen       Size of buffer in bytes.
20975  * @param [in]  with_header  Whether to use SubjectPublicKeyInfo format.
20976  * @return  Size of encoded data in bytes on success.
20977  * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
20978  * @return  MEMORY_E when dynamic memory allocation failed.
20979  */
20980 static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
20981                            int with_header)
20982 {
20983 #ifndef WOLFSSL_ASN_TEMPLATE
20984     byte bitString[1 + MAX_LENGTH_SZ + 1];
20985     int  algoSz;
20986     int  curveSz;
20987     int  bitStringSz;
20988     int  idx;
20989     word32 pubSz = ECC_BUFSIZE;
20990 #ifdef WOLFSSL_SMALL_STACK
20991     byte* algo = NULL;
20992     byte* curve = NULL;
20993     byte* pub;
20994 #else
20995     byte algo[MAX_ALGO_SZ];
20996     byte curve[MAX_ALGO_SZ];
20997     byte pub[ECC_BUFSIZE];
20998 #endif
20999     int ret;
21000 
21001     (void)outLen;
21002 
21003 #ifdef WOLFSSL_SMALL_STACK
21004     pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21005     if (pub == NULL)
21006         return MEMORY_E;
21007 #endif
21008 
21009 #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS)
21010     /* older version of ecc.c can not handle dp being NULL */
21011     if (key != NULL && key->dp == NULL) {
21012         ret = BAD_FUNC_ARG;
21013     }
21014     else {
21015         PRIVATE_KEY_UNLOCK();
21016         ret = wc_ecc_export_x963(key, pub, &pubSz);
21017         PRIVATE_KEY_LOCK();
21018     }
21019 #else
21020     ret = wc_ecc_export_x963(key, pub, &pubSz);
21021 #endif
21022     if (ret != 0) {
21023 #ifdef WOLFSSL_SMALL_STACK
21024         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21025 #endif
21026         return ret;
21027     }
21028 
21029     /* headers */
21030     if (with_header) {
21031 #ifdef WOLFSSL_SMALL_STACK
21032         curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21033         if (curve == NULL) {
21034             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21035             return MEMORY_E;
21036         }
21037 #endif
21038         curveSz = SetCurve(key, curve);
21039         if (curveSz <= 0) {
21040 #ifdef WOLFSSL_SMALL_STACK
21041             XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21042             XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21043 #endif
21044             return curveSz;
21045         }
21046 
21047 #ifdef WOLFSSL_SMALL_STACK
21048         algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21049         if (algo == NULL) {
21050             XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21051             XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21052             return MEMORY_E;
21053         }
21054 #endif
21055         algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
21056 
21057         bitStringSz = SetBitString(pubSz, 0, bitString);
21058 
21059         idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
21060         /* algo */
21061         if (output)
21062             XMEMCPY(output + idx, algo, algoSz);
21063         idx += algoSz;
21064         /* curve */
21065         if (output)
21066             XMEMCPY(output + idx, curve, curveSz);
21067         idx += curveSz;
21068         /* bit string */
21069         if (output)
21070             XMEMCPY(output + idx, bitString, bitStringSz);
21071         idx += bitStringSz;
21072     }
21073     else
21074         idx = 0;
21075 
21076     /* pub */
21077     if (output)
21078         XMEMCPY(output + idx, pub, pubSz);
21079     idx += pubSz;
21080 
21081 #ifdef WOLFSSL_SMALL_STACK
21082     if (with_header) {
21083         XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21084         XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21085     }
21086     XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
21087 #endif
21088 
21089     return idx;
21090 #else
21091     word32 pubSz = 0;
21092     int sz = 0;
21093     int ret = 0;
21094 
21095     /* Check key validity. */
21096     if ((key == NULL) || (key->dp == NULL)) {
21097         ret = BAD_FUNC_ARG;
21098     }
21099 
21100     if (ret == 0) {
21101         /* Calculate the size of the encoded public point. */
21102         PRIVATE_KEY_UNLOCK();
21103         ret = wc_ecc_export_x963(key, NULL, &pubSz);
21104         PRIVATE_KEY_LOCK();
21105         /* LENGTH_ONLY_E on success. */
21106         if (ret == LENGTH_ONLY_E) {
21107             ret = 0;
21108         }
21109     }
21110     if ((ret == 0) && with_header) {
21111         /* Including SubjectPublicKeyInfo header. */
21112         DECL_ASNSETDATA(dataASN, eccPublicKeyASN_Length);
21113 
21114         CALLOC_ASNSETDATA(dataASN, eccPublicKeyASN_Length, ret, key->heap);
21115 
21116         if (ret == 0) {
21117             /* Set the key type OID. */
21118             SetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], ECDSAk,
21119                     oidKeyType);
21120             /* Set the curve OID. */
21121             SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID],
21122                     key->dp->oid, key->dp->oidSz);
21123             /* Don't try to write out explicit parameters. */
21124             dataASN[ECCPUBLICKEYASN_IDX_ALGOID_PARAMS].noOut = 1;
21125             /* Set size of public point to ensure space is made for it. */
21126             SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_PUBKEY], NULL, pubSz);
21127             /* Calculate size of ECC public key. */
21128             ret = SizeASN_Items(eccPublicKeyASN, dataASN,
21129                                 eccPublicKeyASN_Length, &sz);
21130         }
21131         /* Check buffer, if passed in, is big enough for encoded data. */
21132         if ((ret == 0) && (output != NULL) && (sz > outLen)) {
21133             ret = BUFFER_E;
21134         }
21135         if ((ret == 0) && (output != NULL)) {
21136             /* Encode ECC public key. */
21137             SetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length,
21138                          output);
21139             /* Skip to where public point is to be encoded. */
21140             output += sz - pubSz;
21141         }
21142 
21143         FREE_ASNSETDATA(dataASN, key->heap);
21144     }
21145     else if ((ret == 0) && (output != NULL) && (pubSz > (word32)outLen)) {
21146         ret = BUFFER_E;
21147     }
21148     else {
21149         /* Total size is the public point size. */
21150         sz = pubSz;
21151     }
21152 
21153     if ((ret == 0) && (output != NULL)) {
21154         /* Encode public point. */
21155         PRIVATE_KEY_UNLOCK();
21156         ret = wc_ecc_export_x963(key, output, &pubSz);
21157         PRIVATE_KEY_LOCK();
21158     }
21159     if (ret == 0) {
21160         /* Return the size of the encoding. */
21161         ret = sz;
21162     }
21163 
21164     return ret;
21165 #endif
21166 }
21167 
21168 
21169 /* Encode the public part of an ECC key in a DER.
21170  *
21171  * Pass NULL for output to get the size of the encoding.
21172  *
21173  * @param [in]  key            ECC key object.
21174  * @param [out] output         Buffer to hold DER encoding.
21175  * @param [in]  inLen          Size of buffer in bytes.
21176  * @param [in]  with_AlgCurve  Whether to use SubjectPublicKeyInfo format.
21177  * @return  Size of encoded data in bytes on success.
21178  * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
21179  * @return  MEMORY_E when dynamic memory allocation failed.
21180  */
21181 int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
21182                                                               int with_AlgCurve)
21183 {
21184 #ifndef WOLFSSL_ASN_TEMPLATE
21185     word32 infoSz = 0;
21186     word32 keySz  = 0;
21187     int ret;
21188 
21189     if (key == NULL) {
21190         return BAD_FUNC_ARG;
21191     }
21192 
21193     if (with_AlgCurve) {
21194         /* buffer space for algorithm/curve */
21195         infoSz += MAX_SEQ_SZ;
21196         infoSz += 2 * MAX_ALGO_SZ;
21197 
21198         /* buffer space for public key sequence */
21199         infoSz += MAX_SEQ_SZ;
21200         infoSz += TRAILING_ZERO;
21201     }
21202 
21203 #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS)
21204     /* older version of ecc.c can not handle dp being NULL */
21205     if (key->dp == NULL) {
21206         keySz = 1 + 2 * MAX_ECC_BYTES;
21207         ret = LENGTH_ONLY_E;
21208     }
21209     else {
21210         PRIVATE_KEY_UNLOCK();
21211         ret = wc_ecc_export_x963(key, NULL, &keySz);
21212         PRIVATE_KEY_LOCK();
21213     }
21214 #else
21215     ret = wc_ecc_export_x963(key, NULL, &keySz);
21216 #endif
21217     if (ret != LENGTH_ONLY_E) {
21218         WOLFSSL_MSG("Error in getting ECC public key size");
21219         return ret;
21220     }
21221 
21222     /* if output null then just return size */
21223     if (output == NULL) {
21224         return keySz + infoSz;
21225     }
21226 
21227     if (inLen < keySz + infoSz) {
21228         return BUFFER_E;
21229     }
21230 #endif
21231 
21232     return SetEccPublicKey(output, key, inLen, with_AlgCurve);
21233 }
21234 
21235 int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
21236 {
21237 #ifndef WOLFSSL_ASN_TEMPLATE
21238     return wc_EccPublicKeyToDer(key, NULL, 0, with_AlgCurve);
21239 #else
21240     return SetEccPublicKey(NULL, key, 0, with_AlgCurve);
21241 #endif
21242 }
21243 
21244 #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
21245 
21246 #ifdef WOLFSSL_ASN_TEMPLATE
21247 #if defined(WC_ENABLE_ASYM_KEY_EXPORT) || defined(WC_ENABLE_ASYM_KEY_IMPORT)
21248 /* ASN.1 template for Ed25519 and Ed448 public key (SubkectPublicKeyInfo).
21249  * RFC 8410, 4 - Subject Public Key Fields
21250  */
21251 static const ASNItem edPubKeyASN[] = {
21252             /* SubjectPublicKeyInfo */
21253 /* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21254                                      /* AlgorithmIdentifier */
21255 /* ALGOID_SEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
21256                                          /* Ed25519/Ed448 OID */
21257 /* ALGOID_OID */         { 2, ASN_OBJECT_ID, 0, 0, 1 },
21258                                      /* Public key stream */
21259 /* PUBKEY     */     { 1, ASN_BIT_STRING, 0, 0, 0 },
21260 };
21261 enum {
21262     EDPUBKEYASN_IDX_SEQ = 0,
21263     EDPUBKEYASN_IDX_ALGOID_SEQ,
21264     EDPUBKEYASN_IDX_ALGOID_OID,
21265     EDPUBKEYASN_IDX_PUBKEY,
21266 };
21267 
21268 /* Number of items in ASN.1 template for Ed25519 and Ed448 public key. */
21269 #define edPubKeyASN_Length (sizeof(edPubKeyASN) / sizeof(ASNItem))
21270 #endif /* WC_ENABLE_ASYM_KEY_EXPORT || WC_ENABLE_ASYM_KEY_IMPORT */
21271 #endif /* WOLFSSL_ASN_TEMPLATE */
21272 
21273 #ifdef WC_ENABLE_ASYM_KEY_EXPORT
21274 
21275 /* Build ASN.1 formatted public key based on RFC 8410
21276  *
21277  * Pass NULL for output to get the size of the encoding.
21278  *
21279  * @param [in]  pubKey       public key buffer
21280  * @param [in]  pubKeyLen    public ket buffer length
21281  * @param [out] output       Buffer to put encoded data in (optional)
21282  * @param [in]  outLen       Size of buffer in bytes
21283  * @param [in]  keyType      is "enum Key_Sum" like ED25519k
21284  * @param [in]  withHeader   Whether to include SubjectPublicKeyInfo around key.
21285  * @return  Size of encoded data in bytes on success
21286  * @return  BAD_FUNC_ARG when key is NULL.
21287  * @return  MEMORY_E when dynamic memory allocation failed.
21288  */
21289 static int SetAsymKeyDerPublic(const byte* pubKey, word32 pubKeyLen,
21290     byte* output, word32 outLen, int keyType, int withHeader)
21291 {
21292     int ret = 0;
21293 #ifndef WOLFSSL_ASN_TEMPLATE
21294     word32 idx = 0;
21295     word32 seqDataSz = 0;
21296     word32 sz;
21297 #else
21298     int sz = 0;
21299     DECL_ASNSETDATA(dataASN, edPubKeyASN_Length);
21300 #endif
21301 
21302     if (pubKey == NULL) {
21303         return BAD_FUNC_ARG;
21304     }
21305 
21306 #ifndef WOLFSSL_ASN_TEMPLATE
21307     /* calculate size */
21308     if (withHeader) {
21309         word32 algoSz      = SetAlgoID(keyType, NULL, oidKeyType, 0);
21310         word32 bitStringSz = SetBitString(pubKeyLen, 0, NULL);
21311 
21312         seqDataSz = algoSz + bitStringSz + pubKeyLen;
21313         sz = SetSequence(seqDataSz, NULL) + seqDataSz;
21314     }
21315     else {
21316         sz = pubKeyLen;
21317     }
21318 
21319     /* checkout output size */
21320     if (output != NULL && sz > outLen) {
21321         ret = BUFFER_E;
21322     }
21323 
21324     /* headers */
21325     if (ret == 0 && output != NULL && withHeader) {
21326         /* sequence */
21327         idx = SetSequence(seqDataSz, output);
21328         /* algo */
21329         idx += SetAlgoID(keyType, output + idx, oidKeyType, 0);
21330         /* bit string */
21331         idx += SetBitString(pubKeyLen, 0, output + idx);
21332     }
21333 
21334     if (ret == 0 && output != NULL) {
21335         /* pub */
21336         XMEMCPY(output + idx, pubKey, pubKeyLen);
21337         idx += pubKeyLen;
21338 
21339         sz = idx;
21340     }
21341 
21342     if (ret == 0) {
21343         ret = sz;
21344     }
21345 #else
21346     if (withHeader) {
21347         CALLOC_ASNSETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
21348 
21349         if (ret == 0) {
21350             /* Set the OID. */
21351             SetASN_OID(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], keyType,
21352                     oidKeyType);
21353             /* Leave space for public point. */
21354             SetASN_Buffer(&dataASN[EDPUBKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
21355             /* Calculate size of public key encoding. */
21356             ret = SizeASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, &sz);
21357         }
21358         if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
21359             ret = BUFFER_E;
21360         }
21361         if ((ret == 0) && (output != NULL)) {
21362             /* Encode public key. */
21363             SetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, output);
21364             /* Set location to encode public point. */
21365             output = (byte*)dataASN[EDPUBKEYASN_IDX_PUBKEY].data.buffer.data;
21366         }
21367 
21368         FREE_ASNSETDATA(dataASN, NULL);
21369     }
21370     else if ((output != NULL) && (pubKeyLen > outLen)) {
21371         ret = BUFFER_E;
21372     }
21373     else if (ret == 0) {
21374         sz = pubKeyLen;
21375     }
21376 
21377     if ((ret == 0) && (output != NULL)) {
21378         /* Put public key into space provided. */
21379         XMEMCPY(output, pubKey, pubKeyLen);
21380     }
21381     if (ret == 0) {
21382         ret = sz;
21383     }
21384 #endif /* WOLFSSL_ASN_TEMPLATE */
21385     return ret;
21386 }
21387 #endif /* WC_ENABLE_ASYM_KEY_EXPORT */
21388 
21389 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
21390 /* Encode the public part of an Ed25519 key in DER.
21391  *
21392  * Pass NULL for output to get the size of the encoding.
21393  *
21394  * @param [in]  key       Ed25519 key object.
21395  * @param [out] output    Buffer to put encoded data in.
21396  * @param [in]  outLen    Size of buffer in bytes.
21397  * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
21398  * @return  Size of encoded data in bytes on success.
21399  * @return  BAD_FUNC_ARG when key is NULL.
21400  * @return  MEMORY_E when dynamic memory allocation failed.
21401  */
21402 int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
21403                              int withAlg)
21404 {
21405     int    ret;
21406     byte   pubKey[ED25519_PUB_KEY_SIZE];
21407     word32 pubKeyLen = (word32)sizeof(pubKey);
21408 
21409     if (key == NULL) {
21410         return BAD_FUNC_ARG;
21411     }
21412 
21413     ret = wc_ed25519_export_public(key, pubKey, &pubKeyLen);
21414     if (ret == 0) {
21415         ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
21416             ED25519k, withAlg);
21417     }
21418     return ret;
21419 }
21420 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
21421 
21422 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
21423 /* Encode the public part of an Ed448 key in DER.
21424  *
21425  * Pass NULL for output to get the size of the encoding.
21426  *
21427  * @param [in]  key       Ed448 key object.
21428  * @param [out] output    Buffer to put encoded data in.
21429  * @param [in]  outLen    Size of buffer in bytes.
21430  * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
21431  * @return  Size of encoded data in bytes on success.
21432  * @return  BAD_FUNC_ARG when key is NULL.
21433  * @return  MEMORY_E when dynamic memory allocation failed.
21434  */
21435 int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
21436                            int withAlg)
21437 {
21438     int    ret;
21439     byte   pubKey[ED448_PUB_KEY_SIZE];
21440     word32 pubKeyLen = (word32)sizeof(pubKey);
21441 
21442     if (key == NULL) {
21443         return BAD_FUNC_ARG;
21444     }
21445 
21446     ret = wc_ed448_export_public(key, pubKey, &pubKeyLen);
21447     if (ret == 0) {
21448         ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
21449             ED448k, withAlg);
21450     }
21451     return ret;
21452 }
21453 #endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
21454 
21455 #if defined(HAVE_PQC)
21456 /* Encode the public part of an Falcon key in DER.
21457  *
21458  * Pass NULL for output to get the size of the encoding.
21459  *
21460  * @param [in]  key       Falcon key object.
21461  * @param [out] output    Buffer to put encoded data in.
21462  * @param [in]  outLen    Size of buffer in bytes.
21463  * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
21464  * @return  Size of encoded data in bytes on success.
21465  * @return  BAD_FUNC_ARG when key is NULL.
21466  * @return  MEMORY_E when dynamic memory allocation failed.
21467  */
21468 int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output, word32 inLen,
21469                              int withAlg)
21470 {
21471     int    ret;
21472     byte   pubKey[FALCON_MAX_PUB_KEY_SIZE];
21473     word32 pubKeyLen = (word32)sizeof(pubKey);
21474     int    keytype = 0;
21475 
21476     if (key == NULL || output == NULL) {
21477         return BAD_FUNC_ARG;
21478     }
21479 
21480     if (key->level == 1) {
21481         keytype = FALCON_LEVEL1k;
21482     }
21483     else if (key->level == 5) {
21484         keytype = FALCON_LEVEL5k;
21485     }
21486     else {
21487         return BAD_FUNC_ARG;
21488     }
21489 
21490     ret = wc_falcon_export_public(key, pubKey, &pubKeyLen);
21491     if (ret == 0) {
21492         ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen, keytype,
21493                                   withAlg);
21494     }
21495 
21496     return ret;
21497 }
21498 #endif /* HAVE_PQC */
21499 
21500 #ifdef WOLFSSL_CERT_GEN
21501 
21502 #ifndef NO_ASN_TIME
21503 static WC_INLINE byte itob(int number)
21504 {
21505     return (byte)number + 0x30;
21506 }
21507 
21508 
21509 /* write time to output, format */
21510 static void SetTime(struct tm* date, byte* output)
21511 {
21512     int i = 0;
21513 
21514     output[i++] = itob((date->tm_year % 10000) / 1000);
21515     output[i++] = itob((date->tm_year % 1000)  /  100);
21516     output[i++] = itob((date->tm_year % 100)   /   10);
21517     output[i++] = itob( date->tm_year % 10);
21518 
21519     output[i++] = itob(date->tm_mon / 10);
21520     output[i++] = itob(date->tm_mon % 10);
21521 
21522     output[i++] = itob(date->tm_mday / 10);
21523     output[i++] = itob(date->tm_mday % 10);
21524 
21525     output[i++] = itob(date->tm_hour / 10);
21526     output[i++] = itob(date->tm_hour % 10);
21527 
21528     output[i++] = itob(date->tm_min / 10);
21529     output[i++] = itob(date->tm_min % 10);
21530 
21531     output[i++] = itob(date->tm_sec / 10);
21532     output[i++] = itob(date->tm_sec % 10);
21533 
21534     output[i] = 'Z';  /* Zulu profile */
21535 }
21536 #endif
21537 
21538 #ifdef WOLFSSL_ALT_NAMES
21539 #ifndef WOLFSSL_ASN_TEMPLATE
21540 
21541 /* Copy Dates from cert, return bytes written */
21542 static int CopyValidity(byte* output, Cert* cert)
21543 {
21544     int seqSz;
21545 
21546     WOLFSSL_ENTER("CopyValidity");
21547 
21548     /* headers and output */
21549     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
21550     if (output) {
21551         XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
21552         XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
21553                                                      cert->afterDateSz);
21554     }
21555     return seqSz + cert->beforeDateSz + cert->afterDateSz;
21556 }
21557 
21558 #endif /* !WOLFSSL_ASN_TEMPLATE */
21559 #endif
21560 
21561 
21562 /* Simple name OID size. */
21563 #define NAME_OID_SZ     3
21564 
21565 /* Domain name OIDs. */
21566 static const byte nameOid[][NAME_OID_SZ] = {
21567     { 0x55, 0x04, ASN_COUNTRY_NAME },
21568     { 0x55, 0x04, ASN_STATE_NAME },
21569     { 0x55, 0x04, ASN_STREET_ADDR },
21570     { 0x55, 0x04, ASN_LOCALITY_NAME },
21571     { 0x55, 0x04, ASN_SUR_NAME },
21572     { 0x55, 0x04, ASN_ORG_NAME },
21573     { 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */
21574                                          /* list all DC values before OUs */
21575     { 0x55, 0x04, ASN_ORGUNIT_NAME },
21576     { 0x55, 0x04, ASN_COMMON_NAME },
21577     { 0x55, 0x04, ASN_SERIAL_NUMBER },
21578 #ifdef WOLFSSL_CERT_EXT
21579     { 0x55, 0x04, ASN_BUS_CAT },
21580 #endif
21581     { 0x55, 0x04, ASN_POSTAL_CODE },
21582     { 0x00, 0x00, ASN_EMAIL_NAME},       /* not actual OID - see attrEmailOid */
21583     { 0x00, 0x00, ASN_USER_ID},          /* not actual OID - see uidOid */
21584 #ifdef WOLFSSL_CUSTOM_OID
21585     { 0x00, 0x00, ASN_CUSTOM_NAME} /* OID comes from CertOidField */
21586 #endif
21587 };
21588 #define NAME_ENTRIES (int)(sizeof(nameOid)/NAME_OID_SZ)
21589 
21590 
21591 /* Get ASN Name from index */
21592 byte GetCertNameId(int idx)
21593 {
21594     if (idx < NAME_ENTRIES)
21595         return nameOid[idx][2];
21596     return 0;
21597 }
21598 
21599 /* Get Which Name from index */
21600 const char* GetOneCertName(CertName* name, int idx)
21601 {
21602     byte type = GetCertNameId(idx);
21603     switch (type) {
21604     case ASN_COUNTRY_NAME:
21605        return name->country;
21606     case ASN_STATE_NAME:
21607        return name->state;
21608     case ASN_STREET_ADDR:
21609        return name->street;
21610     case ASN_LOCALITY_NAME:
21611        return name->locality;
21612     case ASN_SUR_NAME:
21613        return name->sur;
21614     case ASN_ORG_NAME:
21615        return name->org;
21616     case ASN_ORGUNIT_NAME:
21617        return name->unit;
21618     case ASN_COMMON_NAME:
21619        return name->commonName;
21620     case ASN_SERIAL_NUMBER:
21621        return name->serialDev;
21622     case ASN_POSTAL_CODE:
21623        return name->postalCode;
21624     case ASN_EMAIL_NAME:
21625        return name->email;
21626 #ifdef WOLFSSL_CERT_EXT
21627     case ASN_BUS_CAT:
21628        return name->busCat;
21629 #endif
21630 #ifdef WOLFSSL_CUSTOM_OID
21631     case ASN_CUSTOM_NAME:
21632         return (const char*)name->custom.val;
21633 #endif
21634     default:
21635        return NULL;
21636     }
21637 }
21638 
21639 
21640 /* Get Which Name Encoding from index */
21641 static char GetNameType(CertName* name, int idx)
21642 {
21643     byte type = GetCertNameId(idx);
21644     switch (type) {
21645     case ASN_COUNTRY_NAME:
21646        return name->countryEnc;
21647     case ASN_STATE_NAME:
21648        return name->stateEnc;
21649     case ASN_STREET_ADDR:
21650        return name->streetEnc;
21651     case ASN_LOCALITY_NAME:
21652        return name->localityEnc;
21653     case ASN_SUR_NAME:
21654        return name->surEnc;
21655     case ASN_ORG_NAME:
21656        return name->orgEnc;
21657     case ASN_ORGUNIT_NAME:
21658        return name->unitEnc;
21659     case ASN_COMMON_NAME:
21660        return name->commonNameEnc;
21661     case ASN_SERIAL_NUMBER:
21662        return name->serialDevEnc;
21663     case ASN_POSTAL_CODE:
21664        return name->postalCodeEnc;
21665     case ASN_EMAIL_NAME:
21666        return 0; /* special */
21667 #ifdef WOLFSSL_CERT_EXT
21668     case ASN_BUS_CAT:
21669        return name->busCatEnc;
21670 #endif
21671 #ifdef WOLFSSL_CUSTOM_OID
21672     case ASN_CUSTOM_NAME:
21673         return name->custom.enc;
21674 #endif
21675     default:
21676        return 0;
21677     }
21678 }
21679 
21680 #ifndef WOLFSSL_ASN_TEMPLATE
21681 /*
21682  Extensions ::= SEQUENCE OF Extension
21683 
21684  Extension ::= SEQUENCE {
21685  extnId     OBJECT IDENTIFIER,
21686  critical   BOOLEAN DEFAULT FALSE,
21687  extnValue  OCTET STRING }
21688  */
21689 
21690 /* encode all extensions, return total bytes written */
21691 static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
21692                          const byte* ext, int extSz)
21693 {
21694     if (out == NULL || IdxInOut == NULL || ext == NULL)
21695         return BAD_FUNC_ARG;
21696 
21697     if (outSz < (word32)(*IdxInOut+extSz))
21698         return BUFFER_E;
21699 
21700     XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
21701     *IdxInOut += extSz;
21702 
21703     return *IdxInOut;
21704 }
21705 
21706 /* encode extensions header, return total bytes written */
21707 static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
21708 {
21709     byte sequence[MAX_SEQ_SZ];
21710     byte len[MAX_LENGTH_SZ];
21711     int seqSz, lenSz, idx = 0;
21712 
21713     if (out == NULL)
21714         return BAD_FUNC_ARG;
21715 
21716     if (outSz < 3)
21717         return BUFFER_E;
21718 
21719     seqSz = SetSequence(extSz, sequence);
21720 
21721     /* encode extensions length provided */
21722     lenSz = SetLength(extSz+seqSz, len);
21723 
21724     if (outSz < (word32)(lenSz+seqSz+1))
21725         return BUFFER_E;
21726 
21727     out[idx++] = ASN_EXTENSIONS; /* extensions id */
21728     XMEMCPY(&out[idx], len, lenSz);  /* length */
21729     idx += lenSz;
21730 
21731     XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
21732     idx += seqSz;
21733 
21734     return idx;
21735 }
21736 
21737 
21738 /* encode CA basic constraint true, return total bytes written */
21739 static int SetCa(byte* out, word32 outSz)
21740 {
21741     const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
21742                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
21743 
21744     if (out == NULL)
21745         return BAD_FUNC_ARG;
21746 
21747     if (outSz < sizeof(ca))
21748         return BUFFER_E;
21749 
21750     XMEMCPY(out, ca, sizeof(ca));
21751 
21752     return (int)sizeof(ca);
21753 }
21754 #endif
21755 
21756 
21757 #ifdef WOLFSSL_CERT_EXT
21758 #ifndef WOLFSSL_ASN_TEMPLATE
21759 /* encode OID and associated value, return total bytes written */
21760 static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
21761                        byte *in, word32 inSz)
21762 {
21763     int idx = 0;
21764 
21765     if (out == NULL || oid == NULL || in == NULL)
21766         return BAD_FUNC_ARG;
21767 
21768     if (outSz < 3)
21769         return BUFFER_E;
21770 
21771     /* sequence,  + 1 => byte to put value size */
21772     idx = SetSequence(inSz + oidSz + 1, out);
21773 
21774     if ((idx + inSz + oidSz + 1) > outSz)
21775         return BUFFER_E;
21776 
21777     XMEMCPY(out+idx, oid, oidSz);
21778     idx += oidSz;
21779     out[idx++] = (byte)inSz;
21780     XMEMCPY(out+idx, in, inSz);
21781 
21782     return (idx+inSz);
21783 }
21784 
21785 /* encode Subject Key Identifier, return total bytes written
21786  * RFC5280 : non-critical */
21787 static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
21788 {
21789     byte skid_len[1 + MAX_LENGTH_SZ];
21790     byte skid_enc_len[MAX_LENGTH_SZ];
21791     int idx = 0, skid_lenSz, skid_enc_lenSz;
21792     const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
21793 
21794     if (output == NULL || input == NULL)
21795         return BAD_FUNC_ARG;
21796 
21797     /* Octet String header */
21798     skid_lenSz = SetOctetString(length, skid_len);
21799 
21800     /* length of encoded value */
21801     skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
21802 
21803     if (outSz < 3)
21804         return BUFFER_E;
21805 
21806     idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
21807                       output);
21808 
21809     if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
21810         return BUFFER_E;
21811 
21812     /* put oid */
21813     XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
21814     idx += sizeof(skid_oid);
21815 
21816     /* put encoded len */
21817     XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
21818     idx += skid_enc_lenSz;
21819 
21820     /* put octet header */
21821     XMEMCPY(output+idx, skid_len, skid_lenSz);
21822     idx += skid_lenSz;
21823 
21824     /* put value */
21825     XMEMCPY(output+idx, input, length);
21826     idx += length;
21827 
21828     return idx;
21829 }
21830 
21831 /* encode Authority Key Identifier, return total bytes written
21832  * RFC5280 : non-critical */
21833 static int SetAKID(byte* output, word32 outSz, byte *input, word32 length,
21834                    byte rawAkid)
21835 {
21836     int     enc_valSz, inSeqSz;
21837     byte enc_val_buf[MAX_KID_SZ];
21838     byte* enc_val;
21839     const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23 };
21840     const byte akid_cs[] = { 0x80 };
21841     word32 idx;
21842 
21843     (void)rawAkid;
21844 
21845     if (output == NULL || input == NULL)
21846         return BAD_FUNC_ARG;
21847 
21848 #ifdef WOLFSSL_AKID_NAME
21849     if (rawAkid) {
21850         enc_val = input;
21851         enc_valSz = length;
21852     }
21853     else
21854 #endif
21855     {
21856         enc_val = enc_val_buf;
21857         enc_valSz = length + 3 + sizeof(akid_cs);
21858         if (enc_valSz > (int)sizeof(enc_val_buf))
21859             return BAD_FUNC_ARG;
21860 
21861         /* sequence for ContentSpec & value */
21862         enc_valSz = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
21863                           input, length);
21864         if (enc_valSz <= 0)
21865             return enc_valSz;
21866     }
21867 
21868     /* The size of the extension sequence contents */
21869     inSeqSz = sizeof(akid_oid) + SetOctetString(enc_valSz, NULL) +
21870             enc_valSz;
21871 
21872     if (SetSequence(inSeqSz, NULL) + inSeqSz > outSz)
21873         return BAD_FUNC_ARG;
21874 
21875     /* Write out the sequence header */
21876     idx = SetSequence(inSeqSz, output);
21877 
21878     /* Write out OID */
21879     XMEMCPY(output + idx, akid_oid, sizeof(akid_oid));
21880     idx += sizeof(akid_oid);
21881 
21882     /* Write out AKID */
21883     idx += SetOctetString(enc_valSz, output + idx);
21884     XMEMCPY(output + idx, enc_val, enc_valSz);
21885 
21886     return idx + enc_valSz;
21887 }
21888 
21889 /* encode Key Usage, return total bytes written
21890  * RFC5280 : critical */
21891 static int SetKeyUsage(byte* output, word32 outSz, word16 input)
21892 {
21893     byte ku[5];
21894     int  idx;
21895     const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
21896                                          0x01, 0x01, 0xff, 0x04};
21897     if (output == NULL)
21898         return BAD_FUNC_ARG;
21899 
21900     idx = SetBitString16Bit(input, ku);
21901     return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
21902                        ku, idx);
21903 }
21904 
21905 static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
21906     const byte* oid, word32 oidSz)
21907 {
21908     /* verify room */
21909     if (*idx + 2 + oidSz >= outSz)
21910         return ASN_PARSE_E;
21911 
21912     *idx += SetObjectId(oidSz, &output[*idx]);
21913     XMEMCPY(&output[*idx], oid, oidSz);
21914     *idx += oidSz;
21915 
21916     return 0;
21917 }
21918 #endif
21919 
21920 #ifdef WOLFSSL_ASN_TEMPLATE
21921 /* ASN.1 template for extended key usage.
21922  * X.509: RFC 5280, 4.2.12 - Extended Key Usage
21923  * Dynamic creation of template for encoding.
21924  */
21925 static const ASNItem ekuASN[] = {
21926 /* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21927 /* OID */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
21928 };
21929 enum {
21930     EKUASN_IDX_SEQ = 0,
21931     EKUASN_IDX_OID,
21932 };
21933 
21934 /* OIDs corresponding to extended key usage. */
21935 struct {
21936     const byte* oid;
21937     word32 oidSz;
21938 } ekuOid[] = {
21939     { extExtKeyUsageServerAuthOid,   sizeof(extExtKeyUsageServerAuthOid) },
21940     { extExtKeyUsageClientAuthOid,   sizeof(extExtKeyUsageClientAuthOid) },
21941     { extExtKeyUsageCodeSigningOid,  sizeof(extExtKeyUsageCodeSigningOid) },
21942     { extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid) },
21943     { extExtKeyUsageTimestampOid,    sizeof(extExtKeyUsageTimestampOid) },
21944     { extExtKeyUsageOcspSignOid,     sizeof(extExtKeyUsageOcspSignOid) },
21945 };
21946 
21947 #define EKU_OID_LO      1
21948 #define EKU_OID_HI      6
21949 #endif /* WOLFSSL_ASN_TEMPLATE */
21950 
21951 /* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
21952 static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
21953 {
21954 #ifndef WOLFSSL_ASN_TEMPLATE
21955     int idx = 0, oidListSz = 0, totalSz, ret = 0;
21956     const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
21957 
21958     if (output == NULL)
21959         return BAD_FUNC_ARG;
21960 
21961     /* Skip to OID List */
21962     totalSz = 2 + sizeof(extkeyusage_oid) + 4;
21963     idx = totalSz;
21964 
21965     /* Build OID List */
21966     /* If any set, then just use it */
21967     if (input & EXTKEYUSE_ANY) {
21968         ret |= SetOjectIdValue(output, outSz, &idx,
21969             extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
21970     }
21971     else {
21972         if (input & EXTKEYUSE_SERVER_AUTH)
21973             ret |= SetOjectIdValue(output, outSz, &idx,
21974                 extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
21975         if (input & EXTKEYUSE_CLIENT_AUTH)
21976             ret |= SetOjectIdValue(output, outSz, &idx,
21977                 extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
21978         if (input & EXTKEYUSE_CODESIGN)
21979             ret |= SetOjectIdValue(output, outSz, &idx,
21980                 extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
21981         if (input & EXTKEYUSE_EMAILPROT)
21982             ret |= SetOjectIdValue(output, outSz, &idx,
21983                 extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
21984         if (input & EXTKEYUSE_TIMESTAMP)
21985             ret |= SetOjectIdValue(output, outSz, &idx,
21986                 extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
21987         if (input & EXTKEYUSE_OCSP_SIGN)
21988             ret |= SetOjectIdValue(output, outSz, &idx,
21989                 extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
21990     #ifdef WOLFSSL_EKU_OID
21991         /* iterate through OID values */
21992         if (input & EXTKEYUSE_USER) {
21993             int i, sz;
21994             for (i = 0; i < CTC_MAX_EKU_NB; i++) {
21995                 sz = cert->extKeyUsageOIDSz[i];
21996                 if (sz > 0) {
21997                     ret |= SetOjectIdValue(output, outSz, &idx,
21998                         cert->extKeyUsageOID[i], sz);
21999                 }
22000             }
22001         }
22002     #endif /* WOLFSSL_EKU_OID */
22003     }
22004     if (ret != 0)
22005         return ASN_PARSE_E;
22006 
22007     /* Calculate Sizes */
22008     oidListSz = idx - totalSz;
22009     totalSz = idx - 2; /* exclude first seq/len (2) */
22010 
22011     /* 1. Seq + Total Len (2) */
22012     idx = SetSequence(totalSz, output);
22013 
22014     /* 2. Object ID (2) */
22015     XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
22016     idx += sizeof(extkeyusage_oid);
22017 
22018     /* 3. Octet String (2) */
22019     idx += SetOctetString(totalSz - idx, &output[idx]);
22020 
22021     /* 4. Seq + OidListLen (2) */
22022     idx += SetSequence(oidListSz, &output[idx]);
22023 
22024     /* 5. Oid List (already set in-place above) */
22025     idx += oidListSz;
22026 
22027     (void)cert;
22028     return idx;
22029 #else
22030     /* TODO: consider calculating size of OBJECT_IDs, setting length into
22031      * SEQUENCE, encode SEQUENCE, encode OBJECT_IDs into buffer.  */
22032     ASNSetData* dataASN;
22033     ASNItem* extKuASN = NULL;
22034     int asnIdx = 1;
22035     int cnt = 1 + EKU_OID_HI;
22036     int i;
22037     int ret = 0;
22038     int sz;
22039 
22040 #ifdef WOLFSSL_EKU_OID
22041     cnt += CTC_MAX_EKU_NB;
22042 #endif
22043 
22044     /* Allocate memory for dynamic data items. */
22045     dataASN = (ASNSetData*)XMALLOC(cnt * sizeof(ASNSetData), cert->heap,
22046                                                        DYNAMIC_TYPE_TMP_BUFFER);
22047     if (dataASN == NULL) {
22048         ret = MEMORY_E;
22049     }
22050     if (ret == 0) {
22051         /* Allocate memory for dynamic ASN.1 template. */
22052         extKuASN = (ASNItem*)XMALLOC(cnt * sizeof(ASNItem), cert->heap,
22053                                                        DYNAMIC_TYPE_TMP_BUFFER);
22054         if (extKuASN == NULL) {
22055             ret = MEMORY_E;
22056         }
22057     }
22058 
22059     if (ret == 0) {
22060         /* Copy Sequence into dynamic ASN.1 template. */
22061         XMEMCPY(&extKuASN[EKUASN_IDX_SEQ], ekuASN, sizeof(ASNItem));
22062         /* Clear dynamic data. */
22063         XMEMSET(dataASN, 0, cnt * sizeof(ASNSetData));
22064 
22065         /* Build up the template and data. */
22066         /* If 'any' set, then just use it. */
22067         if ((input & EXTKEYUSE_ANY) == EXTKEYUSE_ANY) {
22068             /* Set template item. */
22069             XMEMCPY(&extKuASN[EKUASN_IDX_OID], &ekuASN[EKUASN_IDX_OID],
22070                     sizeof(ASNItem));
22071             /* Set data item. */
22072             SetASN_Buffer(&dataASN[asnIdx], extExtKeyUsageAnyOid,
22073                 sizeof(extExtKeyUsageAnyOid));
22074             asnIdx++;
22075         }
22076         else {
22077             /* Step through the flagged purposes. */
22078             for (i = EKU_OID_LO; i <= EKU_OID_HI; i++) {
22079                 if ((input & (1 << i)) != 0) {
22080                     /* Set template item. */
22081                     XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
22082                             sizeof(ASNItem));
22083                     /* Set data item. */
22084                     SetASN_Buffer(&dataASN[asnIdx], ekuOid[i - 1].oid,
22085                         ekuOid[i - 1].oidSz);
22086                     asnIdx++;
22087                 }
22088             }
22089         #ifdef WOLFSSL_EKU_OID
22090             if (input & EXTKEYUSE_USER) {
22091                 /* Iterate through OID values */
22092                 for (i = 0; i < CTC_MAX_EKU_NB; i++) {
22093                     int sz = cert->extKeyUsageOIDSz[i];
22094                     if (sz > 0) {
22095                         /* Set template item. */
22096                         XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
22097                                 sizeof(ASNItem));
22098                         /* Set data item. */
22099                         SetASN_Buffer(&dataASN[asnIdx], cert->extKeyUsageOID[i],
22100                             sz);
22101                         asnIdx++;
22102                     }
22103                 }
22104             }
22105         #endif /* WOLFSSL_EKU_OID */
22106             (void)cert;
22107         }
22108 
22109         /* Calculate size of encoding. */
22110         ret = SizeASN_Items(extKuASN, dataASN, asnIdx, &sz);
22111     }
22112     /* When buffer to write to, ensure it's big enough. */
22113     if ((ret == 0) && (output != NULL) && (sz > (int)outSz)) {
22114         ret = BUFFER_E;
22115     }
22116     if ((ret == 0) && (output != NULL)) {
22117         /* Encode extended key usage. */
22118         SetASN_Items(extKuASN, dataASN, asnIdx, output);
22119     }
22120     if (ret == 0) {
22121         /* Return the encoding size. */
22122         ret = sz;
22123     }
22124 
22125     /* Dispose of allocated data. */
22126     if (extKuASN != NULL) {
22127         XFREE(extKuASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
22128     }
22129     if (dataASN != NULL) {
22130         XFREE(dataASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
22131     }
22132 
22133     return ret;
22134 #endif
22135 }
22136 
22137 #ifndef IGNORE_NETSCAPE_CERT_TYPE
22138 #ifndef WOLFSSL_ASN_TEMPLATE
22139 static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input)
22140 {
22141     word32 idx;
22142     byte unusedBits = 0;
22143     byte nsCertType = input;
22144     word32 totalSz;
22145     word32 bitStrSz;
22146     const byte nscerttype_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
22147                                     0x86, 0xF8, 0x42, 0x01, 0x01 };
22148 
22149     if (cert == NULL || output == NULL ||
22150             input == 0)
22151         return BAD_FUNC_ARG;
22152 
22153     totalSz = sizeof(nscerttype_oid);
22154 
22155     /* Get amount of lsb zero's */
22156     for (;(input & 1) == 0; input >>= 1)
22157         unusedBits++;
22158 
22159     /* 1 byte of NS Cert Type extension */
22160     bitStrSz = SetBitString(1, unusedBits, NULL) + 1;
22161     totalSz += SetOctetString(bitStrSz, NULL) + bitStrSz;
22162 
22163     if (SetSequence(totalSz, NULL) + totalSz > outSz)
22164         return BAD_FUNC_ARG;
22165 
22166     /* 1. Seq + Total Len */
22167     idx = SetSequence(totalSz, output);
22168 
22169     /* 2. Object ID */
22170     XMEMCPY(&output[idx], nscerttype_oid, sizeof(nscerttype_oid));
22171     idx += sizeof(nscerttype_oid);
22172 
22173     /* 3. Octet String */
22174     idx += SetOctetString(bitStrSz, &output[idx]);
22175 
22176     /* 4. Bit String */
22177     idx += SetBitString(1, unusedBits, &output[idx]);
22178     output[idx++] = nsCertType;
22179 
22180     return idx;
22181 }
22182 #endif
22183 #endif
22184 
22185 #ifndef WOLFSSL_ASN_TEMPLATE
22186 static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input,
22187                       int inSz)
22188 {
22189     word32 idx;
22190     word32 totalSz;
22191     const byte crlinfo_oid[] = { 0x06, 0x03, 0x55, 0x1D, 0x1F };
22192 
22193     if (cert == NULL || output == NULL ||
22194             input == 0 || inSz <= 0)
22195         return BAD_FUNC_ARG;
22196 
22197     totalSz = sizeof(crlinfo_oid) + SetOctetString(inSz, NULL) + inSz;
22198 
22199     if (SetSequence(totalSz, NULL) + totalSz > outSz)
22200         return BAD_FUNC_ARG;
22201 
22202     /* 1. Seq + Total Len */
22203     idx = SetSequence(totalSz, output);
22204 
22205     /* 2. Object ID */
22206     XMEMCPY(&output[idx], crlinfo_oid, sizeof(crlinfo_oid));
22207     idx += sizeof(crlinfo_oid);
22208 
22209     /* 3. Octet String */
22210     idx += SetOctetString(inSz, &output[idx]);
22211 
22212     /* 4. CRL Info */
22213     XMEMCPY(&output[idx], input, inSz);
22214     idx += inSz;
22215 
22216     return idx;
22217 }
22218 #endif
22219 
22220 /* encode Certificate Policies, return total bytes written
22221  * each input value must be ITU-T X.690 formatted : a.b.c...
22222  * input must be an array of values with a NULL terminated for the latest
22223  * RFC5280 : non-critical */
22224 static int SetCertificatePolicies(byte *output,
22225                                   word32 outputSz,
22226                                   char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
22227                                   word16 nb_certpol,
22228                                   void* heap)
22229 {
22230 #ifndef WOLFSSL_ASN_TEMPLATE
22231     byte    oid[MAX_OID_SZ];
22232     byte    der_oid[MAX_CERTPOL_NB][MAX_OID_SZ];
22233     byte    out[MAX_CERTPOL_SZ];
22234     word32  oidSz;
22235     word32  outSz;
22236     word32  i = 0;
22237     word32  der_oidSz[MAX_CERTPOL_NB];
22238     int     ret;
22239 
22240     const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
22241     const byte oid_oid[] = { 0x06 };
22242 
22243     if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
22244         return BAD_FUNC_ARG;
22245 
22246     for (i = 0; i < nb_certpol; i++) {
22247         oidSz = sizeof(oid);
22248         XMEMSET(oid, 0, oidSz);
22249 
22250         ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
22251         if (ret != 0)
22252             return ret;
22253 
22254         /* compute sequence value for the oid */
22255         ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
22256                           sizeof(oid_oid), oid, oidSz);
22257         if (ret <= 0)
22258             return ret;
22259         else
22260             der_oidSz[i] = (word32)ret;
22261     }
22262 
22263     /* concatenate oid, keep two byte for sequence/size of the created value */
22264     for (i = 0, outSz = 2; i < nb_certpol; i++) {
22265         XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
22266         outSz += der_oidSz[i];
22267     }
22268 
22269     /* add sequence */
22270     ret = SetSequence(outSz-2, out);
22271     if (ret <= 0)
22272         return ret;
22273 
22274     /* add Policy OID to compute final value */
22275     return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
22276                       out, outSz);
22277 #else
22278     int    i;
22279     int    ret = 0;
22280     byte   oid[MAX_OID_SZ];
22281     word32 oidSz;
22282     word32 sz = 0;
22283     int    piSz;
22284 
22285     if ((input == NULL) || (nb_certpol > MAX_CERTPOL_NB)) {
22286         ret = BAD_FUNC_ARG;
22287     }
22288     /* Put in policyIdentifier but not policyQualifiers. */
22289     for (i = 0; (ret == 0) && (i < nb_certpol); i++) {
22290         ASNSetData dataASN[policyInfoASN_Length];
22291 
22292         oidSz = sizeof(oid);
22293         XMEMSET(oid, 0, oidSz);
22294         dataASN[POLICYINFOASN_IDX_QUALI].noOut = 1;
22295 
22296         ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
22297         if (ret == 0) {
22298             XMEMSET(dataASN, 0, sizeof(dataASN));
22299             SetASN_Buffer(&dataASN[POLICYINFOASN_IDX_ID], oid, oidSz);
22300             ret = SizeASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
22301                                 &piSz);
22302         }
22303         if ((ret == 0) && (output != NULL) && (sz + piSz > outputSz)) {
22304             ret = BUFFER_E;
22305         }
22306         if (ret == 0) {
22307             if (output != NULL) {
22308                 SetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
22309                     output);
22310                 output += piSz;
22311             }
22312             sz += piSz;
22313         }
22314     }
22315 
22316     if (ret == 0) {
22317         ret = sz;
22318     }
22319     return ret;
22320 #endif
22321 }
22322 #endif /* WOLFSSL_CERT_EXT */
22323 
22324 
22325 #ifdef WOLFSSL_ALT_NAMES
22326 
22327 #ifndef WOLFSSL_ASN_TEMPLATE
22328 /* encode Alternative Names, return total bytes written */
22329 static int SetAltNames(byte *output, word32 outSz,
22330         const byte *input, word32 length)
22331 {
22332     byte san_len[1 + MAX_LENGTH_SZ];
22333     int idx = 0, san_lenSz;
22334     const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
22335 
22336     if (output == NULL || input == NULL)
22337         return BAD_FUNC_ARG;
22338 
22339     if (outSz < length)
22340         return BUFFER_E;
22341 
22342     /* Octet String header */
22343     san_lenSz = SetOctetString(length, san_len);
22344 
22345     if (outSz < MAX_SEQ_SZ)
22346         return BUFFER_E;
22347 
22348     idx = SetSequence(length + sizeof(san_oid) + san_lenSz, output);
22349 
22350     if ((length + sizeof(san_oid) + san_lenSz) > outSz)
22351         return BUFFER_E;
22352 
22353     /* put oid */
22354     XMEMCPY(output+idx, san_oid, sizeof(san_oid));
22355     idx += sizeof(san_oid);
22356 
22357     /* put octet header */
22358     XMEMCPY(output+idx, san_len, san_lenSz);
22359     idx += san_lenSz;
22360 
22361     /* put value */
22362     XMEMCPY(output+idx, input, length);
22363     idx += length;
22364 
22365     return idx;
22366 }
22367 #endif /* WOLFSSL_ASN_TEMPLATE */
22368 
22369 
22370 #ifdef WOLFSSL_CERT_GEN
22371 
22372 int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
22373 {
22374     word32 idx;
22375     const DNS_entry* curName;
22376     word32 namesSz = 0;
22377 #ifdef WOLFSSL_ALT_NAMES_NO_REV
22378     word32 i;
22379 #endif
22380 
22381     if (output == NULL)
22382         return BAD_FUNC_ARG;
22383 
22384     if (names == NULL)
22385         return 0;
22386 
22387     curName = names;
22388     do {
22389         namesSz += curName->len + 2 +
22390             ((curName->len < ASN_LONG_LENGTH) ? 0
22391              : BytePrecision(curName->len));
22392         curName = curName->next;
22393     } while (curName != NULL);
22394 
22395     if (outputSz < MAX_SEQ_SZ + namesSz)
22396         return BUFFER_E;
22397 
22398     idx = SetSequence(namesSz, output);
22399 #ifdef WOLFSSL_ALT_NAMES_NO_REV
22400     namesSz += idx;
22401     i = namesSz;
22402 #endif
22403 
22404     curName = names;
22405     do {
22406 #ifdef WOLFSSL_ALT_NAMES_NO_REV
22407         word32 len = SetLength(curName->len, NULL);
22408         idx = i - curName->len - len - 1;
22409         i = idx;
22410 #endif
22411         output[idx] = ASN_CONTEXT_SPECIFIC | curName->type;
22412         if (curName->type == ASN_DIR_TYPE) {
22413             output[idx] |= ASN_CONSTRUCTED;
22414         }
22415         idx++;
22416         idx += SetLength(curName->len, output + idx);
22417         XMEMCPY(output + idx, curName->name, curName->len);
22418 #ifndef WOLFSSL_ALT_NAMES_NO_REV
22419         idx += curName->len;
22420 #endif
22421         curName = curName->next;
22422     } while (curName != NULL);
22423 
22424 #ifdef WOLFSSL_ALT_NAMES_NO_REV
22425     idx = namesSz;
22426 #endif
22427     return idx;
22428 }
22429 
22430 #endif /* WOLFSSL_CERT_GEN */
22431 
22432 #endif /* WOLFSSL_ALT_NAMES */
22433 
22434 /* Simple domain name OID size. */
22435 #define DN_OID_SZ     3
22436 
22437 /* Encodes one attribute of the name (issuer/subject)
22438  *
22439  * name     structure to hold result of encoding
22440  * nameStr  value to be encoded
22441  * nameTag  tag of encoding i.e CTC_UTF8
22442  * type     id of attribute i.e ASN_COMMON_NAME
22443  * emailTag tag of email i.e CTC_UTF8
22444  * returns length on success
22445  */
22446 static int EncodeName(EncodedName* name, const char* nameStr,
22447                     byte nameTag, byte type, byte emailTag, CertName* cname)
22448 {
22449 #if !defined(WOLFSSL_ASN_TEMPLATE)
22450     word32 idx = 0;
22451     /* bottom up */
22452     byte firstLen[1 + MAX_LENGTH_SZ];
22453     byte secondLen[MAX_LENGTH_SZ];
22454     byte sequence[MAX_SEQ_SZ];
22455     byte set[MAX_SET_SZ];
22456 
22457     int strLen;
22458     int thisLen;
22459     int firstSz, secondSz, seqSz, setSz;
22460 
22461     if (nameStr == NULL) {
22462         name->used = 0;
22463         return 0;
22464     }
22465 
22466     thisLen = strLen = (int)XSTRLEN(nameStr);
22467 #ifdef WOLFSSL_CUSTOM_OID
22468     if (type == ASN_CUSTOM_NAME) {
22469         if (cname == NULL || cname->custom.oidSz == 0) {
22470             name->used = 0;
22471             return 0;
22472         }
22473         thisLen = strLen = cname->custom.valSz;
22474     }
22475 #else
22476     (void)cname;
22477 #endif
22478 
22479     if (strLen == 0) { /* no user data for this item */
22480         name->used = 0;
22481         return 0;
22482     }
22483 
22484     /* Restrict country code size */
22485     if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) {
22486         WOLFSSL_MSG("Country code size error");
22487         return ASN_COUNTRY_SIZE_E;
22488     }
22489 
22490     secondSz = SetLength(strLen, secondLen);
22491     thisLen += secondSz;
22492     switch (type) {
22493         case ASN_EMAIL_NAME: /* email */
22494             thisLen += (int)sizeof(attrEmailOid);
22495             firstSz  = (int)sizeof(attrEmailOid);
22496             break;
22497         case ASN_DOMAIN_COMPONENT:
22498             thisLen += (int)sizeof(dcOid);
22499             firstSz  = (int)sizeof(dcOid);
22500             break;
22501     #ifdef WOLFSSL_CUSTOM_OID
22502         case ASN_CUSTOM_NAME:
22503             thisLen += cname->custom.oidSz;
22504             firstSz = cname->custom.oidSz;
22505             break;
22506     #endif
22507         default:
22508             thisLen += DN_OID_SZ;
22509             firstSz  = DN_OID_SZ;
22510     }
22511     thisLen++; /* id  type */
22512     firstSz  = SetObjectId(firstSz, firstLen);
22513     thisLen += firstSz;
22514 
22515     seqSz = SetSequence(thisLen, sequence);
22516     thisLen += seqSz;
22517     setSz = SetSet(thisLen, set);
22518     thisLen += setSz;
22519 
22520     if (thisLen > (int)sizeof(name->encoded)) {
22521         return BUFFER_E;
22522     }
22523 
22524     /* store it */
22525     idx = 0;
22526     /* set */
22527     XMEMCPY(name->encoded, set, setSz);
22528     idx += setSz;
22529     /* seq */
22530     XMEMCPY(name->encoded + idx, sequence, seqSz);
22531     idx += seqSz;
22532     /* asn object id */
22533     XMEMCPY(name->encoded + idx, firstLen, firstSz);
22534     idx += firstSz;
22535     switch (type) {
22536         case ASN_EMAIL_NAME:
22537             /* email joint id */
22538             XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid));
22539             idx += (int)sizeof(attrEmailOid);
22540             name->encoded[idx++] = emailTag;
22541             break;
22542         case ASN_DOMAIN_COMPONENT:
22543             XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1);
22544             idx += (int)sizeof(dcOid)-1;
22545             /* id type */
22546             name->encoded[idx++] = type;
22547             /* str type */
22548             name->encoded[idx++] = nameTag;
22549             break;
22550     #ifdef WOLFSSL_CUSTOM_OID
22551         case ASN_CUSTOM_NAME:
22552             XMEMCPY(name->encoded + idx, cname->custom.oid,
22553                     cname->custom.oidSz);
22554             idx += cname->custom.oidSz;
22555             /* str type */
22556             name->encoded[idx++] = nameTag;
22557             break;
22558     #endif
22559         default:
22560             name->encoded[idx++] = 0x55;
22561             name->encoded[idx++] = 0x04;
22562             /* id type */
22563             name->encoded[idx++] = type;
22564             /* str type */
22565             name->encoded[idx++] = nameTag;
22566     }
22567     /* second length */
22568     XMEMCPY(name->encoded + idx, secondLen, secondSz);
22569     idx += secondSz;
22570     /* str value */
22571     XMEMCPY(name->encoded + idx, nameStr, strLen);
22572     idx += strLen;
22573 
22574     name->type = type;
22575     name->totalLen = idx;
22576     name->used = 1;
22577 
22578     return idx;
22579 #else
22580     DECL_ASNSETDATA(dataASN, rdnASN_Length);
22581     ASNItem namesASN[rdnASN_Length];
22582     byte dnOid[DN_OID_SZ] = { 0x55, 0x04, 0x00 };
22583     int ret = 0;
22584     int sz;
22585     const byte* oid;
22586     int oidSz;
22587     word32 nameSz;
22588 
22589     /* Validate input parameters. */
22590     if ((name == NULL) || (nameStr == NULL)) {
22591         ret = BAD_FUNC_ARG;
22592     }
22593 
22594     CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL);
22595     if (ret == 0) {
22596         nameSz = (word32)XSTRLEN(nameStr);
22597         /* Copy the RDN encoding template. ASN.1 tag for the name string is set
22598          * based on type. */
22599         XMEMCPY(namesASN, rdnASN, sizeof(namesASN));
22600 
22601         /* Set OID and ASN.1 tag for name depending on type. */
22602         switch (type) {
22603             case ASN_EMAIL_NAME:
22604                 /* email OID different to standard types. */
22605                 oid = attrEmailOid;
22606                 oidSz = sizeof(attrEmailOid);
22607                 /* Use email specific type/tag. */
22608                 nameTag = emailTag;
22609                 break;
22610             case ASN_DOMAIN_COMPONENT:
22611                 /* Domain component OID different to standard types. */
22612                 oid = dcOid;
22613                 oidSz = sizeof(dcOid);
22614                 break;
22615         #ifdef WOLFSSL_CUSTOM_OID
22616             case ASN_CUSTOM_NAME:
22617                 nameSz = cname->custom.valSz;
22618                 oid = cname->custom.oid;
22619                 oidSz = cname->custom.oidSz;
22620                 break;
22621         #endif
22622             default:
22623                 /* Construct OID using type. */
22624                 dnOid[2] = type;
22625                 oid = dnOid;
22626                 oidSz = DN_OID_SZ;
22627                 break;
22628         }
22629 
22630         /* Set OID corresponding to the name type. */
22631         SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
22632         /* Set name string. */
22633         SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], (const byte *)nameStr, nameSz);
22634         /* Set the ASN.1 tag for the name string. */
22635         namesASN[RDNASN_IDX_ATTR_VAL].tag = nameTag;
22636 
22637         /* Calculate size of encoded name and indexes of components. */
22638         ret = SizeASN_Items(namesASN, dataASN, rdnASN_Length, &sz);
22639     }
22640     /* Check if name's buffer is big enough. */
22641     if ((ret == 0) && (sz > (int)sizeof(name->encoded))) {
22642         ret = BUFFER_E;
22643     }
22644     if (ret == 0) {
22645         /* Encode name into the buffer. */
22646         SetASN_Items(namesASN, dataASN, rdnASN_Length, name->encoded);
22647         /* Cache the type and size, and set that it is used. */
22648         name->type = type;
22649         name->totalLen = sz;
22650         name->used = 1;
22651 
22652         /* Return size of encoding. */
22653         ret = sz;
22654     }
22655     (void)cname;
22656 
22657     FREE_ASNSETDATA(dataASN, NULL);
22658     return ret;
22659 #endif /* WOLFSSL_ASN_TEMPLATE */
22660 }
22661 
22662 /* canonical encoding one attribute of the name (issuer/subject)
22663  * call EncodeName with CTC_UTF8 for email type
22664  *
22665  * name     structure to hold result of encoding
22666  * nameStr  value to be encoded
22667  * nameType type of encoding i.e CTC_UTF8
22668  * type     id of attribute i.e ASN_COMMON_NAME
22669  *
22670  * returns length on success
22671  */
22672 int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
22673                            char nameType, byte type)
22674 {
22675     return EncodeName(name, nameStr, (byte)nameType, type,
22676         ASN_UTF8STRING, NULL);
22677 }
22678 
22679 /* Encodes one attribute of the name (issuer/subject)
22680  * call we_EncodeName_ex with 0x16, IA5String for email type
22681  * name     structure to hold result of encoding
22682  * nameStr  value to be encoded
22683  * nameType type of encoding i.e CTC_UTF8
22684  * type     id of attribute i.e ASN_COMMON_NAME
22685  *
22686  * returns length on success
22687  */
22688 int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
22689                   byte type)
22690 {
22691     return EncodeName(name, nameStr, (byte)nameType, type,
22692         ASN_IA5_STRING, NULL);
22693 }
22694 
22695 #ifdef WOLFSSL_ASN_TEMPLATE
22696 static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid,
22697     int oidSz, byte tag, const byte* data, int sz)
22698 {
22699     XMEMCPY(namesASN, rdnASN, sizeof(rdnASN));
22700     SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
22701     namesASN[RDNASN_IDX_ATTR_VAL].tag = tag;
22702     SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], data, sz);
22703 }
22704 
22705 #ifdef WOLFSSL_MULTI_ATTRIB
22706 static int FindMultiAttrib(CertName* name, int id, int* idx)
22707 {
22708     int i;
22709     for (i = *idx + 1; i < CTC_MAX_ATTRIB; i++) {
22710         if (name->name[i].sz > 0 && name->name[i].id == id) {
22711             break;
22712         }
22713     }
22714     if (i == CTC_MAX_ATTRIB) {
22715         i = -1;
22716     }
22717     *idx = i;
22718     return i >= 0;
22719 }
22720 #endif
22721 
22722 /* ASN.1 template for the SEQUENCE around the RDNs.
22723  * X.509: RFC 5280, 4.1.2.4 - RDNSequence
22724  */
22725 static const ASNItem nameASN[] = {
22726     { 0, ASN_SEQUENCE, 1, 1, 0 },
22727 };
22728 enum {
22729     NAMEASN_IDX_SEQ = 0,
22730 };
22731 
22732 /* Number of items in ASN.1 template for the SEQUENCE around the RDNs. */
22733 #define nameASN_Length (sizeof(nameASN) / sizeof(ASNItem))
22734 
22735 static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN,
22736         int maxIdx, CertName* name)
22737 {
22738     int         i;
22739     int         idx;
22740     int         ret = 0;
22741     int         nameLen[NAME_ENTRIES];
22742 #ifdef WOLFSSL_MULTI_ATTRIB
22743     int         j;
22744 #endif
22745 
22746     for (i = 0; i < NAME_ENTRIES; i++) {
22747         /* Keep name length to identify component is to be encoded. */
22748         const char* nameStr = GetOneCertName(name, i);
22749         nameLen[i] = nameStr ? (int)XSTRLEN(nameStr) : 0;
22750     }
22751 
22752     idx = nameASN_Length;
22753     for (i = 0; i < NAME_ENTRIES; i++) {
22754         int type = GetCertNameId(i);
22755 
22756     #ifdef WOLFSSL_MULTI_ATTRIB
22757         j = -1;
22758         /* Put DomainComponents before OrgUnitName. */
22759         while (FindMultiAttrib(name, type, &j)) {
22760             if (dataASN != NULL && namesASN != NULL) {
22761                 if (idx > maxIdx - (int)rdnASN_Length) {
22762                     WOLFSSL_MSG("Wanted to write more ASN than allocated");
22763                     ret = BUFFER_E;
22764                     break;
22765                 }
22766                 /* Copy data into dynamic vars. */
22767                 SetRdnItems(namesASN + idx, dataASN + idx, dcOid,
22768                     sizeof(dcOid), name->name[j].type,
22769                     (byte*)name->name[j].value, name->name[j].sz);
22770             }
22771             idx += rdnASN_Length;
22772         }
22773         if (ret != 0)
22774             break;
22775     #endif
22776 
22777         if (nameLen[i] > 0) {
22778             if (dataASN != NULL) {
22779                 if (idx > maxIdx - (int)rdnASN_Length) {
22780                     WOLFSSL_MSG("Wanted to write more ASN than allocated");
22781                     ret = BUFFER_E;
22782                     break;
22783                 }
22784                 /* Write out first instance of attribute type. */
22785                 if (type == ASN_EMAIL_NAME) {
22786                     /* Copy email data into dynamic vars. */
22787                     SetRdnItems(namesASN + idx, dataASN + idx, attrEmailOid,
22788                         sizeof(attrEmailOid), ASN_IA5_STRING,
22789                         (const byte*)GetOneCertName(name, i), nameLen[i]);
22790                 }
22791                 else if (type == ASN_CUSTOM_NAME) {
22792                 #ifdef WOLFSSL_CUSTOM_OID
22793                     SetRdnItems(namesASN + idx, dataASN + idx, name->custom.oid,
22794                         name->custom.oidSz, name->custom.enc,
22795                         name->custom.val, name->custom.valSz);
22796                 #endif
22797                 }
22798                 else {
22799                     /* Copy name data into dynamic vars. */
22800                     SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
22801                         NAME_OID_SZ, GetNameType(name, i),
22802                         (const byte*)GetOneCertName(name, i), nameLen[i]);
22803                 }
22804             }
22805             idx += rdnASN_Length;
22806         }
22807 
22808     #ifdef WOLFSSL_MULTI_ATTRIB
22809         j = -1;
22810         /* Write all other attributes of this type. */
22811         while (FindMultiAttrib(name, type, &j)) {
22812             if (dataASN != NULL && namesASN != NULL) {
22813                 if (idx > maxIdx - (int)rdnASN_Length) {
22814                     WOLFSSL_MSG("Wanted to write more ASN than allocated");
22815                     ret = BUFFER_E;
22816                     break;
22817                 }
22818                 /* Copy data into dynamic vars. */
22819                 SetRdnItems(namesASN + idx, dataASN + idx, nameOid[type],
22820                     NAME_OID_SZ, name->name[j].type,
22821                     (byte*)name->name[j].value, name->name[j].sz);
22822             }
22823             idx += rdnASN_Length;
22824         }
22825         if (ret != 0)
22826             break;
22827     #endif
22828     }
22829     if (ret == 0)
22830         ret = idx;
22831     return ret;
22832 }
22833 #endif
22834 
22835 /* encode CertName into output, return total bytes written */
22836 int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
22837 {
22838 #ifndef WOLFSSL_ASN_TEMPLATE
22839     int ret;
22840     int totalBytes = 0, i, idx;
22841 #ifdef WOLFSSL_SMALL_STACK
22842     EncodedName* names = NULL;
22843 #else
22844     EncodedName  names[NAME_ENTRIES];
22845 #endif
22846 #ifdef WOLFSSL_MULTI_ATTRIB
22847     EncodedName addNames[CTC_MAX_ATTRIB];
22848     int j, type;
22849 #endif
22850 
22851     if (output == NULL || name == NULL)
22852         return BAD_FUNC_ARG;
22853 
22854     if (outputSz < 3)
22855         return BUFFER_E;
22856 
22857 #ifdef WOLFSSL_SMALL_STACK
22858     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
22859                                                        DYNAMIC_TYPE_TMP_BUFFER);
22860     if (names == NULL)
22861         return MEMORY_E;
22862 #endif
22863 
22864     for (i = 0; i < NAME_ENTRIES; i++) {
22865         const char* nameStr = GetOneCertName(name, i);
22866 
22867         ret = EncodeName(&names[i], nameStr, GetNameType(name, i),
22868                           GetCertNameId(i), ASN_IA5_STRING, name);
22869         if (ret < 0) {
22870         #ifdef WOLFSSL_SMALL_STACK
22871             XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22872         #endif
22873             WOLFSSL_MSG("EncodeName failed");
22874             return BUFFER_E;
22875         }
22876         totalBytes += ret;
22877     }
22878 #ifdef WOLFSSL_MULTI_ATTRIB
22879     for (i = 0; i < CTC_MAX_ATTRIB; i++) {
22880         if (name->name[i].sz > 0) {
22881             ret = EncodeName(&addNames[i], name->name[i].value,
22882                         (byte)name->name[i].type, name->name[i].id,
22883                         ASN_IA5_STRING, NULL);
22884             if (ret < 0) {
22885             #ifdef WOLFSSL_SMALL_STACK
22886                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22887             #endif
22888                 WOLFSSL_MSG("EncodeName on multiple attributes failed");
22889                 return BUFFER_E;
22890             }
22891             totalBytes += ret;
22892         }
22893         else {
22894             addNames[i].used = 0;
22895         }
22896     }
22897 #endif /* WOLFSSL_MULTI_ATTRIB */
22898 
22899     /* header */
22900     idx = SetSequence(totalBytes, output);
22901     totalBytes += idx;
22902     if (totalBytes > ASN_NAME_MAX) {
22903 #ifdef WOLFSSL_SMALL_STACK
22904         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22905 #endif
22906         WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
22907         return BUFFER_E;
22908     }
22909 
22910     for (i = 0; i < NAME_ENTRIES; i++) {
22911     #ifdef WOLFSSL_MULTI_ATTRIB
22912         type = GetCertNameId(i);
22913         for (j = 0; j < CTC_MAX_ATTRIB; j++) {
22914             if (name->name[j].sz > 0 && type == name->name[j].id) {
22915                 if (outputSz < (word32)(idx+addNames[j].totalLen)) {
22916                 #ifdef WOLFSSL_SMALL_STACK
22917                     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22918                 #endif
22919                     WOLFSSL_MSG("Not enough space left for DC value");
22920                     return BUFFER_E;
22921                 }
22922 
22923                 XMEMCPY(output + idx, addNames[j].encoded,
22924                         addNames[j].totalLen);
22925                 idx += addNames[j].totalLen;
22926             }
22927         }
22928     #endif /* WOLFSSL_MULTI_ATTRIB */
22929 
22930         if (names[i].used) {
22931             if (outputSz < (word32)(idx+names[i].totalLen)) {
22932 #ifdef WOLFSSL_SMALL_STACK
22933                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22934 #endif
22935                 return BUFFER_E;
22936             }
22937 
22938             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
22939             idx += names[i].totalLen;
22940         }
22941     }
22942 
22943 #ifdef WOLFSSL_SMALL_STACK
22944     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22945 #endif
22946     (void)heap;
22947 
22948     return totalBytes;
22949 #else
22950     /* TODO: consider calculating size of entries, putting length into
22951      * SEQUENCE, encode SEQUENCE, encode entries into buffer.  */
22952     ASNSetData* dataASN = NULL; /* Can't use DECL_ASNSETDATA. Always dynamic. */
22953     ASNItem*    namesASN = NULL;
22954     int         items = 0;
22955     int         ret = 0;
22956     int         sz;
22957 
22958     /* Calculate length of name entries and size for allocating. */
22959     ret = SetNameRdnItems(NULL, NULL, 0, name);
22960     if (ret > 0) {
22961         items = ret;
22962         ret = 0;
22963     }
22964 
22965     /* Allocate dynamic data items. */
22966     dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap,
22967                                    DYNAMIC_TYPE_TMP_BUFFER);
22968     if (dataASN == NULL) {
22969         ret = MEMORY_E;
22970     }
22971     else {
22972         /* Allocate dynamic ASN.1 template items. */
22973         namesASN = (ASNItem*)XMALLOC(items * sizeof(ASNItem), heap,
22974                                      DYNAMIC_TYPE_TMP_BUFFER);
22975         if (namesASN == NULL) {
22976             ret = MEMORY_E;
22977         }
22978     }
22979 
22980     if (ret == 0) {
22981         /* Clear the dynamic data. */
22982         XMEMSET(dataASN, 0, items * sizeof(ASNSetData));
22983         /* Copy in the outer sequence. */
22984         XMEMCPY(namesASN, nameASN, sizeof(nameASN));
22985 
22986         ret = SetNameRdnItems(dataASN, namesASN, items, name);
22987         if (ret == items)
22988             ret = 0;
22989         else if (ret > 0) {
22990             WOLFSSL_MSG("SetNameRdnItems returned different length");
22991             ret = BUFFER_E;
22992         }
22993     }
22994     if (ret == 0) {
22995         /* Calculate size of encoding. */
22996         ret = SizeASN_Items(namesASN, dataASN, items, &sz);
22997     }
22998     /* Check buffer size if passed in. */
22999     if (ret == 0 && output != NULL && sz > (int)outputSz) {
23000         ret = BUFFER_E;
23001     }
23002     if (ret == 0) {
23003         if (output != NULL) {
23004             /* Encode Name. */
23005             ret = SetASN_Items(namesASN, dataASN, items, output);
23006         }
23007         else {
23008             /* Return the encoding size. */
23009             ret = sz;
23010         }
23011     }
23012 
23013     if (namesASN != NULL)
23014         XFREE(namesASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
23015     if (dataASN != NULL)
23016         XFREE(dataASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
23017     (void)heap;
23018     return ret;
23019 #endif
23020 }
23021 int SetName(byte* output, word32 outputSz, CertName* name)
23022 {
23023     return SetNameEx(output, outputSz, name, NULL);
23024 }
23025 
23026 #ifdef WOLFSSL_ASN_TEMPLATE
23027 static int EncodePublicKey(int keyType, byte* output, int outLen,
23028                            RsaKey* rsaKey, ecc_key* eccKey,
23029                            ed25519_key* ed25519Key, ed448_key* ed448Key,
23030                            DsaKey* dsaKey)
23031 {
23032     int ret = 0;
23033 
23034     (void)outLen;
23035     (void)rsaKey;
23036     (void)eccKey;
23037     (void)ed25519Key;
23038     (void)ed448Key;
23039     (void)dsaKey;
23040 
23041     switch (keyType) {
23042     #ifndef NO_RSA
23043         case RSA_KEY:
23044             ret = SetRsaPublicKey(output, rsaKey, outLen, 1);
23045             if (ret <= 0) {
23046                 ret = PUBLIC_KEY_E;
23047             }
23048             break;
23049     #endif
23050     #ifdef HAVE_ECC
23051         case ECC_KEY:
23052             ret = SetEccPublicKey(output, eccKey, outLen, 1);
23053             if (ret <= 0) {
23054                 ret = PUBLIC_KEY_E;
23055             }
23056             break;
23057     #endif /* HAVE_ECC */
23058     #ifdef HAVE_ED25519
23059         case ED25519_KEY:
23060             ret = wc_Ed25519PublicKeyToDer(ed25519Key, output, outLen, 1);
23061             if (ret <= 0) {
23062                 ret = PUBLIC_KEY_E;
23063             }
23064             break;
23065     #endif
23066     #ifdef HAVE_ED448
23067         case ED448_KEY:
23068             ret = wc_Ed448PublicKeyToDer(ed448Key, output, outLen, 1);
23069             if (ret <= 0) {
23070                 ret = PUBLIC_KEY_E;
23071             }
23072             break;
23073     #endif
23074         default:
23075             ret = PUBLIC_KEY_E;
23076             break;
23077     }
23078 
23079     return ret;
23080 }
23081 
23082 /* ASN.1 template for certificate extensions.
23083  * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
23084  * All extensions supported for encoding are described.
23085  */
23086 static const ASNItem certExtsASN[] = {
23087             /* Basic Constraints Extension - 4.2.1.9 */
23088 /* BC_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23089 /* BC_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23090 /* BC_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23091 /* BC_STR_SEQ    */            { 2, ASN_SEQUENCE, 1, 1, 0 },
23092                                                    /* cA */
23093 /* BC_CA         */                { 3, ASN_BOOLEAN, 0, 0, 0 },
23094                                                    /* pathLenConstraint */
23095 /* BC_PATHLEN    */                { 3, ASN_INTEGER, 0, 0, 1 },
23096                                        /* Subject Alternative Name - 4.2.1.6  */
23097 /* SAN_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23098 /* SAN_OID       */       { 1, ASN_OBJECT_ID, 0, 0, 0 },
23099 /* SAN_STR       */       { 1, ASN_OCTET_STRING, 0, 0, 0 },
23100 #ifdef WOLFSSL_CERT_EXT
23101             /* Subject Key Identifier - 4.2.1.2 */
23102 /* SKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23103 /* SKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23104 /* SKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23105 /* SKID_KEYID    */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
23106                                        /* Authority Key Identifier - 4.2.1.1 */
23107 /* AKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23108 /* AKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23109 /* AKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23110 /* AKID_STR_SEQ, */            { 2, ASN_SEQUENCE, 1, 1, 0 },
23111 /* AKID_KEYID    */                { 3, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
23112                                        /* Key Usage - 4.2.1.3 */
23113 /* KU_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23114 /* KU_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23115 /* KU_CRIT       */        { 1, ASN_BOOLEAN, 0, 0, 0 },
23116 /* KU_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23117 /* KU_USAGE      */            { 2, ASN_BIT_STRING, 0, 0, 0 },
23118                                        /* Extended Key Usage - 4,2,1,12 */
23119 /* EKU_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23120 /* EKU_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23121 /* EKU_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
23122                                        /* Certificate Policies - 4.2.1.4 */
23123 /* POLICIES_SEQ, */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23124 /* POLICIES_OID, */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23125 /* POLICIES_STR, */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23126 /* POLICIES_INFO */            { 2, ASN_SEQUENCE, 0, 0, 0 },
23127                                        /* Netscape Certificate Type */
23128 /* NSTYPE_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23129 /* NSTYPE_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23130 /* NSTYPE_STR    */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
23131 /* NSTYPE_USAGE, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
23132 /* CRLINFO_SEQ   */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23133 /* CRLINFO_OID   */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23134 /* CRLINFO_STR   */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
23135 #endif /* WOLFSSL_CERT_EXT */
23136 #ifdef WOLFSSL_CUSTOM_OID
23137 /* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23138 /* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
23139 /* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
23140 #endif
23141 };
23142 enum {
23143     CERTEXTSASN_IDX_BC_SEQ = 0,
23144     CERTEXTSASN_IDX_BC_OID,
23145     CERTEXTSASN_IDX_BC_STR,
23146     CERTEXTSASN_IDX_BC_STR_SEQ,
23147     CERTEXTSASN_IDX_BC_CA,
23148     CERTEXTSASN_IDX_BC_PATHLEN,
23149     CERTEXTSASN_IDX_SAN_SEQ,
23150     CERTEXTSASN_IDX_SAN_OID,
23151     CERTEXTSASN_IDX_SAN_STR,
23152     CERTEXTSASN_IDX_SKID_SEQ,
23153     CERTEXTSASN_IDX_SKID_OID,
23154     CERTEXTSASN_IDX_SKID_STR,
23155     CERTEXTSASN_IDX_SKID_KEYID,
23156     CERTEXTSASN_IDX_AKID_SEQ,
23157     CERTEXTSASN_IDX_AKID_OID,
23158     CERTEXTSASN_IDX_AKID_STR,
23159     CERTEXTSASN_IDX_AKID_STR_SEQ,
23160     CERTEXTSASN_IDX_AKID_KEYID,
23161     CERTEXTSASN_IDX_KU_SEQ,
23162     CERTEXTSASN_IDX_KU_OID,
23163     CERTEXTSASN_IDX_KU_CRIT,
23164     CERTEXTSASN_IDX_KU_STR,
23165     CERTEXTSASN_IDX_KU_USAGE,
23166     CERTEXTSASN_IDX_EKU_SEQ,
23167     CERTEXTSASN_IDX_EKU_OID,
23168     CERTEXTSASN_IDX_EKU_STR,
23169     CERTEXTSASN_IDX_POLICIES_SEQ,
23170     CERTEXTSASN_IDX_POLICIES_OID,
23171     CERTEXTSASN_IDX_POLICIES_STR,
23172     CERTEXTSASN_IDX_POLICIES_INFO,
23173     CERTEXTSASN_IDX_NSTYPE_SEQ,
23174     CERTEXTSASN_IDX_NSTYPE_OID,
23175     CERTEXTSASN_IDX_NSTYPE_STR,
23176     CERTEXTSASN_IDX_NSTYPE_USAGE,
23177     CERTEXTSASN_IDX_CRLINFO_SEQ,
23178     CERTEXTSASN_IDX_CRLINFO_OID,
23179     CERTEXTSASN_IDX_CRLINFO_STR,
23180     CERTEXTSASN_IDX_CUSTOM_SEQ,
23181     CERTEXTSASN_IDX_CUSTOM_OID,
23182     CERTEXTSASN_IDX_CUSTOM_STR,
23183 };
23184 
23185 /* Number of items in ASN.1 template for certificate extensions. */
23186 #define certExtsASN_Length (sizeof(certExtsASN) / sizeof(ASNItem))
23187 
23188 static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
23189                             int forRequest)
23190 {
23191     DECL_ASNSETDATA(dataASN, certExtsASN_Length);
23192     int sz;
23193     int ret = 0;
23194     static const byte bcOID[]   = { 0x55, 0x1d, 0x13 };
23195 #ifdef WOLFSSL_ALT_NAMES
23196     static const byte sanOID[]  = { 0x55, 0x1d, 0x11 };
23197 #endif
23198 #ifdef WOLFSSL_CERT_EXT
23199     static const byte skidOID[] = { 0x55, 0x1d, 0x0e };
23200     static const byte akidOID[] = { 0x55, 0x1d, 0x23 };
23201     static const byte kuOID[]   = { 0x55, 0x1d, 0x0f };
23202     static const byte ekuOID[]  = { 0x55, 0x1d, 0x25 };
23203     static const byte cpOID[]   = { 0x55, 0x1d, 0x20 };
23204     static const byte nsCertOID[] = { 0x60, 0x86, 0x48, 0x01,
23205                                       0x86, 0xF8, 0x42, 0x01, 0x01 };
23206     static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F };
23207 #endif
23208 
23209     (void)forRequest;
23210 
23211     CALLOC_ASNSETDATA(dataASN, certExtsASN_Length, ret, cert->heap);
23212 
23213     if (ret == 0) {
23214         if (cert->isCA) {
23215             /* Set Basic Constraints to be a Certificate Authority. */
23216             SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1);
23217             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
23218             /* TODO: consider adding path length field in Cert. */
23219             dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
23220         }
23221         else {
23222             /* Don't write out Basic Constraints extension items. */
23223             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
23224                     CERTEXTSASN_IDX_BC_PATHLEN);
23225         }
23226     #ifdef WOLFSSL_ALT_NAMES
23227         if (!forRequest && cert->altNamesSz > 0) {
23228             /* Set Subject Alternative Name OID and data. */
23229             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_OID],
23230                     sanOID, sizeof(sanOID));
23231             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_STR],
23232                     cert->altNames, cert->altNamesSz);
23233         }
23234         else
23235     #endif
23236         {
23237             /* Don't write out Subject Alternative Name extension items. */
23238             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SAN_SEQ,
23239                     CERTEXTSASN_IDX_SAN_STR);
23240         }
23241     #ifdef WOLFSSL_CERT_EXT
23242         if (cert->skidSz > 0) {
23243             /* Set Subject Key Identifier OID and data. */
23244             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_OID],
23245                     skidOID, sizeof(skidOID));
23246             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_KEYID],
23247                     cert->skid, cert->skidSz);
23248         }
23249         else {
23250             /* Don't write out Subject Key Identifier extension items. */
23251             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SKID_SEQ,
23252                     CERTEXTSASN_IDX_SKID_KEYID);
23253         }
23254         if (cert->akidSz > 0) {
23255             /* Set Authority Key Identifier OID and data. */
23256             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_OID],
23257                     akidOID, sizeof(akidOID));
23258         #ifdef WOLFSSL_AKID_NAME
23259             if (cert->rawAkid) {
23260                 SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_STR],
23261                         cert->akid, cert->akidSz);
23262                 /* cert->akid contains the internal ext structure */
23263                 SetASNItem_NoOutBelow(dataASN, certExtsASN,
23264                         CERTEXTSASN_IDX_AKID_STR, certExtsASN_Length);
23265             }
23266             else
23267         #endif
23268             {
23269                 SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_KEYID],
23270                         cert->akid, cert->akidSz);
23271             }
23272         }
23273         else {
23274             /* Don't write out Authority Key Identifier extension items. */
23275             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_AKID_SEQ,
23276                     CERTEXTSASN_IDX_AKID_KEYID);
23277         }
23278         if (cert->keyUsage != 0) {
23279             /* Set Key Usage OID, critical and value. */
23280             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_KU_OID],
23281                     kuOID, sizeof(kuOID));
23282             SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_KU_CRIT], 1);
23283             SetASN_Int16Bit(&dataASN[CERTEXTSASN_IDX_KU_USAGE],
23284                     cert->keyUsage);
23285         }
23286         else {
23287             /* Don't write out Key Usage extension items. */
23288             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_KU_SEQ,
23289                     CERTEXTSASN_IDX_KU_USAGE);
23290         }
23291         if (cert->extKeyUsage != 0) {
23292             /* Calculate size of Extended Key Usage data. */
23293             sz = SetExtKeyUsage(cert, NULL, 0, cert->extKeyUsage);
23294             if (sz <= 0) {
23295                 ret = KEYUSAGE_E;
23296             }
23297             /* Set Extended Key Usage OID and data. */
23298             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_OID],
23299                     ekuOID, sizeof(ekuOID));
23300             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_STR],
23301                     NULL, sz);
23302         }
23303         else {
23304             /* Don't write out Extended Key Usage extension items. */
23305             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_EKU_SEQ,
23306                     CERTEXTSASN_IDX_EKU_STR);
23307         }
23308 
23309         if ((!forRequest) && (cert->certPoliciesNb > 0)) {
23310             /* Calculate size of certificate policies. */
23311             sz = SetCertificatePolicies(NULL, 0, cert->certPolicies,
23312                     cert->certPoliciesNb, cert->heap);
23313             if (sz > 0) {
23314                 /* Set Certificate Policies OID. */
23315                 SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_OID],
23316                         cpOID, sizeof(cpOID));
23317                 /* Make space for data. */
23318                 SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_INFO],
23319                         NULL, sz);
23320             }
23321             else {
23322                 ret = CERTPOLICIES_E;
23323             }
23324         }
23325         else {
23326             /* Don't write out Certificate Policies extension items. */
23327             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_POLICIES_SEQ,
23328                     CERTEXTSASN_IDX_POLICIES_INFO);
23329         }
23330     #ifndef IGNORE_NETSCAPE_CERT_TYPE
23331         /* Netscape Certificate Type */
23332         if (cert->nsCertType != 0) {
23333             /* Set Netscape Certificate Type OID and data. */
23334             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_OID],
23335                     nsCertOID, sizeof(nsCertOID));
23336             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_USAGE],
23337                     &cert->nsCertType, 1);
23338         }
23339         else
23340     #endif
23341         {
23342             /* Don't write out Netscape Certificate Type. */
23343             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_NSTYPE_SEQ,
23344                     CERTEXTSASN_IDX_NSTYPE_USAGE);
23345         }
23346         if (cert->crlInfoSz > 0) {
23347             /* Set CRL Distribution Points OID and data. */
23348             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_OID],
23349                     crlInfoOID, sizeof(crlInfoOID));
23350             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_STR],
23351                     cert->crlInfo, cert->crlInfoSz);
23352         }
23353         else {
23354             /* Don't write out CRL Distribution Points. */
23355             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CRLINFO_SEQ,
23356                     CERTEXTSASN_IDX_CRLINFO_STR);
23357         }
23358     #endif /* WOLFSSL_CERT_EXT */
23359 
23360     #ifdef WOLFSSL_CUSTOM_OID
23361         /* encode a custom oid and value */
23362         if (cert->extCustom.oidSz > 0) {
23363             /* Set CRL Distribution Points OID and data. */
23364             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_OID],
23365                     cert->extCustom.oid, cert->extCustom.oidSz);
23366             SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_STR],
23367                     cert->extCustom.val, cert->extCustom.valSz);
23368         }
23369         else {
23370             /* Don't write out custom OID. */
23371             SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CUSTOM_SEQ,
23372                     CERTEXTSASN_IDX_CUSTOM_STR);
23373         }
23374     #endif
23375     }
23376 
23377     if (ret == 0) {
23378         /* Calculate size of encoded extensions. */
23379         ret = SizeASN_Items(certExtsASN, dataASN, certExtsASN_Length, &sz);
23380     }
23381     if (ret == 0) {
23382         /* Only SEQUENCE - don't encode extensions. */
23383         if (sz == 2) {
23384             sz = 0;
23385         }
23386         /* Check buffer is big enough. */
23387         else if ((output != NULL) && (sz > (int)maxSz)) {
23388             ret = BUFFER_E;
23389         }
23390     }
23391 
23392     if ((ret == 0) && (output != NULL) && (sz > 0)) {
23393         /* Encode certificate extensions into buffer. */
23394         SetASN_Items(certExtsASN, dataASN, certExtsASN_Length, output);
23395 
23396     #ifdef WOLFSSL_CERT_EXT
23397         if (cert->extKeyUsage != 0){
23398             /* Encode Extended Key Usage into space provided. */
23399             if (SetExtKeyUsage(cert,
23400                     (byte*)dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.data,
23401                     dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.length,
23402                     cert->extKeyUsage) <= 0) {
23403                 ret = KEYUSAGE_E;
23404             }
23405         }
23406         if ((!forRequest) && (cert->certPoliciesNb > 0)) {
23407             /* Encode Certificate Policies into space provided. */
23408             if (SetCertificatePolicies(
23409                     (byte*)dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.data,
23410                     dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.length,
23411                     cert->certPolicies, cert->certPoliciesNb, cert->heap) <= 0) {
23412                 ret = CERTPOLICIES_E;
23413             }
23414         }
23415     #endif
23416     }
23417     if (ret == 0) {
23418         /* Return the encoding size. */
23419         ret = sz;
23420     }
23421 
23422     FREE_ASNSETDATA(dataASN, cert->heap);
23423     return ret;
23424 }
23425 #endif /* WOLFSSL_ASN_TEMPLATE */
23426 
23427 #ifndef WOLFSSL_ASN_TEMPLATE
23428 /* Set Date validity from now until now + daysValid
23429  * return size in bytes written to output, 0 on error */
23430 /* TODO https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5
23431  * "MUST always encode certificate validity dates through the year 2049 as
23432  *  UTCTime; certificate validity dates in 2050 or later MUST be encoded as
23433  *  GeneralizedTime." */
23434 static int SetValidity(byte* output, int daysValid)
23435 {
23436 #ifndef NO_ASN_TIME
23437     byte before[MAX_DATE_SIZE];
23438     byte  after[MAX_DATE_SIZE];
23439 
23440     int beforeSz;
23441     int afterSz;
23442     int seqSz;
23443 
23444     time_t now;
23445     time_t then;
23446     struct tm* tmpTime;
23447     struct tm* expandedTime;
23448     struct tm localTime;
23449 
23450 #if defined(NEED_TMP_TIME)
23451     /* for use with gmtime_r */
23452     struct tm tmpTimeStorage;
23453     tmpTime = &tmpTimeStorage;
23454 #else
23455     tmpTime = NULL;
23456 #endif
23457     (void)tmpTime;
23458 
23459     now = XTIME(0);
23460 
23461     /* before now */
23462     before[0] = ASN_GENERALIZED_TIME;
23463     beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
23464 
23465     /* subtract 1 day of seconds for more compliance */
23466     then = now - 86400;
23467     expandedTime = XGMTIME(&then, tmpTime);
23468     if (expandedTime == NULL) {
23469         WOLFSSL_MSG("XGMTIME failed");
23470         return 0;   /* error */
23471     }
23472     localTime = *expandedTime;
23473 
23474     /* adjust */
23475     localTime.tm_year += 1900;
23476     localTime.tm_mon +=    1;
23477 
23478     SetTime(&localTime, before + beforeSz);
23479     beforeSz += ASN_GEN_TIME_SZ;
23480 
23481     after[0] = ASN_GENERALIZED_TIME;
23482     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
23483 
23484     /* add daysValid of seconds */
23485     then = now + (daysValid * (time_t)86400);
23486     expandedTime = XGMTIME(&then, tmpTime);
23487     if (expandedTime == NULL) {
23488         WOLFSSL_MSG("XGMTIME failed");
23489         return 0;   /* error */
23490     }
23491     localTime = *expandedTime;
23492 
23493     /* adjust */
23494     localTime.tm_year += 1900;
23495     localTime.tm_mon  +=    1;
23496 
23497     SetTime(&localTime, after + afterSz);
23498     afterSz += ASN_GEN_TIME_SZ;
23499 
23500     /* headers and output */
23501     seqSz = SetSequence(beforeSz + afterSz, output);
23502     XMEMCPY(output + seqSz, before, beforeSz);
23503     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
23504 
23505     return seqSz + beforeSz + afterSz;
23506 #else
23507     (void)output;
23508     (void)daysValid;
23509     return NOT_COMPILED_IN;
23510 #endif
23511 }
23512 #else
23513 static int SetValidity(byte* before, byte* after, int daysValid)
23514 {
23515     int ret = 0;
23516     time_t now;
23517     time_t then;
23518     struct tm* tmpTime;
23519     struct tm* expandedTime;
23520     struct tm localTime;
23521 #if defined(NEED_TMP_TIME)
23522     /* for use with gmtime_r */
23523     struct tm tmpTimeStorage;
23524     tmpTime = &tmpTimeStorage;
23525 #else
23526     tmpTime = NULL;
23527 #endif
23528     (void)tmpTime;
23529 
23530     now = XTIME(0);
23531 
23532     /* subtract 1 day of seconds for more compliance */
23533     then = now - 86400;
23534     expandedTime = XGMTIME(&then, tmpTime);
23535     if (expandedTime == NULL) {
23536         WOLFSSL_MSG("XGMTIME failed");
23537         ret = DATE_E;
23538     }
23539     if (ret == 0) {
23540         localTime = *expandedTime;
23541 
23542         /* adjust */
23543         localTime.tm_year += 1900;
23544         localTime.tm_mon +=    1;
23545 
23546         SetTime(&localTime, before);
23547 
23548         /* add daysValid of seconds */
23549         then = now + (daysValid * (time_t)86400);
23550         expandedTime = XGMTIME(&then, tmpTime);
23551         if (expandedTime == NULL) {
23552             WOLFSSL_MSG("XGMTIME failed");
23553             ret = DATE_E;
23554         }
23555     }
23556     if (ret == 0) {
23557         localTime = *expandedTime;
23558 
23559         /* adjust */
23560         localTime.tm_year += 1900;
23561         localTime.tm_mon  +=    1;
23562 
23563         SetTime(&localTime, after);
23564     }
23565 
23566     return ret;
23567 }
23568 #endif /* WOLFSSL_ASN_TEMPLATE */
23569 
23570 
23571 #ifndef WOLFSSL_ASN_TEMPLATE
23572 /* encode info from cert into DER encoded format */
23573 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
23574                       WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
23575                       ed448_key* ed448Key, falcon_key* falconKey)
23576 {
23577     int ret;
23578 
23579     if (cert == NULL || der == NULL || rng == NULL)
23580         return BAD_FUNC_ARG;
23581 
23582     /* make sure at least one key type is provided */
23583     if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
23584         dsaKey == NULL && ed448Key == NULL && falconKey == NULL) {
23585         return PUBLIC_KEY_E;
23586     }
23587 
23588     /* init */
23589     XMEMSET(der, 0, sizeof(DerCert));
23590 
23591     /* version */
23592     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
23593 
23594     /* serial number (must be positive) */
23595     if (cert->serialSz == 0) {
23596         /* generate random serial */
23597         cert->serialSz = CTC_GEN_SERIAL_SZ;
23598         ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
23599         if (ret != 0)
23600             return ret;
23601         /* Clear the top bit to avoid a negative value */
23602         cert->serial[0] &= 0x7f;
23603     }
23604     der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,
23605         sizeof(der->serial), CTC_SERIAL_SIZE);
23606     if (der->serialSz < 0)
23607         return der->serialSz;
23608 
23609     /* signature algo */
23610     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
23611     if (der->sigAlgoSz <= 0)
23612         return ALGO_ID_E;
23613 
23614     /* public key */
23615 #ifndef NO_RSA
23616     if (cert->keyType == RSA_KEY) {
23617         if (rsaKey == NULL)
23618             return PUBLIC_KEY_E;
23619         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
23620                                            sizeof(der->publicKey), 1);
23621     }
23622 #endif
23623 
23624 #ifdef HAVE_ECC
23625     if (cert->keyType == ECC_KEY) {
23626         if (eccKey == NULL)
23627             return PUBLIC_KEY_E;
23628         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
23629                                            sizeof(der->publicKey), 1);
23630     }
23631 #endif
23632 
23633 #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
23634     if (cert->keyType == DSA_KEY) {
23635         if (dsaKey == NULL)
23636             return PUBLIC_KEY_E;
23637         der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
23638                                               sizeof(der->publicKey), 1);
23639     }
23640 #endif
23641 
23642 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
23643     if (cert->keyType == ED25519_KEY) {
23644         if (ed25519Key == NULL)
23645             return PUBLIC_KEY_E;
23646         der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
23647             (word32)sizeof(der->publicKey), 1);
23648     }
23649 #endif
23650 
23651 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
23652     if (cert->keyType == ED448_KEY) {
23653         if (ed448Key == NULL)
23654             return PUBLIC_KEY_E;
23655         der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
23656             (word32)sizeof(der->publicKey), 1);
23657     }
23658 #endif
23659 
23660 #if defined(HAVE_PQC)
23661     if ((cert->keyType == FALCON_LEVEL1_KEY) ||
23662         (cert->keyType == FALCON_LEVEL5_KEY)) {
23663         if (falconKey == NULL)
23664             return PUBLIC_KEY_E;
23665 
23666         der->publicKeySz =
23667             wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
23668                                      (word32)sizeof(der->publicKey), 1);
23669     }
23670 #endif
23671 
23672     if (der->publicKeySz <= 0)
23673         return PUBLIC_KEY_E;
23674 
23675     der->validitySz = 0;
23676 #ifdef WOLFSSL_ALT_NAMES
23677     /* date validity copy ? */
23678     if (cert->beforeDateSz && cert->afterDateSz) {
23679         der->validitySz = CopyValidity(der->validity, cert);
23680         if (der->validitySz <= 0)
23681             return DATE_E;
23682     }
23683 #endif
23684 
23685     /* date validity */
23686     if (der->validitySz == 0) {
23687         der->validitySz = SetValidity(der->validity, cert->daysValid);
23688         if (der->validitySz <= 0)
23689             return DATE_E;
23690     }
23691 
23692     /* subject name */
23693 #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
23694     if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
23695         /* Use the raw subject */
23696         int idx;
23697 
23698         der->subjectSz = min(sizeof(der->subject),
23699                 (word32)XSTRLEN((const char*)cert->sbjRaw));
23700         /* header */
23701         idx = SetSequence(der->subjectSz, der->subject);
23702         if (der->subjectSz + idx > (int)sizeof(der->subject)) {
23703             return SUBJECT_E;
23704         }
23705 
23706         XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
23707                 der->subjectSz);
23708         der->subjectSz += idx;
23709     }
23710     else
23711 #endif
23712     {
23713         /* Use the name structure */
23714         der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
23715                 &cert->subject, cert->heap);
23716     }
23717     if (der->subjectSz <= 0)
23718         return SUBJECT_E;
23719 
23720     /* issuer name */
23721 #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
23722     if (XSTRLEN((const char*)cert->issRaw) > 0) {
23723         /* Use the raw issuer */
23724         int idx;
23725 
23726         der->issuerSz = min(sizeof(der->issuer),
23727                 (word32)XSTRLEN((const char*)cert->issRaw));
23728 
23729         /* header */
23730         idx = SetSequence(der->issuerSz, der->issuer);
23731         if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
23732             return ISSUER_E;
23733         }
23734 
23735         XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
23736                 der->issuerSz);
23737         der->issuerSz += idx;
23738     }
23739     else
23740 #endif
23741     {
23742         /* Use the name structure */
23743         der->issuerSz = SetNameEx(der->issuer, sizeof(der->issuer),
23744                 cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
23745     }
23746     if (der->issuerSz <= 0)
23747         return ISSUER_E;
23748 
23749     /* set the extensions */
23750     der->extensionsSz = 0;
23751 
23752     /* CA */
23753     if (cert->isCA) {
23754         der->caSz = SetCa(der->ca, sizeof(der->ca));
23755         if (der->caSz <= 0)
23756             return CA_TRUE_E;
23757 
23758         der->extensionsSz += der->caSz;
23759     }
23760     else
23761         der->caSz = 0;
23762 
23763 #ifdef WOLFSSL_ALT_NAMES
23764     /* Alternative Name */
23765     if (cert->altNamesSz) {
23766         der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
23767                                       cert->altNames, cert->altNamesSz);
23768         if (der->altNamesSz <= 0)
23769             return ALT_NAME_E;
23770 
23771         der->extensionsSz += der->altNamesSz;
23772     }
23773     else
23774         der->altNamesSz = 0;
23775 #endif
23776 
23777 #ifdef WOLFSSL_CERT_EXT
23778     /* SKID */
23779     if (cert->skidSz) {
23780         /* check the provided SKID size */
23781         if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
23782             return SKID_E;
23783 
23784         /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
23785             cert (CTC_MAX_SKID_SIZE). */
23786         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
23787                               cert->skid, cert->skidSz);
23788         if (der->skidSz <= 0)
23789             return SKID_E;
23790 
23791         der->extensionsSz += der->skidSz;
23792     }
23793     else
23794         der->skidSz = 0;
23795 
23796     /* AKID */
23797     if (cert->akidSz) {
23798         /* check the provided AKID size */
23799         if ((
23800 #ifdef WOLFSSL_AKID_NAME
23801              !cert->rawAkid &&
23802 #endif
23803               cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
23804 #ifdef WOLFSSL_AKID_NAME
23805           || (cert->rawAkid && cert->akidSz > (int)sizeof(der->akid))
23806 #endif
23807              )
23808             return AKID_E;
23809 
23810         der->akidSz = SetAKID(der->akid, sizeof(der->akid), cert->akid,
23811                                 cert->akidSz,
23812 #ifdef WOLFSSL_AKID_NAME
23813                                 cert->rawAkid
23814 #else
23815                                 0
23816 #endif
23817                                 );
23818         if (der->akidSz <= 0)
23819             return AKID_E;
23820 
23821         der->extensionsSz += der->akidSz;
23822     }
23823     else
23824         der->akidSz = 0;
23825 
23826     /* Key Usage */
23827     if (cert->keyUsage != 0){
23828         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
23829                                       cert->keyUsage);
23830         if (der->keyUsageSz <= 0)
23831             return KEYUSAGE_E;
23832 
23833         der->extensionsSz += der->keyUsageSz;
23834     }
23835     else
23836         der->keyUsageSz = 0;
23837 
23838     /* Extended Key Usage */
23839     if (cert->extKeyUsage != 0){
23840         der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
23841                                 sizeof(der->extKeyUsage), cert->extKeyUsage);
23842         if (der->extKeyUsageSz <= 0)
23843             return EXTKEYUSAGE_E;
23844 
23845         der->extensionsSz += der->extKeyUsageSz;
23846     }
23847     else
23848         der->extKeyUsageSz = 0;
23849 
23850 #ifndef IGNORE_NETSCAPE_CERT_TYPE
23851     /* Netscape Certificate Type */
23852     if (cert->nsCertType != 0) {
23853         der->nsCertTypeSz = SetNsCertType(cert, der->nsCertType,
23854                                 sizeof(der->nsCertType), cert->nsCertType);
23855         if (der->nsCertTypeSz <= 0)
23856             return EXTENSIONS_E;
23857 
23858         der->extensionsSz += der->nsCertTypeSz;
23859     }
23860     else
23861         der->nsCertTypeSz = 0;
23862 #endif
23863 
23864     if (cert->crlInfoSz > 0) {
23865         der->crlInfoSz = SetCRLInfo(cert, der->crlInfo, sizeof(der->crlInfo),
23866                                 cert->crlInfo, cert->crlInfoSz);
23867         if (der->crlInfoSz <= 0)
23868             return EXTENSIONS_E;
23869 
23870         der->extensionsSz += der->crlInfoSz;
23871     }
23872     else
23873         der->crlInfoSz = 0;
23874 
23875     /* Certificate Policies */
23876     if (cert->certPoliciesNb != 0) {
23877         der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
23878                                                      sizeof(der->certPolicies),
23879                                                      cert->certPolicies,
23880                                                      cert->certPoliciesNb,
23881                                                      cert->heap);
23882         if (der->certPoliciesSz <= 0)
23883             return CERTPOLICIES_E;
23884 
23885         der->extensionsSz += der->certPoliciesSz;
23886     }
23887     else
23888         der->certPoliciesSz = 0;
23889 #endif /* WOLFSSL_CERT_EXT */
23890 
23891     /* put extensions */
23892     if (der->extensionsSz > 0) {
23893 
23894         /* put the start of extensions sequence (ID, Size) */
23895         der->extensionsSz = SetExtensionsHeader(der->extensions,
23896                                                 sizeof(der->extensions),
23897                                                 der->extensionsSz);
23898         if (der->extensionsSz <= 0)
23899             return EXTENSIONS_E;
23900 
23901         /* put CA */
23902         if (der->caSz) {
23903             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23904                                 &der->extensionsSz,
23905                                 der->ca, der->caSz);
23906             if (ret == 0)
23907                 return EXTENSIONS_E;
23908         }
23909 
23910 #ifdef WOLFSSL_ALT_NAMES
23911         /* put Alternative Names */
23912         if (der->altNamesSz) {
23913             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23914                                 &der->extensionsSz,
23915                                 der->altNames, der->altNamesSz);
23916             if (ret <= 0)
23917                 return EXTENSIONS_E;
23918         }
23919 #endif
23920 
23921 #ifdef WOLFSSL_CERT_EXT
23922         /* put SKID */
23923         if (der->skidSz) {
23924             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23925                                 &der->extensionsSz,
23926                                 der->skid, der->skidSz);
23927             if (ret <= 0)
23928                 return EXTENSIONS_E;
23929         }
23930 
23931         /* put AKID */
23932         if (der->akidSz) {
23933             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23934                                 &der->extensionsSz,
23935                                 der->akid, der->akidSz);
23936             if (ret <= 0)
23937                 return EXTENSIONS_E;
23938         }
23939 
23940         /* put CRL Distribution Points */
23941         if (der->crlInfoSz) {
23942             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23943                                 &der->extensionsSz,
23944                                 der->crlInfo, der->crlInfoSz);
23945             if (ret <= 0)
23946                 return EXTENSIONS_E;
23947         }
23948 
23949         /* put KeyUsage */
23950         if (der->keyUsageSz) {
23951             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23952                                 &der->extensionsSz,
23953                                 der->keyUsage, der->keyUsageSz);
23954             if (ret <= 0)
23955                 return EXTENSIONS_E;
23956         }
23957 
23958         /* put ExtendedKeyUsage */
23959         if (der->extKeyUsageSz) {
23960             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23961                                 &der->extensionsSz,
23962                                 der->extKeyUsage, der->extKeyUsageSz);
23963             if (ret <= 0)
23964                 return EXTENSIONS_E;
23965         }
23966 
23967         /* put Netscape Cert Type */
23968 #ifndef IGNORE_NETSCAPE_CERT_TYPE
23969         if (der->nsCertTypeSz) {
23970             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23971                                 &der->extensionsSz,
23972                                 der->nsCertType, der->nsCertTypeSz);
23973             if (ret <= 0)
23974                 return EXTENSIONS_E;
23975         }
23976 #endif
23977 
23978         /* put Certificate Policies */
23979         if (der->certPoliciesSz) {
23980             ret = SetExtensions(der->extensions, sizeof(der->extensions),
23981                                 &der->extensionsSz,
23982                                 der->certPolicies, der->certPoliciesSz);
23983             if (ret <= 0)
23984                 return EXTENSIONS_E;
23985         }
23986 #endif /* WOLFSSL_CERT_EXT */
23987     }
23988 
23989     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
23990         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
23991         der->extensionsSz;
23992 
23993     return 0;
23994 }
23995 
23996 
23997 /* write DER encoded cert to buffer, size already checked */
23998 static int WriteCertBody(DerCert* der, byte* buf)
23999 {
24000     int idx;
24001 
24002     /* signed part header */
24003     idx = SetSequence(der->total, buf);
24004     /* version */
24005     XMEMCPY(buf + idx, der->version, der->versionSz);
24006     idx += der->versionSz;
24007     /* serial */
24008     XMEMCPY(buf + idx, der->serial, der->serialSz);
24009     idx += der->serialSz;
24010     /* sig algo */
24011     XMEMCPY(buf + idx, der->sigAlgo, der->sigAlgoSz);
24012     idx += der->sigAlgoSz;
24013     /* issuer */
24014     XMEMCPY(buf + idx, der->issuer, der->issuerSz);
24015     idx += der->issuerSz;
24016     /* validity */
24017     XMEMCPY(buf + idx, der->validity, der->validitySz);
24018     idx += der->validitySz;
24019     /* subject */
24020     XMEMCPY(buf + idx, der->subject, der->subjectSz);
24021     idx += der->subjectSz;
24022     /* public key */
24023     XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
24024     idx += der->publicKeySz;
24025     if (der->extensionsSz) {
24026         /* extensions */
24027         XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
24028                                                    (int)sizeof(der->extensions)));
24029         idx += der->extensionsSz;
24030     }
24031 
24032     return idx;
24033 }
24034 #endif /* !WOLFSSL_ASN_TEMPLATE */
24035 
24036 
24037 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
24038 static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
24039     byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
24040     ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
24041     WC_RNG* rng, int sigAlgoType, void* heap)
24042 {
24043     int digestSz = 0, typeH = 0, ret = 0;
24044 
24045     (void)digestSz;
24046     (void)typeH;
24047     (void)buf;
24048     (void)sz;
24049     (void)sig;
24050     (void)sigSz;
24051     (void)rsaKey;
24052     (void)eccKey;
24053     (void)ed25519Key;
24054     (void)ed448Key;
24055     (void)falconKey;
24056     (void)rng;
24057     (void)heap;
24058 
24059     switch (certSignCtx->state) {
24060     case CERTSIGN_STATE_BEGIN:
24061     case CERTSIGN_STATE_DIGEST:
24062 
24063         certSignCtx->state = CERTSIGN_STATE_DIGEST;
24064         certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
24065             DYNAMIC_TYPE_TMP_BUFFER);
24066         if (certSignCtx->digest == NULL) {
24067             ret = MEMORY_E; goto exit_ms;
24068         }
24069 
24070         ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest,
24071                                &typeH, &digestSz, 0);
24072         /* set next state, since WC_PENDING_E rentry for these are not "call again" */
24073         certSignCtx->state = CERTSIGN_STATE_ENCODE;
24074         if (ret != 0) {
24075             goto exit_ms;
24076         }
24077         FALL_THROUGH;
24078 
24079     case CERTSIGN_STATE_ENCODE:
24080     #ifndef NO_RSA
24081         if (rsaKey) {
24082             certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
24083                 DYNAMIC_TYPE_TMP_BUFFER);
24084             if (certSignCtx->encSig == NULL) {
24085                 ret = MEMORY_E; goto exit_ms;
24086             }
24087 
24088             /* signature */
24089             certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
24090                                           certSignCtx->digest, digestSz, typeH);
24091         }
24092     #endif /* !NO_RSA */
24093         FALL_THROUGH;
24094 
24095     case CERTSIGN_STATE_DO:
24096         certSignCtx->state = CERTSIGN_STATE_DO;
24097         ret = ALGO_ID_E; /* default to error */
24098 
24099     #ifndef NO_RSA
24100         if (rsaKey) {
24101             /* signature */
24102             ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
24103                                  sig, sigSz, rsaKey, rng);
24104         }
24105     #endif /* !NO_RSA */
24106 
24107     #ifdef HAVE_ECC
24108         if (!rsaKey && eccKey) {
24109             word32 outSz = sigSz;
24110 
24111             ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
24112                                    sig, &outSz, rng, eccKey);
24113             if (ret == 0)
24114                 ret = outSz;
24115         }
24116     #endif /* HAVE_ECC */
24117 
24118     #if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
24119         if (!rsaKey && !eccKey && ed25519Key) {
24120             word32 outSz = sigSz;
24121 
24122             ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key);
24123             if (ret == 0)
24124                 ret = outSz;
24125         }
24126     #endif /* HAVE_ED25519 && HAVE_ED25519_SIGN */
24127 
24128     #if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
24129         if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
24130             word32 outSz = sigSz;
24131 
24132             ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0);
24133             if (ret == 0)
24134                 ret = outSz;
24135         }
24136     #endif /* HAVE_ED448 && HAVE_ED448_SIGN */
24137 
24138     #if defined(HAVE_PQC)
24139         if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && falconKey) {
24140             word32 outSz = sigSz;
24141             ret = wc_falcon_sign_msg(buf, sz, sig, &outSz, falconKey);
24142             if (ret == 0)
24143                 ret = outSz;
24144         }
24145     #endif /* HAVE_PQC */
24146 
24147         break;
24148     }
24149 
24150 exit_ms:
24151 
24152 #ifdef WOLFSSL_ASYNC_CRYPT
24153     if (ret == WC_PENDING_E) {
24154         return ret;
24155     }
24156 #endif
24157 
24158 #ifndef NO_RSA
24159     if (rsaKey) {
24160         XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
24161     }
24162 #endif /* !NO_RSA */
24163 
24164     XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
24165     certSignCtx->digest = NULL;
24166 
24167     /* reset state */
24168     certSignCtx->state = CERTSIGN_STATE_BEGIN;
24169 
24170     return ret;
24171 }
24172 
24173 
24174 #ifdef WOLFSSL_ASN_TEMPLATE
24175 /* Generate a random integer value of at most len bytes.
24176  *
24177  * Most-significant bit will not be set when maximum size.
24178  * Random value may be smaller than maximum size in bytes.
24179  *
24180  * @param [in]  rng  Random number generator.
24181  * @param [out] out  Buffer to hold integer value.
24182  * @param [in]  len  Maximum number of bytes of integer.
24183  * @return  0 on success.
24184  * @return  -ve when random number generation failed.
24185  */
24186 static int GenerateInteger(WC_RNG* rng, byte* out, int len)
24187 {
24188     int ret;
24189 
24190     /* Generate random number. */
24191     ret = wc_RNG_GenerateBlock(rng, out, len);
24192     if (ret == 0) {
24193         int i;
24194 
24195         /* Clear the top bit to make positive. */
24196         out[0] &= 0x7f;
24197 
24198         /* Find first non-zero byte. One zero byte is valid though. */
24199         for (i = 0; i < len - 1; i++) {
24200             if (out[i] != 0) {
24201                 break;
24202             }
24203         }
24204         if (i != 0) {
24205             /* Remove leading zeros. */
24206             XMEMMOVE(out, out + i, len - i);
24207         }
24208     }
24209 
24210     return ret;
24211 }
24212 
24213 /* ASN.1 template for a Certificate.
24214  * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
24215  */
24216 static const ASNItem sigASN[] = {
24217 /* SEQ          */    { 0, ASN_SEQUENCE, 1, 1, 0 },
24218                                      /* tbsCertificate */
24219 /* TBS_SEQ      */        { 1, ASN_SEQUENCE, 1, 0, 0 },
24220                                      /* signatureAlgorithm */
24221 /* SIGALGO_SEQ  */        { 1, ASN_SEQUENCE, 1, 1, 0 },
24222 /* SIGALGO_OID  */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
24223 /* SIGALGO_NULL */            { 2, ASN_TAG_NULL, 0, 0, 0 },
24224                                      /* signatureValue */
24225 /* SIGNATURE    */        { 1, ASN_BIT_STRING, 0, 0, 0 },
24226 };
24227 enum {
24228     SIGASN_IDX_SEQ = 0,
24229     SIGASN_IDX_TBS_SEQ,
24230     SIGASN_IDX_SIGALGO_SEQ,
24231     SIGASN_IDX_SIGALGO_OID,
24232     SIGASN_IDX_SIGALGO_NULL,
24233     SIGASN_IDX_SIGNATURE,
24234 };
24235 
24236 /* Number of items in ASN.1 template for a Certificate. */
24237 #define sigASN_Length (sizeof(sigASN) / sizeof(ASNItem))
24238 #endif
24239 
24240 /* add signature to end of buffer, size of buffer assumed checked, return
24241    new length */
24242 int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
24243                         int sigAlgoType)
24244 {
24245 #ifndef WOLFSSL_ASN_TEMPLATE
24246     byte seq[MAX_SEQ_SZ];
24247     int  idx = bodySz, seqSz;
24248 
24249     /* algo */
24250     idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
24251     /* bit string */
24252     idx += SetBitString(sigSz, 0, buf ? buf + idx : NULL);
24253     /* signature */
24254     if (buf)
24255         XMEMCPY(buf + idx, sig, sigSz);
24256     idx += sigSz;
24257 
24258     /* make room for overall header */
24259     seqSz = SetSequence(idx, seq);
24260     if (buf) {
24261         XMEMMOVE(buf + seqSz, buf, idx);
24262         XMEMCPY(buf, seq, seqSz);
24263     }
24264 
24265     return idx + seqSz;
24266 #else
24267     DECL_ASNSETDATA(dataASN, sigASN_Length);
24268     word32 seqSz;
24269     int sz;
24270     int ret = 0;
24271 
24272     CALLOC_ASNSETDATA(dataASN, sigASN_Length, ret, NULL);
24273 
24274     /* In place, put body between SEQUENCE and signature. */
24275     if (ret == 0) {
24276         /* Set sigature OID and signature data. */
24277         SetASN_OID(&dataASN[SIGASN_IDX_SIGALGO_OID], sigAlgoType, oidSigType);
24278         if (IsSigAlgoECC(sigAlgoType)) {
24279             /* ECDSA and EdDSA doesn't have NULL tagged item. */
24280             dataASN[SIGASN_IDX_SIGALGO_NULL].noOut = 1;
24281         }
24282         SetASN_Buffer(&dataASN[SIGASN_IDX_SIGNATURE], sig, sigSz);
24283         /* Calcuate size of signature data. */
24284         ret = SizeASN_Items(&sigASN[SIGASN_IDX_SIGALGO_SEQ],
24285                 &dataASN[SIGASN_IDX_SIGALGO_SEQ], sigASN_Length - 2, &sz);
24286     }
24287     if (ret == 0) {
24288         /* Calculate size of outer sequence by calculating size of the encoded
24289          * length and adding 1 for tag. */
24290         seqSz = SizeASNHeader(bodySz + sz);
24291         if (buf != NULL) {
24292             /* Move body to after sequence. */
24293             XMEMMOVE(buf + seqSz, buf, bodySz);
24294         }
24295         /* Leave space for body in encoding. */
24296         SetASN_ReplaceBuffer(&dataASN[SIGASN_IDX_TBS_SEQ], NULL, bodySz);
24297 
24298         /* Calculate overall size and put in offsets and lengths. */
24299         ret = SizeASN_Items(sigASN, dataASN, sigASN_Length, &sz);
24300     }
24301     if ((ret == 0) && (buf != NULL)) {
24302         /* Write SEQUENCE and signature around body. */
24303         SetASN_Items(sigASN, dataASN, sigASN_Length, buf);
24304     }
24305 
24306     if (ret == 0) {
24307         /* Return the encoding size. */
24308         ret = sz;
24309     }
24310 
24311     FREE_ASNSETDATA(dataASN, NULL);
24312     return ret;
24313 #endif /* WOLFSSL_ASN_TEMPLATE */
24314 }
24315 
24316 
24317 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
24318 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
24319                        RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
24320                        DsaKey* dsaKey, ed25519_key* ed25519Key,
24321                        ed448_key* ed448Key, falcon_key* falconKey)
24322 {
24323 #ifndef WOLFSSL_ASN_TEMPLATE
24324     int ret;
24325 #ifdef WOLFSSL_SMALL_STACK
24326     DerCert* der;
24327 #else
24328     DerCert der[1];
24329 #endif
24330 
24331     if (derBuffer == NULL)
24332         return BAD_FUNC_ARG;
24333 
24334     if (eccKey)
24335         cert->keyType = ECC_KEY;
24336     else if (rsaKey)
24337         cert->keyType = RSA_KEY;
24338     else if (dsaKey)
24339         cert->keyType = DSA_KEY;
24340     else if (ed25519Key)
24341         cert->keyType = ED25519_KEY;
24342     else if (ed448Key)
24343         cert->keyType = ED448_KEY;
24344 #ifdef HAVE_PQC
24345     else if ((falconKey != NULL) && (falconKey->level == 1))
24346         cert->keyType = FALCON_LEVEL1_KEY;
24347     else if ((falconKey != NULL) && (falconKey->level == 5))
24348         cert->keyType = FALCON_LEVEL5_KEY;
24349 #endif
24350     else
24351         return BAD_FUNC_ARG;
24352 
24353 #ifdef WOLFSSL_SMALL_STACK
24354     der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
24355     if (der == NULL)
24356         return MEMORY_E;
24357 #endif
24358 
24359     ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
24360                      ed448Key, falconKey);
24361     if (ret == 0) {
24362         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
24363             ret = BUFFER_E;
24364         else
24365             ret = cert->bodySz = WriteCertBody(der, derBuffer);
24366     }
24367 
24368 #ifdef WOLFSSL_SMALL_STACK
24369     XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
24370 #endif
24371 
24372     return ret;
24373 #else
24374     /* TODO: issRaw and sbjRaw should be NUL terminated. */
24375     DECL_ASNSETDATA(dataASN, x509CertASN_Length);
24376     word32 publicKeySz = 0;
24377     word32 issuerSz = 0;
24378     word32 subjectSz = 0;
24379     word32 extSz = 0;
24380     int sz;
24381     int ret = 0;
24382     word32 issRawLen = 0;
24383     word32 sbjRawLen = 0;
24384 
24385     (void)falconKey; /* Unused without OQS */
24386     CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
24387 
24388     if (ret == 0) {
24389         /* Set key type into certificate object based on key passed in. */
24390         if (rsaKey) {
24391             cert->keyType = RSA_KEY;
24392         }
24393         else if (eccKey) {
24394             cert->keyType = ECC_KEY;
24395         }
24396         else if (dsaKey) {
24397             cert->keyType = DSA_KEY;
24398         }
24399         else if (ed25519Key) {
24400             cert->keyType = ED25519_KEY;
24401         }
24402         else if (ed448Key) {
24403             cert->keyType = ED448_KEY;
24404         }
24405         else if (falconKey != NULL) {
24406         #ifdef HAVE_PQC
24407             if (falconKey->level == 1)
24408                 cert->keyType = FALCON_LEVEL1_KEY;
24409             else if (falconKey->level == 5)
24410                 cert->keyType = FALCON_LEVEL5_KEY;
24411         #endif
24412         }
24413         else {
24414             ret = BAD_FUNC_ARG;
24415         }
24416     }
24417     if ((ret == 0) && (cert->serialSz == 0)) {
24418         /* Generate random serial number. */
24419         cert->serialSz = CTC_GEN_SERIAL_SZ;
24420         ret = GenerateInteger(rng, cert->serial, CTC_GEN_SERIAL_SZ);
24421     }
24422     if (ret == 0) {
24423         /* Determine issuer name size. */
24424     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
24425         defined(WOLFSSL_CERT_REQ)
24426         issRawLen = (word32)XSTRLEN((const char*)cert->issRaw);
24427         if (issRawLen > 0) {
24428             issuerSz = min(sizeof(cert->issRaw), issRawLen);
24429         }
24430         else
24431     #endif
24432         {
24433             /* Calcuate issuer name encoding size. */
24434             issuerSz = SetNameEx(NULL, ASN_NAME_MAX, &cert->issuer, cert->heap);
24435             ret = issuerSz;
24436         }
24437     }
24438     if (ret >= 0) {
24439         /* Determine subject name size. */
24440     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
24441         defined(WOLFSSL_CERT_REQ)
24442         sbjRawLen = (word32)XSTRLEN((const char*)cert->sbjRaw);
24443         if (sbjRawLen > 0) {
24444             subjectSz = min(sizeof(cert->sbjRaw), sbjRawLen);
24445         }
24446         else
24447     #endif
24448         {
24449             /* Calcuate subject name encoding size. */
24450             subjectSz = SetNameEx(NULL, ASN_NAME_MAX, &cert->subject, cert->heap);
24451             ret = subjectSz;
24452         }
24453     }
24454     if (ret >= 0) {
24455         /* Calcuate public key encoding size. */
24456         ret = publicKeySz = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
24457             eccKey, ed25519Key, ed448Key, dsaKey);
24458     }
24459     if (ret >= 0) {
24460         /* Calcuate extensions encoding size - may be 0. */
24461         ret = extSz = EncodeExtensions(cert, NULL, 0, 0);
24462     }
24463     if (ret >= 0) {
24464         /* Don't write out outer sequence - only doing body. */
24465         dataASN[X509CERTASN_IDX_SEQ].noOut = 1;
24466         /* Set version, serial number and signature OID */
24467         SetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], cert->version);
24468         SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
24469                 cert->serialSz);
24470         SetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], cert->sigType,
24471                 oidSigType);
24472         if (IsSigAlgoECC(cert->sigType)) {
24473             /* No NULL tagged item with ECDSA and EdDSA signature OIDs. */
24474             dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].noOut = 1;
24475         }
24476         if (issRawLen > 0) {
24477     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
24478         defined(WOLFSSL_CERT_REQ)
24479             /* Put in encoded issuer name. */
24480             SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
24481                     cert->issRaw, issuerSz);
24482     #endif
24483         }
24484         else {
24485             /* Leave space for issuer name. */
24486             SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
24487                     NULL, issuerSz);
24488         }
24489 
24490 #ifdef WOLFSSL_ALT_NAMES
24491         if (cert->beforeDateSz && cert->afterDateSz) {
24492             if (cert->beforeDate[0] == ASN_UTC_TIME) {
24493                 /* Make space for before date data. */
24494                 SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC],
24495                         cert->beforeDate + 2, ASN_UTC_TIME_SIZE - 1);
24496                 /* Don't put out Generalized Time before data. */
24497                 dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT].noOut = 1;
24498             }
24499             else {
24500                 /* Don't put out UTC before data. */
24501                 dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
24502                 /* Make space for before date data. */
24503                 SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
24504                         cert->beforeDate + 2, ASN_GEN_TIME_SZ);
24505             }
24506             if (cert->afterDate[0] == ASN_UTC_TIME) {
24507                 /* Make space for after date data. */
24508                 SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC],
24509                         cert->afterDate + 2, ASN_UTC_TIME_SIZE - 1);
24510                 /* Don't put out UTC Generalized Time after data. */
24511                 dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT].noOut = 1;
24512             }
24513             else {
24514                 /* Don't put out UTC after data. */
24515                 dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
24516                 /* Make space for after date data. */
24517                 SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
24518                         cert->afterDate + 2, ASN_GEN_TIME_SZ);
24519             }
24520         }
24521         else
24522 #endif
24523         {
24524             /* Don't put out UTC before data. */
24525             dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
24526             /* Make space for before date data. */
24527             SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
24528                     NULL, ASN_GEN_TIME_SZ);
24529             /* Don't put out UTC after data. */
24530             dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
24531             /* Make space for after date data. */
24532             SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
24533                     NULL, ASN_GEN_TIME_SZ);
24534         }
24535         if (sbjRawLen > 0) {
24536             /* Put in encoded subject name. */
24537     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
24538         defined(WOLFSSL_CERT_REQ)
24539             SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
24540                     cert->sbjRaw, subjectSz);
24541     #endif
24542         }
24543         else {
24544             /* Leave space for subject name. */
24545             SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
24546                     NULL, subjectSz);
24547         }
24548         /* Leave space for public key. */
24549         SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ],
24550                 NULL, publicKeySz);
24551         /* Replacement buffer instead of algorithm identifier items. */
24552         SetASNItem_NoOut(dataASN,
24553                 X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
24554                 X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY);
24555         /* issuerUniqueID and subjectUniqueID not supported. */
24556         dataASN[X509CERTASN_IDX_TBS_ISSUERUID].noOut = 1;
24557         dataASN[X509CERTASN_IDX_TBS_SUBJECTUID].noOut = 1;
24558         /* Leave space for extensions if any set into certificate object. */
24559         if (extSz > 0) {
24560             SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_EXT_SEQ], NULL, extSz);
24561         }
24562         else {
24563             SetASNItem_NoOutNode(dataASN, x509CertASN,
24564                     X509CERTASN_IDX_TBS_EXT, x509CertASN_Length);
24565         }
24566         /* No signature - added later. */
24567         SetASNItem_NoOut(dataASN, X509CERTASN_IDX_SIGALGO_SEQ,
24568                 X509CERTASN_IDX_SIGNATURE);
24569 
24570         /* Calculate encoded certificate body size. */
24571         ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
24572     }
24573     /* Check buffer is big enough for encoded data. */
24574     if ((ret == 0) && (sz > (int)derSz)) {
24575         ret = BUFFER_E;
24576     }
24577     if (ret == 0) {
24578         /* Encode certificate body into buffer. */
24579         SetASN_Items(x509CertASN, dataASN, x509CertASN_Length, derBuffer);
24580 
24581         if (issRawLen == 0) {
24582             /* Encode issuer name into buffer. */
24583             ret = SetNameEx(
24584                 (byte*)dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.data,
24585                 dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.length,
24586                 &cert->issuer, cert->heap);
24587         }
24588     }
24589     if ((ret >= 0) && (sbjRawLen == 0)) {
24590         /* Encode subject name into buffer. */
24591         ret = SetNameEx(
24592             (byte*)dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.data,
24593             dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.length,
24594             &cert->subject, cert->heap);
24595     }
24596     if (ret >= 0) {
24597 #ifdef WOLFSSL_ALT_NAMES
24598         if (cert->beforeDateSz == 0 || cert->afterDateSz == 0)
24599 #endif
24600         {
24601             /* Encode validity into buffer. */
24602             ret = SetValidity(
24603                 (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT]
24604                                .data.buffer.data,
24605                 (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT]
24606                                .data.buffer.data, cert->daysValid);
24607         }
24608     }
24609     if (ret >= 0) {
24610         /* Encode public key into buffer. */
24611         ret = EncodePublicKey(cert->keyType,
24612             (byte*)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
24613                            .data.buffer.data,
24614             dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
24615                            .data.buffer.length,
24616             rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
24617     }
24618     if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) {
24619         /* Encode extensions into buffer. */
24620         ret = EncodeExtensions(cert,
24621                 (byte*)dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.data,
24622                 dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.length, 0);
24623     }
24624     if (ret >= 0) {
24625         /* Store encoded certifcate body size. */
24626         cert->bodySz = sz;
24627         /* Return the encoding size. */
24628         ret = sz;
24629     }
24630 
24631     FREE_ASNSETDATA(dataASN, cert->heap);
24632     return ret;
24633 #endif
24634 }
24635 
24636 
24637 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
24638 int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
24639                    void* key, WC_RNG* rng)
24640 {
24641     RsaKey*            rsaKey = NULL;
24642     DsaKey*            dsaKey = NULL;
24643     ecc_key*           eccKey = NULL;
24644     ed25519_key*       ed25519Key = NULL;
24645     ed448_key*         ed448Key = NULL;
24646     falcon_key*        falconKey = NULL;
24647 
24648     if (keyType == RSA_TYPE)
24649         rsaKey = (RsaKey*)key;
24650     else if (keyType == DSA_TYPE)
24651         dsaKey = (DsaKey*)key;
24652     else if (keyType == ECC_TYPE)
24653         eccKey = (ecc_key*)key;
24654     else if (keyType == ED25519_TYPE)
24655         ed25519Key = (ed25519_key*)key;
24656     else if (keyType == ED448_TYPE)
24657         ed448Key = (ed448_key*)key;
24658     else if (keyType == FALCON_LEVEL1_TYPE)
24659         falconKey = (falcon_key*)key;
24660     else if (keyType == FALCON_LEVEL5_TYPE)
24661         falconKey = (falcon_key*)key;
24662 
24663     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
24664                        ed25519Key, ed448Key, falconKey);
24665 }
24666 
24667 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
24668 int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
24669              ecc_key* eccKey, WC_RNG* rng)
24670 {
24671     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
24672                        NULL, NULL);
24673 }
24674 
24675 #ifdef WOLFSSL_CERT_REQ
24676 
24677 #ifndef WOLFSSL_ASN_TEMPLATE
24678 static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
24679                         int extSz)
24680 {
24681     int sz      = 0; /* overall size */
24682     int cpSz    = 0; /* Challenge Password section size */
24683     int cpSeqSz = 0;
24684     int cpSetSz = 0;
24685     int cpStrSz = 0;
24686     int pwSz    = 0;
24687     int erSz    = 0; /* Extension Request section size */
24688     int erSeqSz = 0;
24689     int erSetSz = 0;
24690     byte cpSeq[MAX_SEQ_SZ];
24691     byte cpSet[MAX_SET_SZ];
24692     byte cpStr[MAX_PRSTR_SZ];
24693     byte erSeq[MAX_SEQ_SZ];
24694     byte erSet[MAX_SET_SZ];
24695 
24696     output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
24697     sz++;
24698 
24699     if (pw && pw[0]) {
24700         int cpOidSz = SetObjectId(sizeof(attrChallengePasswordOid), NULL);
24701         cpOidSz += sizeof(attrChallengePasswordOid);
24702         pwSz = (int)XSTRLEN(pw);
24703         if (pwPrintableString) {
24704             cpStrSz = SetPrintableString(pwSz, cpStr);
24705         } else {
24706             cpStrSz = SetUTF8String(pwSz, cpStr);
24707         }
24708         cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
24709         /* +2 for tag and length parts of the TLV triplet */
24710         cpSeqSz = SetSequence(cpOidSz + cpSetSz +
24711                 cpStrSz + pwSz, cpSeq);
24712         cpSz = cpSeqSz + cpOidSz + cpSetSz +
24713                 cpStrSz + pwSz;
24714     }
24715 
24716     if (extSz) {
24717         int erOidSz = SetObjectId(sizeof(attrExtensionRequestOid), NULL);
24718         erOidSz += sizeof(attrExtensionRequestOid);
24719         erSetSz = SetSet(extSz, erSet);
24720         erSeqSz = SetSequence(erSetSz + erOidSz + extSz, erSeq);
24721         erSz = extSz + erSetSz + erSeqSz + erOidSz;
24722     }
24723 
24724     /* Put the pieces together. */
24725     sz += SetLength(cpSz + erSz, &output[sz]);
24726 
24727     if (cpSz) {
24728         XMEMCPY(&output[sz], cpSeq, cpSeqSz);
24729         sz += cpSeqSz;
24730         sz += SetObjectId(sizeof(attrChallengePasswordOid), output + sz);
24731         XMEMCPY(&output[sz], attrChallengePasswordOid,
24732                 sizeof(attrChallengePasswordOid));
24733         sz += sizeof(attrChallengePasswordOid);
24734         XMEMCPY(&output[sz], cpSet, cpSetSz);
24735         sz += cpSetSz;
24736         XMEMCPY(&output[sz], cpStr, cpStrSz);
24737         sz += cpStrSz;
24738         XMEMCPY(&output[sz], pw, pwSz);
24739         sz += pwSz;
24740     }
24741 
24742     if (erSz) {
24743         XMEMCPY(&output[sz], erSeq, erSeqSz);
24744         sz += erSeqSz;
24745         sz += SetObjectId(sizeof(attrExtensionRequestOid), output + sz);
24746         XMEMCPY(&output[sz], attrExtensionRequestOid,
24747                 sizeof(attrExtensionRequestOid));
24748         sz += sizeof(attrExtensionRequestOid);
24749         XMEMCPY(&output[sz], erSet, erSetSz);
24750         sz += erSetSz;
24751         /* The actual extension data will be tacked onto the output later. */
24752     }
24753 
24754     return sz;
24755 }
24756 
24757 #ifdef WOLFSSL_CUSTOM_OID
24758 /* encode a custom oid and value */
24759 static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
24760     CertOidField* custom)
24761 {
24762     int idx = 0, cust_lenSz, cust_oidSz;
24763 
24764     if (cert == NULL || output == NULL || custom == NULL) {
24765         return BAD_FUNC_ARG;
24766     }
24767     if (custom->oid == NULL || custom->oidSz <= 0) {
24768         return 0; /* none set */
24769     }
24770 
24771     /* Octet String header */
24772     cust_lenSz = SetOctetString(custom->valSz, NULL);
24773     cust_oidSz = SetObjectId(custom->oidSz, NULL);
24774 
24775     /* check for output buffer room */
24776     if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) >
24777                                                                         outSz) {
24778         return BUFFER_E;
24779     }
24780 
24781     /* put sequence with total */
24782     idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz,
24783                       output);
24784 
24785     /* put oid header */
24786     idx += SetObjectId(custom->oidSz, output+idx);
24787     XMEMCPY(output+idx, custom->oid, custom->oidSz);
24788     idx += custom->oidSz;
24789 
24790     /* put value */
24791     idx += SetOctetString(custom->valSz, output+idx);
24792     XMEMCPY(output+idx, custom->val, custom->valSz);
24793     idx += custom->valSz;
24794 
24795     return idx;
24796 }
24797 #endif /* WOLFSSL_CUSTOM_OID */
24798 
24799 
24800 /* encode info from cert into DER encoded format */
24801 static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
24802                          DsaKey* dsaKey, ecc_key* eccKey,
24803                          ed25519_key* ed25519Key, ed448_key* ed448Key,
24804                          falcon_key* falconKey)
24805 {
24806     int ret;
24807 
24808     (void)eccKey;
24809     (void)ed25519Key;
24810     (void)ed448Key;
24811     (void)falconKey;
24812 
24813     if (cert == NULL || der == NULL)
24814         return BAD_FUNC_ARG;
24815 
24816     if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
24817         dsaKey == NULL && ed448Key == NULL && falconKey == NULL) {
24818         return PUBLIC_KEY_E;
24819     }
24820 
24821     /* init */
24822     XMEMSET(der, 0, sizeof(DerCert));
24823 
24824     /* version */
24825     der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
24826 
24827     /* subject name */
24828 #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
24829     if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
24830         /* Use the raw subject */
24831         int idx;
24832 
24833         der->subjectSz = min(sizeof(der->subject),
24834                 (word32)XSTRLEN((const char*)cert->sbjRaw));
24835         /* header */
24836         idx = SetSequence(der->subjectSz, der->subject);
24837         if (der->subjectSz + idx > (int)sizeof(der->subject)) {
24838             return SUBJECT_E;
24839         }
24840 
24841         XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
24842                 der->subjectSz);
24843         der->subjectSz += idx;
24844     }
24845     else
24846 #endif
24847     {
24848         der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
24849                 &cert->subject, cert->heap);
24850     }
24851     if (der->subjectSz <= 0)
24852         return SUBJECT_E;
24853 
24854     /* public key */
24855 #ifndef NO_RSA
24856     if (cert->keyType == RSA_KEY) {
24857         if (rsaKey == NULL)
24858             return PUBLIC_KEY_E;
24859         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
24860                                            sizeof(der->publicKey), 1);
24861     }
24862 #endif
24863 
24864 #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
24865     if (cert->keyType == DSA_KEY) {
24866         if (dsaKey == NULL)
24867             return PUBLIC_KEY_E;
24868         der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
24869                                            sizeof(der->publicKey), 1);
24870     }
24871 #endif
24872 
24873 #ifdef HAVE_ECC
24874     if (cert->keyType == ECC_KEY) {
24875         if (eccKey == NULL)
24876             return PUBLIC_KEY_E;
24877         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
24878                                            sizeof(der->publicKey), 1);
24879     }
24880 #endif
24881 
24882 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
24883     if (cert->keyType == ED25519_KEY) {
24884         if (ed25519Key == NULL)
24885             return PUBLIC_KEY_E;
24886         der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
24887             (word32)sizeof(der->publicKey), 1);
24888     }
24889 #endif
24890 
24891 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
24892     if (cert->keyType == ED448_KEY) {
24893         if (ed448Key == NULL)
24894             return PUBLIC_KEY_E;
24895         der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
24896             (word32)sizeof(der->publicKey), 1);
24897     }
24898 #endif
24899 #if defined(HAVE_PQC)
24900     if ((cert->keyType == FALCON_LEVEL1_KEY) ||
24901         (cert->keyType == FALCON_LEVEL5_KEY)) {
24902         if (falconKey == NULL)
24903             return PUBLIC_KEY_E;
24904         der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
24905             der->publicKey, (word32)sizeof(der->publicKey), 1);
24906     }
24907 #endif
24908 
24909     if (der->publicKeySz <= 0)
24910         return PUBLIC_KEY_E;
24911 
24912     /* set the extensions */
24913     der->extensionsSz = 0;
24914 
24915     /* CA */
24916     if (cert->isCA) {
24917         der->caSz = SetCa(der->ca, sizeof(der->ca));
24918         if (der->caSz <= 0)
24919             return CA_TRUE_E;
24920 
24921         der->extensionsSz += der->caSz;
24922     }
24923     else
24924         der->caSz = 0;
24925 
24926 #ifdef WOLFSSL_ALT_NAMES
24927     /* Alternative Name */
24928     if (cert->altNamesSz) {
24929         der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
24930                                       cert->altNames, cert->altNamesSz);
24931         if (der->altNamesSz <= 0)
24932             return ALT_NAME_E;
24933 
24934         der->extensionsSz += der->altNamesSz;
24935     }
24936     else
24937         der->altNamesSz = 0;
24938 #endif
24939 
24940 #ifdef WOLFSSL_CERT_EXT
24941     /* SKID */
24942     if (cert->skidSz) {
24943         /* check the provided SKID size */
24944         if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
24945             return SKID_E;
24946 
24947         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
24948                               cert->skid, cert->skidSz);
24949         if (der->skidSz <= 0)
24950             return SKID_E;
24951 
24952         der->extensionsSz += der->skidSz;
24953     }
24954     else
24955         der->skidSz = 0;
24956 
24957     /* Key Usage */
24958     if (cert->keyUsage != 0) {
24959         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
24960                                       cert->keyUsage);
24961         if (der->keyUsageSz <= 0)
24962             return KEYUSAGE_E;
24963 
24964         der->extensionsSz += der->keyUsageSz;
24965     }
24966     else
24967         der->keyUsageSz = 0;
24968 
24969     /* Extended Key Usage */
24970     if (cert->extKeyUsage != 0) {
24971         der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
24972                                 sizeof(der->extKeyUsage), cert->extKeyUsage);
24973         if (der->extKeyUsageSz <= 0)
24974             return EXTKEYUSAGE_E;
24975 
24976         der->extensionsSz += der->extKeyUsageSz;
24977     }
24978     else
24979         der->extKeyUsageSz = 0;
24980 
24981 #endif /* WOLFSSL_CERT_EXT */
24982 
24983 #ifdef WOLFSSL_CUSTOM_OID
24984     /* encode a custom oid and value */
24985     /* zero returns, means none set */
24986     ret = SetCustomObjectId(cert, der->extCustom,
24987         sizeof(der->extCustom), &cert->extCustom);
24988     if (ret < 0)
24989         return ret;
24990     der->extCustomSz = ret;
24991     der->extensionsSz += der->extCustomSz;
24992 #endif
24993 
24994     /* put extensions */
24995     if (der->extensionsSz > 0) {
24996         /* put the start of sequence (ID, Size) */
24997         der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
24998         if (der->extensionsSz <= 0)
24999             return EXTENSIONS_E;
25000 
25001         /* put CA */
25002         if (der->caSz) {
25003             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25004                                 &der->extensionsSz,
25005                                 der->ca, der->caSz);
25006             if (ret <= 0)
25007                 return EXTENSIONS_E;
25008         }
25009 
25010 #ifdef WOLFSSL_ALT_NAMES
25011         /* put Alternative Names */
25012         if (der->altNamesSz) {
25013             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25014                                 &der->extensionsSz,
25015                                 der->altNames, der->altNamesSz);
25016             if (ret <= 0)
25017                 return EXTENSIONS_E;
25018         }
25019 #endif
25020 
25021 #ifdef WOLFSSL_CERT_EXT
25022         /* put SKID */
25023         if (der->skidSz) {
25024             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25025                                 &der->extensionsSz,
25026                                 der->skid, der->skidSz);
25027             if (ret <= 0)
25028                 return EXTENSIONS_E;
25029         }
25030 
25031         /* put AKID */
25032         if (der->akidSz) {
25033             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25034                                 &der->extensionsSz,
25035                                 der->akid, der->akidSz);
25036             if (ret <= 0)
25037                 return EXTENSIONS_E;
25038         }
25039 
25040         /* put KeyUsage */
25041         if (der->keyUsageSz) {
25042             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25043                                 &der->extensionsSz,
25044                                 der->keyUsage, der->keyUsageSz);
25045             if (ret <= 0)
25046                 return EXTENSIONS_E;
25047         }
25048 
25049         /* put ExtendedKeyUsage */
25050         if (der->extKeyUsageSz) {
25051             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25052                                 &der->extensionsSz,
25053                                 der->extKeyUsage, der->extKeyUsageSz);
25054             if (ret <= 0)
25055                 return EXTENSIONS_E;
25056         }
25057 
25058     #ifdef WOLFSSL_CUSTOM_OID
25059         if (der->extCustomSz) {
25060             ret = SetExtensions(der->extensions, sizeof(der->extensions),
25061                                 &der->extensionsSz,
25062                                 der->extCustom, der->extCustomSz);
25063             if (ret <= 0)
25064                 return EXTENSIONS_E;
25065         }
25066     #endif
25067 #endif /* WOLFSSL_CERT_EXT */
25068     }
25069 
25070     der->attribSz = SetReqAttrib(der->attrib, cert->challengePw,
25071                                  cert->challengePwPrintableString,
25072                                  der->extensionsSz);
25073     if (der->attribSz <= 0)
25074         return REQ_ATTRIBUTE_E;
25075 
25076     der->total = der->versionSz + der->subjectSz + der->publicKeySz +
25077         der->extensionsSz + der->attribSz;
25078 
25079     return 0;
25080 }
25081 
25082 
25083 /* write DER encoded cert req to buffer, size already checked */
25084 static int WriteCertReqBody(DerCert* der, byte* buf)
25085 {
25086     int idx;
25087 
25088     /* signed part header */
25089     idx = SetSequence(der->total, buf);
25090     /* version */
25091     if (buf)
25092         XMEMCPY(buf + idx, der->version, der->versionSz);
25093     idx += der->versionSz;
25094     /* subject */
25095     if (buf)
25096         XMEMCPY(buf + idx, der->subject, der->subjectSz);
25097     idx += der->subjectSz;
25098     /* public key */
25099     if (buf)
25100         XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
25101     idx += der->publicKeySz;
25102     /* attributes */
25103     if (buf)
25104         XMEMCPY(buf + idx, der->attrib, der->attribSz);
25105     idx += der->attribSz;
25106     /* extensions */
25107     if (der->extensionsSz) {
25108         if (buf)
25109             XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
25110                                                (int)sizeof(der->extensions)));
25111         idx += der->extensionsSz;
25112     }
25113 
25114     return idx;
25115 }
25116 #endif
25117 
25118 #ifdef WOLFSSL_ASN_TEMPLATE
25119 /* ASN.1 template for Certificate Request body.
25120  * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
25121  */
25122 static const ASNItem certReqBodyASN[] = {
25123 /* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
25124                                              /* version */
25125 /* VER             */     { 1, ASN_INTEGER, 0, 0, 0 },
25126                                              /* subject */
25127 /* SUBJ_SEQ        */     { 1, ASN_SEQUENCE, 1, 0, 0 },
25128                                              /* subjectPKInfo */
25129 /* SPUBKEYINFO_SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
25130                                              /*  attributes*/
25131 /* ATTRS           */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
25132                                                  /* Challenge Password Attribute */
25133 /* ATTRS_CPW_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 1 },
25134 /* ATTRS_CPW_OID   */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
25135 /* ATTRS_CPW_SET   */             { 3, ASN_SET, 1, 1, 0 },
25136 /* ATTRS_CPW_PS    */                 { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
25137 /* ATTRS_CPW_UTF   */                 { 4, ASN_UTF8STRING, 0, 0, 0 },
25138                                                  /* Extensions Attribute */
25139 /* EXT_SEQ         */         { 2, ASN_SEQUENCE, 1, 1, 1 },
25140 /* EXT_OID         */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
25141 /* EXT_SET         */             { 3, ASN_SET, 1, 1, 0 },
25142 /* EXT_BODY        */                 { 4, ASN_SEQUENCE, 1, 0, 0 },
25143 };
25144 enum {
25145     CERTREQBODYASN_IDX_SEQ = 0,
25146     CERTREQBODYASN_IDX_VER,
25147     CERTREQBODYASN_IDX_SUBJ_SEQ,
25148     CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ,
25149     CERTREQBODYASN_IDX_ATTRS,
25150     CERTREQBODYASN_IDX_ATTRS_CPW_SEQ,
25151     CERTREQBODYASN_IDX_ATTRS_CPW_OID,
25152     CERTREQBODYASN_IDX_ATTRS_CPW_SET,
25153     CERTREQBODYASN_IDX_ATTRS_CPW_PS,
25154     CERTREQBODYASN_IDX_ATTRS_CPW_UTF,
25155     CERTREQBODYASN_IDX_EXT_SEQ,
25156     CERTREQBODYASN_IDX_EXT_OID,
25157     CERTREQBODYASN_IDX_EXT_SET,
25158     CERTREQBODYASN_IDX_EXT_BODY,
25159 };
25160 
25161 /* Number of items in ASN.1 template for Certificate Request body. */
25162 #define certReqBodyASN_Length (sizeof(certReqBodyASN) / sizeof(ASNItem))
25163 #endif
25164 
25165 static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
25166                    RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
25167                    ed25519_key* ed25519Key, ed448_key* ed448Key,
25168                    falcon_key* falconKey)
25169 {
25170 #ifndef WOLFSSL_ASN_TEMPLATE
25171     int ret;
25172 #ifdef WOLFSSL_SMALL_STACK
25173     DerCert* der;
25174 #else
25175     DerCert der[1];
25176 #endif
25177 
25178     if (eccKey)
25179         cert->keyType = ECC_KEY;
25180     else if (rsaKey)
25181         cert->keyType = RSA_KEY;
25182     else if (dsaKey)
25183         cert->keyType = DSA_KEY;
25184     else if (ed25519Key)
25185         cert->keyType = ED25519_KEY;
25186     else if (ed448Key)
25187         cert->keyType = ED448_KEY;
25188 #ifdef HAVE_PQC
25189     else if ((falconKey != NULL) && (falconKey->level == 1))
25190         cert->keyType = FALCON_LEVEL1_KEY;
25191     else if ((falconKey != NULL) && (falconKey->level == 5))
25192         cert->keyType = FALCON_LEVEL5_KEY;
25193 #endif
25194     else
25195         return BAD_FUNC_ARG;
25196 
25197 #ifdef WOLFSSL_SMALL_STACK
25198     der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
25199                                                     DYNAMIC_TYPE_TMP_BUFFER);
25200     if (der == NULL)
25201         return MEMORY_E;
25202 #endif
25203 
25204     ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
25205                         falconKey);
25206 
25207     if (ret == 0) {
25208         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
25209             ret = BUFFER_E;
25210         else
25211             ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
25212     }
25213 
25214 #ifdef WOLFSSL_SMALL_STACK
25215     XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25216 #endif
25217 
25218     return ret;
25219 #else
25220     DECL_ASNSETDATA(dataASN, certReqBodyASN_Length);
25221     word32 publicKeySz, subjectSz, extSz;
25222     int sz;
25223     int ret = 0;
25224 #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
25225     word32 sbjRawSz;
25226 #endif
25227 
25228     (void)falconKey; /* Unused without OQS */
25229     CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap);
25230 
25231     if (ret == 0) {
25232         /* Set key type into certificate object based on key passed in. */
25233         if (rsaKey != NULL) {
25234             cert->keyType = RSA_KEY;
25235         }
25236         else if (eccKey != NULL) {
25237             cert->keyType = ECC_KEY;
25238         }
25239         else if (dsaKey != NULL) {
25240             cert->keyType = DSA_KEY;
25241         }
25242         else if (ed25519Key != NULL) {
25243             cert->keyType = ED25519_KEY;
25244         }
25245         else if (ed448Key != NULL) {
25246             cert->keyType = ED448_KEY;
25247         }
25248         else if (falconKey != NULL) {
25249         #ifdef HAVE_PQC
25250             if (falconKey->level == 1)
25251                 cert->keyType = FALCON_LEVEL1_KEY;
25252             else if (falconKey->level == 5)
25253                 cert->keyType = FALCON_LEVEL5_KEY;
25254         #endif
25255         }
25256         else {
25257             ret = BAD_FUNC_ARG;
25258         }
25259     }
25260     if (ret == 0) {
25261         /* Determine subject name size. */
25262     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
25263         sbjRawSz = (word32)XSTRLEN((const char*)cert->sbjRaw);
25264         if (sbjRawSz > 0) {
25265             subjectSz = min(sizeof(cert->sbjRaw), sbjRawSz);
25266         }
25267         else
25268     #endif
25269         {
25270             subjectSz = SetNameEx(NULL, ASN_NAME_MAX, &cert->subject, cert->heap);
25271             ret = subjectSz;
25272         }
25273     }
25274     if (ret >= 0) {
25275         /* Determine encode public key size. */
25276          ret = publicKeySz = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
25277              eccKey, ed25519Key, ed448Key, dsaKey);
25278     }
25279     if (ret >= 0) {
25280         /* Determine encode extensions size. */
25281         ret = extSz = EncodeExtensions(cert, NULL, 0, 1);
25282     }
25283     if (ret >= 0) {
25284         /* Set version. */
25285         SetASN_Int8Bit(&dataASN[CERTREQBODYASN_IDX_VER], cert->version);
25286     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
25287         if (sbjRawSz > 0) {
25288             /* Put in encoded subject name. */
25289             SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], cert->sbjRaw,
25290                     subjectSz);
25291         }
25292         else
25293     #endif
25294         {
25295             /* Leave space for subject name. */
25296             SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], NULL,
25297                     subjectSz);
25298         }
25299         /* Leave space for public key. */
25300         SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ],
25301                 NULL, publicKeySz);
25302         if (cert->challengePw[0] != '\0') {
25303             /* Add challenge password attribute. */
25304             /* Set challenge password OID. */
25305             SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_OID], attrChallengePasswordOid,
25306                 sizeof(attrChallengePasswordOid));
25307             /* Enable the ASN template item with the appropriate tag. */
25308             if (cert->challengePwPrintableString) {
25309                 /* PRINTABLE_STRING - set buffer */
25310                 SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS],
25311                         (byte*)cert->challengePw,
25312                         (word32)XSTRLEN(cert->challengePw));
25313                 /* UTF8STRING - don't encode */
25314                 dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF].noOut = 1;
25315             }
25316             else {
25317                 /* PRINTABLE_STRING - don't encode */
25318                 dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS].noOut = 1;
25319                 /* UTF8STRING - set buffer */
25320                 SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF],
25321                         (byte*)cert->challengePw,
25322                         (word32)XSTRLEN(cert->challengePw));
25323             }
25324         }
25325         else {
25326             /* Leave out challenge password attribute items. */
25327             SetASNItem_NoOutNode(dataASN, certReqBodyASN,
25328                     CERTREQBODYASN_IDX_ATTRS_CPW_SEQ, certReqBodyASN_Length);
25329         }
25330         if (extSz > 0) {
25331             /* Set extension attribute OID. */
25332             SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_OID], attrExtensionRequestOid,
25333                 sizeof(attrExtensionRequestOid));
25334             /* Leave space for data. */
25335             SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_BODY], NULL, extSz);
25336         }
25337         else {
25338             /* Leave out extension attribute items. */
25339             SetASNItem_NoOutNode(dataASN, certReqBodyASN,
25340                     CERTREQBODYASN_IDX_EXT_SEQ, certReqBodyASN_Length);
25341         }
25342 
25343         /* Calculate size of encoded certificate request body. */
25344         ret = SizeASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length,
25345                             &sz);
25346     }
25347     /* Check buffer is big enough for encoded data. */
25348     if ((ret == 0) && (sz > (int)derSz)) {
25349         ret = BUFFER_E;
25350     }
25351     if (ret == 0) {
25352         /* Encode certificate request body into buffer. */
25353         SetASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length, derBuffer);
25354 
25355         /* Put in generated data */
25356     #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
25357         if (sbjRawSz == 0)
25358     #endif
25359         {
25360             /* Encode subject name into space in buffer. */
25361             ret = SetNameEx(
25362                 (byte*)dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.data,
25363                 dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.length,
25364                 &cert->subject, cert->heap);
25365         }
25366     }
25367     if (ret >= 0) {
25368         /* Encode public key into space in buffer. */
25369         ret = EncodePublicKey(cert->keyType,
25370             (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data,
25371             dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length,
25372             rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
25373     }
25374     if ((ret >= 0) && (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) {
25375         /* Encode extensions into space in buffer. */
25376         ret = EncodeExtensions(cert,
25377                 (byte*)dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.data,
25378                 dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.length, 1);
25379     }
25380     if (ret >= 0) {
25381         /* Store encoded certifcate request body size. */
25382         cert->bodySz = sz;
25383         /* Return the encoding size. */
25384         ret = sz;
25385     }
25386 
25387     FREE_ASNSETDATA(dataASN, cert->heap);
25388     return ret;
25389 #endif /* WOLFSSL_ASN_TEMPLATE */
25390 }
25391 
25392 int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
25393                       void* key)
25394 {
25395     RsaKey*      rsaKey = NULL;
25396     DsaKey*      dsaKey = NULL;
25397     ecc_key*     eccKey = NULL;
25398     ed25519_key* ed25519Key = NULL;
25399     ed448_key*   ed448Key = NULL;
25400     falcon_key* falconKey = NULL;
25401 
25402     if (keyType == RSA_TYPE)
25403         rsaKey = (RsaKey*)key;
25404     else if (keyType == DSA_TYPE)
25405         dsaKey = (DsaKey*)key;
25406     else if (keyType == ECC_TYPE)
25407         eccKey = (ecc_key*)key;
25408     else if (keyType == ED25519_TYPE)
25409         ed25519Key = (ed25519_key*)key;
25410     else if (keyType == ED448_TYPE)
25411         ed448Key = (ed448_key*)key;
25412     else if (keyType == FALCON_LEVEL1_TYPE)
25413         falconKey = (falcon_key*)key;
25414     else if (keyType == FALCON_LEVEL5_TYPE)
25415         falconKey = (falcon_key*)key;
25416 
25417     return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
25418                        ed25519Key, ed448Key, falconKey);
25419 }
25420 
25421 int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
25422                    RsaKey* rsaKey, ecc_key* eccKey)
25423 {
25424     return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
25425                        NULL, NULL);
25426 }
25427 #endif /* WOLFSSL_CERT_REQ */
25428 
25429 
25430 static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
25431                     RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
25432                     ed448_key* ed448Key, falcon_key* falconKey, WC_RNG* rng)
25433 {
25434     int sigSz = 0;
25435     void* heap = NULL;
25436     CertSignCtx* certSignCtx;
25437 #ifndef WOLFSSL_ASYNC_CRYPT
25438     CertSignCtx  certSignCtx_lcl;
25439 
25440     certSignCtx = &certSignCtx_lcl;
25441     XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
25442 #else
25443     certSignCtx = NULL;
25444 #endif
25445 
25446     if (requestSz < 0)
25447         return requestSz;
25448 
25449     /* locate ctx */
25450     if (rsaKey) {
25451     #ifndef NO_RSA
25452     #ifdef WOLFSSL_ASYNC_CRYPT
25453         certSignCtx = &rsaKey->certSignCtx;
25454     #endif
25455         heap = rsaKey->heap;
25456     #else
25457         return NOT_COMPILED_IN;
25458     #endif /* NO_RSA */
25459     }
25460     else if (eccKey) {
25461     #ifdef HAVE_ECC
25462     #ifdef WOLFSSL_ASYNC_CRYPT
25463         certSignCtx = &eccKey->certSignCtx;
25464     #endif
25465         heap = eccKey->heap;
25466     #else
25467         return NOT_COMPILED_IN;
25468     #endif /* HAVE_ECC */
25469     }
25470 
25471 #ifdef WOLFSSL_ASYNC_CRYPT
25472     if (certSignCtx == NULL) {
25473         return BAD_FUNC_ARG;
25474     }
25475 #endif
25476 
25477     if (certSignCtx->sig == NULL) {
25478         certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
25479             DYNAMIC_TYPE_TMP_BUFFER);
25480         if (certSignCtx->sig == NULL)
25481             return MEMORY_E;
25482     }
25483 
25484     sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig,
25485         MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
25486         falconKey, rng, sType, heap);
25487 #ifdef WOLFSSL_ASYNC_CRYPT
25488     if (sigSz == WC_PENDING_E) {
25489         /* Not free'ing certSignCtx->sig here because it could still be in use
25490          * with async operations. */
25491         return sigSz;
25492     }
25493 #endif
25494 
25495     if (sigSz >= 0) {
25496         if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
25497             sigSz = BUFFER_E;
25498         else
25499             sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz,
25500                                  sType);
25501     }
25502 
25503     XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
25504     certSignCtx->sig = NULL;
25505 
25506     return sigSz;
25507 }
25508 
25509 int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
25510                    int keyType, void* key, WC_RNG* rng)
25511 {
25512     RsaKey*            rsaKey = NULL;
25513     ecc_key*           eccKey = NULL;
25514     ed25519_key*       ed25519Key = NULL;
25515     ed448_key*         ed448Key = NULL;
25516     falcon_key*        falconKey = NULL;
25517 
25518     if (keyType == RSA_TYPE)
25519         rsaKey = (RsaKey*)key;
25520     else if (keyType == ECC_TYPE)
25521         eccKey = (ecc_key*)key;
25522     else if (keyType == ED25519_TYPE)
25523         ed25519Key = (ed25519_key*)key;
25524     else if (keyType == ED448_TYPE)
25525         ed448Key = (ed448_key*)key;
25526     else if (keyType == FALCON_LEVEL1_TYPE)
25527         falconKey = (falcon_key*)key;
25528     else if (keyType == FALCON_LEVEL5_TYPE)
25529         falconKey = (falcon_key*)key;
25530 
25531 
25532     return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
25533                     ed448Key, falconKey, rng);
25534 }
25535 
25536 int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
25537                 RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
25538 {
25539     return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
25540                     NULL, rng);
25541 }
25542 
25543 int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
25544                     RsaKey* key, WC_RNG* rng)
25545 {
25546     int ret;
25547 
25548     ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng);
25549     if (ret < 0)
25550         return ret;
25551 
25552     return wc_SignCert(cert->bodySz, cert->sigType,
25553                        buf, buffSz, key, NULL, rng);
25554 }
25555 
25556 
25557 #ifdef WOLFSSL_CERT_EXT
25558 
25559 /* Get raw subject from cert, which may contain OIDs not parsed by Decode.
25560    The raw subject pointer will only be valid while "cert" is valid. */
25561 int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
25562 {
25563     int rc = BAD_FUNC_ARG;
25564     if ((subjectRaw != NULL) && (cert != NULL)) {
25565         *subjectRaw = cert->sbjRaw;
25566         rc = 0;
25567     }
25568     return rc;
25569 }
25570 
25571 /* Set KID from public key */
25572 static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
25573                                  ed25519_key* ed25519Key, ed448_key* ed448Key,
25574                                  falcon_key* falconKey, int kid_type)
25575 {
25576     byte *buf;
25577     int   bufferSz, ret;
25578 
25579     if (cert == NULL ||
25580         (rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
25581          ed448Key == NULL && falconKey == NULL) ||
25582         (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
25583         return BAD_FUNC_ARG;
25584 
25585     buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
25586                                                        DYNAMIC_TYPE_TMP_BUFFER);
25587     if (buf == NULL)
25588         return MEMORY_E;
25589 
25590     /* Public Key */
25591     bufferSz = -1;
25592 #ifndef NO_RSA
25593     /* RSA public key */
25594     if (rsakey != NULL)
25595         bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0);
25596 #endif
25597 #ifdef HAVE_ECC
25598     /* ECC public key */
25599     if (eckey != NULL)
25600         bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0);
25601 #endif
25602 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
25603     /* ED25519 public key */
25604     if (ed25519Key != NULL) {
25605         bufferSz = wc_Ed25519PublicKeyToDer(ed25519Key, buf, MAX_PUBLIC_KEY_SZ, 0);
25606     }
25607 #endif
25608 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
25609     /* ED448 public key */
25610     if (ed448Key != NULL) {
25611         bufferSz = wc_Ed448PublicKeyToDer(ed448Key, buf, MAX_PUBLIC_KEY_SZ, 0);
25612     }
25613 #endif
25614 #if defined(HAVE_PQC)
25615     if (falconKey != NULL) {
25616         bufferSz = wc_Falcon_PublicKeyToDer(falconKey, buf, MAX_PUBLIC_KEY_SZ,
25617                                             0);
25618     }
25619 #endif
25620 
25621     if (bufferSz <= 0) {
25622         XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25623         return PUBLIC_KEY_E;
25624     }
25625 
25626     /* Compute SKID by hashing public key */
25627     if (kid_type == SKID_TYPE) {
25628         ret = CalcHashId(buf, bufferSz, cert->skid);
25629         cert->skidSz = KEYID_SIZE;
25630     }
25631     else if (kid_type == AKID_TYPE) {
25632         ret = CalcHashId(buf, bufferSz, cert->akid);
25633         cert->akidSz = KEYID_SIZE;
25634     }
25635     else
25636         ret = BAD_FUNC_ARG;
25637 
25638     XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25639     return ret;
25640 }
25641 
25642 int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
25643 {
25644     RsaKey*            rsaKey = NULL;
25645     ecc_key*           eccKey = NULL;
25646     ed25519_key*       ed25519Key = NULL;
25647     ed448_key*         ed448Key = NULL;
25648     falcon_key*        falconKey = NULL;
25649 
25650     if (keyType == RSA_TYPE)
25651         rsaKey = (RsaKey*)key;
25652     else if (keyType == ECC_TYPE)
25653         eccKey = (ecc_key*)key;
25654     else if (keyType == ED25519_TYPE)
25655         ed25519Key = (ed25519_key*)key;
25656     else if (keyType == ED448_TYPE)
25657         ed448Key = (ed448_key*)key;
25658     else if (keyType == FALCON_LEVEL1_TYPE)
25659         falconKey = (falcon_key*)key;
25660     else if (keyType == FALCON_LEVEL5_TYPE)
25661         falconKey = (falcon_key*)key;
25662 
25663     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
25664                                  falconKey, SKID_TYPE);
25665 }
25666 
25667 /* Set SKID from RSA or ECC public key */
25668 int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
25669 {
25670     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL,
25671                                  SKID_TYPE);
25672 }
25673 
25674 int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
25675 {
25676     RsaKey*            rsaKey = NULL;
25677     ecc_key*           eccKey = NULL;
25678     ed25519_key*       ed25519Key = NULL;
25679     ed448_key*         ed448Key = NULL;
25680     falcon_key*        falconKey = NULL;
25681 
25682     if (keyType == RSA_TYPE)
25683         rsaKey = (RsaKey*)key;
25684     else if (keyType == ECC_TYPE)
25685         eccKey = (ecc_key*)key;
25686     else if (keyType == ED25519_TYPE)
25687         ed25519Key = (ed25519_key*)key;
25688     else if (keyType == ED448_TYPE)
25689         ed448Key = (ed448_key*)key;
25690     else if (keyType == FALCON_LEVEL1_TYPE)
25691         falconKey = (falcon_key*)key;
25692 
25693     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
25694                                  falconKey, AKID_TYPE);
25695 }
25696 
25697 /* Set SKID from RSA or ECC public key */
25698 int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
25699 {
25700     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL,
25701                                  AKID_TYPE);
25702 }
25703 
25704 
25705 #if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
25706 
25707 /* Set SKID from public key file in PEM */
25708 int wc_SetSubjectKeyId(Cert *cert, const char* file)
25709 {
25710     int     ret, derSz;
25711     byte*   der;
25712     word32  idx;
25713     RsaKey  *rsakey = NULL;
25714     ecc_key *eckey = NULL;
25715 
25716     if (cert == NULL || file == NULL)
25717         return BAD_FUNC_ARG;
25718 
25719     der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
25720     if (der == NULL) {
25721         WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
25722         return MEMORY_E;
25723     }
25724     derSz = MAX_PUBLIC_KEY_SZ;
25725 
25726     XMEMSET(der, 0, derSz);
25727     derSz = wc_PemPubKeyToDer(file, der, derSz);
25728     if (derSz <= 0) {
25729         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25730         return derSz;
25731     }
25732 
25733     /* Load PubKey in internal structure */
25734 #ifndef NO_RSA
25735     rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
25736     if (rsakey == NULL) {
25737         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25738         return MEMORY_E;
25739     }
25740 
25741     if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
25742         WOLFSSL_MSG("wc_InitRsaKey failure");
25743         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
25744         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25745         return MEMORY_E;
25746     }
25747 
25748     idx = 0;
25749     ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
25750     if (ret != 0)
25751 #endif
25752     {
25753 #ifndef NO_RSA
25754         WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
25755         wc_FreeRsaKey(rsakey);
25756         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
25757         rsakey = NULL;
25758 #endif
25759 #ifdef HAVE_ECC
25760         /* Check to load ecc public key */
25761         eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
25762                                                               DYNAMIC_TYPE_ECC);
25763         if (eckey == NULL) {
25764             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25765             return MEMORY_E;
25766         }
25767 
25768         if (wc_ecc_init(eckey) != 0) {
25769             WOLFSSL_MSG("wc_ecc_init failure");
25770             wc_ecc_free(eckey);
25771             XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
25772             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25773             return MEMORY_E;
25774         }
25775 
25776         idx = 0;
25777         ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
25778         if (ret != 0) {
25779             WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
25780             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25781             wc_ecc_free(eckey);
25782             XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
25783             return PUBLIC_KEY_E;
25784         }
25785 #else
25786         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25787         return PUBLIC_KEY_E;
25788 #endif /* HAVE_ECC */
25789     }
25790 
25791     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
25792 
25793     ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
25794 
25795 #ifndef NO_RSA
25796     wc_FreeRsaKey(rsakey);
25797     XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
25798 #endif
25799 #ifdef HAVE_ECC
25800     wc_ecc_free(eckey);
25801     XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
25802 #endif
25803     return ret;
25804 }
25805 
25806 #endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
25807 
25808 static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
25809 {
25810     int ret = 0;
25811 
25812     /* Subject Key Id not found !! */
25813     if (decoded->extSubjKeyIdSet == 0) {
25814         ret = ASN_NO_SKID;
25815     }
25816 
25817     /* SKID invalid size */
25818     else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
25819         ret = MEMORY_E;
25820     }
25821 
25822     else {
25823         /* Put the SKID of CA to AKID of certificate */
25824         XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
25825         cert->akidSz = KEYID_SIZE;
25826     }
25827 
25828     return ret;
25829 }
25830 
25831 /* Set AKID from certificate contains in buffer (DER encoded) */
25832 int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
25833 {
25834     int ret = 0;
25835 
25836     if (cert == NULL) {
25837         ret = BAD_FUNC_ARG;
25838     }
25839     else {
25840         /* Check if decodedCert is cached */
25841         if (cert->der != der) {
25842             /* Allocate cache for the decoded cert */
25843             ret = wc_SetCert_LoadDer(cert, der, derSz);
25844         }
25845 
25846         if (ret >= 0) {
25847             ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);
25848 #ifndef WOLFSSL_CERT_GEN_CACHE
25849             wc_SetCert_Free(cert);
25850 #endif
25851         }
25852     }
25853 
25854     return ret;
25855 }
25856 
25857 
25858 #ifndef NO_FILESYSTEM
25859 
25860 /* Set AKID from certificate file in PEM */
25861 int wc_SetAuthKeyId(Cert *cert, const char* file)
25862 {
25863     int         ret;
25864     DerBuffer*  der = NULL;
25865 
25866     if (cert == NULL || file == NULL)
25867         return BAD_FUNC_ARG;
25868 
25869     ret = wc_PemCertToDer_ex(file, &der);
25870     if (ret == 0)
25871     {
25872         ret = wc_SetAuthKeyIdFromCert(cert, der->buffer, der->length);
25873         FreeDer(&der);
25874     }
25875 
25876     return ret;
25877 }
25878 
25879 #endif /* !NO_FILESYSTEM */
25880 
25881 /* Set KeyUsage from human readable string */
25882 int wc_SetKeyUsage(Cert *cert, const char *value)
25883 {
25884     int ret = 0;
25885     char *token, *str, *ptr;
25886     word32 len;
25887 
25888     if (cert == NULL || value == NULL)
25889         return BAD_FUNC_ARG;
25890 
25891     cert->keyUsage = 0;
25892 
25893     /* duplicate string (including terminator) */
25894     len = (word32)XSTRLEN(value);
25895     str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25896     if (str == NULL)
25897         return MEMORY_E;
25898     XMEMCPY(str, value, len+1);
25899 
25900     /* parse value, and set corresponding Key Usage value */
25901     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
25902         XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25903         return KEYUSAGE_E;
25904     }
25905     while (token != NULL)
25906     {
25907         len = (word32)XSTRLEN(token);
25908 
25909         if (!XSTRNCASECMP(token, "digitalSignature", len))
25910             cert->keyUsage |= KEYUSE_DIGITAL_SIG;
25911         else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
25912                  !XSTRNCASECMP(token, "contentCommitment", len))
25913             cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
25914         else if (!XSTRNCASECMP(token, "keyEncipherment", len))
25915             cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
25916         else if (!XSTRNCASECMP(token, "dataEncipherment", len))
25917             cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
25918         else if (!XSTRNCASECMP(token, "keyAgreement", len))
25919             cert->keyUsage |= KEYUSE_KEY_AGREE;
25920         else if (!XSTRNCASECMP(token, "keyCertSign", len))
25921             cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
25922         else if (!XSTRNCASECMP(token, "cRLSign", len))
25923             cert->keyUsage |= KEYUSE_CRL_SIGN;
25924         else if (!XSTRNCASECMP(token, "encipherOnly", len))
25925             cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
25926         else if (!XSTRNCASECMP(token, "decipherOnly", len))
25927             cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
25928         else {
25929             ret = KEYUSAGE_E;
25930             break;
25931         }
25932 
25933         token = XSTRTOK(NULL, ",", &ptr);
25934     }
25935 
25936     XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25937     return ret;
25938 }
25939 
25940 /* Set ExtendedKeyUsage from human readable string */
25941 int wc_SetExtKeyUsage(Cert *cert, const char *value)
25942 {
25943     int ret = 0;
25944     char *token, *str, *ptr;
25945     word32 len;
25946 
25947     if (cert == NULL || value == NULL)
25948         return BAD_FUNC_ARG;
25949 
25950     cert->extKeyUsage = 0;
25951 
25952     /* duplicate string (including terminator) */
25953     len = (word32)XSTRLEN(value);
25954     str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25955     if (str == NULL)
25956         return MEMORY_E;
25957     XMEMCPY(str, value, len+1);
25958 
25959     /* parse value, and set corresponding Key Usage value */
25960     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
25961         XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25962         return EXTKEYUSAGE_E;
25963     }
25964 
25965     while (token != NULL)
25966     {
25967         len = (word32)XSTRLEN(token);
25968 
25969         if (!XSTRNCASECMP(token, "any", len))
25970             cert->extKeyUsage |= EXTKEYUSE_ANY;
25971         else if (!XSTRNCASECMP(token, "serverAuth", len))
25972             cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
25973         else if (!XSTRNCASECMP(token, "clientAuth", len))
25974             cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
25975         else if (!XSTRNCASECMP(token, "codeSigning", len))
25976             cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
25977         else if (!XSTRNCASECMP(token, "emailProtection", len))
25978             cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
25979         else if (!XSTRNCASECMP(token, "timeStamping", len))
25980             cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
25981         else if (!XSTRNCASECMP(token, "OCSPSigning", len))
25982             cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
25983         else {
25984             ret = EXTKEYUSAGE_E;
25985             break;
25986         }
25987 
25988         token = XSTRTOK(NULL, ",", &ptr);
25989     }
25990 
25991     XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25992     return ret;
25993 }
25994 
25995 #ifdef WOLFSSL_EKU_OID
25996 /*
25997  * cert structure to set EKU oid in
25998  * oid  the oid in byte representation
25999  * sz   size of oid buffer
26000  * idx  index of array to place oid
26001  *
26002  * returns 0 on success
26003  */
26004 int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
26005         void* heap)
26006 {
26007     byte oid[MAX_OID_SZ];
26008     word32 oidSz = MAX_OID_SZ;
26009 
26010     if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
26011         WOLFSSL_MSG("Either idx or sz was too large");
26012         return BAD_FUNC_ARG;
26013     }
26014 
26015     if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
26016         return BUFFER_E;
26017     }
26018 
26019     XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
26020     cert->extKeyUsageOIDSz[idx] = oidSz;
26021     cert->extKeyUsage |= EXTKEYUSE_USER;
26022 
26023     return 0;
26024 }
26025 #endif /* WOLFSSL_EKU_OID */
26026 #endif /* WOLFSSL_CERT_EXT */
26027 
26028 
26029 #ifdef WOLFSSL_ALT_NAMES
26030 
26031 static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
26032 {
26033     int ret = 0;
26034 
26035     cert->altNamesSz = 0;
26036     if (decoded->altNames) {
26037         ret = FlattenAltNames(cert->altNames,
26038             sizeof(cert->altNames), decoded->altNames);
26039         if (ret >= 0) {
26040             cert->altNamesSz = ret;
26041             ret = 0;
26042         }
26043     }
26044 
26045     return ret;
26046 }
26047 
26048 #ifndef NO_FILESYSTEM
26049 
26050 /* Set Alt Names from der cert, return 0 on success */
26051 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
26052 {
26053     int ret;
26054 #ifdef WOLFSSL_SMALL_STACK
26055     DecodedCert* decoded;
26056 #else
26057     DecodedCert decoded[1];
26058 #endif
26059 
26060     if (derSz < 0)
26061         return derSz;
26062 
26063 #ifdef WOLFSSL_SMALL_STACK
26064     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
26065                                                        DYNAMIC_TYPE_TMP_BUFFER);
26066     if (decoded == NULL)
26067         return MEMORY_E;
26068 #endif
26069 
26070     InitDecodedCert(decoded, der, derSz, NULL);
26071     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
26072 
26073     if (ret < 0) {
26074         WOLFSSL_MSG("ParseCertRelative error");
26075     }
26076     else {
26077         ret = SetAltNamesFromDcert(cert, decoded);
26078     }
26079 
26080     FreeDecodedCert(decoded);
26081 #ifdef WOLFSSL_SMALL_STACK
26082     XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26083 #endif
26084 
26085     return ret < 0 ? ret : 0;
26086 }
26087 
26088 #endif
26089 
26090 static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
26091 {
26092     int ret = 0;
26093 
26094     if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
26095         WOLFSSL_MSG("Couldn't extract dates");
26096         ret = -1;
26097     }
26098     else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
26099                                         decoded->afterDateLen > MAX_DATE_SIZE) {
26100         WOLFSSL_MSG("Bad date size");
26101         ret = -1;
26102     }
26103     else {
26104         XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
26105         XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
26106 
26107         cert->beforeDateSz = decoded->beforeDateLen;
26108         cert->afterDateSz  = decoded->afterDateLen;
26109     }
26110 
26111     return ret;
26112 }
26113 
26114 #endif /* WOLFSSL_ALT_NAMES */
26115 
26116 static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
26117 {
26118     int sz;
26119 
26120     if (decoded->subjectCN) {
26121         sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
26122                                                      : CTC_NAME_SIZE - 1;
26123         XSTRNCPY(cn->commonName, decoded->subjectCN, sz);
26124         cn->commonName[sz] = '\0';
26125         cn->commonNameEnc = decoded->subjectCNEnc;
26126     }
26127     if (decoded->subjectC) {
26128         sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
26129                                                     : CTC_NAME_SIZE - 1;
26130         XSTRNCPY(cn->country, decoded->subjectC, sz);
26131         cn->country[sz] = '\0';
26132         cn->countryEnc = decoded->subjectCEnc;
26133     }
26134     if (decoded->subjectST) {
26135         sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
26136                                                      : CTC_NAME_SIZE - 1;
26137         XSTRNCPY(cn->state, decoded->subjectST, sz);
26138         cn->state[sz] = '\0';
26139         cn->stateEnc = decoded->subjectSTEnc;
26140     }
26141     if (decoded->subjectL) {
26142         sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
26143                                                     : CTC_NAME_SIZE - 1;
26144         XSTRNCPY(cn->locality, decoded->subjectL, sz);
26145         cn->locality[sz] = '\0';
26146         cn->localityEnc = decoded->subjectLEnc;
26147     }
26148     if (decoded->subjectO) {
26149         sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
26150                                                     : CTC_NAME_SIZE - 1;
26151         XSTRNCPY(cn->org, decoded->subjectO, sz);
26152         cn->org[sz] = '\0';
26153         cn->orgEnc = decoded->subjectOEnc;
26154     }
26155     if (decoded->subjectOU) {
26156         sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
26157                                                      : CTC_NAME_SIZE - 1;
26158         XSTRNCPY(cn->unit, decoded->subjectOU, sz);
26159         cn->unit[sz] = '\0';
26160         cn->unitEnc = decoded->subjectOUEnc;
26161     }
26162     if (decoded->subjectSN) {
26163         sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
26164                                                      : CTC_NAME_SIZE - 1;
26165         XSTRNCPY(cn->sur, decoded->subjectSN, sz);
26166         cn->sur[sz] = '\0';
26167         cn->surEnc = decoded->subjectSNEnc;
26168     }
26169     if (decoded->subjectSND) {
26170         sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
26171                                                      : CTC_NAME_SIZE - 1;
26172         XSTRNCPY(cn->serialDev, decoded->subjectSND, sz);
26173         cn->serialDev[sz] = '\0';
26174         cn->serialDevEnc = decoded->subjectSNDEnc;
26175     }
26176 #ifdef WOLFSSL_CERT_EXT
26177     if (decoded->subjectBC) {
26178         sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
26179                                                      : CTC_NAME_SIZE - 1;
26180         XSTRNCPY(cn->busCat, decoded->subjectBC, sz);
26181         cn->busCat[sz] = '\0';
26182         cn->busCatEnc = decoded->subjectBCEnc;
26183     }
26184     if (decoded->subjectJC) {
26185         sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
26186                                                      : CTC_NAME_SIZE - 1;
26187         XSTRNCPY(cn->joiC, decoded->subjectJC, sz);
26188         cn->joiC[sz] = '\0';
26189         cn->joiCEnc = decoded->subjectJCEnc;
26190     }
26191     if (decoded->subjectJS) {
26192         sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
26193                                                      : CTC_NAME_SIZE - 1;
26194         XSTRNCPY(cn->joiSt, decoded->subjectJS, sz);
26195         cn->joiSt[sz] = '\0';
26196         cn->joiStEnc = decoded->subjectJSEnc;
26197     }
26198 #endif
26199     if (decoded->subjectEmail) {
26200         sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
26201            ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
26202         XSTRNCPY(cn->email, decoded->subjectEmail, sz);
26203         cn->email[sz] = '\0';
26204     }
26205 }
26206 
26207 #ifndef NO_FILESYSTEM
26208 
26209 /* Set cn name from der buffer, return 0 on success */
26210 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
26211 {
26212     int ret;
26213 #ifdef WOLFSSL_SMALL_STACK
26214     DecodedCert* decoded;
26215 #else
26216     DecodedCert decoded[1];
26217 #endif
26218 
26219     if (derSz < 0)
26220         return derSz;
26221 
26222 #ifdef WOLFSSL_SMALL_STACK
26223     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
26224                                                        DYNAMIC_TYPE_TMP_BUFFER);
26225     if (decoded == NULL)
26226         return MEMORY_E;
26227 #endif
26228 
26229     InitDecodedCert(decoded, der, derSz, NULL);
26230     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
26231 
26232     if (ret < 0) {
26233         WOLFSSL_MSG("ParseCertRelative error");
26234     }
26235     else {
26236         SetNameFromDcert(cn, decoded);
26237     }
26238 
26239     FreeDecodedCert(decoded);
26240 
26241 #ifdef WOLFSSL_SMALL_STACK
26242     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26243 #endif
26244 
26245     return ret < 0 ? ret : 0;
26246 }
26247 
26248 /* Set cert issuer from issuerFile in PEM */
26249 int wc_SetIssuer(Cert* cert, const char* issuerFile)
26250 {
26251     int         ret;
26252     DerBuffer*  der = NULL;
26253 
26254     if (cert == NULL || issuerFile == NULL)
26255         return BAD_FUNC_ARG;
26256 
26257     ret = wc_PemCertToDer_ex(issuerFile, &der);
26258     if (ret == 0) {
26259         cert->selfSigned = 0;
26260         ret = SetNameFromCert(&cert->issuer, der->buffer, der->length);
26261 
26262         FreeDer(&der);
26263     }
26264 
26265     return ret;
26266 }
26267 
26268 
26269 /* Set cert subject from subjectFile in PEM */
26270 int wc_SetSubject(Cert* cert, const char* subjectFile)
26271 {
26272     int         ret;
26273     DerBuffer*  der = NULL;
26274 
26275     if (cert == NULL || subjectFile == NULL)
26276         return BAD_FUNC_ARG;
26277 
26278     ret = wc_PemCertToDer_ex(subjectFile, &der);
26279     if (ret == 0) {
26280         ret = SetNameFromCert(&cert->subject, der->buffer, der->length);
26281 
26282         FreeDer(&der);
26283     }
26284 
26285     return ret;
26286 }
26287 
26288 #ifdef WOLFSSL_ALT_NAMES
26289 
26290 /* Set alt names from file in PEM */
26291 int wc_SetAltNames(Cert* cert, const char* file)
26292 {
26293     int         ret;
26294     DerBuffer*  der = NULL;
26295 
26296     if (cert == NULL) {
26297         return BAD_FUNC_ARG;
26298     }
26299 
26300     ret = wc_PemCertToDer_ex(file, &der);
26301     if (ret == 0) {
26302         ret = SetAltNamesFromCert(cert, der->buffer, der->length);
26303 
26304         FreeDer(&der);
26305     }
26306 
26307     return ret;
26308 }
26309 
26310 #endif /* WOLFSSL_ALT_NAMES */
26311 
26312 #endif /* !NO_FILESYSTEM */
26313 
26314 /* Set cert issuer from DER buffer */
26315 int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
26316 {
26317     int ret = 0;
26318 
26319     if (cert == NULL) {
26320         ret = BAD_FUNC_ARG;
26321     }
26322     else {
26323         cert->selfSigned = 0;
26324 
26325         /* Check if decodedCert is cached */
26326         if (cert->der != der) {
26327             /* Allocate cache for the decoded cert */
26328             ret = wc_SetCert_LoadDer(cert, der, derSz);
26329         }
26330 
26331         if (ret >= 0) {
26332             SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);
26333 #ifndef WOLFSSL_CERT_GEN_CACHE
26334             wc_SetCert_Free(cert);
26335 #endif
26336         }
26337     }
26338 
26339     return ret;
26340 }
26341 
26342 /* Set cert subject from DER buffer */
26343 int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
26344 {
26345     int ret = 0;
26346 
26347     if (cert == NULL) {
26348         ret = BAD_FUNC_ARG;
26349     }
26350     else {
26351         /* Check if decodedCert is cached */
26352         if (cert->der != der) {
26353             /* Allocate cache for the decoded cert */
26354             ret = wc_SetCert_LoadDer(cert, der, derSz);
26355         }
26356 
26357         if (ret >= 0) {
26358             SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);
26359 #ifndef WOLFSSL_CERT_GEN_CACHE
26360             wc_SetCert_Free(cert);
26361 #endif
26362         }
26363     }
26364 
26365     return ret;
26366 }
26367 #ifdef WOLFSSL_CERT_EXT
26368 /* Set cert raw subject from DER buffer */
26369 int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
26370 {
26371     int ret = 0;
26372 
26373     if (cert == NULL) {
26374         ret = BAD_FUNC_ARG;
26375     }
26376     else {
26377         /* Check if decodedCert is cached */
26378         if (cert->der != der) {
26379             /* Allocate cache for the decoded cert */
26380             ret = wc_SetCert_LoadDer(cert, der, derSz);
26381         }
26382 
26383         if (ret >= 0) {
26384             if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
26385                 (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
26386                         (int)sizeof(CertName))) {
26387                 XMEMCPY(cert->sbjRaw,
26388                         ((DecodedCert*)cert->decodedCert)->subjectRaw,
26389                         ((DecodedCert*)cert->decodedCert)->subjectRawLen);
26390             }
26391 #ifndef WOLFSSL_CERT_GEN_CACHE
26392             wc_SetCert_Free(cert);
26393 #endif
26394         }
26395     }
26396 
26397     return ret;
26398 }
26399 
26400 /* Set cert raw issuer from DER buffer */
26401 int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
26402 {
26403     int ret = 0;
26404 
26405     if (cert == NULL) {
26406         ret = BAD_FUNC_ARG;
26407     }
26408     else {
26409         /* Check if decodedCert is cached */
26410         if (cert->der != der) {
26411             /* Allocate cache for the decoded cert */
26412             ret = wc_SetCert_LoadDer(cert, der, derSz);
26413         }
26414 
26415         if (ret >= 0) {
26416             if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
26417                 (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
26418                         (int)sizeof(CertName))) {
26419                 /* Copy the subject to the issuer field */
26420                 XMEMCPY(cert->issRaw,
26421                         ((DecodedCert*)cert->decodedCert)->subjectRaw,
26422                         ((DecodedCert*)cert->decodedCert)->subjectRawLen);
26423             }
26424 #ifndef WOLFSSL_CERT_GEN_CACHE
26425             wc_SetCert_Free(cert);
26426 #endif
26427         }
26428     }
26429     return ret;
26430 }
26431 #endif
26432 
26433 #ifdef WOLFSSL_ALT_NAMES
26434 
26435 /* Set cert alt names from DER buffer */
26436 int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
26437 {
26438     int ret = 0;
26439 
26440     if (cert == NULL) {
26441        ret = BAD_FUNC_ARG;
26442     }
26443     else {
26444         /* Check if decodedCert is cached */
26445         if (cert->der != der) {
26446             /* Allocate cache for the decoded cert */
26447             ret = wc_SetCert_LoadDer(cert, der, derSz);
26448         }
26449 
26450         if (ret >= 0) {
26451             ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);
26452 #ifndef WOLFSSL_CERT_GEN_CACHE
26453             wc_SetCert_Free(cert);
26454 #endif
26455        }
26456     }
26457 
26458     return(ret);
26459 }
26460 
26461 /* Set cert dates from DER buffer */
26462 int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
26463 {
26464     int ret = 0;
26465 
26466     if (cert == NULL) {
26467      ret = BAD_FUNC_ARG;
26468     }
26469     else {
26470         /* Check if decodedCert is cached */
26471         if (cert->der != der) {
26472             /* Allocate cache for the decoded cert */
26473             ret = wc_SetCert_LoadDer(cert, der, derSz);
26474         }
26475 
26476         if (ret >= 0) {
26477             ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);
26478 #ifndef WOLFSSL_CERT_GEN_CACHE
26479             wc_SetCert_Free(cert);
26480 #endif
26481         }
26482     }
26483 
26484     return(ret);
26485 }
26486 
26487 #endif /* WOLFSSL_ALT_NAMES */
26488 
26489 #endif /* WOLFSSL_CERT_GEN */
26490 
26491 #if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \
26492         || defined(OPENSSL_EXTRA)
26493 /* Encode OID string representation to ITU-T X.690 format */
26494 int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
26495 {
26496     word32 val, idx = 0, nb_val;
26497     char *token, *str, *ptr;
26498     word32 len;
26499 
26500     (void)heap;
26501 
26502     if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
26503         return BAD_FUNC_ARG;
26504 
26505     /* duplicate string (including terminator) */
26506     len = (word32)XSTRLEN(in);
26507     str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
26508     if (str == NULL)
26509         return MEMORY_E;
26510     XMEMCPY(str, in, len+1);
26511 
26512     nb_val = 0;
26513 
26514     /* parse value, and set corresponding Policy OID value */
26515     token = XSTRTOK(str, ".", &ptr);
26516     while (token != NULL)
26517     {
26518         val = (word32)XATOI(token);
26519 
26520         if (nb_val == 0) {
26521             if (val > 2) {
26522                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26523                 return ASN_OBJECT_ID_E;
26524             }
26525 
26526             out[idx] = (byte)(40 * val);
26527         }
26528         else if (nb_val == 1) {
26529             if (val > 127) {
26530                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26531                 return ASN_OBJECT_ID_E;
26532             }
26533 
26534             if (idx > *outSz) {
26535                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26536                 return BUFFER_E;
26537             }
26538 
26539             out[idx++] += (byte)val;
26540         }
26541         else {
26542             word32  tb = 0, x;
26543             int     i = 0;
26544             byte    oid[MAX_OID_SZ];
26545 
26546             while (val >= 128) {
26547                 x = val % 128;
26548                 val /= 128;
26549                 oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
26550             }
26551 
26552             if ((idx+(word32)i) >= *outSz) {
26553                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26554                 return BUFFER_E;
26555             }
26556 
26557             oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
26558 
26559             /* push value in the right order */
26560             while (i >= 0)
26561                 out[idx++] = oid[i--];
26562         }
26563 
26564         token = XSTRTOK(NULL, ".", &ptr);
26565         nb_val++;
26566     }
26567 
26568     *outSz = idx;
26569 
26570     XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26571     return 0;
26572 }
26573 #endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
26574 
26575 #endif /* !NO_CERTS */
26576 
26577 #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
26578 /* Helper function for wolfSSL_i2d_DHparams */
26579 int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
26580 {
26581 #ifndef WOLFSSL_ASN_TEMPLATE
26582     word32 idx = 0;
26583     word32 total;
26584 
26585     WOLFSSL_ENTER("StoreDHparams");
26586 
26587     if (out == NULL) {
26588         WOLFSSL_MSG("Null buffer error");
26589         return BUFFER_E;
26590     }
26591 
26592     /* determine size */
26593     /* integer - g */
26594     idx = SetASNIntMP(g, -1, NULL);
26595     /* integer - p */
26596     idx += SetASNIntMP(p, -1, NULL);
26597     total = idx;
26598      /* sequence */
26599     idx += SetSequence(idx, NULL);
26600 
26601     /* make sure output fits in buffer */
26602     if (idx > *outLen) {
26603         return BUFFER_E;
26604     }
26605 
26606     /* write DH parameters */
26607     /* sequence - for P and G only */
26608     idx = SetSequence(total, out);
26609     /* integer - p */
26610     idx += SetASNIntMP(p, -1, out + idx);
26611     /* integer - g */
26612     idx += SetASNIntMP(g, -1, out + idx);
26613     *outLen = idx;
26614 
26615     return 0;
26616 #else
26617     ASNSetData dataASN[dhParamASN_Length];
26618     int ret = 0;
26619     int sz;
26620 
26621     WOLFSSL_ENTER("StoreDHparams");
26622     if (out == NULL) {
26623         ret = BUFFER_E;
26624     }
26625     if (ret == 0) {
26626         XMEMSET(dataASN, 0, sizeof(dataASN));
26627         /* Set mp_int containing p and g. */
26628         SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], p);
26629         SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], g);
26630         /* privateValueLength not encoded. */
26631         dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
26632 
26633         /* Calculate the size of the DH parameters. */
26634         ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
26635     }
26636     /* Check buffer is big enough for encoding. */
26637     if ((ret == 0) && ((int)*outLen < sz)) {
26638         ret = BUFFER_E;
26639     }
26640     if (ret == 0) {
26641         /* Encode the DH parameters into buffer. */
26642         SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, out);
26643         /* Set the actual encoding size. */
26644         *outLen = sz;
26645     }
26646 
26647     return ret;
26648 #endif /* WOLFSSL_ASN_TEMPLATE */
26649 }
26650 #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
26651 
26652 #if defined(HAVE_ECC) || !defined(NO_DSA)
26653 
26654 #ifdef WOLFSSL_ASN_TEMPLATE
26655 /* ASN.1 template for DSA signature.
26656  * RFC 5912, 6 - DSA-Sig-Value
26657  */
26658 static const ASNItem dsaSigASN[] = {
26659 /* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
26660                             /* r */
26661 /* R   */     { 1, ASN_INTEGER, 0, 0, 0 },
26662                             /* s */
26663 /* S   */     { 1, ASN_INTEGER, 0, 0, 0 },
26664 };
26665 enum {
26666     DSASIGASN_IDX_SEQ = 0,
26667     DSASIGASN_IDX_R,
26668     DSASIGASN_IDX_S,
26669 };
26670 
26671 #define dsaSigASN_Length (sizeof(dsaSigASN) / sizeof(ASNItem))
26672 #endif
26673 
26674 /* Der Encode r & s ints into out, outLen is (in/out) size */
26675 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
26676 {
26677 #ifndef WOLFSSL_ASN_TEMPLATE
26678     word32 idx = 0;
26679     int    rSz;                           /* encoding size */
26680     int    sSz;
26681     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
26682 
26683     /* If the leading bit on the INTEGER is a 1, add a leading zero */
26684     int rLeadingZero = mp_leading_bit(r);
26685     int sLeadingZero = mp_leading_bit(s);
26686     int rLen = mp_unsigned_bin_size(r);   /* big int size */
26687     int sLen = mp_unsigned_bin_size(s);
26688 
26689     if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
26690                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
26691         return BUFFER_E;
26692 
26693     idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
26694 
26695     /* store r */
26696     rSz = SetASNIntMP(r, *outLen - idx, &out[idx]);
26697     if (rSz < 0)
26698         return rSz;
26699     idx += rSz;
26700 
26701     /* store s */
26702     sSz = SetASNIntMP(s, *outLen - idx, &out[idx]);
26703     if (sSz < 0)
26704         return sSz;
26705     idx += sSz;
26706 
26707     *outLen = idx;
26708 
26709     return 0;
26710 #else
26711     ASNSetData dataASN[dsaSigASN_Length];
26712     int ret;
26713     int sz;
26714 
26715     /* Clear dynamic data and set mp_ints r and s */
26716     XMEMSET(dataASN, 0, sizeof(dataASN));
26717     SetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
26718     SetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
26719 
26720     /* Calculate size of encoding. */
26721     ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
26722     /* Check buffer is big enough for encoding. */
26723     if ((ret == 0) && ((int)*outLen < sz)) {
26724        ret = BUFFER_E;
26725     }
26726     if (ret == 0) {
26727         /* Encode DSA signature into buffer. */
26728         SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
26729         /* Set the actual encoding size. */
26730         *outLen = sz;
26731     }
26732 
26733     return ret;
26734 #endif /* WOLFSSL_ASN_TEMPLATE */
26735 }
26736 
26737 #ifndef WOLFSSL_ASN_TEMPLATE
26738 /* determine if leading bit is set */
26739 static int is_leading_bit_set(const byte* input, word32 sz)
26740 {
26741     byte c = 0;
26742     if (sz > 0)
26743         c = input[0];
26744     return (c & 0x80) != 0;
26745 }
26746 static int trim_leading_zeros(const byte** input, word32 sz)
26747 {
26748     int i, leadingZeroCount = 0;
26749     const byte* tmp = *input;
26750     for (i=0; i<(int)sz; i++) {
26751         if (tmp[i] != 0)
26752             break;
26753         leadingZeroCount++;
26754     }
26755     /* catch all zero case */
26756     if (sz > 0 && leadingZeroCount == (int)sz) {
26757         leadingZeroCount--;
26758     }
26759     *input += leadingZeroCount;
26760     sz -= leadingZeroCount;
26761     return sz;
26762 }
26763 #endif
26764 
26765 /* Der Encode r & s ints into out, outLen is (in/out) size */
26766 /* All input/outputs are assumed to be big-endian */
26767 int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, const byte* r, word32 rLen,
26768     const byte* s, word32 sLen)
26769 {
26770 #ifndef WOLFSSL_ASN_TEMPLATE
26771     int ret;
26772     word32 idx;
26773     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
26774     int rAddLeadZero, sAddLeadZero;
26775 
26776     if ((out == NULL) || (outLen == NULL) || (r == NULL) || (s == NULL))
26777         return BAD_FUNC_ARG;
26778 
26779     /* Trim leading zeros */
26780     rLen = trim_leading_zeros(&r, rLen);
26781     sLen = trim_leading_zeros(&s, sLen);
26782     /* If the leading bit on the INTEGER is a 1, add a leading zero */
26783     /* Add leading zero if MSB is set */
26784     rAddLeadZero = is_leading_bit_set(r, rLen);
26785     sAddLeadZero = is_leading_bit_set(s, sLen);
26786 
26787     if (*outLen < (rLen + rAddLeadZero + sLen + sAddLeadZero +
26788                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
26789         return BUFFER_E;
26790 
26791     idx = SetSequence(rLen+rAddLeadZero + sLen+sAddLeadZero + headerSz, out);
26792 
26793     /* store r */
26794     ret = SetASNInt(rLen, rAddLeadZero ? 0x80 : 0x00, &out[idx]);
26795     if (ret < 0)
26796         return ret;
26797     idx += ret;
26798     XMEMCPY(&out[idx], r, rLen);
26799     idx += rLen;
26800 
26801     /* store s */
26802     ret = SetASNInt(sLen, sAddLeadZero ? 0x80 : 0x00, &out[idx]);
26803     if (ret < 0)
26804         return ret;
26805     idx += ret;
26806     XMEMCPY(&out[idx], s, sLen);
26807     idx += sLen;
26808 
26809     *outLen = idx;
26810 
26811     return 0;
26812 #else
26813     ASNSetData dataASN[dsaSigASN_Length];
26814     int ret;
26815     int sz;
26816 
26817     /* Clear dynamic data and set buffers for r and s */
26818     XMEMSET(dataASN, 0, sizeof(dataASN));
26819     SetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
26820     SetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
26821 
26822     /* Calculate size of encoding. */
26823     ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
26824     /* Check buffer is big enough for encoding. */
26825     if ((ret == 0) && ((int)*outLen < sz)) {
26826        ret = BUFFER_E;
26827     }
26828     if (ret == 0) {
26829         /* Encode DSA signature into buffer. */
26830         SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
26831         /* Set the actual encoding size. */
26832         *outLen = sz;
26833     }
26834 
26835     return ret;
26836 #endif /* WOLFSSL_ASN_TEMPLATE */
26837 }
26838 
26839 /* Der Decode ECC-DSA Signature with R/S as unsigned bin */
26840 /* All input/outputs are assumed to be big-endian */
26841 int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen,
26842     byte* s, word32* sLen)
26843 {
26844 #ifndef WOLFSSL_ASN_TEMPLATE
26845     int    ret;
26846     word32 idx = 0;
26847     int    len = 0;
26848 
26849     if (GetSequence(sig, &idx, &len, sigLen) < 0) {
26850         return ASN_ECC_KEY_E;
26851     }
26852 
26853 #ifndef NO_STRICT_ECDSA_LEN
26854     /* enable strict length checking for signature */
26855     if (sigLen != idx + (word32)len) {
26856         return ASN_ECC_KEY_E;
26857     }
26858 #else
26859     /* allow extra signature bytes at end */
26860     if ((word32)len > (sigLen - idx)) {
26861         return ASN_ECC_KEY_E;
26862     }
26863 #endif
26864 
26865     ret = GetASNInt(sig, &idx, &len, sigLen);
26866     if (ret != 0)
26867         return ret;
26868     if (rLen)
26869         *rLen = len;
26870     if (r)
26871         XMEMCPY(r, (byte*)sig + idx, len);
26872     idx += len;
26873 
26874     ret = GetASNInt(sig, &idx, &len, sigLen);
26875     if (ret != 0)
26876         return ret;
26877     if (sLen)
26878         *sLen = len;
26879     if (s)
26880         XMEMCPY(s, (byte*)sig + idx, len);
26881 
26882 #ifndef NO_STRICT_ECDSA_LEN
26883     /* sanity check that the index has been advanced all the way to the end of
26884      * the buffer */
26885     if (idx + len != sigLen) {
26886         ret = ASN_ECC_KEY_E;
26887     }
26888 #endif
26889 
26890     return ret;
26891 #else
26892     ASNGetData dataASN[dsaSigASN_Length];
26893     word32 idx = 0;
26894 
26895     /* Clear dynamic data and set buffers to put r and s into. */
26896     XMEMSET(dataASN, 0, sizeof(dataASN));
26897     GetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
26898     GetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
26899 
26900     /* Decode the DSA signature. */
26901     return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
26902                         sigLen);
26903 #endif /* WOLFSSL_ASN_TEMPLATE */
26904 }
26905 
26906 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
26907 {
26908 #ifndef WOLFSSL_ASN_TEMPLATE
26909     word32 idx = 0;
26910     int    len = 0;
26911 
26912     if (GetSequence(sig, &idx, &len, sigLen) < 0) {
26913         return ASN_ECC_KEY_E;
26914     }
26915 
26916 #ifndef NO_STRICT_ECDSA_LEN
26917     /* enable strict length checking for signature */
26918     if (sigLen != idx + (word32)len) {
26919         return ASN_ECC_KEY_E;
26920     }
26921 #else
26922     /* allow extra signature bytes at end */
26923     if ((word32)len > (sigLen - idx)) {
26924         return ASN_ECC_KEY_E;
26925     }
26926 #endif
26927 
26928     if (GetInt(r, sig, &idx, sigLen) < 0) {
26929         return ASN_ECC_KEY_E;
26930     }
26931 
26932     if (GetInt(s, sig, &idx, sigLen) < 0) {
26933         mp_clear(r);
26934         return ASN_ECC_KEY_E;
26935     }
26936 
26937 #ifndef NO_STRICT_ECDSA_LEN
26938     /* sanity check that the index has been advanced all the way to the end of
26939      * the buffer */
26940     if (idx != sigLen) {
26941         mp_clear(r);
26942         mp_clear(s);
26943         return ASN_ECC_KEY_E;
26944     }
26945 #endif
26946 
26947     return 0;
26948 #else
26949     ASNGetData dataASN[dsaSigASN_Length];
26950     word32 idx = 0;
26951 
26952     /* Clear dynamic data and set mp_ints to put r and s into. */
26953     XMEMSET(dataASN, 0, sizeof(dataASN));
26954     GetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
26955     GetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
26956 
26957     /* Decode the DSA signature. */
26958     return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
26959                         sigLen);
26960 #endif /* WOLFSSL_ASN_TEMPLATE */
26961 }
26962 #endif
26963 
26964 
26965 #ifdef WOLFSSL_ASN_TEMPLATE
26966 #ifdef WOLFSSL_CUSTOM_CURVES
26967 /* Convert data to hex string.
26968  *
26969  * Big-endian byte array is converted to big-endian hexadecimal string.
26970  *
26971  * @param [in]  input  Buffer containing data.
26972  * @param [in]  inSz   Size of data in buffer.
26973  * @param [out] out    Buffer to hold hex string.
26974  */
26975 static void DataToHexString(const byte* input, word32 inSz, char* out)
26976 {
26977     static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
26978                                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
26979     word32 i;
26980 
26981     /* Converting a byte of data at a time to two hex characters. */
26982     for (i = 0; i < inSz; i++) {
26983         out[i*2 + 0] = hexChar[input[i] >> 4];
26984         out[i*2 + 1] = hexChar[input[i] & 0xf];
26985     }
26986     /* NUL terminate string. */
26987     out[i * 2] = '\0';
26988 }
26989 
26990 /* Convert data to hex string and place in allocated buffer.
26991  *
26992  * Big-endian byte array is converted to big-endian hexadecimal string.
26993  *
26994  * @param [in]  input     Buffer containing data.
26995  * @param [in]  inSz      Size of data in buffer.
26996  * @param [out] out       Allocated buffer holding hex string.
26997  * @param [in]  heap      Dynamic memory allocation hint.
26998  * @param [in]  heapType  Type of heap to use.
26999  * @return  0 on succcess.
27000  * @return  MEMORY_E when dynamic memory allocation fails.
27001  */
27002 static int DataToHexStringAlloc(const byte* input, word32 inSz, char** out,
27003                                 void* heap, int heapType)
27004 {
27005     int ret = 0;
27006     char* str;
27007 
27008     /* Allocate for 2 string characters ber byte plus NUL. */
27009     str = (char*)XMALLOC(inSz * 2 + 1, heap, heapType);
27010     if (str == NULL) {
27011         ret = MEMORY_E;
27012     }
27013     else {
27014         /* Convert to hex string. */
27015         DataToHexString(input, inSz, str);
27016         *out = str;
27017     }
27018 
27019     (void)heap;
27020     (void)heapType;
27021 
27022     return ret;
27023 }
27024 
27025 /* ASN.1 template for SpecifiedECDomain.
27026  * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
27027  * NOTE: characteristic-two-field not supported. */
27028 static const ASNItem eccSpecifiedASN[] = {
27029             /* version */
27030 /* VER        */ { 0, ASN_INTEGER, 0, 0, 0 },
27031                                      /* fieldID */
27032 /* PRIME_SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
27033                                          /* prime-field or characteristic-two-field */
27034 /* PRIME_OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
27035                                          /* Prime-p */
27036 /* PRIME_P    */     { 1, ASN_INTEGER, 0, 0, 0 },
27037                                      /* fieldID */
27038 /* PARAM_SEQ, */ { 0, ASN_SEQUENCE, 1, 1, 0 },
27039                                          /* a */
27040 /* PARAM_A    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
27041                                          /* b */
27042 /* PARAM_B    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
27043                                          /* seed */
27044 /* PARAM_SEED */     { 1, ASN_BIT_STRING, 0, 0, 1 },
27045                                      /* base */
27046 /* BASE       */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
27047                                      /* order */
27048 /* ORDER      */ { 0, ASN_INTEGER, 0, 0, 0 },
27049                                      /* cofactor */
27050 /* COFACTOR   */ { 0, ASN_INTEGER, 0, 0, 1 },
27051                                      /* hash */
27052 /* HASH_SEQ   */ { 0, ASN_SEQUENCE, 0, 0, 1 },
27053 };
27054 enum {
27055     ECCSPECIFIEDASN_IDX_VER = 0,
27056     ECCSPECIFIEDASN_IDX_PRIME_SEQ,
27057     ECCSPECIFIEDASN_IDX_PRIME_OID,
27058     ECCSPECIFIEDASN_IDX_PRIME_P,
27059     ECCSPECIFIEDASN_IDX_PARAM_SEQ,
27060     ECCSPECIFIEDASN_IDX_PARAM_A,
27061     ECCSPECIFIEDASN_IDX_PARAM_B,
27062     ECCSPECIFIEDASN_IDX_PARAM_SEED,
27063     ECCSPECIFIEDASN_IDX_BASE,
27064     ECCSPECIFIEDASN_IDX_ORDER,
27065     ECCSPECIFIEDASN_IDX_COFACTOR,
27066     ECCSPECIFIEDASN_IDX_HASH_SEQ,
27067 };
27068 
27069 /* Number of items in ASN.1 template for SpecifiedECDomain. */
27070 #define eccSpecifiedASN_Length (sizeof(eccSpecifiedASN) / sizeof(ASNItem))
27071 
27072 /* OID indicating the prime field is explicity defined. */
27073 static const byte primeFieldOID[] = {
27074     0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01
27075 };
27076 static const char ecSetCustomName[] = "Custom";
27077 
27078 /* Explicit EC parameter values. */
27079 static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
27080                                       ecc_key* key)
27081 {
27082     DECL_ASNGETDATA(dataASN, eccSpecifiedASN_Length);
27083     int ret = 0;
27084     ecc_set_type* curve;
27085     word32 idx = 0;
27086     byte version;
27087     byte cofactor;
27088     const byte *base;
27089     word32 baseLen;
27090 
27091     /* Allocate a new parameter set. */
27092     curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
27093                                                        DYNAMIC_TYPE_ECC_BUFFER);
27094     if (curve == NULL)
27095         ret = MEMORY_E;
27096 
27097     CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, key->heap);
27098 
27099     if (ret == 0) {
27100         /* Clear out parameters and set fields to indicate it is custom. */
27101         XMEMSET(curve, 0, sizeof(*curve));
27102         /* Set name to be: "Custom" */
27103     #ifndef WOLFSSL_ECC_CURVE_STATIC
27104         curve->name = ecSetCustomName;
27105     #else
27106         XMEMCPY((void*)curve->name, ecSetCustomName, sizeof(ecSetCustomName));
27107     #endif
27108         curve->id = ECC_CURVE_CUSTOM;
27109 
27110         /* Get version, must have prime field OID and get co-factor. */
27111         GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_VER], &version);
27112         GetASN_ExpBuffer(&dataASN[ECCSPECIFIEDASN_IDX_PRIME_OID],
27113                 primeFieldOID, sizeof(primeFieldOID));
27114         GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_COFACTOR], &cofactor);
27115         /* Decode the explicit parameters. */
27116         ret = GetASN_Items(eccSpecifiedASN, dataASN, eccSpecifiedASN_Length, 1,
27117                            input, &idx, inSz);
27118     }
27119     /* Version must be 1 or 2 for supporting explicit parameters. */
27120     if ((ret == 0) && (version < 1 || version > 3)) {
27121         ret = ASN_PARSE_E;
27122     }
27123     /* Only version 2 and above can have a seed. */
27124     if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_PARAM_SEED].tag != 0) &&
27125             (version < 2)) {
27126         ret = ASN_PARSE_E;
27127     }
27128     /* Only version 2 and above can have a hash algorithm. */
27129     if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_HASH_SEQ].tag != 0) &&
27130             (version < 2)) {
27131         ret = ASN_PARSE_E;
27132     }
27133     if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_COFACTOR].tag != 0)) {
27134         /* Store optional co-factor. */
27135         curve->cofactor = cofactor;
27136     }
27137     if (ret == 0) {
27138         /* Length of the prime in bytes is the curve size. */
27139         curve->size =
27140                 (int)dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length;
27141         /* Base point: 0x04 <x> <y> (must be uncompressed). */
27142         GetASN_GetConstRef(&dataASN[ECCSPECIFIEDASN_IDX_BASE], &base,
27143                 &baseLen);
27144         if ((baseLen < (word32)curve->size * 2 + 1) || (base[0] != 0x4)) {
27145             ret = ASN_PARSE_E;
27146         }
27147     }
27148     /* Put the curve parameters into the set.
27149      * Convert the big-endian number byte array to a big-endian string.
27150      */
27151     #ifndef WOLFSSL_ECC_CURVE_STATIC
27152     /* Allocate buffer to put hex strings into. */
27153     if (ret == 0) {
27154         /* Base X-ordinate */
27155         ret = DataToHexStringAlloc(base + 1, curve->size,
27156                                    (char**)&curve->Gx, key->heap,
27157                                    DYNAMIC_TYPE_ECC_BUFFER);
27158     }
27159     if (ret == 0) {
27160         /* Base Y-ordinate */
27161         ret = DataToHexStringAlloc(base + 1 + curve->size, curve->size,
27162                                    (char**)&curve->Gy, key->heap,
27163                                    DYNAMIC_TYPE_ECC_BUFFER);
27164     }
27165     if (ret == 0) {
27166         /* Prime */
27167         ret = DataToHexStringAlloc(
27168                 dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
27169                 dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
27170                 (char**)&curve->prime, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27171     }
27172     if (ret == 0) {
27173         /* Parameter A */
27174         ret = DataToHexStringAlloc(
27175                 dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
27176                 dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
27177                 (char**)&curve->Af, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27178     }
27179     if (ret == 0) {
27180         /* Parameter B */
27181         ret = DataToHexStringAlloc(
27182                 dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
27183                 dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
27184                 (char**)&curve->Bf, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27185     }
27186     if (ret == 0) {
27187         /* Order of curve */
27188         ret = DataToHexStringAlloc(
27189                 dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
27190                 dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
27191                 (char**)&curve->order, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27192     }
27193     #else
27194     if (ret == 0) {
27195         /* Base X-ordinate */
27196         DataToHexString(base + 1, curve->size, curve->Gx);
27197         /* Base Y-ordinate */
27198         DataToHexString(base + 1 + curve->size, curve->size, curve->Gy);
27199         /* Prime */
27200         DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
27201                         dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
27202                         curve->prime);
27203         /* Parameter A */
27204         DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
27205                         dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
27206                         curve->Af);
27207         /* Parameter B */
27208         DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
27209                         dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
27210                         curve->Bf);
27211         /* Order of curve */
27212         DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
27213                         dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
27214                         curve->order);
27215     }
27216     #endif /* WOLFSSL_ECC_CURVE_STATIC */
27217 
27218     /* Store parameter set in key. */
27219     if ((ret == 0) && (wc_ecc_set_custom_curve(key, curve) < 0)) {
27220         ret = ASN_PARSE_E;
27221     }
27222     if (ret == 0) {
27223         /* The parameter set was allocated.. */
27224         key->deallocSet = 1;
27225     }
27226 
27227     if ((ret != 0) && (curve != NULL)) {
27228         /* Failed to set parameters so free paramter set. */
27229         wc_ecc_free_curve(curve, key->heap);
27230     }
27231 
27232     FREE_ASNGETDATA(dataASN, key->heap);
27233     return ret;
27234 }
27235 #endif /* WOLFSSL_CUSTOM_CURVES */
27236 #endif /* WOLFSSL_ASN_TEMPLATE */
27237 
27238 #ifdef HAVE_ECC
27239 
27240 #ifdef WOLFSSL_ASN_TEMPLATE
27241 /* ASN.1 template for ECC private key.
27242  * SEC.1 Ver 2.0, C.4 - Syntax for Elliptic Curve Private Keys
27243  */
27244 static const ASNItem eccKeyASN[] = {
27245 /* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27246                                        /* version */
27247 /* VER         */        { 1, ASN_INTEGER, 0, 0, 0 },
27248                                        /* privateKey */
27249 /* PKEY        */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27250                                        /* parameters */
27251 /* PARAMS      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PARAMS, 1, 1, 1 },
27252                                            /* named */
27253 /* CURVEID     */            { 2, ASN_OBJECT_ID, 0, 0, 2 },
27254                                            /* specified */
27255 /* CURVEPARAMS */            { 2, ASN_SEQUENCE, 1, 0, 2 },
27256                                        /* publicKey */
27257 /* PUBKEY      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PUBKEY, 1, 1, 1 },
27258                                            /* Uncompressed point - X9.62. */
27259 /* PUBKEY_VAL, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
27260 };
27261 enum {
27262     ECCKEYASN_IDX_SEQ = 0,
27263     ECCKEYASN_IDX_VER,
27264     ECCKEYASN_IDX_PKEY,
27265     ECCKEYASN_IDX_PARAMS,
27266     ECCKEYASN_IDX_CURVEID,
27267     ECCKEYASN_IDX_CURVEPARAMS,
27268     ECCKEYASN_IDX_PUBKEY,
27269     ECCKEYASN_IDX_PUBKEY_VAL,
27270 };
27271 
27272 /* Number of items in ASN.1 template for ECC private key. */
27273 #define eccKeyASN_Length (sizeof(eccKeyASN) / sizeof(ASNItem))
27274 #endif
27275 
27276 int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
27277                         word32 inSz)
27278 {
27279 #ifndef WOLFSSL_ASN_TEMPLATE
27280     word32 oidSum;
27281     int    version, length;
27282     int    privSz, pubSz = 0;
27283     byte   b;
27284     int    ret = 0;
27285     int    curve_id = ECC_CURVE_DEF;
27286 #ifdef WOLFSSL_SMALL_STACK
27287     byte* priv;
27288     byte* pub = NULL;
27289 #else
27290     byte priv[ECC_MAXSIZE+1];
27291     byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
27292 #endif
27293     word32 algId = 0;
27294     byte* pubData = NULL;
27295 
27296     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
27297         return BAD_FUNC_ARG;
27298 
27299     /* if has pkcs8 header skip it */
27300     if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
27301         /* ignore error, did not have pkcs8 header */
27302     }
27303 
27304     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27305         return ASN_PARSE_E;
27306 
27307     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
27308         return ASN_PARSE_E;
27309 
27310     if (*inOutIdx >= inSz)
27311         return ASN_PARSE_E;
27312 
27313     b = input[*inOutIdx];
27314     *inOutIdx += 1;
27315 
27316     /* priv type */
27317     if (b != 4 && b != 6 && b != 7)
27318         return ASN_PARSE_E;
27319 
27320     if (GetLength(input, inOutIdx, &length, inSz) < 0)
27321         return ASN_PARSE_E;
27322     privSz = length;
27323 
27324     if (privSz > ECC_MAXSIZE)
27325         return BUFFER_E;
27326 
27327 #ifdef WOLFSSL_SMALL_STACK
27328     priv = (byte*)XMALLOC(privSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27329     if (priv == NULL)
27330         return MEMORY_E;
27331 #endif
27332 
27333     /* priv key */
27334     XMEMCPY(priv, &input[*inOutIdx], privSz);
27335     *inOutIdx += length;
27336 
27337     if ((*inOutIdx + 1) < inSz) {
27338         /* prefix 0, may have */
27339         b = input[*inOutIdx];
27340         if (b == ECC_PREFIX_0) {
27341             *inOutIdx += 1;
27342 
27343             if (GetLength(input, inOutIdx, &length, inSz) <= 0)
27344                 ret = ASN_PARSE_E;
27345             else {
27346                 ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
27347                                   inSz);
27348                 if (ret == 0) {
27349                     if ((ret = CheckCurve(oidSum)) < 0)
27350                         ret = ECC_CURVE_OID_E;
27351                     else {
27352                         curve_id = ret;
27353                         ret = 0;
27354                     }
27355                 }
27356             }
27357         }
27358     }
27359 
27360     if (ret == 0 && (*inOutIdx + 1) < inSz) {
27361         /* prefix 1 */
27362         b = input[*inOutIdx];
27363         *inOutIdx += 1;
27364 
27365         if (b != ECC_PREFIX_1) {
27366             ret = ASN_ECC_KEY_E;
27367         }
27368         else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
27369             ret = ASN_PARSE_E;
27370         }
27371         else {
27372             /* key header */
27373             ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
27374             if (ret == 0) {
27375                 /* pub key */
27376                 pubSz = length;
27377                 if (pubSz > 2*(ECC_MAXSIZE+1))
27378                     ret = BUFFER_E;
27379                 else {
27380             #ifdef WOLFSSL_SMALL_STACK
27381                     pub = (byte*)XMALLOC(pubSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27382                     if (pub == NULL)
27383                         ret = MEMORY_E;
27384                     else
27385             #endif
27386                     {
27387                         XMEMCPY(pub, &input[*inOutIdx], pubSz);
27388                         *inOutIdx += length;
27389                         pubData = pub;
27390                     }
27391                 }
27392             }
27393         }
27394     }
27395 
27396     if (ret == 0) {
27397         ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,
27398                                                                       curve_id);
27399     }
27400 
27401 #ifdef WOLFSSL_SMALL_STACK
27402     XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27403     XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27404 #endif
27405 
27406     return ret;
27407 #else
27408     DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
27409     byte version;
27410     int ret = 0;
27411     int curve_id = ECC_CURVE_DEF;
27412 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
27413     word32 algId = 0;
27414 #endif
27415 
27416     /* Validate parameters. */
27417     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
27418         ret = BAD_FUNC_ARG;
27419     }
27420 
27421 #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
27422     /* if has pkcs8 header skip it */
27423     if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
27424         /* ignore error, did not have pkcs8 header */
27425     }
27426 #endif
27427 
27428     CALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
27429 
27430     if (ret == 0) {
27431         /* Get the version and set the expected OID type. */
27432         GetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], &version);
27433         GetASN_OID(&dataASN[ECCKEYASN_IDX_CURVEID], oidCurveType);
27434         /* Decode the private ECC key. */
27435         ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
27436                            inOutIdx, inSz);
27437     }
27438     /* Only version 1 supported. */
27439     if ((ret == 0) && (version != 1)) {
27440         ret = ASN_PARSE_E;
27441     }
27442     /* Curve Parameters are optional. */
27443     if ((ret == 0) && (dataASN[ECCKEYASN_IDX_PARAMS].tag != 0)) {
27444         if (dataASN[ECCKEYASN_IDX_CURVEID].tag != 0) {
27445             /* Named curve - check and get id. */
27446             curve_id = CheckCurve(dataASN[ECCKEYASN_IDX_CURVEID].data.oid.sum);
27447             if (curve_id < 0) {
27448                 ret = ECC_CURVE_OID_E;
27449             }
27450         }
27451         else {
27452     #ifdef WOLFSSL_CUSTOM_CURVES
27453             /* Parse explicit parameters. */
27454             ret = EccSpecifiedECDomainDecode(
27455                     dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.data,
27456                     dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.length, key);
27457     #else
27458             /* Explicit parameters not supported in build configuration. */
27459             ret = ASN_PARSE_E;
27460     #endif
27461         }
27462     }
27463     if (ret == 0) {
27464         /* Import private key value and public point (may be NULL). */
27465         ret = wc_ecc_import_private_key_ex(
27466                 dataASN[ECCKEYASN_IDX_PKEY].data.ref.data,
27467                 dataASN[ECCKEYASN_IDX_PKEY].data.ref.length,
27468                 dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.data,
27469                 dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.length,
27470                 key, curve_id);
27471     }
27472 
27473     FREE_ASNGETDATA(dataASN, key->heap);
27474     return ret;
27475 #endif
27476 }
27477 
27478 
27479 #ifdef WOLFSSL_CUSTOM_CURVES
27480 #ifndef WOLFSSL_ASN_TEMPLATE
27481 /* returns 0 on success */
27482 static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
27483                           word32 inSz, void* heap, int heapType)
27484 {
27485     int len;
27486     int i;
27487     char* str;
27488     word32 localIdx;
27489     byte   tag;
27490 
27491     if (*inOutIdx >= inSz) {
27492         return BUFFER_E;
27493     }
27494 
27495     localIdx = *inOutIdx;
27496     if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
27497         if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
27498             return ASN_PARSE_E;
27499     }
27500     else {
27501         if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
27502             return ASN_PARSE_E;
27503     }
27504 
27505     str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
27506     if (str == NULL) {
27507         return MEMORY_E;
27508     }
27509 
27510     for (i=0; i<len; i++)
27511         ByteToHexStr(input[*inOutIdx + i], str + i*2);
27512     str[len*2] = '\0';
27513 
27514     *inOutIdx += len;
27515     *out = str;
27516 
27517     (void)heap;
27518     (void)heapType;
27519 
27520     return 0;
27521 }
27522 
27523 static int EccKeyParamCopy(char** dst, char* src)
27524 {
27525     int ret = 0;
27526 #ifdef WOLFSSL_ECC_CURVE_STATIC
27527     word32 length;
27528 #endif
27529 
27530     if (dst == NULL || src == NULL)
27531         return BAD_FUNC_ARG;
27532 
27533 #ifndef WOLFSSL_ECC_CURVE_STATIC
27534     *dst = src;
27535 #else
27536     length = (int)XSTRLEN(src) + 1;
27537     if (length > MAX_ECC_STRING) {
27538         WOLFSSL_MSG("ECC Param too large for buffer");
27539         ret = BUFFER_E;
27540     }
27541     else {
27542         XSTRNCPY(*dst, src, MAX_ECC_STRING);
27543     }
27544     XFREE(src, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27545 #endif
27546 
27547     return ret;
27548 }
27549 #endif /* !WOLFSSL_ASN_TEMPLATE */
27550 #endif /* WOLFSSL_CUSTOM_CURVES */
27551 
27552 int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
27553                           ecc_key* key, word32 inSz)
27554 {
27555 #ifndef WOLFSSL_ASN_TEMPLATE
27556     int    ret;
27557     int    version, length;
27558     int    curve_id = ECC_CURVE_DEF;
27559     word32 oidSum, localIdx;
27560     byte   tag, isPrivFormat = 0;
27561 
27562     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
27563         return BAD_FUNC_ARG;
27564 
27565     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27566         return ASN_PARSE_E;
27567 
27568     /* Check if ECC private key is being used and skip private portion */
27569     if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) {
27570         isPrivFormat = 1;
27571 
27572         /* Type private key */
27573         if (*inOutIdx >= inSz)
27574             return ASN_PARSE_E;
27575         tag = input[*inOutIdx];
27576         *inOutIdx += 1;
27577         if (tag != 4 && tag != 6 && tag != 7)
27578             return ASN_PARSE_E;
27579 
27580         /* Skip Private Key */
27581         if (GetLength(input, inOutIdx, &length, inSz) < 0)
27582             return ASN_PARSE_E;
27583         if (length > ECC_MAXSIZE)
27584             return BUFFER_E;
27585         *inOutIdx += length;
27586 
27587         /* Private Curve Header */
27588         if (*inOutIdx >= inSz)
27589             return ASN_PARSE_E;
27590         tag = input[*inOutIdx];
27591         *inOutIdx += 1;
27592         if (tag != ECC_PREFIX_0)
27593             return ASN_ECC_KEY_E;
27594         if (GetLength(input, inOutIdx, &length, inSz) <= 0)
27595             return ASN_PARSE_E;
27596     }
27597     /* Standard ECC public key */
27598     else {
27599         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27600             return ASN_PARSE_E;
27601 
27602         ret = SkipObjectId(input, inOutIdx, inSz);
27603         if (ret != 0)
27604             return ret;
27605     }
27606 
27607     if (*inOutIdx >= inSz) {
27608         return BUFFER_E;
27609     }
27610 
27611     localIdx = *inOutIdx;
27612     if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
27613             tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
27614 #ifdef WOLFSSL_CUSTOM_CURVES
27615         ecc_set_type* curve;
27616         int len;
27617         char* point = NULL;
27618 
27619         ret = 0;
27620 
27621         curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
27622                                                        DYNAMIC_TYPE_ECC_BUFFER);
27623         if (curve == NULL)
27624             ret = MEMORY_E;
27625 
27626         if (ret == 0) {
27627             static const char customName[] = "Custom";
27628             XMEMSET(curve, 0, sizeof(*curve));
27629         #ifndef WOLFSSL_ECC_CURVE_STATIC
27630             curve->name = customName;
27631         #else
27632             XMEMCPY((void*)curve->name, customName, sizeof(customName));
27633         #endif
27634             curve->id = ECC_CURVE_CUSTOM;
27635 
27636             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27637                 ret = ASN_PARSE_E;
27638         }
27639 
27640         if (ret == 0) {
27641             GetInteger7Bit(input, inOutIdx, inSz);
27642             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27643                 ret = ASN_PARSE_E;
27644         }
27645         if (ret == 0) {
27646             char* p = NULL;
27647             SkipObjectId(input, inOutIdx, inSz);
27648             ret = ASNToHexString(input, inOutIdx, &p, inSz,
27649                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27650             if (ret == 0)
27651                 ret = EccKeyParamCopy((char**)&curve->prime, p);
27652         }
27653         if (ret == 0) {
27654             curve->size = (int)XSTRLEN(curve->prime) / 2;
27655 
27656             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
27657                 ret = ASN_PARSE_E;
27658         }
27659         if (ret == 0) {
27660             char* af = NULL;
27661             ret = ASNToHexString(input, inOutIdx, &af, inSz,
27662                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27663             if (ret == 0)
27664                 ret = EccKeyParamCopy((char**)&curve->Af, af);
27665         }
27666         if (ret == 0) {
27667             char* bf = NULL;
27668             ret = ASNToHexString(input, inOutIdx, &bf, inSz,
27669                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27670             if (ret == 0)
27671                 ret = EccKeyParamCopy((char**)&curve->Bf, bf);
27672         }
27673         if (ret == 0) {
27674             localIdx = *inOutIdx;
27675             if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
27676                     == 0 && tag == ASN_BIT_STRING) {
27677                 len = 0;
27678                 ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
27679                 if (ret > 0)
27680                     ret = 0; /* reset on success */
27681                 *inOutIdx += len;
27682             }
27683         }
27684         if (ret == 0) {
27685             ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
27686                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27687 
27688             /* sanity check that point buffer is not smaller than the expected
27689              * size to hold ( 0 4 || Gx || Gy )
27690              * where Gx and Gy are each the size of curve->size * 2 */
27691             if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
27692                 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27693                 ret = BUFFER_E;
27694             }
27695         }
27696         if (ret == 0) {
27697         #ifndef WOLFSSL_ECC_CURVE_STATIC
27698             curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
27699                                                        DYNAMIC_TYPE_ECC_BUFFER);
27700             curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
27701                                                        DYNAMIC_TYPE_ECC_BUFFER);
27702             if (curve->Gx == NULL || curve->Gy == NULL) {
27703                 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27704                 ret = MEMORY_E;
27705             }
27706         #else
27707             if (curve->size * 2 + 2 > MAX_ECC_STRING) {
27708                 WOLFSSL_MSG("curve size is too large to fit in buffer");
27709                 ret = BUFFER_E;
27710             }
27711         #endif
27712         }
27713         if (ret == 0) {
27714             char* o = NULL;
27715 
27716             XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
27717             XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
27718                                                                curve->size * 2);
27719             ((char*)curve->Gx)[curve->size * 2] = '\0';
27720             ((char*)curve->Gy)[curve->size * 2] = '\0';
27721             XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27722             ret = ASNToHexString(input, inOutIdx, &o, inSz,
27723                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
27724             if (ret == 0)
27725                 ret = EccKeyParamCopy((char**)&curve->order, o);
27726         }
27727         if (ret == 0) {
27728             curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
27729 
27730         #ifndef WOLFSSL_ECC_CURVE_STATIC
27731             curve->oid = NULL;
27732         #else
27733             XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
27734         #endif
27735             curve->oidSz = 0;
27736             curve->oidSum = 0;
27737 
27738             if (wc_ecc_set_custom_curve(key, curve) < 0) {
27739                 ret = ASN_PARSE_E;
27740             }
27741         #ifdef WOLFSSL_CUSTOM_CURVES
27742             key->deallocSet = 1;
27743         #endif
27744             curve = NULL;
27745         }
27746         if (curve != NULL)
27747             wc_ecc_free_curve(curve, key->heap);
27748 
27749         if (ret < 0)
27750             return ret;
27751 #else
27752         return ASN_PARSE_E;
27753 #endif /* WOLFSSL_CUSTOM_CURVES */
27754     }
27755     else {
27756         /* ecc params information */
27757         ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
27758         if (ret != 0)
27759             return ret;
27760 
27761         /* get curve id */
27762         if ((ret = CheckCurve(oidSum)) < 0)
27763             return ECC_CURVE_OID_E;
27764         else {
27765             curve_id = ret;
27766         }
27767     }
27768 
27769     if (isPrivFormat) {
27770         /* Public Curve Header - skip */
27771         if (*inOutIdx >= inSz)
27772             return ASN_PARSE_E;
27773         tag = input[*inOutIdx];
27774         *inOutIdx += 1;
27775         if (tag != ECC_PREFIX_1)
27776             return ASN_ECC_KEY_E;
27777         if (GetLength(input, inOutIdx, &length, inSz) <= 0)
27778             return ASN_PARSE_E;
27779     }
27780 
27781     /* key header */
27782     ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
27783     if (ret != 0)
27784         return ret;
27785 
27786     /* This is the raw point data compressed or uncompressed. */
27787     if (wc_ecc_import_x963_ex(input + *inOutIdx, length, key,
27788                                                             curve_id) != 0) {
27789         return ASN_ECC_KEY_E;
27790     }
27791 
27792     *inOutIdx += length;
27793 
27794     return 0;
27795 #else
27796     /* eccKeyASN is longer than eccPublicKeyASN. */
27797     DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
27798     int ret = 0;
27799     int curve_id = ECC_CURVE_DEF;
27800     int oidIdx = ECCPUBLICKEYASN_IDX_ALGOID_CURVEID;
27801 #ifdef WOLFSSL_CUSTOM_CURVES
27802     int specIdx = ECCPUBLICKEYASN_IDX_ALGOID_PARAMS;
27803 #endif
27804     int pubIdx = ECCPUBLICKEYASN_IDX_PUBKEY;
27805 
27806     if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
27807         ret = BAD_FUNC_ARG;
27808     }
27809 
27810     ALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
27811 
27812     if (ret == 0) {
27813         /* Clear dynamic data for ECC public key. */
27814         XMEMSET(dataASN, 0, sizeof(*dataASN) * eccPublicKeyASN_Length);
27815         /* Set required ECDSA OID and ignore the curve OID type. */
27816         GetASN_ExpBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], keyEcdsaOid,
27817                 sizeof(keyEcdsaOid));
27818         GetASN_OID(&dataASN[oidIdx], oidIgnoreType);
27819         /* Decode the public ECC key. */
27820         ret = GetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length, 1,
27821                            input, inOutIdx, inSz);
27822         if (ret != 0) {
27823             oidIdx = ECCKEYASN_IDX_CURVEID;
27824         #ifdef WOLFSSL_CUSTOM_CURVES
27825             specIdx = ECCKEYASN_IDX_CURVEPARAMS;
27826         #endif
27827             pubIdx = ECCKEYASN_IDX_PUBKEY_VAL;
27828 
27829             /* Clear dynamic data for ECC private key. */
27830             XMEMSET(dataASN, 0, sizeof(*dataASN) * eccKeyASN_Length);
27831             /* Check named curve OID type. */
27832             GetASN_OID(&dataASN[oidIdx], oidIgnoreType);
27833             /* Try private key format .*/
27834             ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
27835                                inOutIdx, inSz);
27836             if (ret != 0) {
27837                 ret = ASN_PARSE_E;
27838             }
27839         }
27840     }
27841 
27842     if (ret == 0) {
27843         if (dataASN[oidIdx].tag != 0) {
27844             /* Named curve - check and get id. */
27845             curve_id = CheckCurve(dataASN[oidIdx].data.oid.sum);
27846             if (curve_id < 0) {
27847                 ret = ASN_OBJECT_ID_E;
27848             }
27849         }
27850         else {
27851         #ifdef WOLFSSL_CUSTOM_CURVES
27852             /* Parse explicit parameters. */
27853             ret = EccSpecifiedECDomainDecode(dataASN[specIdx].data.ref.data,
27854                                          dataASN[specIdx].data.ref.length, key);
27855         #else
27856             /* Explicit parameters not supported in build configuration. */
27857             ret = ASN_PARSE_E;
27858         #endif
27859         }
27860     }
27861     if (ret == 0) {
27862         /* Import public point. */
27863         ret = wc_ecc_import_x963_ex(dataASN[pubIdx].data.ref.data,
27864                 dataASN[pubIdx].data.ref.length, key, curve_id);
27865         if (ret != 0) {
27866             ret = ASN_ECC_KEY_E;
27867         }
27868     }
27869 
27870     FREE_ASNGETDATA(dataASN, key->heap);
27871     return ret;
27872 #endif /* WOLFSSL_ASN_TEMPLATE */
27873 }
27874 
27875 #if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
27876 /* build DER formatted ECC key, include optional public key if requested,
27877  * return length on success, negative on error */
27878 static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
27879                              int pubIn, int curveIn)
27880 {
27881 #ifndef WOLFSSL_ASN_TEMPLATE
27882     byte   curve[MAX_ALGO_SZ+2];
27883     byte   ver[MAX_VERSION_SZ];
27884     byte   seq[MAX_SEQ_SZ];
27885     int    ret, totalSz, curveSz, verSz;
27886     int    privHdrSz  = ASN_ECC_HEADER_SZ;
27887     int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
27888 #ifdef WOLFSSL_NO_MALLOC
27889     byte   prv[MAX_ECC_BYTES + ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
27890     byte   pub[(MAX_ECC_BYTES * 2) + 1 + ASN_ECC_CONTEXT_SZ +
27891                               ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
27892 #else
27893     byte   *prv = NULL, *pub = NULL;
27894 #endif
27895 
27896     word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
27897     word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
27898 
27899     if (key == NULL || (output == NULL && inLen == NULL))
27900         return BAD_FUNC_ARG;
27901 
27902     if (curveIn) {
27903         /* curve */
27904         curve[curveidx++] = ECC_PREFIX_0;
27905         curveidx++ /* to put the size after computation */;
27906         curveSz = SetCurve(key, curve+curveidx);
27907         if (curveSz < 0)
27908             return curveSz;
27909         /* set computed size */
27910         curve[1] = (byte)curveSz;
27911         curveidx += curveSz;
27912     }
27913 
27914     /* private */
27915     privSz = key->dp->size;
27916 
27917 #ifdef WOLFSSL_QNX_CAAM
27918     /* check if is a black key, and add MAC size if so */
27919     if (key->blackKey > 0) {
27920         privSz = privSz + WC_CAAM_MAC_SZ;
27921     }
27922 #endif
27923 
27924 #ifndef WOLFSSL_NO_MALLOC
27925     prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
27926                          key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27927     if (prv == NULL) {
27928         return MEMORY_E;
27929     }
27930 #else
27931     if (sizeof(prv) < privSz + privHdrSz + MAX_SEQ_SZ) {
27932         return BUFFER_E;
27933     }
27934 #endif
27935     if (privSz < ASN_LONG_LENGTH) {
27936         prvidx += SetOctetString8Bit(privSz, &prv[prvidx]);
27937     }
27938     else {
27939         prvidx += SetOctetString(privSz, &prv[prvidx]);
27940     }
27941     ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
27942     if (ret < 0) {
27943     #ifndef WOLFSSL_NO_MALLOC
27944         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27945     #endif
27946         return ret;
27947     }
27948     prvidx += privSz;
27949 
27950     /* pubIn */
27951     if (pubIn) {
27952         PRIVATE_KEY_UNLOCK();
27953         ret = wc_ecc_export_x963(key, NULL, &pubSz);
27954         PRIVATE_KEY_LOCK();
27955         if (ret != LENGTH_ONLY_E) {
27956         #ifndef WOLFSSL_NO_MALLOC
27957             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27958         #endif
27959             return ret;
27960         }
27961 
27962     #ifndef WOLFSSL_NO_MALLOC
27963         pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
27964                              key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27965         if (pub == NULL) {
27966             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27967             return MEMORY_E;
27968         }
27969     #else
27970         if (sizeof(pub) < pubSz + pubHdrSz + MAX_SEQ_SZ) {
27971             return BUFFER_E;
27972         }
27973     #endif
27974 
27975         pub[pubidx++] = ECC_PREFIX_1;
27976         if (pubSz > 128) /* leading zero + extra size byte */
27977             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
27978         else /* leading zero */
27979             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
27980 
27981         /* SetBitString adds leading zero */
27982         pubidx += SetBitString(pubSz, 0, pub + pubidx);
27983         PRIVATE_KEY_UNLOCK();
27984         ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
27985         PRIVATE_KEY_LOCK();
27986         if (ret != 0) {
27987         #ifndef WOLFSSL_NO_MALLOC
27988             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27989             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
27990         #endif
27991             return ret;
27992         }
27993         pubidx += pubSz;
27994     }
27995 
27996     /* make headers */
27997     verSz = SetMyVersion(1, ver, FALSE);
27998     seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
27999 
28000     totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
28001     if (output == NULL) {
28002         *inLen = totalSz;
28003     #ifndef WOLFSSL_NO_MALLOC
28004         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28005         if (pub) {
28006             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28007         }
28008     #endif
28009         return LENGTH_ONLY_E;
28010     }
28011     if (inLen != NULL && totalSz > (int)*inLen) {
28012         #ifndef WOLFSSL_NO_MALLOC
28013         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28014         if (pubIn) {
28015             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28016         }
28017         #endif
28018         return BAD_FUNC_ARG;
28019     }
28020 
28021     /* write out */
28022     /* seq */
28023     XMEMCPY(output + idx, seq, seqSz);
28024     idx = seqSz;
28025 
28026     /* ver */
28027     XMEMCPY(output + idx, ver, verSz);
28028     idx += verSz;
28029 
28030     /* private */
28031     XMEMCPY(output + idx, prv, prvidx);
28032     idx += prvidx;
28033 #ifndef WOLFSSL_NO_MALLOC
28034     XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28035 #endif
28036 
28037     /* curve */
28038     XMEMCPY(output + idx, curve, curveidx);
28039     idx += curveidx;
28040 
28041     /* pubIn */
28042     if (pubIn) {
28043         XMEMCPY(output + idx, pub, pubidx);
28044         /* idx += pubidx;  not used after write, if more data remove comment */
28045     #ifndef WOLFSSL_NO_MALLOC
28046         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28047     #endif
28048     }
28049 
28050     return totalSz;
28051 #else
28052     DECL_ASNSETDATA(dataASN, eccKeyASN_Length);
28053     word32 privSz, pubSz;
28054     int sz = 0;
28055     int ret = 0;
28056 
28057     /* Check validity of parameters. */
28058     if ((key == NULL) || ((output == NULL) && (inLen == NULL))) {
28059         ret = BAD_FUNC_ARG;
28060     }
28061 
28062     /* Check key has parameters when encoding curve. */
28063     if ((ret == 0) && curveIn && (key->dp == NULL)) {
28064         ret = BAD_FUNC_ARG;
28065     }
28066 
28067     CALLOC_ASNSETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
28068 
28069     if (ret == 0) {
28070         /* Private key size is the curve size. */
28071         privSz = key->dp->size;
28072         if (pubIn) {
28073             /* Get the length of the public key. */
28074             PRIVATE_KEY_UNLOCK();
28075             ret = wc_ecc_export_x963(key, NULL, &pubSz);
28076             PRIVATE_KEY_LOCK();
28077             if (ret == LENGTH_ONLY_E)
28078                 ret = 0;
28079         }
28080     }
28081     if (ret == 0) {
28082         /* Version: 1 */
28083         SetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], 1);
28084         /* Leave space for private key. */
28085         SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PKEY], NULL, privSz);
28086         if (curveIn) {
28087             /* Curve OID */
28088             SetASN_Buffer(&dataASN[ECCKEYASN_IDX_CURVEID], key->dp->oid,
28089                     key->dp->oidSz);
28090             /* TODO: add support for SpecifiedECDomain curve. */
28091             dataASN[ECCKEYASN_IDX_CURVEPARAMS].noOut = 1;
28092         }
28093         else {
28094             SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PARAMS,
28095                     eccKeyASN_Length);
28096         }
28097         if (pubIn) {
28098             /* Leave space for public key. */
28099             SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PUBKEY_VAL], NULL, pubSz);
28100         }
28101         else {
28102             /* Don't write out public key. */
28103             SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PUBKEY,
28104                     eccKeyASN_Length);
28105         }
28106         /* Calculate size of the private key encoding. */
28107         ret = SizeASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, &sz);
28108     }
28109     /* Return the size if no buffer. */
28110     if ((ret == 0) && (output == NULL)) {
28111         *inLen = sz;
28112         ret = LENGTH_ONLY_E;
28113     }
28114     /* Check the buffer is big enough. */
28115     if ((ret == 0) && (inLen != NULL) && (sz > (int)*inLen)) {
28116         ret = BAD_FUNC_ARG;
28117     }
28118     if ((ret == 0) && (output != NULL)) {
28119         /* Encode the private key. */
28120         SetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, output);
28121 
28122         /* Export the private value into the buffer. */
28123         ret = wc_ecc_export_private_only(key,
28124                 (byte*)dataASN[ECCKEYASN_IDX_PKEY].data.buffer.data, &privSz);
28125         if ((ret == 0) && pubIn) {
28126             /* Export the public point into the buffer. */
28127             PRIVATE_KEY_UNLOCK();
28128             ret = wc_ecc_export_x963(key,
28129                     (byte*)dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.buffer.data,
28130                     &pubSz);
28131             PRIVATE_KEY_LOCK();
28132         }
28133     }
28134     if (ret == 0) {
28135         /* Return the encoding size. */
28136         ret = sz;
28137     }
28138 
28139     FREE_ASNSETDATA(dataASN, key->heap);
28140     return ret;
28141 #endif
28142 }
28143 
28144 /* Write a Private ecc key, including public to DER format,
28145  * length on success else < 0 */
28146 int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
28147 {
28148     return wc_BuildEccKeyDer(key, output, &inLen, 1, 1);
28149 }
28150 
28151 /* Write only private ecc key to DER format,
28152  * length on success else < 0 */
28153 int wc_EccKeyDerSize(ecc_key* key, int pub)
28154 {
28155     word32 sz = 0;
28156     int ret;
28157 
28158     ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);
28159 
28160     if (ret != LENGTH_ONLY_E) {
28161         return ret;
28162     }
28163     return sz;
28164  }
28165 
28166 /* Write only private ecc key to DER format,
28167  * length on success else < 0 */
28168 int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
28169 {
28170     return wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
28171 }
28172 
28173 
28174 
28175 #ifdef HAVE_PKCS8
28176 
28177 /* Write only private ecc key or both private and public parts to unencrypted
28178  * PKCS#8 format.
28179  *
28180  * If output is NULL, places required PKCS#8 buffer size in outLen and
28181  * returns LENGTH_ONLY_E.
28182  *
28183  * return length on success else < 0 */
28184 static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
28185         int includePublic)
28186 {
28187     int ret, tmpDerSz;
28188     int algoID = 0;
28189     word32 oidSz = 0;
28190     word32 pkcs8Sz = 0;
28191     const byte* curveOID = NULL;
28192 #ifdef WOLFSSL_NO_MALLOC
28193     byte  tmpDer[ECC_BUFSIZE];
28194 #else
28195     byte* tmpDer = NULL;
28196 #endif
28197     word32 sz = ECC_BUFSIZE;
28198 
28199     if (key == NULL || key->dp == NULL || outLen == NULL)
28200         return BAD_FUNC_ARG;
28201 
28202     /* set algoID, get curve OID */
28203     algoID = ECDSAk;
28204     ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
28205     if (ret < 0)
28206         return ret;
28207 
28208 #ifndef WOLFSSL_NO_MALLOC
28209     /* temp buffer for plain DER key */
28210     tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28211     if (tmpDer == NULL)
28212         return MEMORY_E;
28213 #endif
28214     XMEMSET(tmpDer, 0, ECC_BUFSIZE);
28215 
28216     ret = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic, 0);
28217     if (ret < 0) {
28218     #ifndef WOLFSSL_NO_MALLOC
28219         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28220     #endif
28221         return ret;
28222     }
28223     tmpDerSz = ret;
28224 
28225     /* get pkcs8 expected output size */
28226     ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
28227                             curveOID, oidSz);
28228     if (ret != LENGTH_ONLY_E) {
28229     #ifndef WOLFSSL_NO_MALLOC
28230         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28231     #endif
28232         return ret;
28233     }
28234 
28235     if (output == NULL) {
28236     #ifndef WOLFSSL_NO_MALLOC
28237         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28238     #endif
28239         *outLen = pkcs8Sz;
28240         return LENGTH_ONLY_E;
28241 
28242     }
28243     else if (*outLen < pkcs8Sz) {
28244     #ifndef WOLFSSL_NO_MALLOC
28245         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28246     #endif
28247         WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
28248         return BUFFER_E;
28249     }
28250 
28251     ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
28252                             algoID, curveOID, oidSz);
28253     if (ret < 0) {
28254     #ifndef WOLFSSL_NO_MALLOC
28255         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28256     #endif
28257         return ret;
28258     }
28259 
28260 #ifndef WOLFSSL_NO_MALLOC
28261     XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
28262 #endif
28263 
28264     *outLen = ret;
28265     return ret;
28266 }
28267 
28268 /* Write only private ecc key to unencrypted PKCS#8 format.
28269  *
28270  * return length on success else < 0 */
28271 int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
28272 {
28273     return eccToPKCS8(key, output, outLen, 0);
28274 }
28275 
28276 /* Write both private and public ecc keys to unencrypted PKCS#8 format.
28277  *
28278  * return length on success else < 0 */
28279 int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
28280                      word32* outLen)
28281 {
28282     return eccToPKCS8(key, output, outLen, 1);
28283 }
28284 #endif /* HAVE_PKCS8 */
28285 #endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
28286 #endif /* HAVE_ECC */
28287 
28288 #ifdef WC_ENABLE_ASYM_KEY_IMPORT
28289 #ifdef WOLFSSL_ASN_TEMPLATE
28290 /* ASN.1 template for Ed25519 and Ed448 private key.
28291  * RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING)
28292  */
28293 static const ASNItem edKeyASN[] = {
28294 /* SEQ            */    { 0, ASN_SEQUENCE, 1, 1, 0 },
28295                                          /* Version */
28296 /* VER            */        { 1, ASN_INTEGER, 0, 0, 0 },
28297                                          /* privateKeyAlgorithm */
28298 /* PKEYALGO_SEQ   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
28299 /* PKEYALGO_OID   */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
28300                                          /* privateKey */
28301 /* PKEY           */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
28302                                              /* CurvePrivateKey */
28303 /* PKEY_CURVEPKEY */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
28304                                          /* attributes */
28305 /* ATTRS          */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 },
28306                                          /* publicKey */
28307 /* PUBKEY         */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY, 1, 1, 1 },
28308                                              /* Public value */
28309 /* PUBKEY_VAL     */            { 2, ASN_OCTET_STRING, 0, 0, 0 }
28310 };
28311 enum {
28312     EDKEYASN_IDX_SEQ = 0,
28313     EDKEYASN_IDX_VER,
28314     EDKEYASN_IDX_PKEYALGO_SEQ,
28315     EDKEYASN_IDX_PKEYALGO_OID,
28316     EDKEYASN_IDX_PKEY,
28317     EDKEYASN_IDX_PKEY_CURVEPKEY,
28318     EDKEYASN_IDX_ATTRS,
28319     EDKEYASN_IDX_PUBKEY,
28320     EDKEYASN_IDX_PUBKEY_VAL,
28321 };
28322 
28323 /* Number of items in ASN.1 template for Ed25519 and Ed448 private key. */
28324 #define edKeyASN_Length (sizeof(edKeyASN) / sizeof(ASNItem))
28325 #endif
28326 
28327 static int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
28328     byte* privKey, word32* privKeyLen,
28329     byte* pubKey, word32* pubKeyLen, int keyType)
28330 {
28331 #ifndef WOLFSSL_ASN_TEMPLATE
28332     word32 oid;
28333     int version, length, endKeyIdx, privSz, pubSz;
28334     const byte* priv;
28335     const byte* pub;
28336 #else
28337     DECL_ASNGETDATA(dataASN, edKeyASN_Length);
28338 #endif
28339 
28340     if (input == NULL || inOutIdx == NULL || inSz == 0 ||
28341         privKey == NULL || privKeyLen == NULL) {
28342         return BAD_FUNC_ARG;
28343     }
28344 
28345 #ifndef WOLFSSL_ASN_TEMPLATE
28346     if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
28347         endKeyIdx = *inOutIdx + length;
28348 
28349         if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
28350             return ASN_PARSE_E;
28351         if (version != 0) {
28352             WOLFSSL_MSG("Unrecognized version of ED25519 private key");
28353             return ASN_PARSE_E;
28354         }
28355 
28356         if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
28357             return ASN_PARSE_E;
28358         if (oid != (word32)keyType)
28359             return ASN_PARSE_E;
28360 
28361         if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
28362             return ASN_PARSE_E;
28363 
28364         if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
28365             return ASN_PARSE_E;
28366 
28367         priv = input + *inOutIdx;
28368         *inOutIdx += privSz;
28369     }
28370     else {
28371         if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
28372             return ASN_PARSE_E;
28373 
28374         priv = input + *inOutIdx;
28375         *inOutIdx += privSz;
28376         endKeyIdx = *inOutIdx;
28377     }
28378 
28379     if ((word32)privSz > *privKeyLen)
28380         return BUFFER_E;
28381 
28382     if (endKeyIdx == (int)*inOutIdx) {
28383         *privKeyLen = privSz;
28384         XMEMCPY(privKey, priv, *privKeyLen);
28385         if (pubKeyLen != NULL)
28386             *pubKeyLen = 0;
28387     }
28388     else {
28389         if (pubKeyLen == NULL) {
28390             return BAD_FUNC_ARG;
28391         }
28392 
28393         if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
28394                          inOutIdx, &length, inSz) < 0) {
28395             return ASN_PARSE_E;
28396         }
28397         if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0) {
28398             return ASN_PARSE_E;
28399         }
28400 
28401         if ((word32)pubSz > *pubKeyLen)
28402             return BUFFER_E;
28403 
28404         pub = input + *inOutIdx;
28405         *inOutIdx += pubSz;
28406 
28407         *privKeyLen = privSz;
28408         XMEMCPY(privKey, priv, *privKeyLen);
28409         if (pubKeyLen != NULL)
28410             *pubKeyLen = pubSz;
28411         if (pubKey != NULL && pubKeyLen != NULL)
28412             XMEMCPY(pubKey, pub, *pubKeyLen);
28413     }
28414     if (endKeyIdx != (int)*inOutIdx)
28415         return ASN_PARSE_E;
28416     return 0;
28417 #else
28418     int ret = 0;
28419 
28420     CALLOC_ASNGETDATA(dataASN, edKeyASN_Length, ret, NULL);
28421 
28422     if (ret == 0) {
28423         /* Require OID. */
28424         word32 oidSz;
28425         const byte* oid = OidFromId(keyType, oidKeyType, &oidSz);
28426         GetASN_ExpBuffer(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], oid, oidSz);
28427         /* Parse full private key. */
28428         ret = GetASN_Items(edKeyASN, dataASN, edKeyASN_Length, 1, input,
28429                 inOutIdx, inSz);
28430         if (ret != 0) {
28431             /* Parse just the OCTET_STRING. */
28432             ret = GetASN_Items(&edKeyASN[EDKEYASN_IDX_PKEY_CURVEPKEY],
28433                     &dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], 1, 0, input,
28434                     inOutIdx, inSz);
28435             if (ret != 0) {
28436                 ret = ASN_PARSE_E;
28437             }
28438         }
28439     }
28440     /* Check the private value length is correct. */
28441     if ((ret == 0) && dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length
28442             > *privKeyLen) {
28443         ret = ASN_PARSE_E;
28444     }
28445     if ((ret == 0) && dataASN[EDKEYASN_IDX_PUBKEY].tag == 0) {
28446         *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
28447         XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
28448                 *privKeyLen);
28449         if (pubKeyLen != NULL)
28450             *pubKeyLen = 0;
28451     }
28452     else if ((ret == 0) &&
28453              (dataASN[EDKEYASN_IDX_PUBKEY_VAL].data.ref.length > *pubKeyLen)) {
28454         ret = ASN_PARSE_E;
28455     }
28456     else if (ret == 0) {
28457         /* Import private and public value. */
28458         *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
28459         XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
28460                 *privKeyLen);
28461         if (pubKeyLen != NULL)
28462             *pubKeyLen = dataASN[EDKEYASN_IDX_PUBKEY_VAL].data.ref.length;
28463         if (pubKey != NULL && pubKeyLen != NULL)
28464             XMEMCPY(pubKey, dataASN[EDKEYASN_IDX_PUBKEY_VAL].data.ref.data,
28465                     *pubKeyLen);
28466     }
28467 
28468     FREE_ASNGETDATA(dataASN, NULL);
28469     return ret;
28470 #endif /* WOLFSSL_ASN_TEMPLATE */
28471 }
28472 
28473 static int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz,
28474     byte* pubKey, word32* pubKeyLen, int keyType)
28475 {
28476     int ret = 0;
28477 #ifndef WOLFSSL_ASN_TEMPLATE
28478     int length;
28479     word32 oid;
28480 #else
28481     word32 len;
28482     DECL_ASNGETDATA(dataASN, edPubKeyASN_Length);
28483 #endif
28484 
28485     if (input == NULL || inSz == 0 || inOutIdx == NULL ||
28486         pubKey == NULL || pubKeyLen == NULL) {
28487         return BAD_FUNC_ARG;
28488     }
28489 
28490 #ifndef WOLFSSL_ASN_TEMPLATE
28491     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
28492         return ASN_PARSE_E;
28493 
28494     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
28495         return ASN_PARSE_E;
28496 
28497     if (GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
28498         return ASN_PARSE_E;
28499     if (oid != (word32)keyType)
28500         return ASN_PARSE_E;
28501 
28502     /* key header */
28503     ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
28504     if (ret != 0)
28505         return ret;
28506 
28507     /* check that the value found is not too large for pubKey buffer */
28508     if ((word32)length > *pubKeyLen)
28509         return ASN_PARSE_E;
28510 
28511     /* check that input buffer is exhausted */
28512     if (*inOutIdx + (word32)length != inSz)
28513         return ASN_PARSE_E;
28514 
28515     /* This is the raw point data compressed or uncompressed. */
28516     *pubKeyLen = length;
28517     XMEMCPY(pubKey, input + *inOutIdx, *pubKeyLen);
28518 #else
28519     len = inSz - *inOutIdx;
28520 
28521     CALLOC_ASNGETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
28522 
28523     if (ret == 0) {
28524         /* Require OID. */
28525         word32 oidSz;
28526         const byte* oid = OidFromId(keyType, oidKeyType, &oidSz);
28527 
28528         GetASN_ExpBuffer(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], oid, oidSz);
28529         /* Decode Ed25519 private key. */
28530         ret = GetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, 1, input,
28531                 inOutIdx, inSz);
28532         if (ret != 0)
28533             ret = ASN_PARSE_E;
28534         /* check that input buffer is exhausted */
28535         if (*inOutIdx != inSz)
28536             ret = ASN_PARSE_E;
28537     }
28538     /* Check the public value length is correct. */
28539     if ((ret == 0) &&
28540             (dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length > *pubKeyLen)) {
28541         ret = ASN_PARSE_E;
28542     }
28543     /* Check that the all the buffer was used. */
28544     if ((ret == 0) &&
28545             (GetASNItem_Length(dataASN[EDPUBKEYASN_IDX_SEQ], input) != len)) {
28546         ret = ASN_PARSE_E;
28547     }
28548     if (ret == 0) {
28549         *pubKeyLen = dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length;
28550         XMEMCPY(pubKey, dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.data,
28551                 *pubKeyLen);
28552     }
28553 
28554     FREE_ASNGETDATA(dataASN, NULL);
28555 #endif /* WOLFSSL_ASN_TEMPLATE */
28556     return ret;
28557 }
28558 #endif /* WC_ENABLE_ASYM_KEY_IMPORT */
28559 
28560 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
28561 int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
28562                                ed25519_key* key, word32 inSz)
28563 {
28564     int ret;
28565     byte privKey[ED25519_KEY_SIZE], pubKey[ED25519_PUB_KEY_SIZE];
28566     word32 privKeyLen = (word32)sizeof(privKey);
28567     word32 pubKeyLen = (word32)sizeof(pubKey);
28568 
28569     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28570         return BAD_FUNC_ARG;
28571     }
28572 
28573     ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
28574         pubKey, &pubKeyLen, ED25519k);
28575     if (ret == 0) {
28576         if (pubKeyLen == 0) {
28577             ret = wc_ed25519_import_private_only(privKey, privKeyLen, key);
28578         }
28579         else {
28580             ret = wc_ed25519_import_private_key(privKey, privKeyLen,
28581                 pubKey, pubKeyLen, key);
28582         }
28583     }
28584     return ret;
28585 }
28586 
28587 int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
28588                               ed25519_key* key, word32 inSz)
28589 {
28590     int ret;
28591     byte pubKey[ED25519_PUB_KEY_SIZE];
28592     word32 pubKeyLen = (word32)sizeof(pubKey);
28593 
28594     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28595         return BAD_FUNC_ARG;
28596     }
28597 
28598     ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
28599         pubKey, &pubKeyLen, ED25519k);
28600     if (ret == 0) {
28601         ret = wc_ed25519_import_public(pubKey, pubKeyLen, key);
28602     }
28603     return ret;
28604 }
28605 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
28606 
28607 #if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)
28608 int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
28609                                curve25519_key* key, word32 inSz)
28610 {
28611     int ret;
28612     byte privKey[CURVE25519_KEYSIZE];
28613     word32 privKeyLen = CURVE25519_KEYSIZE;
28614 
28615     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28616         return BAD_FUNC_ARG;
28617     }
28618 
28619     ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
28620         NULL, NULL, X25519k);
28621     if (ret == 0) {
28622         ret = wc_curve25519_import_private(privKey, privKeyLen, key);
28623     }
28624     return ret;
28625 }
28626 
28627 int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
28628                               curve25519_key* key, word32 inSz)
28629 {
28630     int ret;
28631     byte pubKey[CURVE25519_KEYSIZE];
28632     word32 pubKeyLen = (word32)sizeof(pubKey);
28633 
28634     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28635         return BAD_FUNC_ARG;
28636     }
28637 
28638     ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
28639         pubKey, &pubKeyLen, X25519k);
28640     if (ret == 0) {
28641         ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
28642     }
28643     return ret;
28644 }
28645 #endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */
28646 
28647 
28648 #ifdef WC_ENABLE_ASYM_KEY_EXPORT
28649 
28650 /* Build ASN.1 formatted key based on RFC 5958 (Asymmetric Key Packages)
28651  *
28652  * Pass NULL for output to get the size of the encoding.
28653  *
28654  * @param [in]  privKey      private key buffer
28655  * @param [in]  privKeyLen   private ket buffer length
28656  * @param [in]  pubKey       public key buffer (optional)
28657  * @param [in]  pubKeyLen    public ket buffer length
28658  * @param [out] output       Buffer to put encoded data in (optional)
28659  * @param [in]  outLen       Size of buffer in bytes
28660  * @param [in]  keyType      is "enum Key_Sum" like ED25519k
28661  * @return  Size of encoded data in bytes on success
28662  * @return  BAD_FUNC_ARG when key is NULL.
28663  * @return  MEMORY_E when dynamic memory allocation failed.
28664  * @return  LENGTH_ONLY_E return length only.
28665  */
28666 static int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
28667     const byte* pubKey, word32 pubKeyLen,
28668     byte* output, word32 outLen, int keyType)
28669 {
28670     int ret = 0;
28671 #ifndef WOLFSSL_ASN_TEMPLATE
28672     word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0, sz;
28673 #else
28674     DECL_ASNSETDATA(dataASN, edKeyASN_Length);
28675     int sz;
28676 #endif
28677 
28678     /* Validate parameters. */
28679     if (privKey == NULL || outLen == 0) {
28680         return BAD_FUNC_ARG;
28681     }
28682 
28683 #ifndef WOLFSSL_ASN_TEMPLATE
28684     /* calculate size */
28685     if (pubKey) {
28686         pubSz = 2 + 2 + pubKeyLen;
28687     }
28688     privSz = 2 + 2 + privKeyLen;
28689     algoSz = SetAlgoID(keyType, NULL, oidKeyType, 0);
28690     verSz  = 3; /* version is 3 bytes (enum + id + version(byte)) */
28691     seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, NULL);
28692     sz = seqSz + verSz + algoSz + privSz + pubSz;
28693 
28694     /* checkout output size */
28695     if (output != NULL && sz > outLen) {
28696         ret = BAD_FUNC_ARG;
28697     }
28698 
28699     if (ret == 0 && output != NULL) {
28700         /* write out */
28701         /* seq */
28702         seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, output);
28703         idx = seqSz;
28704         /* ver */
28705         SetMyVersion(0, output + idx, FALSE);
28706         idx += verSz;
28707         /* algo */
28708         algoSz = SetAlgoID(keyType, output + idx, oidKeyType, 0);
28709         idx += algoSz;
28710         /* privKey */
28711         idx += SetOctetString(2 + privKeyLen, output + idx);
28712         idx += SetOctetString(privKeyLen, output + idx);
28713         XMEMCPY(output + idx, privKey, privKeyLen);
28714         idx += privKeyLen;
28715         /* pubKey */
28716         if (pubKey) {
28717             idx += SetExplicit(1, 2 + pubKeyLen, output + idx);
28718             idx += SetOctetString(pubKeyLen, output + idx);
28719             XMEMCPY(output + idx, pubKey, pubKeyLen);
28720             idx += pubKeyLen;
28721         }
28722 
28723         ret = idx;
28724     }
28725 #else
28726 
28727     CALLOC_ASNSETDATA(dataASN, edKeyASN_Length, ret, NULL);
28728 
28729     if (ret == 0) {
28730         /* Set version = 0 */
28731         SetASN_Int8Bit(&dataASN[EDKEYASN_IDX_VER], 0);
28732         /* Set OID. */
28733         SetASN_OID(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], keyType, oidKeyType);
28734         /* Leave space for private key. */
28735         SetASN_Buffer(&dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen);
28736         /* Don't write out attributes. */
28737         dataASN[EDKEYASN_IDX_ATTRS].noOut = 1;
28738         if (pubKey) {
28739             /* Leave space for public key. */
28740             SetASN_Buffer(&dataASN[EDKEYASN_IDX_PUBKEY_VAL], NULL, pubKeyLen);
28741         }
28742         else {
28743             /* Don't put out public part. */
28744             SetASNItem_NoOutNode(dataASN, edKeyASN, EDKEYASN_IDX_PUBKEY,
28745                     edKeyASN_Length);
28746         }
28747 
28748         /* Calculate the size of encoding. */
28749         ret = SizeASN_Items(edKeyASN, dataASN, edKeyASN_Length, &sz);
28750     }
28751 
28752     /* Check buffer is big enough. */
28753     if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
28754         ret = BAD_FUNC_ARG;
28755     }
28756     if ((ret == 0) && (output != NULL)) {
28757         /* Encode private key. */
28758         SetASN_Items(edKeyASN, dataASN, edKeyASN_Length, output);
28759 
28760         /* Put private value into space provided. */
28761         XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.buffer.data,
28762                 privKey, privKeyLen);
28763 
28764         if (pubKey != NULL) {
28765             /* Put public value into space provided. */
28766             XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PUBKEY_VAL].data.buffer.data,
28767                     pubKey, pubKeyLen);
28768         }
28769 
28770         /* Return size of encoding. */
28771         ret = sz;
28772     }
28773 
28774     FREE_ASNSETDATA(dataASN, NULL);
28775 #endif
28776     return ret;
28777 }
28778 #endif /* WC_ENABLE_ASYM_KEY_EXPORT */
28779 
28780 #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
28781 /* Write a Private ED25519 key, including public to DER format,
28782  * length on success else < 0 */
28783 int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
28784 {
28785     if (key == NULL) {
28786         return BAD_FUNC_ARG;
28787     }
28788     return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
28789         key->p, ED25519_PUB_KEY_SIZE, output, inLen, ED25519k);
28790 }
28791 
28792 /* Write only private ED25519 key to DER format,
28793  * length on success else < 0 */
28794 int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
28795 {
28796     if (key == NULL) {
28797         return BAD_FUNC_ARG;
28798     }
28799     return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
28800         NULL, 0, output, inLen, ED25519k);
28801 }
28802 #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
28803 
28804 #if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
28805 /* Write only private Curve25519 key to DER format,
28806  * length on success else < 0 */
28807 int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output, word32 inLen)
28808 {
28809     int    ret;
28810     byte   privKey[CURVE25519_KEYSIZE];
28811     word32 privKeyLen = CURVE25519_KEYSIZE;
28812 
28813     if (key == NULL) {
28814         return BAD_FUNC_ARG;
28815     }
28816 
28817     ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
28818     if (ret == 0) {
28819         ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
28820             X25519k);
28821     }
28822     return ret;
28823 }
28824 
28825 /* Write a public Curve25519 key to DER format,
28826  * length on success else < 0 */
28827 int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
28828                              int withAlg)
28829 {
28830     int    ret;
28831     byte   pubKey[CURVE25519_KEYSIZE];
28832     word32 pubKeyLen = (word32)sizeof(pubKey);
28833 
28834     if (key == NULL || output == NULL) {
28835         return BAD_FUNC_ARG;
28836     }
28837 
28838     ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
28839     if (ret == 0) {
28840         ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
28841             X25519k, withAlg);
28842     }
28843     return ret;
28844 }
28845 #endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */
28846 
28847 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
28848 int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx,
28849                                ed448_key* key, word32 inSz)
28850 {
28851     int ret;
28852     byte privKey[ED448_KEY_SIZE], pubKey[ED448_PUB_KEY_SIZE];
28853     word32 privKeyLen = (word32)sizeof(privKey);
28854     word32 pubKeyLen = (word32)sizeof(pubKey);
28855 
28856     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28857         return BAD_FUNC_ARG;
28858     }
28859 
28860     ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
28861         pubKey, &pubKeyLen, ED448k);
28862     if (ret == 0) {
28863         if (pubKeyLen == 0) {
28864             ret = wc_ed448_import_private_only(privKey, privKeyLen, key);
28865         }
28866         else {
28867             ret = wc_ed448_import_private_key(privKey, privKeyLen,
28868                 pubKey, pubKeyLen, key);
28869         }
28870     }
28871     return ret;
28872 }
28873 
28874 int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
28875                               ed448_key* key, word32 inSz)
28876 {
28877     int ret;
28878     byte pubKey[ED448_PUB_KEY_SIZE];
28879     word32 pubKeyLen = (word32)sizeof(pubKey);
28880 
28881     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28882         return BAD_FUNC_ARG;
28883     }
28884 
28885     ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
28886         pubKey, &pubKeyLen, ED448k);
28887     if (ret == 0) {
28888         ret = wc_ed448_import_public(pubKey, pubKeyLen, key);
28889     }
28890     return ret;
28891 }
28892 #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
28893 
28894 #if defined(HAVE_PQC)
28895 int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
28896                                      falcon_key* key, word32 inSz)
28897 {
28898     int ret = 0;
28899     byte privKey[FALCON_MAX_KEY_SIZE], pubKey[FALCON_MAX_PUB_KEY_SIZE];
28900     word32 privKeyLen = (word32)sizeof(privKey);
28901     word32 pubKeyLen = (word32)sizeof(pubKey);
28902     int keytype = 0;
28903 
28904     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28905         return BAD_FUNC_ARG;
28906     }
28907 
28908     if (key->level == 1) {
28909         keytype = FALCON_LEVEL1k;
28910     }
28911     else if (key->level == 5) {
28912         keytype = FALCON_LEVEL5k;
28913     }
28914     else {
28915         return BAD_FUNC_ARG;
28916     }
28917 
28918     ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
28919                         pubKey, &pubKeyLen, keytype);
28920     if (ret == 0) {
28921         if (pubKeyLen == 0) {
28922             ret = wc_falcon_import_private_only(input, inSz, key);
28923         }
28924         else {
28925             ret = wc_falcon_import_private_key(privKey, privKeyLen,
28926                                                pubKey, pubKeyLen, key);
28927         }
28928     }
28929     return ret;
28930 }
28931 
28932 int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
28933                                     falcon_key* key, word32 inSz)
28934 {
28935     int ret = 0;
28936     byte pubKey[FALCON_MAX_PUB_KEY_SIZE];
28937     word32 pubKeyLen = (word32)sizeof(pubKey);
28938     int keytype = 0;
28939 
28940     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28941         return BAD_FUNC_ARG;
28942     }
28943 
28944     if (key->level == 1) {
28945         keytype = FALCON_LEVEL1k;
28946     }
28947     else if (key->level == 5) {
28948         keytype = FALCON_LEVEL5k;
28949     }
28950     else {
28951         return BAD_FUNC_ARG;
28952     }
28953 
28954     ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen,
28955                               keytype);
28956     if (ret == 0) {
28957         ret = wc_falcon_import_public(pubKey, pubKeyLen, key);
28958     }
28959     return ret;
28960 }
28961 #endif /* HAVE_PQC */
28962 
28963 #if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
28964 int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
28965                                curve448_key* key, word32 inSz)
28966 {
28967     int ret;
28968     byte privKey[CURVE448_KEY_SIZE];
28969     word32 privKeyLen = CURVE448_KEY_SIZE;
28970 
28971     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28972         return BAD_FUNC_ARG;
28973     }
28974 
28975     ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
28976         NULL, NULL, X448k);
28977     if (ret == 0) {
28978         ret = wc_curve448_import_private(privKey, privKeyLen, key);
28979     }
28980     return ret;
28981 }
28982 
28983 int wc_Curve448PublicKeyDecode(const byte* input, word32* inOutIdx,
28984                               curve448_key* key, word32 inSz)
28985 {
28986     int ret;
28987     byte pubKey[CURVE448_PUB_KEY_SIZE];
28988     word32 pubKeyLen = (word32)sizeof(pubKey);
28989 
28990     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
28991         return BAD_FUNC_ARG;
28992     }
28993 
28994     ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
28995         pubKey, &pubKeyLen, X448k);
28996     if (ret == 0) {
28997         ret = wc_curve448_import_public(pubKey, pubKeyLen, key);
28998     }
28999     return ret;
29000 }
29001 #endif /* HAVE_CURVE448 && HAVE_ED448_KEY_IMPORT */
29002 
29003 #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
29004 /* Write a Private ecc key, including public to DER format,
29005  * length on success else < 0 */
29006 int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen)
29007 {
29008     if (key == NULL) {
29009         return BAD_FUNC_ARG;
29010     }
29011     return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
29012         key->p, ED448_KEY_SIZE, output, inLen, ED448k);
29013 }
29014 
29015 /* Write only private ecc key to DER format,
29016  * length on success else < 0 */
29017 int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
29018 {
29019     if (key == NULL) {
29020         return BAD_FUNC_ARG;
29021     }
29022     return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
29023         NULL, 0, output, inLen, ED448k);
29024 }
29025 
29026 #endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
29027 
29028 #if defined(HAVE_PQC)
29029 int wc_Falcon_KeyToDer(falcon_key* key, byte* output, word32 inLen)
29030 {
29031     if (key == NULL) {
29032         return BAD_FUNC_ARG;
29033     }
29034 
29035     if (key->level == 1) {
29036         return SetAsymKeyDer(key->k, FALCON_LEVEL1_KEY_SIZE, key->p,
29037                              FALCON_LEVEL1_KEY_SIZE, output, inLen,
29038                              FALCON_LEVEL1k);
29039     }
29040     else if (key->level == 5) {
29041         return SetAsymKeyDer(key->k, FALCON_LEVEL5_KEY_SIZE, key->p,
29042                              FALCON_LEVEL5_KEY_SIZE, output, inLen,
29043                              FALCON_LEVEL5k);
29044     }
29045 
29046     return BAD_FUNC_ARG;
29047 }
29048 
29049 int wc_Falcon_PrivateKeyToDer(falcon_key* key, byte* output, word32 inLen)
29050 {
29051     if (key == NULL) {
29052         return BAD_FUNC_ARG;
29053     }
29054 
29055     if (key->level == 1) {
29056         return SetAsymKeyDer(key->k, FALCON_LEVEL1_KEY_SIZE, NULL, 0, output,
29057                              inLen, FALCON_LEVEL1k);
29058     }
29059     else if (key->level == 5) {
29060         return SetAsymKeyDer(key->k, FALCON_LEVEL5_KEY_SIZE, NULL, 0, output,
29061                              inLen, FALCON_LEVEL5k);
29062     }
29063 
29064     return BAD_FUNC_ARG;
29065 }
29066 
29067 #endif /* HAVE_PQC */
29068 
29069 #if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
29070 /* Write private Curve448 key to DER format,
29071  * length on success else < 0 */
29072 int wc_Curve448PrivateKeyToDer(curve448_key* key, byte* output, word32 inLen)
29073 {
29074     int    ret;
29075     byte   privKey[CURVE448_KEY_SIZE];
29076     word32 privKeyLen = CURVE448_KEY_SIZE;
29077 
29078     if (key == NULL) {
29079         return BAD_FUNC_ARG;
29080     }
29081 
29082     ret = wc_curve448_export_private_raw(key, privKey, &privKeyLen);
29083     if (ret == 0) {
29084         ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
29085             X448k);
29086     }
29087     return ret;
29088 }
29089 /* Write a public Curve448 key to DER format,
29090  * length on success else < 0 */
29091 int wc_Curve448PublicKeyToDer(curve448_key* key, byte* output, word32 inLen,
29092                              int withAlg)
29093 {
29094     int    ret;
29095     byte   pubKey[CURVE448_PUB_KEY_SIZE];
29096     word32 pubKeyLen = (word32)sizeof(pubKey);
29097 
29098     if (key == NULL || output == NULL) {
29099         return BAD_FUNC_ARG;
29100     }
29101 
29102     ret = wc_curve448_export_public(key, pubKey, &pubKeyLen);
29103     if (ret == 0) {
29104         ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
29105             X448k, withAlg);
29106     }
29107     return ret;
29108 }
29109 #endif /* HAVE_CURVE448 && HAVE_CURVE448_KEY_EXPORT */
29110 
29111 
29112 #ifndef WOLFSSL_ASN_TEMPLATE
29113 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
29114 
29115 /* Get raw Date only, no processing, 0 on success */
29116 static int GetBasicDate(const byte* source, word32* idx, byte* date,
29117                         byte* format, int maxIdx)
29118 {
29119     int    ret, length;
29120     const byte *datePtr = NULL;
29121 
29122     WOLFSSL_ENTER("GetBasicDate");
29123 
29124     ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
29125     if (ret < 0)
29126         return ret;
29127 
29128     XMEMCPY(date, datePtr, length);
29129 
29130     return 0;
29131 }
29132 
29133 #endif /* HAVE_OCSP || HAVE_CRL */
29134 #endif /* WOLFSSL_ASN_TEMPLATE */
29135 
29136 
29137 #ifdef HAVE_OCSP
29138 
29139 #ifndef WOLFSSL_ASN_TEMPLATE
29140 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
29141         int sz)
29142 {
29143     word32 idx = *inOutIdx;
29144     word32 len;
29145     byte   tag;
29146 
29147     WOLFSSL_ENTER("GetEnumerated");
29148 
29149     *value = 0;
29150 
29151     if (GetASNTag(input, &idx, &tag, sz) < 0)
29152         return ASN_PARSE_E;
29153 
29154     if (tag != ASN_ENUMERATED)
29155         return ASN_PARSE_E;
29156 
29157     if ((int)idx >= sz)
29158         return BUFFER_E;
29159 
29160     len = input[idx++];
29161     if (len > 4 || (int)(len + idx) > sz)
29162         return ASN_PARSE_E;
29163 
29164     while (len--) {
29165         *value  = *value << 8 | input[idx++];
29166     }
29167 
29168     *inOutIdx = idx;
29169 
29170     return *value;
29171 }
29172 #endif /* !WOLFSSL_ASN_TEMPLATE */
29173 
29174 
29175 #ifdef WOLFSSL_ASN_TEMPLATE
29176 /* ASN.1 template for OCSP single response.
29177  * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
29178  */
29179 static const ASNItem singleResponseASN[] = {
29180 /* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
29181                                                       /* certId */
29182 /* CID_SEQ               */     { 1, ASN_SEQUENCE, 1, 1, 0 },
29183                                                           /* hashAlgorithm */
29184 /* CID_HASHALGO_SEQ      */         { 2, ASN_SEQUENCE, 1, 1, 0 },
29185 /* CID_HASHALGO_OID      */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
29186 /* CID_HASHALGO_NULL     */             { 3, ASN_TAG_NULL, 0, 0, 1 },
29187                                                           /* issuerNameHash */
29188 /* CID_ISSUERHASH        */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
29189                                                           /* issuerKeyHash */
29190 /* CID_ISSUERKEYHASH     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
29191                                                           /* serialNumber */
29192 /* CID_SERIAL            */         { 2, ASN_INTEGER, 0, 0, 0 },
29193                                                       /* certStatus - CHOICE */
29194                                                       /* good              [0] IMPLICIT NULL */
29195 /* CS_GOOD               */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 },
29196                                                       /* revoked           [1] IMPLICIT RevokedInfo */
29197 /* CS_REVOKED            */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 2 },
29198                                                           /* revocationTime */
29199 /* CS_REVOKED_TIME       */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
29200                                                           /* revocationReason  [0] EXPLICIT CRLReason OPTIONAL */
29201 /* CS_REVOKED_REASON     */         { 2, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 1 },
29202                                                               /* crlReason */
29203 /* CS_REVOKED_REASON_VAL */             { 3, ASN_ENUMERATED, 0, 0, 0 },
29204                                                       /* unknown           [2] IMPLICIT UnknownInfo ::= NULL */
29205 /* UNKNOWN               */     { 1, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 2 },
29206 
29207                                                       /* thisUpdate */
29208 /* THISUPDATE_GT         */     { 1, ASN_GENERALIZED_TIME, 0, 0, 0 },
29209                                                       /* nextUpdate */
29210 /* NEXTUPDATE            */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
29211 /* NEXTUPDATE_GT         */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
29212                                                       /* singleExtensions */
29213 /* EXT                   */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
29214 };
29215 enum {
29216     SINGLERESPONSEASN_IDX_SEQ = 0,
29217     SINGLERESPONSEASN_IDX_CID_SEQ,
29218     SINGLERESPONSEASN_IDX_CID_HASHALGO_SEQ,
29219     SINGLERESPONSEASN_IDX_CID_HASHALGO_OID,
29220     SINGLERESPONSEASN_IDX_CID_HASHALGO_NULL,
29221     SINGLERESPONSEASN_IDX_CID_ISSUERHASH,
29222     SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH,
29223     SINGLERESPONSEASN_IDX_CID_SERIAL,
29224     SINGLERESPONSEASN_IDX_CS_GOOD,
29225     SINGLERESPONSEASN_IDX_CS_REVOKED,
29226     SINGLERESPONSEASN_IDX_CS_REVOKED_TIME,
29227     SINGLERESPONSEASN_IDX_CS_REVOKED_REASON,
29228     SINGLERESPONSEASN_IDX_CS_REVOKED_REASON_VAL,
29229     SINGLERESPONSEASN_IDX_UNKNOWN,
29230     SINGLERESPONSEASN_IDX_THISUPDATE_GT,
29231     SINGLERESPONSEASN_IDX_NEXTUPDATE,
29232     SINGLERESPONSEASN_IDX_NEXTUPDATE_GT,
29233     SINGLERESPONSEASN_IDX_EXT,
29234 };
29235 
29236 /* Number of items in ASN.1 template for OCSP single response. */
29237 #define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem))
29238 #endif
29239 
29240 static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
29241                                 int wrapperSz, OcspEntry* single)
29242 {
29243 #ifndef WOLFSSL_ASN_TEMPLATE
29244     word32 idx = *ioIndex, prevIndex, oid, localIdx, certIdIdx;
29245     int length;
29246     int ret;
29247     byte tag;
29248 
29249     WOLFSSL_ENTER("DecodeSingleResponse");
29250 
29251     prevIndex = idx;
29252 
29253     /* Wrapper around the Single Response */
29254     if (GetSequence(source, &idx, &length, size) < 0)
29255         return ASN_PARSE_E;
29256 
29257     /* Wrapper around the CertID */
29258     certIdIdx = idx;
29259     if (GetSequence(source, &idx, &length, size) < 0)
29260         return ASN_PARSE_E;
29261     single->rawCertId = source + certIdIdx;
29262     /* Hash algorithm */
29263     ret = GetAlgoId(source, &idx, &oid, oidIgnoreType, size);
29264     if (ret < 0)
29265         return ret;
29266     single->hashAlgoOID = oid;
29267     /* Save reference to the hash of CN */
29268     ret = GetOctetString(source, &idx, &length, size);
29269     if (ret < 0)
29270         return ret;
29271     if (length > (int)sizeof(single->issuerHash))
29272         return BUFFER_E;
29273     XMEMCPY(single->issuerHash, source + idx, length);
29274     idx += length;
29275     /* Save reference to the hash of the issuer public key */
29276     ret = GetOctetString(source, &idx, &length, size);
29277     if (ret < 0)
29278         return ret;
29279     if (length > (int)sizeof(single->issuerKeyHash))
29280         return BUFFER_E;
29281     XMEMCPY(single->issuerKeyHash, source + idx, length);
29282     idx += length;
29283 
29284     /* Get serial number */
29285     if (GetSerialNumber(source, &idx, single->status->serial, &single->status->serialSz, size) < 0)
29286         return ASN_PARSE_E;
29287     single->rawCertIdSize = idx - certIdIdx;
29288 
29289     if (idx >= size)
29290         return BUFFER_E;
29291 
29292     /* CertStatus */
29293     switch (source[idx++])
29294     {
29295         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
29296             single->status->status = CERT_GOOD;
29297             idx++;
29298             break;
29299         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
29300             single->status->status = CERT_REVOKED;
29301             if (GetLength(source, &idx, &length, size) < 0)
29302                 return ASN_PARSE_E;
29303             idx += length;
29304             break;
29305         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
29306             single->status->status = CERT_UNKNOWN;
29307             idx++;
29308             break;
29309         default:
29310             return ASN_PARSE_E;
29311     }
29312 
29313 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
29314     single->status->thisDateAsn = source + idx;
29315     localIdx = 0;
29316     if (GetDateInfo(single->status->thisDateAsn, &localIdx, NULL,
29317                     (byte*)&single->status->thisDateParsed.type,
29318                     &single->status->thisDateParsed.length, size) < 0)
29319         return ASN_PARSE_E;
29320     XMEMCPY(single->status->thisDateParsed.data,
29321             single->status->thisDateAsn + localIdx - single->status->thisDateParsed.length,
29322             single->status->thisDateParsed.length);
29323 #endif
29324     if (GetBasicDate(source, &idx, single->status->thisDate,
29325                                                 &single->status->thisDateFormat, size) < 0)
29326         return ASN_PARSE_E;
29327 
29328 #ifndef NO_ASN_TIME
29329 #ifndef WOLFSSL_NO_OCSP_DATE_CHECK
29330     if (!XVALIDATE_DATE(single->status->thisDate, single->status->thisDateFormat, BEFORE))
29331         return ASN_BEFORE_DATE_E;
29332 #endif
29333 #endif
29334 
29335     /* The following items are optional. Only check for them if there is more
29336      * unprocessed data in the singleResponse wrapper. */
29337     localIdx = idx;
29338     if (((int)(idx - prevIndex) < wrapperSz) &&
29339         GetASNTag(source, &localIdx, &tag, size) == 0 &&
29340         tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
29341     {
29342         idx++;
29343         if (GetLength(source, &idx, &length, size) < 0)
29344             return ASN_PARSE_E;
29345 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
29346         single->status->nextDateAsn = source + idx;
29347         localIdx = 0;
29348         if (GetDateInfo(single->status->nextDateAsn, &localIdx, NULL,
29349                         (byte*)&single->status->nextDateParsed.type,
29350                         &single->status->nextDateParsed.length, size) < 0)
29351             return ASN_PARSE_E;
29352         XMEMCPY(single->status->nextDateParsed.data,
29353                 single->status->nextDateAsn + localIdx - single->status->nextDateParsed.length,
29354                 single->status->nextDateParsed.length);
29355 #endif
29356         if (GetBasicDate(source, &idx, single->status->nextDate,
29357                                                 &single->status->nextDateFormat, size) < 0)
29358             return ASN_PARSE_E;
29359 
29360 #ifndef NO_ASN_TIME
29361 #ifndef WOLFSSL_NO_OCSP_DATE_CHECK
29362         if (!XVALIDATE_DATE(single->status->nextDate, single->status->nextDateFormat, AFTER))
29363             return ASN_AFTER_DATE_E;
29364 #endif
29365 #endif
29366     }
29367 
29368     /* Skip the optional extensions in singleResponse. */
29369     localIdx = idx;
29370     if (((int)(idx - prevIndex) < wrapperSz) &&
29371         GetASNTag(source, &localIdx, &tag, size) == 0 &&
29372         tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
29373     {
29374         idx++;
29375         if (GetLength(source, &idx, &length, size) < 0)
29376             return ASN_PARSE_E;
29377         idx += length;
29378     }
29379 
29380     *ioIndex = idx;
29381 
29382     return 0;
29383 #else
29384     DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
29385     int ret = 0;
29386     CertStatus* cs = NULL;
29387     word32 serialSz;
29388     word32 issuerHashLen;
29389     word32 issuerKeyHashLen;
29390     word32 thisDateLen;
29391     word32 nextDateLen;
29392 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
29393     defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
29394     WOLFSSL_ASN1_TIME *at;
29395 #endif
29396 
29397     (void)wrapperSz;
29398 
29399     WOLFSSL_ENTER("DecodeSingleResponse");
29400 
29401     CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL);
29402 
29403     if (ret == 0) {
29404         /* Certificate Status field. */
29405         cs = single->status;
29406 
29407         /* Set maximum lengths for data. */
29408         issuerHashLen    = OCSP_DIGEST_SIZE;
29409         issuerKeyHashLen = OCSP_DIGEST_SIZE;
29410         serialSz         = EXTERNAL_SERIAL_SIZE;
29411         thisDateLen      = MAX_DATE_SIZE;
29412         nextDateLen      = MAX_DATE_SIZE;
29413 
29414         /* Set OID type, buffers to hold data and variables to hold size. */
29415         GetASN_OID(&dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID],
29416                 oidHashType);
29417         GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERHASH],
29418                 single->issuerHash, &issuerHashLen);
29419         GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH],
29420                 single->issuerKeyHash, &issuerKeyHashLen);
29421         GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_SERIAL], cs->serial,
29422                 &serialSz);
29423         GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
29424                 cs->thisDate, &thisDateLen);
29425         GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT],
29426                 cs->nextDate, &nextDateLen);
29427         /* TODO: decode revoked time and reason. */
29428         /* Decode OCSP single response. */
29429         ret = GetASN_Items(singleResponseASN, dataASN, singleResponseASN_Length,
29430                 1, source, ioIndex, size);
29431     }
29432     /* Validate the issuer hash length is the size required. */
29433     if ((ret == 0) && (issuerHashLen != OCSP_DIGEST_SIZE)) {
29434         ret = ASN_PARSE_E;
29435     }
29436     /* Validate the issuer key hash length is the size required. */
29437     if ((ret == 0) && (issuerKeyHashLen != OCSP_DIGEST_SIZE)) {
29438         ret = ASN_PARSE_E;
29439     }
29440     if (ret == 0) {
29441         /* Store serial size. */
29442         cs->serialSz = serialSz;
29443 
29444         /* Determine status by which item was found. */
29445         if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
29446             cs->status = CERT_GOOD;
29447         }
29448         if (dataASN[SINGLERESPONSEASN_IDX_CS_REVOKED].tag != 0) {
29449             cs->status = CERT_REVOKED;
29450         }
29451         if (dataASN[SINGLERESPONSEASN_IDX_UNKNOWN].tag != 0) {
29452             cs->status = CERT_UNKNOWN;
29453         }
29454 
29455         /* Store the thisDate format - only one possible. */
29456         cs->thisDateFormat = ASN_GENERALIZED_TIME;
29457     #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
29458         /* Check date is a valid string and BEFORE now. */
29459         if (!XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, BEFORE)) {
29460             ret = ASN_BEFORE_DATE_E;
29461         }
29462     }
29463     if (ret == 0) {
29464     #endif
29465     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
29466         defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
29467         /* Store ASN.1 version of thisDate. */
29468         cs->thisDateAsn = GetASNItem_Addr(
29469                 dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT], source);
29470         at = &cs->thisDateParsed;
29471         at->type = ASN_GENERALIZED_TIME;
29472         XMEMCPY(at->data, cs->thisDate, thisDateLen);
29473         at->length = thisDateLen;
29474     #endif
29475     }
29476     if ((ret == 0) &&
29477             (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
29478         /* Store the nextDate format - only one possible. */
29479         cs->nextDateFormat = ASN_GENERALIZED_TIME;
29480     #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
29481         /* Check date is a valid string and AFTER now. */
29482         if (!XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, AFTER)) {
29483             ret = ASN_AFTER_DATE_E;
29484         }
29485     }
29486     if ((ret == 0) &&
29487             (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
29488     #endif
29489     #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
29490         defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
29491         /* Store ASN.1 version of thisDate. */
29492         cs->nextDateAsn = GetASNItem_Addr(
29493                 dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT], source);
29494         at = &cs->nextDateParsed;
29495         at->type = ASN_GENERALIZED_TIME;
29496         XMEMCPY(at->data, cs->nextDate, nextDateLen);
29497         at->length = nextDateLen;
29498     #endif
29499     }
29500     if (ret == 0) {
29501         /* OcspEntry now used. */
29502         single->used = 1;
29503     }
29504 
29505     FREE_ASNGETDATA(dataASN, NULL);
29506     return ret;
29507 #endif
29508 }
29509 
29510 #ifdef WOLFSSL_ASN_TEMPLATE
29511 /* ASN.1 template for OCSP response extension header.
29512  * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
29513  */
29514 static const ASNItem respExtHdrASN[] = {
29515                                    /* responseExtensions */
29516 /* EXT     */    { 0, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 0 },
29517                                        /* extensions */
29518 /* EXT_SEQ */        { 1, ASN_SEQUENCE, 1, 1, 0 },
29519 };
29520 enum {
29521     RESPEXTHDRASN_IDX_EXT = 0,
29522     RESPEXTHDRASN_IDX_EXT_SEQ,
29523 };
29524 
29525 /* Number of items in ASN.1 template for OCSP response extension header. */
29526 #define respExtHdrASN_Length (sizeof(respExtHdrASN) / sizeof(ASNItem))
29527 #endif
29528 
29529 static int DecodeOcspRespExtensions(byte* source, word32* ioIndex,
29530                                     OcspResponse* resp, word32 sz)
29531 {
29532 #ifndef WOLFSSL_ASN_TEMPLATE
29533     word32 idx = *ioIndex;
29534     int length;
29535     int ext_bound; /* boundary index for the sequence of extensions */
29536     word32 oid;
29537     int ret;
29538     byte tag;
29539 
29540     WOLFSSL_ENTER("DecodeOcspRespExtensions");
29541 
29542     if ((idx + 1) > sz)
29543         return BUFFER_E;
29544 
29545     if (GetASNTag(source, &idx, &tag, sz) < 0)
29546         return ASN_PARSE_E;
29547 
29548     if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
29549         return ASN_PARSE_E;
29550 
29551     if (GetLength(source, &idx, &length, sz) < 0)
29552         return ASN_PARSE_E;
29553 
29554     if (GetSequence(source, &idx, &length, sz) < 0)
29555         return ASN_PARSE_E;
29556 
29557     ext_bound = idx + length;
29558 
29559     while (idx < (word32)ext_bound) {
29560         word32 localIdx;
29561 
29562         if (GetSequence(source, &idx, &length, sz) < 0) {
29563             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
29564             return ASN_PARSE_E;
29565         }
29566 
29567         oid = 0;
29568         if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
29569             WOLFSSL_MSG("\tfail: OBJECT ID");
29570             return ASN_PARSE_E;
29571         }
29572 
29573         /* check for critical flag */
29574         if ((idx + 1) > (word32)sz) {
29575             WOLFSSL_MSG("\tfail: malformed buffer");
29576             return BUFFER_E;
29577         }
29578 
29579         localIdx = idx;
29580         if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
29581             WOLFSSL_MSG("\tfound optional critical flag, moving past");
29582             ret = GetBoolean(source, &idx, sz);
29583             if (ret < 0)
29584                 return ret;
29585         }
29586 
29587         ret = GetOctetString(source, &idx, &length, sz);
29588         if (ret < 0)
29589             return ret;
29590 
29591         if (oid == OCSP_NONCE_OID) {
29592             /* get data inside extra OCTET_STRING */
29593             ret = GetOctetString(source, &idx, &length, sz);
29594             if (ret < 0)
29595                 return ret;
29596 
29597             resp->nonce = source + idx;
29598             resp->nonceSz = length;
29599         }
29600 
29601         idx += length;
29602     }
29603 
29604     *ioIndex = idx;
29605     return 0;
29606 #else
29607     /* certExtASN_Length is greater than respExtHdrASN_Length */
29608     DECL_ASNGETDATA(dataASN, certExtASN_Length);
29609     int ret = 0;
29610     word32 idx = *ioIndex;
29611     word32 maxIdx = 0;
29612 
29613     WOLFSSL_ENTER("DecodeOcspRespExtensions");
29614 
29615     CALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, resp->heap);
29616 
29617     if (ret == 0) {
29618         /* Check for header and move past. */
29619         ret = GetASN_Items(respExtHdrASN, dataASN, respExtHdrASN_Length, 0,
29620             source, &idx, sz);
29621     }
29622     if (ret == 0) {
29623         /* Keep end extensions index for total length check. */
29624         maxIdx = idx + dataASN[RESPEXTHDRASN_IDX_EXT_SEQ].length;
29625     }
29626 
29627     /* Step through all extensions. */
29628     while ((ret == 0) && (idx < maxIdx)) {
29629         /* Clear dynamic data, set OID type to expect. */
29630         XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
29631         GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidOcspType);
29632         /* TODO: check criticality. */
29633         /* Decode OCSP response extension. */
29634         ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0,
29635                            source, &idx, sz);
29636         if (ret == 0) {
29637             word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
29638             int length = dataASN[CERTEXTASN_IDX_VAL].length;
29639 
29640             if (oid == OCSP_NONCE_OID) {
29641                 /* Extract nonce data. */
29642                 ret = GetOctetString(source, &idx, &length, sz);
29643                 if (ret >= 0) {
29644                     ret = 0;
29645                     /* get data inside extra OCTET_STRING */
29646                     resp->nonce = source + idx;
29647                     resp->nonceSz = length;
29648                 }
29649             }
29650             /* Ignore all other extension types. */
29651 
29652             /* Skip over rest of extension. */
29653             idx += length;
29654         }
29655     }
29656 
29657     /* Return index after extensions. */
29658     *ioIndex = idx;
29659 
29660     FREE_ASNGETDATA(dataASN, resp->heap);
29661     return ret;
29662 #endif
29663 }
29664 
29665 #ifdef WOLFSSL_ASN_TEMPLATE
29666 /* ASN.1 template for OCSP ResponseData.
29667  * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
29668  */
29669 static const ASNItem ocspRespDataASN[] = {
29670 /* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
29671                                              /* version DEFAULT v1 */
29672 /* VER_PRESENT */        { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
29673 /* VER         */            { 2, ASN_INTEGER, 1, 0, 0 },
29674                                              /* byName */
29675 /* BYNAME      */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
29676                                              /* byKey */
29677 /* BYKEY       */        { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 2 },
29678                                              /* producedAt */
29679 /* PA          */        { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
29680                                              /* responses */
29681 /* RESP        */        { 1, ASN_SEQUENCE, 1, 0, 0 },
29682                                              /* responseExtensions */
29683 /* RESPEXT     */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 }
29684 };
29685 enum {
29686     OCSPRESPDATAASN_IDX_SEQ = 0,
29687     OCSPRESPDATAASN_IDX_VER_PRESENT,
29688     OCSPRESPDATAASN_IDX_VER,
29689     OCSPRESPDATAASN_IDX_BYNAME,
29690     OCSPRESPDATAASN_IDX_BYKEY,
29691     OCSPRESPDATAASN_IDX_PA,
29692     OCSPRESPDATAASN_IDX_RESP,
29693     OCSPRESPDATAASN_IDX_RESPEXT,
29694 };
29695 
29696 /* Number of items in ASN.1 template for OCSP ResponseData. */
29697 #define ocspRespDataASN_Length (sizeof(ocspRespDataASN) / sizeof(ASNItem))
29698 #endif
29699 
29700 static int DecodeResponseData(byte* source, word32* ioIndex,
29701                               OcspResponse* resp, word32 size)
29702 {
29703 #ifndef WOLFSSL_ASN_TEMPLATE
29704     word32 idx = *ioIndex, prev_idx, localIdx;
29705     int length;
29706     int version;
29707     int ret;
29708     byte tag;
29709     int wrapperSz;
29710     OcspEntry* single;
29711 
29712     WOLFSSL_ENTER("DecodeResponseData");
29713 
29714     resp->response = source + idx;
29715     prev_idx = idx;
29716     if (GetSequence(source, &idx, &length, size) < 0)
29717         return ASN_PARSE_E;
29718     resp->responseSz = length + idx - prev_idx;
29719 
29720     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
29721      * item isn't an EXPLICIT[0], then set version to zero and move
29722      * onto the next item.
29723      */
29724     localIdx = idx;
29725     if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
29726             tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
29727     {
29728         idx += 2; /* Eat the value and length */
29729         if (GetMyVersion(source, &idx, &version, size) < 0)
29730             return ASN_PARSE_E;
29731     } else
29732         version = 0;
29733 
29734     localIdx = idx;
29735     if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
29736         ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
29737           tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
29738     {
29739         idx++; /* advance past ASN tag */
29740         if (GetLength(source, &idx, &length, size) < 0)
29741             return ASN_PARSE_E;
29742         idx += length;
29743     }
29744     else
29745         return ASN_PARSE_E;
29746 
29747     /* save pointer to the producedAt time */
29748     if (GetBasicDate(source, &idx, resp->producedDate,
29749                                         &resp->producedDateFormat, size) < 0)
29750         return ASN_PARSE_E;
29751 
29752     /* Outer wrapper of the SEQUENCE OF Single Responses. */
29753     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
29754         return ASN_PARSE_E;
29755 
29756     localIdx = idx;
29757     single = resp->single;
29758     while (idx - localIdx < (word32)wrapperSz) {
29759         ret = DecodeSingleResponse(source, &idx, size, wrapperSz, single);
29760         if (ret < 0)
29761             return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
29762         if (idx - localIdx < (word32)wrapperSz) {
29763             single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
29764                 DYNAMIC_TYPE_OCSP_ENTRY);
29765             if (single->next == NULL) {
29766                 return MEMORY_E;
29767             }
29768             XMEMSET(single->next, 0, sizeof(OcspEntry));
29769 
29770             single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
29771                 resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
29772             if (single->next->status == NULL) {
29773                 XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
29774                 single->next = NULL;
29775                 return MEMORY_E;
29776             }
29777             XMEMSET(single->next->status, 0, sizeof(CertStatus));
29778 
29779             single->next->isDynamic = 1;
29780 
29781             single = single->next;
29782         }
29783     }
29784 
29785     /*
29786      * Check the length of the ResponseData against the current index to
29787      * see if there are extensions, they are optional.
29788      */
29789     if (idx - prev_idx < resp->responseSz)
29790         if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
29791             return ASN_PARSE_E;
29792 
29793     *ioIndex = idx;
29794     return 0;
29795 #else
29796     DECL_ASNGETDATA(dataASN, ocspRespDataASN_Length);
29797     int ret = 0;
29798     byte version;
29799     word32 dateSz, idx = *ioIndex;
29800     OcspEntry* single;
29801 
29802     WOLFSSL_ENTER("DecodeResponseData");
29803 
29804     CALLOC_ASNGETDATA(dataASN, ocspRespDataASN_Length, ret, resp->heap);
29805 
29806     if (ret == 0) {
29807         resp->response = source + idx;
29808         /* Default, not present, is v1 = 0. */
29809         version = 0;
29810         /* Max size of date supported. */
29811         dateSz = MAX_DATE_SIZE;
29812 
29813         /* Set the where to put version an produced date. */
29814         GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
29815         GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
29816                 &dateSz);
29817         /* Decode the ResponseData. */
29818         ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
29819                 1, source, ioIndex, size);
29820     }
29821     /* Only support v1 == 0 */
29822     if ((ret == 0) && (version != 0)) {
29823         ret = ASN_PARSE_E;
29824     }
29825     /* Ensure date is a minimal size. */
29826     if ((ret == 0) && (dateSz < MIN_DATE_SIZE)) {
29827         ret = ASN_PARSE_E;
29828     }
29829     if (ret == 0) {
29830         /* TODO: use byName/byKey fields. */
29831         /* Store size of response. */
29832         resp->responseSz = *ioIndex - idx;
29833         /* Store date format/tag. */
29834         resp->producedDateFormat = dataASN[OCSPRESPDATAASN_IDX_PA].tag;
29835 
29836         /* Get the index of the responses SEQUENCE. */
29837         idx = GetASNItem_DataIdx(dataASN[OCSPRESPDATAASN_IDX_RESP], source);
29838         /* Start with the pre-existing OcspEntry. */
29839         single = resp->single;
29840     }
29841     while ((ret == 0) && (idx < dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset)) {
29842         /* Allocate and use a new OCSP entry if this is used. */
29843         if (single->used) {
29844             single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
29845                     DYNAMIC_TYPE_OCSP_ENTRY);
29846             if (single->next == NULL) {
29847                 ret = MEMORY_E;
29848             }
29849             else {
29850                 XMEMSET(single->next, 0, sizeof(OcspEntry));
29851 
29852                 single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
29853                     resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
29854                 if (single->next->status == NULL) {
29855                     XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
29856                     single->next = NULL;
29857                     ret = MEMORY_E;
29858                 }
29859                 else {
29860                     XMEMSET(single->next->status, 0, sizeof(CertStatus));
29861 
29862                     /* Entry to be freed. */
29863                     single->isDynamic = 1;
29864                     /* used will be 0 (false) */
29865 
29866                     single = single->next;
29867                 }
29868             }
29869         }
29870         if (ret == 0) {
29871             /* Decode SingleResponse into OcspEntry. */
29872             ret = DecodeSingleResponse(source, &idx,
29873                     dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset,
29874                     dataASN[OCSPRESPDATAASN_IDX_RESP].length, single);
29875             /* single->used set on successful decode. */
29876         }
29877     }
29878 
29879     /* Check if there were extensions. */
29880     if ((ret == 0) &&
29881             (dataASN[OCSPRESPDATAASN_IDX_RESPEXT].data.buffer.data != NULL)) {
29882         /* Get index of [1] */
29883         idx = dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset;
29884         /* Decode the response extensions. */
29885         if (DecodeOcspRespExtensions(source, &idx, resp, *ioIndex) < 0) {
29886             ret = ASN_PARSE_E;
29887         }
29888     }
29889 
29890     FREE_ASNGETDATA(dataASN, resp->heap);
29891     return ret;
29892 #endif
29893 }
29894 
29895 
29896 #ifndef WOLFSSL_ASN_TEMPLATE
29897 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
29898 
29899 static int DecodeCerts(byte* source,
29900                             word32* ioIndex, OcspResponse* resp, word32 size)
29901 {
29902     word32 idx = *ioIndex;
29903     byte tag;
29904 
29905     WOLFSSL_ENTER("DecodeCerts");
29906 
29907     if (GetASNTag(source, &idx, &tag, size) < 0)
29908         return ASN_PARSE_E;
29909 
29910     if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
29911     {
29912         int length;
29913 
29914         if (GetLength(source, &idx, &length, size) < 0)
29915             return ASN_PARSE_E;
29916 
29917         if (GetSequence(source, &idx, &length, size) < 0)
29918             return ASN_PARSE_E;
29919 
29920         resp->cert = source + idx;
29921         resp->certSz = length;
29922 
29923         idx += length;
29924     }
29925     *ioIndex = idx;
29926     return 0;
29927 }
29928 
29929 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
29930 #endif /* !WOLFSSL_ASN_TEMPLATE */
29931 
29932 #ifdef WOLFSSL_ASN_TEMPLATE
29933 /* ASN.1 template for BasicOCSPResponse.
29934  * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
29935  */
29936 static const ASNItem ocspBasicRespASN[] = {
29937 /* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
29938                                             /* tbsResponseData */
29939 /* TBS_SEQ      */     { 1, ASN_SEQUENCE, 1, 0, 0, },
29940                                             /* signatureAlgorithm */
29941 /* SIGALGO      */     { 1, ASN_SEQUENCE, 1, 1, 0, },
29942 /* SIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
29943 /* SIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 1 },
29944                                             /* signature */
29945 /* SIGNATURE    */     { 1, ASN_BIT_STRING, 0, 0, 0 },
29946                                             /* certs */
29947 /* CERTS        */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
29948 /* CERTS_SEQ    */         { 2, ASN_SEQUENCE, 1, 0, 0, },
29949 };
29950 enum {
29951     OCSPBASICRESPASN_IDX_SEQ = 0,
29952     OCSPBASICRESPASN_IDX_TBS_SEQ,
29953     OCSPBASICRESPASN_IDX_SIGALGO,
29954     OCSPBASICRESPASN_IDX_SIGALGO_OID,
29955     OCSPBASICRESPASN_IDX_SIGALGO_NULL,
29956     OCSPBASICRESPASN_IDX_SIGNATURE,
29957     OCSPBASICRESPASN_IDX_CERTS,
29958     OCSPBASICRESPASN_IDX_CERTS_SEQ,
29959 };
29960 
29961 /* Number of items in ASN.1 template for BasicOCSPResponse. */
29962 #define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
29963 #endif /* WOLFSSL_ASN_TEMPLATE */
29964 
29965 static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
29966             OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
29967 {
29968 #ifndef WOLFSSL_ASN_TEMPLATE
29969     int    length;
29970     word32 idx = *ioIndex;
29971     word32 end_index;
29972     int    ret;
29973     int    sigLength;
29974 
29975     WOLFSSL_ENTER("DecodeBasicOcspResponse");
29976     (void)heap;
29977 
29978     if (GetSequence(source, &idx, &length, size) < 0)
29979         return ASN_PARSE_E;
29980 
29981     if (idx + length > size)
29982         return ASN_INPUT_E;
29983     end_index = idx + length;
29984 
29985     if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
29986         return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
29987 
29988     /* Get the signature algorithm */
29989     if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
29990         return ASN_PARSE_E;
29991 
29992     ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
29993     if (ret != 0)
29994         return ret;
29995 
29996     resp->sigSz = sigLength;
29997     resp->sig = source + idx;
29998     idx += sigLength;
29999 
30000     /*
30001      * Check the length of the BasicOcspResponse against the current index to
30002      * see if there are certificates, they are optional.
30003      */
30004 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
30005     if (idx < end_index)
30006     {
30007         DecodedCert cert;
30008 
30009         if (DecodeCerts(source, &idx, resp, size) < 0)
30010             return ASN_PARSE_E;
30011 
30012         InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
30013 
30014         /* Don't verify if we don't have access to Cert Manager. */
30015         ret = ParseCertRelative(&cert, CERT_TYPE,
30016                                 noVerify ? NO_VERIFY : VERIFY_OCSP_CERT, cm);
30017         if (ret < 0) {
30018             WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
30019             FreeDecodedCert(&cert);
30020             return ret;
30021         }
30022 
30023 #ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
30024         if ((cert.extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
30025             if (XMEMCMP(cert.subjectHash,
30026                         resp->single->issuerHash, OCSP_DIGEST_SIZE) == 0) {
30027                 WOLFSSL_MSG("\tOCSP Response signed by issuer");
30028             }
30029             else {
30030                 WOLFSSL_MSG("\tOCSP Responder key usage check failed");
30031     #ifdef OPENSSL_EXTRA
30032                 resp->verifyError = OCSP_BAD_ISSUER;
30033     #else
30034                 FreeDecodedCert(&cert);
30035                 return BAD_OCSP_RESPONDER;
30036     #endif
30037             }
30038         }
30039 #endif
30040 
30041         /* ConfirmSignature is blocking here */
30042         ret = ConfirmSignature(&cert.sigCtx,
30043             resp->response, resp->responseSz,
30044             cert.publicKey, cert.pubKeySize, cert.keyOID,
30045             resp->sig, resp->sigSz, resp->sigOID, NULL);
30046 
30047         FreeDecodedCert(&cert);
30048 
30049         if (ret != 0) {
30050             WOLFSSL_MSG("\tOCSP Confirm signature failed");
30051             return ASN_OCSP_CONFIRM_E;
30052         }
30053     }
30054     else
30055 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
30056     {
30057         Signer* ca;
30058         int sigValid = -1;
30059 
30060         #ifndef NO_SKID
30061             ca = GetCA(cm, resp->single->issuerKeyHash);
30062         #else
30063             ca = GetCA(cm, resp->single->issuerHash);
30064         #endif
30065 
30066         if (ca) {
30067             SignatureCtx sigCtx;
30068             InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
30069 
30070             /* ConfirmSignature is blocking here */
30071             sigValid = ConfirmSignature(&sigCtx, resp->response,
30072                 resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
30073                                 resp->sig, resp->sigSz, resp->sigOID, NULL);
30074         }
30075         if (ca == NULL || sigValid != 0) {
30076             WOLFSSL_MSG("\tOCSP Confirm signature failed");
30077             return ASN_OCSP_CONFIRM_E;
30078         }
30079 
30080         (void)noVerify;
30081     }
30082 
30083     *ioIndex = idx;
30084     return 0;
30085 #else
30086     DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
30087     int ret = 0;
30088     word32 idx = *ioIndex;
30089 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
30090     #ifdef WOLFSSL_SMALL_STACK
30091         DecodedCert* cert = NULL;
30092     #else
30093         DecodedCert cert[1];
30094     #endif
30095     int certInit = 0;
30096 #endif
30097 
30098     WOLFSSL_ENTER("DecodeBasicOcspResponse");
30099     (void)heap;
30100 
30101     CALLOC_ASNGETDATA(dataASN, ocspBasicRespASN_Length, ret, heap);
30102 
30103     if (ret == 0) {
30104         /* Set expecting signature OID. */
30105         GetASN_OID(&dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID], oidSigType);
30106         /* Decode BasicOCSPResponse. */
30107         ret = GetASN_Items(ocspBasicRespASN, dataASN, ocspBasicRespASN_Length,
30108                 1, source, &idx, size);
30109     }
30110     if (ret == 0) {
30111         word32 dataIdx = 0;
30112         /* Decode the response data. */
30113         if (DecodeResponseData(
30114                 GetASNItem_Addr(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source),
30115                 &dataIdx, resp,
30116                 GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source)
30117                 ) < 0) {
30118             ret = ASN_PARSE_E;
30119         }
30120     }
30121     if (ret == 0) {
30122         /* Get the signature OID and signature. */
30123         resp->sigOID = dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID].data.oid.sum;
30124         GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
30125                 &resp->sigSz);
30126     }
30127 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
30128     if ((ret == 0) &&
30129             (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
30130         /* TODO: support more than one certificate. */
30131         /* Store reference to certificate BER data. */
30132         GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
30133                 &resp->certSz);
30134 
30135         /* Allocate a certificate object to decode cert into. */
30136     #ifdef WOLFSSL_SMALL_STACK
30137         cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
30138                 DYNAMIC_TYPE_TMP_BUFFER);
30139         if (cert == NULL) {
30140             ret = MEMORY_E;
30141         }
30142     }
30143     if ((ret == 0) &&
30144             (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
30145     #endif
30146         /* Initialize the crtificate object. */
30147         InitDecodedCert(cert, resp->cert, resp->certSz, heap);
30148         certInit = 1;
30149         /* Parse the certificate and don't verify if we don't have access to
30150          * Cert Manager. */
30151         ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY,
30152                 cm);
30153         if (ret < 0) {
30154             WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
30155         }
30156     }
30157     if ((ret == 0) &&
30158             (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
30159         /* TODO: ConfirmSignature is blocking here */
30160         /* Check the signature of the response. */
30161         ret = ConfirmSignature(&cert->sigCtx, resp->response, resp->responseSz,
30162             cert->publicKey, cert->pubKeySize, cert->keyOID, resp->sig,
30163             resp->sigSz, resp->sigOID, NULL);
30164         if (ret != 0) {
30165             WOLFSSL_MSG("\tOCSP Confirm signature failed");
30166             ret = ASN_OCSP_CONFIRM_E;
30167         }
30168     }
30169     if ((ret == 0) &&
30170             (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data == NULL))
30171 #else
30172     if (ret == 0)
30173 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
30174     {
30175         Signer* ca;
30176         int sigValid = -1;
30177 
30178         /* Resonse didn't have a certificate - lookup CA. */
30179     #ifndef NO_SKID
30180         ca = GetCA(cm, resp->single->issuerKeyHash);
30181     #else
30182         ca = GetCA(cm, resp->single->issuerHash);
30183     #endif
30184         if (ca) {
30185             SignatureCtx sigCtx;
30186             /* Initialize he signature context. */
30187             InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
30188 
30189             /* TODO: ConfirmSignature is blocking here */
30190             /* Check the signature of the response CA public key. */
30191             sigValid = ConfirmSignature(&sigCtx, resp->response,
30192                 resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
30193                 resp->sig, resp->sigSz, resp->sigOID, NULL);
30194         }
30195         if ((ca == NULL) || (sigValid != 0)) {
30196             /* Didn't find certificate or signature verificate failed. */
30197             WOLFSSL_MSG("\tOCSP Confirm signature failed");
30198             ret = ASN_OCSP_CONFIRM_E;
30199         }
30200     }
30201 
30202     if (ret == 0) {
30203         /* Update the position to after response data. */
30204         *ioIndex = idx;
30205     }
30206 
30207 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
30208     if (certInit) {
30209         FreeDecodedCert(cert);
30210     }
30211     #ifdef WOLFSSL_SMALL_STACK
30212     if (cert != NULL) {
30213         /* Dispose of certificate object. */
30214         XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
30215     }
30216     #endif
30217 #endif
30218     FREE_ASNGETDATA(dataASN, heap);
30219     return ret;
30220 #endif /* WOLFSSL_ASN_TEMPLATE */
30221 }
30222 
30223 
30224 void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status,
30225                       byte* source, word32 inSz, void* heap)
30226 {
30227     WOLFSSL_ENTER("InitOcspResponse");
30228 
30229     XMEMSET(status, 0, sizeof(CertStatus));
30230     XMEMSET(single,  0, sizeof(OcspEntry));
30231     XMEMSET(resp,   0, sizeof(OcspResponse));
30232 
30233     single->status       = status;
30234     resp->responseStatus = -1;
30235     resp->single         = single;
30236     resp->source         = source;
30237     resp->maxIdx         = inSz;
30238     resp->heap           = heap;
30239 }
30240 
30241 void FreeOcspResponse(OcspResponse* resp)
30242 {
30243     OcspEntry *single, *next;
30244     for (single = resp->single; single; single = next) {
30245         next = single->next;
30246         if (single->isDynamic) {
30247             XFREE(single->status, resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
30248             XFREE(single, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
30249         }
30250     }
30251 }
30252 
30253 #ifdef WOLFSSL_ASN_TEMPLATE
30254 /* ASN.1 template for OCSPResponse.
30255  * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
30256  */
30257 static const ASNItem ocspResponseASN[] = {
30258                                      /* OCSPResponse ::= SEQUENCE */
30259 /* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
30260                                          /* responseStatus      OCSPResponseStatus */
30261 /* STATUS     */     { 1, ASN_ENUMERATED, 0, 0, 0, },
30262                                          /* responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL */
30263 /* BYTES      */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
30264                                              /* ResponseBytes ::= SEQUENCE */
30265 /* BYTES_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
30266                                                 /* responseType   OBJECT IDENTIFIER */
30267 /* BYTES_TYPE */            { 3, ASN_OBJECT_ID, 0, 0, 0 },
30268                                                 /* response       OCTET STRING */
30269 /* BYTES_VAL  */            { 3, ASN_OCTET_STRING, 0, 0, 0 },
30270 };
30271 enum {
30272     OCSPRESPONSEASN_IDX_SEQ = 0,
30273 
30274     OCSPRESPONSEASN_IDX_STATUS,
30275 
30276     OCSPRESPONSEASN_IDX_BYTES,
30277 
30278     OCSPRESPONSEASN_IDX_BYTES_SEQ,
30279 
30280     OCSPRESPONSEASN_IDX_BYTES_TYPE,
30281 
30282     OCSPRESPONSEASN_IDX_BYTES_VAL,
30283 };
30284 
30285 /* Number of items in ASN.1 template for OCSPResponse. */
30286 #define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
30287 #endif /* WOLFSSL_ASN_TEMPLATE */
30288 
30289 int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
30290 {
30291 #ifndef WOLFSSL_ASN_TEMPLATE
30292     int ret;
30293     int length = 0;
30294     word32 idx = 0;
30295     byte* source = resp->source;
30296     word32 size = resp->maxIdx;
30297     word32 oid;
30298     byte   tag;
30299 
30300     WOLFSSL_ENTER("OcspResponseDecode");
30301 
30302     /* peel the outer SEQUENCE wrapper */
30303     if (GetSequence(source, &idx, &length, size) < 0) {
30304         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30305         return ASN_PARSE_E;
30306     }
30307 
30308     /* First get the responseStatus, an ENUMERATED */
30309     if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
30310         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30311         return ASN_PARSE_E;
30312     }
30313 
30314     if (resp->responseStatus != OCSP_SUCCESSFUL) {
30315         WOLFSSL_LEAVE("OcspResponseDecode", 0);
30316         return 0;
30317     }
30318 
30319     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
30320     if (idx >= size) {
30321         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30322         return ASN_PARSE_E;
30323     }
30324     if (GetASNTag(source, &idx, &tag, size) < 0) {
30325         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30326         return ASN_PARSE_E;
30327     }
30328     if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
30329         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30330         return ASN_PARSE_E;
30331     }
30332     if (GetLength(source, &idx, &length, size) < 0) {
30333         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30334         return ASN_PARSE_E;
30335     }
30336 
30337     /* Get the responseBytes SEQUENCE */
30338     if (GetSequence(source, &idx, &length, size) < 0) {
30339         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30340         return ASN_PARSE_E;
30341     }
30342 
30343     /* Check ObjectID for the resposeBytes */
30344     if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
30345         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30346         return ASN_PARSE_E;
30347     }
30348     if (oid != OCSP_BASIC_OID) {
30349         WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
30350         return ASN_PARSE_E;
30351     }
30352     ret = GetOctetString(source, &idx, &length, size);
30353     if (ret < 0) {
30354         WOLFSSL_LEAVE("OcspResponseDecode", ret);
30355         return ret;
30356     }
30357 
30358     ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
30359     if (ret < 0) {
30360         WOLFSSL_LEAVE("OcspResponseDecode", ret);
30361         return ret;
30362     }
30363 
30364     WOLFSSL_LEAVE("OcspResponseDecode", 0);
30365     return 0;
30366 #else
30367     DECL_ASNGETDATA(dataASN, ocspResponseASN_Length);
30368     int ret = 0;
30369     word32 idx = 0, size = resp->maxIdx;
30370     byte* source = resp->source;
30371     byte status;
30372     byte* basic;
30373     word32 basicSz;
30374 
30375     WOLFSSL_ENTER("OcspResponseDecode");
30376 
30377     CALLOC_ASNGETDATA(dataASN, ocspResponseASN_Length, ret, resp->heap);
30378 
30379     if (ret == 0) {
30380         /* Set variable to put status in and expect OCSP OID. */
30381         GetASN_Int8Bit(&dataASN[OCSPRESPONSEASN_IDX_STATUS], &status);
30382         GetASN_OID(&dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE], oidOcspType);
30383         /* Decode OCSPResponse (and ResponseBytes). */
30384         ret = GetASN_Items(ocspResponseASN, dataASN, ocspResponseASN_Length, 1,
30385             source, &idx, size);
30386     }
30387     if (ret == 0) {
30388         /* Get response. */
30389         resp->responseStatus = status;
30390         if (dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE].data.oid.sum
30391                 == OCSP_BASIC_OID) {
30392             /* Get reference to BasicOCSPResponse. */
30393             GetASN_GetRef(&dataASN[OCSPRESPONSEASN_IDX_BYTES_VAL], &basic,
30394                     &basicSz);
30395             idx = 0;
30396             /* Decode BasicOCSPResponse. */
30397             ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
30398                 noVerify);
30399         }
30400         /* Only support BasicOCSPResponse. */
30401         else {
30402             ret = ASN_PARSE_E;
30403         }
30404     }
30405 
30406     FREE_ASNGETDATA(dataASN, resp->heap);
30407     WOLFSSL_LEAVE("OcspResponseDecode", ret);
30408     return ret;
30409 #endif /* WOLFSSL_ASN_TEMPLATE */
30410 }
30411 
30412 #ifdef WOLFSSL_ASN_TEMPLATE
30413 /* ASN.1 template for OCSP nonce extension.
30414  * RFC 6960, 4.4.1 - Nonce
30415  * X.509: RFC 5280, 4.1 - Basic Certificate Fields. (Extension)
30416  */
30417 static const ASNItem ocspNonceExtASN[] = {
30418 /* SEQ       */ { 0, ASN_SEQUENCE, 1, 1, 0 },
30419                                      /* Extension */
30420 /* EXT       */     { 1, ASN_SEQUENCE, 1, 1, 0 },
30421                                         /* extnId */
30422 /* EXT_OID   */        {2, ASN_OBJECT_ID, 0, 0, 0 },
30423                                         /* critcal not encoded. */
30424                                         /* extnValue */
30425 /* EXT_VAL   */        {2, ASN_OCTET_STRING, 0, 1, 0 },
30426                                                /* nonce */
30427 /* EXT_NONCE */            {3, ASN_OCTET_STRING, 0, 0, 0 },
30428 };
30429 enum {
30430     OCSPNONCEEXTASN_IDX_SEQ = 0,
30431     OCSPNONCEEXTASN_IDX_EXT,
30432     OCSPNONCEEXTASN_IDX_EXT_OID,
30433     OCSPNONCEEXTASN_IDX_EXT_VAL,
30434     OCSPNONCEEXTASN_IDX_EXT_NONCE,
30435 };
30436 
30437 /* Number of items in ASN.1 template for OCSP nonce extension. */
30438 #define ocspNonceExtASN_Length (sizeof(ocspNonceExtASN) / sizeof(ASNItem))
30439 #endif /* WOLFSSL_ASN_TEMPLATE */
30440 
30441 word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
30442 {
30443     const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
30444                                        0x30, 0x01, 0x02 };
30445 #ifndef WOLFSSL_ASN_TEMPLATE
30446     byte seqArray[5][MAX_SEQ_SZ];
30447     word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
30448 
30449     WOLFSSL_ENTER("SetOcspReqExtensions");
30450 
30451     if (!req || !output || !req->nonceSz)
30452         return 0;
30453 
30454     totalSz += req->nonceSz;
30455     totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
30456     totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
30457     totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
30458     totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
30459     totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
30460 
30461     if (totalSz > size)
30462         return 0;
30463 
30464     totalSz = 0;
30465 
30466     XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
30467     totalSz += seqSz[4];
30468 
30469     XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
30470     totalSz += seqSz[3];
30471 
30472     XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
30473     totalSz += seqSz[2];
30474 
30475     XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
30476     totalSz += (word32)sizeof(NonceObjId);
30477 
30478     XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
30479     totalSz += seqSz[1];
30480 
30481     XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
30482     totalSz += seqSz[0];
30483 
30484     XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
30485     totalSz += req->nonceSz;
30486 
30487     return totalSz;
30488 #else
30489     int ret = 0;
30490 
30491     WOLFSSL_ENTER("SetOcspReqExtensions");
30492 
30493     /* Check request has nonce to write in extension. */
30494     if (req != NULL && req->nonceSz != 0) {
30495         DECL_ASNSETDATA(dataASN, ocspNonceExtASN_Length);
30496         int sz;
30497 
30498         CALLOC_ASNSETDATA(dataASN, ocspNonceExtASN_Length, ret, req->heap);
30499 
30500         /* Set nonce extension OID and nonce. */
30501         SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_OID], NonceObjId,
30502                 sizeof(NonceObjId));
30503         SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_NONCE], req->nonce,
30504                 req->nonceSz);
30505         /* Calculate size of nonce extension. */
30506         ret = SizeASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
30507                             &sz);
30508         /* Check buffer big enough for encoding if supplied. */
30509         if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
30510             ret = BUFFER_E;
30511         }
30512         if ((ret == 0) && (output != NULL)) {
30513             /* Encode nonce extension. */
30514             SetASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
30515                          output);
30516         }
30517         if (ret == 0) {
30518             /* Return size of encoding. */
30519             ret = sz;
30520         }
30521 
30522         FREE_ASNSETDATA(dataASN, req->heap);
30523     }
30524 
30525     return ret;
30526 #endif /* WOLFSSL_ASN_TEMPLATE */
30527 }
30528 
30529 
30530 #ifdef WOLFSSL_ASN_TEMPLATE
30531 /* ASN.1 template for OCSPRequest.
30532  * RFC 6960, 4.1.1 - ASN.1 Specification of the OCSP Request
30533  */
30534 static const ASNItem ocspRequestASN[] = {
30535                                               /* OCSPRequest */
30536 /* SEQ               */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30537                                                   /* tbsRequest */
30538 /* TBS               */        { 1, ASN_SEQUENCE, 1, 1, 0 },
30539                                                       /* version not written - v1 */
30540                                                       /* requestorName not written */
30541                                                       /* requestList */
30542 /* TBS_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
30543                                                           /* Request */
30544 /* TBS_LIST          */                { 3, ASN_SEQUENCE, 1, 1, 0 },
30545                                                               /* reqCert */
30546 /* TBS_REQ_CID       */                    { 4, ASN_SEQUENCE, 1, 1, 0 },
30547                                                                   /* hashAlgorithm */
30548 /* TBS_REQ_HASH      */                        { 5, ASN_SEQUENCE, 1, 1, 0 },
30549 /* TBS_REQ_HASH_OID  */                            { 6, ASN_OBJECT_ID, 0, 0, 0 },
30550                                                                   /* issuerNameHash */
30551 /* TBS_REQ_ISSUER    */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
30552                                                                   /* issuerKeyHash */
30553 /* TBS_REQ_ISSUERKEY */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
30554                                                                   /* serialNumber */
30555 /* TBS_REQ_SERIAL    */                        { 5, ASN_INTEGER, 0, 0, 0 },
30556                                                       /* requestExtensions */
30557 /* TBS_REQEXT        */            { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 0 },
30558                                                   /* optionalSignature not written. */
30559 };
30560 enum {
30561     OCSPREQUESTASN_IDX_SEQ = 0,
30562     OCSPREQUESTASN_IDX_TBS,
30563     OCSPREQUESTASN_IDX_TBS_SEQ,
30564     OCSPREQUESTASN_IDX_TBS_LIST,
30565     OCSPREQUESTASN_IDX_TBS_REQ_CID,
30566     OCSPREQUESTASN_IDX_TBS_REQ_HASH,
30567     OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID,
30568     OCSPREQUESTASN_IDX_TBS_REQ_ISSUER,
30569     OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY,
30570     OCSPREQUESTASN_IDX_TBS_REQ_SERIAL,
30571     OCSPREQUESTASN_IDX_TBS_REQEXT,
30572 };
30573 
30574 /* Number of items in ASN.1 template for OCSPRequest. */
30575 #define ocspRequestASN_Length (sizeof(ocspRequestASN) / sizeof(ASNItem))
30576 #endif
30577 
30578 int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
30579 {
30580 #ifndef WOLFSSL_ASN_TEMPLATE
30581     byte seqArray[5][MAX_SEQ_SZ];
30582     /* The ASN.1 of the OCSP Request is an onion of sequences */
30583     byte algoArray[MAX_ALGO_SZ];
30584     byte issuerArray[MAX_ENCODED_DIG_SZ];
30585     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
30586     byte snArray[MAX_SN_SZ];
30587     byte extArray[MAX_OCSP_EXT_SZ];
30588     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
30589     int i, snSz;
30590 
30591     WOLFSSL_ENTER("EncodeOcspRequest");
30592 
30593 #ifdef NO_SHA
30594     algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
30595 #else
30596     algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
30597 #endif
30598 
30599     issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);
30600     issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);
30601     snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
30602                                                           MAX_SN_SZ, MAX_SN_SZ);
30603     extSz       = 0;
30604 
30605     if (snSz < 0)
30606         return snSz;
30607 
30608     if (req->nonceSz) {
30609         /* TLS Extensions use this function too - put extensions after
30610          * ASN.1: Context Specific [2].
30611          */
30612         extSz = EncodeOcspRequestExtensions(req, extArray + 2,
30613                                             OCSP_NONCE_EXT_SZ);
30614         extSz += SetExplicit(2, extSz, extArray);
30615     }
30616 
30617     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
30618     for (i = 4; i >= 0; i--) {
30619         seqSz[i] = SetSequence(totalSz, seqArray[i]);
30620         totalSz += seqSz[i];
30621         if (i == 2) totalSz += extSz;
30622     }
30623 
30624     if (output == NULL)
30625         return totalSz;
30626     if (totalSz > size)
30627         return BUFFER_E;
30628 
30629     totalSz = 0;
30630     for (i = 0; i < 5; i++) {
30631         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
30632         totalSz += seqSz[i];
30633     }
30634 
30635     XMEMCPY(output + totalSz, algoArray, algoSz);
30636     totalSz += algoSz;
30637 
30638     XMEMCPY(output + totalSz, issuerArray, issuerSz);
30639     totalSz += issuerSz;
30640 
30641     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
30642     totalSz += issuerKeySz;
30643 
30644     XMEMCPY(output + totalSz, snArray, snSz);
30645     totalSz += snSz;
30646 
30647     if (extSz != 0) {
30648         XMEMCPY(output + totalSz, extArray, extSz);
30649         totalSz += extSz;
30650     }
30651 
30652     return totalSz;
30653 #else
30654     DECL_ASNSETDATA(dataASN, ocspRequestASN_Length);
30655     word32 extSz = 0;
30656     int sz;
30657     int ret = 0;
30658 
30659     WOLFSSL_ENTER("EncodeOcspRequest");
30660 
30661     CALLOC_ASNSETDATA(dataASN, ocspRequestASN_Length, ret, req->heap);
30662 
30663     if (ret == 0) {
30664         /* Set OID of hash algorithm use on issuer and key. */
30665     #ifdef NO_SHA
30666         SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHA256h,
30667                 oidHashType);
30668     #else
30669         SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHAh,
30670                 oidHashType);
30671     #endif
30672         /* Set issuer, issuer key hash and serial number of certificate being
30673          * checked. */
30674         SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUER],
30675                 req->issuerHash, KEYID_SIZE);
30676         SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY],
30677                 req->issuerKeyHash, KEYID_SIZE);
30678         SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_SERIAL],
30679                 req->serial, req->serialSz);
30680         /* Only extension to write is nonce - check if one to encode. */
30681         if (req->nonceSz) {
30682             /* Get size of extensions and leave space for them in encoding. */
30683             ret = extSz = EncodeOcspRequestExtensions(req, NULL, 0);
30684             SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT], NULL, extSz);
30685             if (ret > 0) {
30686                 ret = 0;
30687             }
30688         }
30689         else {
30690             /* Don't write out extensions. */
30691             dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].noOut = 1;
30692         }
30693     }
30694     if (ret == 0) {
30695         /* Calculate size of encoding. */
30696         ret = SizeASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length,
30697                 &sz);
30698     }
30699     /* Check buffer big enough for encoding if supplied. */
30700     if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
30701         ret = BUFFER_E;
30702     }
30703     if ((ret == 0) && (output != NULL)) {
30704         /* Encode OCSPRequest. */
30705         SetASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length, output);
30706         if (req->nonceSz) {
30707             /* Encode extensions into space provided. */
30708             ret = EncodeOcspRequestExtensions(req,
30709                 (byte*)dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].data.buffer.data,
30710                 extSz);
30711             if (ret > 0) {
30712                 ret = 0;
30713             }
30714         }
30715     }
30716 
30717     if (ret == 0) {
30718         /* Return size of encoding. */
30719         ret = sz;
30720     }
30721 
30722     FREE_ASNSETDATA(dataASN, req->heap);
30723     return ret;
30724 #endif /* WOLFSSL_ASN_TEMPLATE */
30725 }
30726 
30727 
30728 int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
30729                                                                      void* heap)
30730 {
30731     int ret;
30732 
30733     WOLFSSL_ENTER("InitOcspRequest");
30734 
30735     if (req == NULL)
30736         return BAD_FUNC_ARG;
30737 
30738     ForceZero(req, sizeof(OcspRequest));
30739     req->heap = heap;
30740 
30741     if (cert) {
30742         XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
30743         XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
30744 
30745         req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
30746                                                      DYNAMIC_TYPE_OCSP_REQUEST);
30747         if (req->serial == NULL)
30748             return MEMORY_E;
30749 
30750         XMEMCPY(req->serial, cert->serial, cert->serialSz);
30751         req->serialSz = cert->serialSz;
30752 
30753         if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
30754             req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,
30755                                                      DYNAMIC_TYPE_OCSP_REQUEST);
30756             if (req->url == NULL) {
30757                 XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
30758                 return MEMORY_E;
30759             }
30760 
30761             XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
30762             req->urlSz = cert->extAuthInfoSz;
30763             req->url[req->urlSz] = 0;
30764         }
30765     }
30766 
30767     if (useNonce) {
30768         WC_RNG rng;
30769 
30770     #ifndef HAVE_FIPS
30771         ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
30772     #else
30773         ret = wc_InitRng(&rng);
30774     #endif
30775         if (ret != 0) {
30776             WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
30777         } else {
30778             if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
30779                 WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
30780             else
30781                 req->nonceSz = MAX_OCSP_NONCE_SZ;
30782 
30783             wc_FreeRng(&rng);
30784         }
30785     }
30786 
30787     return 0;
30788 }
30789 
30790 void FreeOcspRequest(OcspRequest* req)
30791 {
30792     WOLFSSL_ENTER("FreeOcspRequest");
30793 
30794     if (req) {
30795         if (req->serial)
30796             XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
30797         req->serial = NULL;
30798 
30799 #ifdef OPENSSL_EXTRA
30800         if (req->serialInt) {
30801             if (req->serialInt->isDynamic) {
30802                 XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
30803             }
30804             XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
30805         }
30806         req->serialInt = NULL;
30807 #endif
30808 
30809         if (req->url)
30810             XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
30811         req->url = NULL;
30812     }
30813 }
30814 
30815 
30816 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
30817 {
30818     int cmp = -1; /* default as not matching, cmp gets set on each check */
30819     OcspEntry *single, *next, *prev = NULL, *top;
30820 
30821     WOLFSSL_ENTER("CompareOcspReqResp");
30822 
30823     if (req == NULL) {
30824         WOLFSSL_MSG("\tReq missing");
30825         return -1;
30826     }
30827     if (resp == NULL || resp->single == NULL) {
30828         WOLFSSL_MSG("\tResp missing");
30829         return 1;
30830     }
30831 
30832     /* Nonces are not critical. The responder may not necessarily add
30833      * the nonce to the response. */
30834     if (req->nonceSz && resp->nonce != NULL
30835 #ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
30836             && resp->nonceSz != 0
30837 #endif
30838     ) {
30839         cmp = req->nonceSz - resp->nonceSz;
30840         if (cmp != 0) {
30841             WOLFSSL_MSG("\tnonceSz mismatch");
30842             return cmp;
30843         }
30844 
30845         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
30846         if (cmp != 0) {
30847             WOLFSSL_MSG("\tnonce mismatch");
30848             return cmp;
30849         }
30850     }
30851 
30852     /* match based on found status and return */
30853     for (single = resp->single; single; single = next) {
30854         cmp = req->serialSz - single->status->serialSz;
30855         if (cmp == 0) {
30856             cmp = XMEMCMP(req->serial, single->status->serial, req->serialSz)
30857                || XMEMCMP(req->issuerHash, single->issuerHash, OCSP_DIGEST_SIZE)
30858                || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash, OCSP_DIGEST_SIZE);
30859             if (cmp == 0) {
30860                 /* match found */
30861                 if (resp->single != single && prev) {
30862                     /* move to top of list */
30863                     top = resp->single;
30864                     resp->single = single;
30865                     prev->next = single->next;
30866                     single->next = top;
30867                 }
30868                 break;
30869             }
30870         }
30871         next = single->next;
30872         prev = single;
30873     }
30874 
30875     if (cmp != 0) {
30876         WOLFSSL_MSG("\trequest and response mismatch");
30877         return cmp;
30878     }
30879 
30880     return 0;
30881 }
30882 
30883 #endif /* HAVE_OCSP */
30884 
30885 
30886 #ifdef WOLFSSL_ASN_TEMPLATE
30887 /* ASN.1 template for certificate name hash. */
30888 static const ASNItem nameHashASN[] = {
30889 /* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
30890 /* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
30891 };
30892 enum {
30893     NAMEHASHASN_IDX_OID = 0,
30894     NAMEHASHASN_IDX_NAME,
30895 };
30896 
30897 /* Number of items in ASN.1 template for certificate name hash. */
30898 #define nameHashASN_Length (sizeof(nameHashASN) / sizeof(ASNItem))
30899 #endif /* WOLFSSL_ASN_TEMPLATE */
30900 
30901 /* store WC_SHA hash of NAME */
30902 int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
30903 {
30904 #ifndef WOLFSSL_ASN_TEMPLATE
30905     int    length;  /* length of all distinguished names */
30906     int    ret;
30907     word32 dummy;
30908     byte   tag;
30909 
30910     WOLFSSL_ENTER("GetNameHash");
30911 
30912     dummy = *idx;
30913     if (GetASNTag(source, &dummy, &tag, maxIdx) == 0 && tag == ASN_OBJECT_ID) {
30914         WOLFSSL_MSG("Trying optional prefix...");
30915 
30916         if (GetLength(source, idx, &length, maxIdx) < 0)
30917             return ASN_PARSE_E;
30918 
30919         *idx += length;
30920         WOLFSSL_MSG("Got optional prefix");
30921     }
30922 
30923     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
30924      * calculated over the entire DER encoding of the Name field, including
30925      * the tag and length. */
30926     dummy = *idx;
30927     if (GetSequence(source, idx, &length, maxIdx) < 0)
30928         return ASN_PARSE_E;
30929 
30930     ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
30931 
30932     *idx += length;
30933 
30934     return ret;
30935 #else
30936     ASNGetData dataASN[nameHashASN_Length];
30937     int ret;
30938 
30939     XMEMSET(dataASN, 0, sizeof(dataASN));
30940     /* Ignore the OID even when present. */
30941     GetASN_OID(&dataASN[NAMEHASHASN_IDX_OID], oidIgnoreType);
30942     /* Decode certificate name. */
30943     ret = GetASN_Items(nameHashASN, dataASN, nameHashASN_Length, 0, source, idx,
30944            maxIdx);
30945     if (ret == 0) {
30946         /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
30947          * calculated over the entire DER encoding of the Name field, including
30948          * the tag and length. */
30949         /* Calculate hash of complete name including SEQUENCE. */
30950         ret = CalcHashId(
30951                 GetASNItem_Addr(dataASN[NAMEHASHASN_IDX_NAME], source),
30952                 GetASNItem_Length(dataASN[NAMEHASHASN_IDX_NAME], source),
30953                 hash);
30954     }
30955 
30956     return ret;
30957 #endif /* WOLFSSL_ASN_TEMPLATE */
30958 }
30959 
30960 
30961 #ifdef HAVE_CRL
30962 
30963 /* initialize decoded CRL */
30964 void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
30965 {
30966     WOLFSSL_MSG("InitDecodedCRL");
30967 
30968     XMEMSET(dcrl, 0, sizeof(DecodedCRL));
30969     dcrl->heap = heap;
30970 #ifdef WOLFSSL_HEAP_TEST
30971     dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
30972 #endif
30973 }
30974 
30975 
30976 /* free decoded CRL resources */
30977 void FreeDecodedCRL(DecodedCRL* dcrl)
30978 {
30979     RevokedCert* tmp = dcrl->certs;
30980 
30981     WOLFSSL_MSG("FreeDecodedCRL");
30982 
30983     while(tmp) {
30984         RevokedCert* next = tmp->next;
30985         XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
30986         tmp = next;
30987     }
30988 }
30989 
30990 
30991 #ifdef WOLFSSL_ASN_TEMPLATE
30992 /* ASN.1 template for revoked certificates.
30993  * X.509: RFC 5280, 5.1 - CRL Fields
30994  */
30995 static const ASNItem revokedASN[] = {
30996 /* SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30997                                      /* userCertificate    CertificateSerialNumber */
30998 /* CERT     */        { 1, ASN_INTEGER, 0, 0, 0 },
30999                                      /* revocationDate     Time */
31000 /* TIME_UTC */        { 1, ASN_UTC_TIME, 0, 0, 2 },
31001 /* TIME_GT  */        { 1, ASN_GENERALIZED_TIME, 0, 0, 2 },
31002                                      /* crlEntryExensions  Extensions */
31003 /* TIME_EXT */        { 1, ASN_SEQUENCE, 1, 0, 1 },
31004 };
31005 enum {
31006     REVOKEDASN_IDX_SEQ = 0,
31007     REVOKEDASN_IDX_CERT,
31008     REVOKEDASN_IDX_TIME_UTC,
31009     REVOKEDASN_IDX_TIME_GT,
31010     REVOKEDASN_IDX_TIME_EXT,
31011 };
31012 
31013 /* Number of items in ASN.1 template for revoked certificates. */
31014 #define revokedASN_Length (sizeof(revokedASN) / sizeof(ASNItem))
31015 #endif
31016 
31017 /* Get Revoked Cert list, 0 on success */
31018 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
31019                       int maxIdx)
31020 {
31021 #ifndef WOLFSSL_ASN_TEMPLATE
31022     int    ret, len;
31023     word32 end;
31024     byte   b;
31025     RevokedCert* rc;
31026 
31027     WOLFSSL_ENTER("GetRevoked");
31028 
31029     if (GetSequence(buff, idx, &len, maxIdx) < 0)
31030         return ASN_PARSE_E;
31031 
31032     end = *idx + len;
31033 
31034     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
31035                                                           DYNAMIC_TYPE_REVOKED);
31036     if (rc == NULL) {
31037         WOLFSSL_MSG("Alloc Revoked Cert failed");
31038         return MEMORY_E;
31039     }
31040 
31041     if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
31042                                                                 maxIdx) < 0) {
31043         XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
31044         return ASN_PARSE_E;
31045     }
31046 
31047     /* add to list */
31048     rc->next = dcrl->certs;
31049     dcrl->certs = rc;
31050     dcrl->totalCerts++;
31051 
31052     /* get date */
31053     ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
31054     if (ret < 0) {
31055         WOLFSSL_MSG("Expecting Date");
31056         return ret;
31057     }
31058 
31059     /* skip extensions */
31060     *idx = end;
31061 
31062     return 0;
31063 #else
31064     DECL_ASNGETDATA(dataASN, revokedASN_Length);
31065     int ret = 0;
31066     word32 serialSz = EXTERNAL_SERIAL_SIZE;
31067     RevokedCert* rc;
31068 
31069     /* Allocate a new revoked certificate object. */
31070     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
31071             DYNAMIC_TYPE_CRL);
31072     if (rc == NULL) {
31073         ret = MEMORY_E;
31074     }
31075 
31076     CALLOC_ASNGETDATA(dataASN, revokedASN_Length, ret, dcrl->heap);
31077 
31078     if (ret == 0) {
31079         /* Set buffer to place serial number into. */
31080         GetASN_Buffer(&dataASN[REVOKEDASN_IDX_CERT], rc->serialNumber,
31081                 &serialSz);
31082         /* Decode the Revoked */
31083         ret = GetASN_Items(revokedASN, dataASN, revokedASN_Length, 1, buff, idx,
31084                 maxIdx);
31085     }
31086     if (ret == 0) {
31087         /* Store size of serial number. */
31088         rc->serialSz = serialSz;
31089         /* TODO: use revocation date */
31090         /* TODO: use extensions, only v2 */
31091         /* Add revoked certificate to chain. */
31092         rc->next = dcrl->certs;
31093         dcrl->certs = rc;
31094         dcrl->totalCerts++;
31095     }
31096 
31097     FREE_ASNGETDATA(dataASN, dcrl->heap);
31098     if ((ret != 0) && (rc != NULL)) {
31099         XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL);
31100     }
31101     return ret;
31102 #endif /* WOLFSSL_ASN_TEMPLATE */
31103 }
31104 
31105 #ifdef WOLFSSL_ASN_TEMPLATE
31106 /* Parse the revoked certificates of a CRL.
31107  *
31108  * @param [in] dcrl    Decoded CRL object.
31109  * @param [in] buff    Buffer holding CRL.
31110  * @param [in] idx     Index into buffer of revoked certificates.
31111  * @param [in] maxIdx  Maximum index of revoked cartificates data.
31112  * @return  0 on success.
31113  * @return  ASN_PARSE_E on failure.
31114  */
31115 static int ParseCRL_RevokedCerts(DecodedCRL* dcrl, const byte* buff, word32 idx,
31116     word32 maxIdx)
31117 {
31118     int ret = 0;
31119 
31120     /* Parse each revoked cerificate. */
31121     while ((ret == 0) && (idx < maxIdx)) {
31122         /* Parse a revoked certificate. */
31123         if (GetRevoked(buff, &idx, dcrl, maxIdx) < 0) {
31124             ret = ASN_PARSE_E;
31125         }
31126     }
31127 
31128     return ret;
31129 }
31130 #endif /* WOLFSSL_ASN_TEMPLATE */
31131 
31132 #ifndef WOLFSSL_ASN_TEMPLATE
31133 /* Get CRL Signature, 0 on success */
31134 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
31135                             int maxIdx)
31136 {
31137     int    length;
31138     int    ret;
31139 
31140     WOLFSSL_ENTER("GetCRL_Signature");
31141 
31142     ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
31143     if (ret != 0)
31144         return ret;
31145     dcrl->sigLength = length;
31146 
31147     dcrl->signature = (byte*)&source[*idx];
31148     *idx += dcrl->sigLength;
31149 
31150     return 0;
31151 }
31152 #endif /* !WOLFSSL_ASN_TEMPLATE */
31153 
31154 int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
31155                         word32 tbsSz, const byte* signature, word32 sigSz,
31156                         word32 signatureOID, Signer *ca, void* heap)
31157 {
31158     /* try to confirm/verify signature */
31159 #ifndef IGNORE_KEY_EXTENSIONS
31160     if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
31161         WOLFSSL_MSG("CA cannot sign CRLs");
31162         return ASN_CRL_NO_SIGNER_E;
31163     }
31164 #endif /* IGNORE_KEY_EXTENSIONS */
31165 
31166     InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
31167     if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
31168                          ca->pubKeySize, ca->keyOID, signature, sigSz,
31169                          signatureOID, NULL) != 0) {
31170         WOLFSSL_MSG("CRL Confirm signature failed");
31171         return ASN_CRL_CONFIRM_E;
31172     }
31173 
31174     return 0;
31175 }
31176 
31177 #ifdef WOLFSSL_ASN_TEMPLATE
31178 /* Find the signer for the CRL and verify the signature.
31179  *
31180  * @param [in] dcrl  Decoded CRL object.
31181  * @param [in] buff  Buffer holding CRL.
31182  * @param [in] cm    Certificate manager object.
31183  * @return  0 on success.
31184  * @return  ASN_CRL_NO_SIGNER_E when no signer found.
31185  * @return  ASN_CRL_CONFIRM_E when signature did not verify.
31186  */
31187 static int PaseCRL_CheckSignature(DecodedCRL* dcrl, const byte* buff, void* cm)
31188 {
31189     int ret = 0;
31190     Signer* ca = NULL;
31191     SignatureCtx sigCtx;
31192 
31193     /* OpenSSL doesn't add skid by default for CRLs cause firefox chokes.
31194      * If experiencing issues uncomment NO_SKID define in CRL section of
31195      * wolfssl/wolfcrypt/settings.h */
31196 #ifndef NO_SKID
31197     if (dcrl->extAuthKeyIdSet) {
31198         /* more unique than issuerHash */
31199         ca = GetCA(cm, dcrl->extAuthKeyId);
31200     }
31201     /* Check issuerHash matched CA's subjectNameHash. */
31202     if ((ca != NULL) && (XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
31203                                  KEYID_SIZE) != 0)) {
31204         ca = NULL;
31205     }
31206     if (ca == NULL) {
31207         ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
31208         /* If AKID is available then this CA doesn't have the public
31209          * key required */
31210         if (ca && dcrl->extAuthKeyIdSet) {
31211             WOLFSSL_MSG("CA SKID doesn't match AKID");
31212             ca = NULL;
31213         }
31214     }
31215 #else
31216     ca = GetCA(cm, dcrl->issuerHash);
31217 #endif /* !NO_SKID */
31218     WOLFSSL_MSG("About to verify CRL signature");
31219 
31220     if (ca == NULL) {
31221         WOLFSSL_MSG("Did NOT find CRL issuer CA");
31222         ret = ASN_CRL_NO_SIGNER_E;
31223     }
31224 
31225     if (ret == 0) {
31226         WOLFSSL_MSG("Found CRL issuer CA");
31227         /* Verify CRL signature with CA. */
31228         ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
31229            dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
31230            dcrl->signatureOID, ca, dcrl->heap);
31231     }
31232 
31233     return ret;
31234 }
31235 #endif
31236 
31237 #ifndef WOLFSSL_ASN_TEMPLATE
31238 static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf,
31239         word32* inOutIdx, int sz)
31240 {
31241     word32 oid, dateIdx, idx, checkIdx;
31242     int version;
31243 #ifdef WOLFSSL_NO_CRL_NEXT_DATE
31244     int doNextDate = 1;
31245 #endif
31246     byte tag;
31247 
31248     if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
31249         return BAD_FUNC_ARG;
31250     }
31251 
31252     /* may have version */
31253     idx = *inOutIdx;
31254 
31255     checkIdx = idx;
31256     if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
31257         if (GetMyVersion(buf, &idx, &version, sz) < 0)
31258             return ASN_PARSE_E;
31259     }
31260 
31261     if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0)
31262         return ASN_PARSE_E;
31263 
31264     if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0)
31265         return ASN_PARSE_E;
31266 
31267     if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
31268         return ASN_PARSE_E;
31269 
31270     dateIdx = idx;
31271 
31272     if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
31273     {
31274 #ifndef WOLFSSL_NO_CRL_NEXT_DATE
31275         (void)dateIdx;
31276         return ASN_PARSE_E;
31277 #else
31278         dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
31279         doNextDate = 0;
31280         idx = dateIdx;
31281 #endif
31282     }
31283 
31284 #ifdef WOLFSSL_NO_CRL_NEXT_DATE
31285     if (doNextDate)
31286 #endif
31287     {
31288 #ifndef NO_ASN_TIME
31289         if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
31290             WOLFSSL_MSG("CRL after date is no longer valid");
31291             return CRL_CERT_DATE_ERR;
31292         }
31293 #endif
31294     }
31295 
31296     checkIdx = idx;
31297     if (idx != dcrl->sigIndex &&
31298            GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
31299 
31300         int len;
31301 
31302         if (GetSequence(buf, &idx, &len, sz) < 0)
31303             return ASN_PARSE_E;
31304         len += idx;
31305 
31306         while (idx < (word32)len) {
31307             if (GetRevoked(buf, &idx, dcrl, len) < 0)
31308                 return ASN_PARSE_E;
31309         }
31310     }
31311 
31312     *inOutIdx = idx;
31313 
31314     return 0;
31315 }
31316 #endif /* !WOLFSSL_ASN_TEMPLATE */
31317 
31318 
31319 #ifndef NO_SKID
31320 static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
31321 {
31322 #ifndef WOLFSSL_ASN_TEMPLATE
31323     word32 idx = 0;
31324     int length = 0, ret = 0;
31325     byte tag;
31326 
31327     WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
31328 
31329     if (GetSequence(input, &idx, &length, sz) < 0) {
31330         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
31331         return ASN_PARSE_E;
31332     }
31333 
31334     if (GetASNTag(input, &idx, &tag, sz) < 0) {
31335         return ASN_PARSE_E;
31336     }
31337 
31338     if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
31339         WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
31340         return 0;
31341     }
31342 
31343     if (GetLength(input, &idx, &length, sz) <= 0) {
31344         WOLFSSL_MSG("\tfail: extension data length");
31345         return ASN_PARSE_E;
31346     }
31347 
31348     dcrl->extAuthKeyIdSet = 1;
31349     /* Get the hash or hash of the hash if wrong size. */
31350     ret = GetHashId(input + idx, length, dcrl->extAuthKeyId);
31351 
31352     return ret;
31353 #else
31354     DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
31355     int ret = 0;
31356     word32 idx = 0;
31357 
31358     WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
31359 
31360     CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, dcrl->heap);
31361 
31362     if (ret == 0) {
31363         /* Parse an authority key identifier. */
31364         ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
31365                            &idx, sz);
31366     }
31367     if (ret == 0) {
31368         /* Key id is optional. */
31369         if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
31370             WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
31371         }
31372         else {
31373             /* Get the hash or hash of the hash if wrong size. */
31374             ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
31375                 dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
31376                 dcrl->extAuthKeyId);
31377         }
31378     }
31379 
31380     FREE_ASNGETDATA(dataASN, dcrl->heap);
31381     return ret;
31382 #endif /* WOLFSSL_ASN_TEMPLATE */
31383 }
31384 #endif
31385 
31386 
31387 #ifndef WOLFSSL_ASN_TEMPLATE
31388 static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
31389         word32* inOutIdx, word32 sz)
31390 {
31391     int length;
31392     word32 idx;
31393     word32 ext_bound; /* boundary index for the sequence of extensions */
31394     word32 oid;
31395     byte tag;
31396 
31397     WOLFSSL_ENTER("ParseCRL_Extensions");
31398     (void)dcrl;
31399 
31400     if (inOutIdx == NULL)
31401         return BAD_FUNC_ARG;
31402 
31403     idx = *inOutIdx;
31404 
31405     /* CRL Extensions are optional */
31406     if ((idx + 1) > sz)
31407         return 0;
31408 
31409     /* CRL Extensions are optional */
31410     if (GetASNTag(buf, &idx, &tag, sz) < 0)
31411         return 0;
31412 
31413     /* CRL Extensions are optional */
31414     if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
31415         return 0;
31416 
31417     if (GetLength(buf, &idx, &length, sz) < 0)
31418         return ASN_PARSE_E;
31419 
31420     if (GetSequence(buf, &idx, &length, sz) < 0)
31421         return ASN_PARSE_E;
31422 
31423     ext_bound = idx + length;
31424 
31425     while (idx < (word32)ext_bound) {
31426         word32 localIdx;
31427         int ret;
31428 
31429         if (GetSequence(buf, &idx, &length, sz) < 0) {
31430             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
31431             return ASN_PARSE_E;
31432         }
31433 
31434         oid = 0;
31435         if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
31436             WOLFSSL_MSG("\tfail: OBJECT ID");
31437             return ASN_PARSE_E;
31438         }
31439 
31440         /* check for critical flag */
31441         if ((idx + 1) > (word32)sz) {
31442             WOLFSSL_MSG("\tfail: malformed buffer");
31443             return BUFFER_E;
31444         }
31445 
31446         localIdx = idx;
31447         if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
31448             WOLFSSL_MSG("\tfound optional critical flag, moving past");
31449             ret = GetBoolean(buf, &idx, sz);
31450             if (ret < 0)
31451                 return ret;
31452         }
31453 
31454         ret = GetOctetString(buf, &idx, &length, sz);
31455         if (ret < 0)
31456             return ret;
31457 
31458         if (oid == AUTH_KEY_OID) {
31459         #ifndef NO_SKID
31460             ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
31461             if (ret < 0) {
31462                 WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
31463                 return ret;
31464             }
31465         #endif
31466         }
31467 
31468         idx += length;
31469     }
31470 
31471     *inOutIdx = idx;
31472 
31473     return 0;
31474 }
31475 #else
31476 /* Parse the extensions of a CRL.
31477  *
31478  * @param [in] dcrl    Decoded CRL object.
31479  * @param [in] buff    Buffer holding CRL.
31480  * @param [in] idx     Index into buffer of extensions.
31481  * @param [in] maxIdx  Maximum index of extension data.
31482  * @return  0 on success.
31483  * @return  ASN_PARSE_E on failure.
31484  */
31485 static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
31486         word32 maxIdx)
31487 {
31488     DECL_ASNGETDATA(dataASN, certExtASN_Length);
31489     int ret = 0;
31490 
31491     ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
31492 
31493     while ((ret == 0) && (idx < maxIdx)) {
31494         byte critical = 0;
31495 
31496         /* Clear dynamic data. */
31497         XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
31498         /* Ensure OID is an extention type. */
31499         GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
31500         /* Set criticality variable. */
31501         GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
31502         /* Parse extension wrapper. */
31503         ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, buf, &idx,
31504                 maxIdx);
31505         if (ret == 0) {
31506             /* OID in extension. */
31507             word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
31508             /* Length of extension data. */
31509             int length = dataASN[CERTEXTASN_IDX_VAL].length;
31510 
31511             if (oid == AUTH_KEY_OID) {
31512             #ifndef NO_SKID
31513                 /* Parse Authority Key Id extesion.
31514                  * idx is at start of OCTET_STRING data. */
31515                 ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
31516                 if (ret != 0) {
31517                     WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
31518                 }
31519             #endif
31520             }
31521             /* TODO: Parse CRL Number extension */
31522             /* TODO: check criticality */
31523             /* Move index on to next extension. */
31524             idx += length;
31525         }
31526     }
31527 
31528     if (ret < 0) {
31529         ret = ASN_PARSE_E;
31530     }
31531     return ret;
31532 }
31533 #endif /* !WOLFSSL_ASN_TEMPLATE */
31534 
31535 
31536 #ifdef WOLFSSL_ASN_TEMPLATE
31537 /* ASN.1 template for a CRL- CertificateList.
31538  * X.509: RFC 5280, 5.1 - CRL Fields
31539  */
31540 static const ASNItem crlASN[] = {
31541                                        /* CertificateList */
31542 /* SEQ                */    { 0, ASN_SEQUENCE, 1, 1, 0 },
31543                                            /* tbsCertList */
31544 /* TBS                */        { 1, ASN_SEQUENCE, 1, 1, 0 },
31545                                                /* version     Version OPTIONAL if present must be v2 */
31546 /* TBS_VER            */            { 2, ASN_INTEGER, 0, 0, 1 },
31547                                                /* signature */
31548 /* TBS_SIGALGO        */            { 2, ASN_SEQUENCE, 1, 1, 0 },
31549 /* TBS_SIGALGO_OID    */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
31550 /* TBS_SIGALGO_NULL   */                { 3, ASN_TAG_NULL, 0, 0, 1 },
31551                                                /* issuer */
31552 /* TBS_ISSUER         */            { 2, ASN_SEQUENCE, 1, 0, 0 },
31553                                                /* thisUpdate */
31554 /* TBS_THISUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 2 },
31555 /* TBS_THISUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 2 },
31556                                                /* nextUpdate */
31557 /* TBS_NEXTUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 3 },
31558 /* TBS_NEXTUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 3 },
31559                                                /* revokedCertificates */
31560 /* TBS_REVOKEDCERTS   */            { 2, ASN_SEQUENCE, 1, 0, 1 },
31561                                                /* crlExtensions */
31562 /* TBS_EXT            */            { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
31563 /* TBS_EXT_SEQ        */                { 3, ASN_SEQUENCE, 1, 0, 0 },
31564                                            /* signatureAlgorithm */
31565 /* SIGALGO            */        { 1, ASN_SEQUENCE, 1, 1, 0 },
31566 /* SIGALGO_OID        */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
31567 /* SIGALGO_NULL       */            { 2, ASN_TAG_NULL, 0, 0, 1 },
31568                                            /* signatureValue */
31569 /* SIGNATURE          */        { 1, ASN_BIT_STRING, 0, 0, 0 },
31570 };
31571 enum {
31572     CRLASN_IDX_SEQ = 0,
31573     CRLASN_IDX_TBS,
31574     CRLASN_IDX_TBS_VER,
31575     CRLASN_IDX_TBS_SIGALGO,
31576     CRLASN_IDX_TBS_SIGALGO_OID,
31577     CRLASN_IDX_TBS_SIGALGO_NULL,
31578     CRLASN_IDX_TBS_ISSUER,
31579     CRLASN_IDX_TBS_THISUPDATE_UTC,
31580     CRLASN_IDX_TBS_THISUPDATE_GT,
31581     CRLASN_IDX_TBS_NEXTUPDATE_UTC,
31582     CRLASN_IDX_TBS_NEXTUPDATE_GT,
31583     CRLASN_IDX_TBS_REVOKEDCERTS,
31584     CRLASN_IDX_TBS_EXT,
31585     CRLASN_IDX_TBS_EXT_SEQ,
31586     CRLASN_IDX_SIGALGO,
31587     CRLASN_IDX_SIGALGO_OID,
31588     CRLASN_IDX_SIGALGO_NULL,
31589     CRLASN_IDX_SIGNATURE,
31590 };
31591 
31592 /* Number of items in ASN.1 template for a CRL- CertificateList. */
31593 #define crlASN_Length (sizeof(crlASN) / sizeof(ASNItem))
31594 #endif
31595 
31596 /* parse crl buffer into decoded state, 0 on success */
31597 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
31598 {
31599 #ifndef WOLFSSL_ASN_TEMPLATE
31600     Signer*      ca = NULL;
31601     SignatureCtx sigCtx;
31602     int          ret = 0;
31603     int          len;
31604     word32       idx = 0;
31605 
31606     WOLFSSL_MSG("ParseCRL");
31607 
31608     /* raw crl hash */
31609     /* hash here if needed for optimized comparisons
31610      * wc_Sha sha;
31611      * wc_InitSha(&sha);
31612      * wc_ShaUpdate(&sha, buff, sz);
31613      * wc_ShaFinal(&sha, dcrl->crlHash); */
31614 
31615     if (GetSequence(buff, &idx, &len, sz) < 0)
31616         return ASN_PARSE_E;
31617 
31618     dcrl->certBegin = idx;
31619     /* Normalize sz for the length inside the outer sequence. */
31620     sz = len + idx;
31621 
31622     if (GetSequence(buff, &idx, &len, sz) < 0)
31623         return ASN_PARSE_E;
31624     dcrl->sigIndex = len + idx;
31625 
31626     if (ParseCRL_CertList(dcrl, buff, &idx, dcrl->sigIndex) < 0)
31627         return ASN_PARSE_E;
31628 
31629     if (ParseCRL_Extensions(dcrl, buff, &idx, dcrl->sigIndex) < 0)
31630         return ASN_PARSE_E;
31631 
31632     idx = dcrl->sigIndex;
31633 
31634     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
31635         return ASN_PARSE_E;
31636 
31637     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
31638         return ASN_PARSE_E;
31639 
31640     /* openssl doesn't add skid by default for CRLs cause firefox chokes
31641        if experiencing issues uncomment NO_SKID define in CRL section of
31642        wolfssl/wolfcrypt/settings.h */
31643 #ifndef NO_SKID
31644     if (dcrl->extAuthKeyIdSet) {
31645         ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
31646     }
31647     if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
31648                 KEYID_SIZE) != 0) {
31649         ca = NULL;
31650     }
31651     if (ca == NULL) {
31652         ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
31653         /* If AKID is available then this CA doesn't have the public
31654          * key required */
31655         if (ca && dcrl->extAuthKeyIdSet) {
31656             WOLFSSL_MSG("CA SKID doesn't match AKID");
31657             ca = NULL;
31658         }
31659     }
31660 #else
31661     ca = GetCA(cm, dcrl->issuerHash);
31662 #endif /* !NO_SKID */
31663     WOLFSSL_MSG("About to verify CRL signature");
31664 
31665     if (ca == NULL) {
31666         WOLFSSL_MSG("Did NOT find CRL issuer CA");
31667         ret = ASN_CRL_NO_SIGNER_E;
31668         goto end;
31669     }
31670 
31671     WOLFSSL_MSG("Found CRL issuer CA");
31672     ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
31673            dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
31674            dcrl->signatureOID, ca, dcrl->heap);
31675 
31676 end:
31677     return ret;
31678 #else
31679     DECL_ASNGETDATA(dataASN, crlASN_Length);
31680     int ret = 0;
31681     /* Default version - v1 = 0 */
31682     byte version = 0;
31683     word32 idx = 0;
31684     /* Size of buffer for date. */
31685     word32 lastDateSz = MAX_DATE_SIZE;
31686     word32 nextDateSz = MAX_DATE_SIZE;
31687 
31688     WOLFSSL_MSG("ParseCRL");
31689 
31690     CALLOC_ASNGETDATA(dataASN, crlASN_Length, ret, dcrl->heap);
31691 
31692     if (ret == 0) {
31693         /* Set variable to store version. */
31694         GetASN_Int8Bit(&dataASN[CRLASN_IDX_TBS_VER], &version);
31695         /* Set expecting signature OID. */
31696         GetASN_OID(&dataASN[CRLASN_IDX_TBS_SIGALGO_OID], oidSigType);
31697         /* Set buffer to put last and next date into. */
31698         GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC], dcrl->lastDate,
31699                 &lastDateSz);
31700         GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_GT], dcrl->lastDate,
31701                 &lastDateSz);
31702         GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC], dcrl->nextDate,
31703                 &nextDateSz);
31704         GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT], dcrl->nextDate,
31705                 &nextDateSz);
31706         /* Set expecting signature OID. */
31707         GetASN_OID(&dataASN[CRLASN_IDX_SIGALGO_OID], oidSigType);
31708         /* Decode the CRL. */
31709         ret = GetASN_Items(crlASN, dataASN, crlASN_Length, 1, buff, &idx, sz);
31710     }
31711     /* Version must be v2 = 1 if present. */
31712     if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_VER].tag != 0) &&
31713             (version != 1)) {
31714         ret = ASN_PARSE_E;
31715     }
31716     /* Check minimum size of last date. */
31717     if ((ret == 0) && (lastDateSz < MIN_DATE_SIZE)) {
31718         ret = ASN_PARSE_E;
31719     }
31720     /* Check minimum size of next date. */
31721     if ((ret == 0) && (nextDateSz < MIN_DATE_SIZE)) {
31722         ret = ASN_PARSE_E;
31723     }
31724     /* 'signatureAlgorithm' OID must be the same as 'signature' OID. */
31725     if ((ret == 0) && (dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum !=
31726             dataASN[CRLASN_IDX_TBS_SIGALGO_OID].data.oid.sum)) {
31727         ret = ASN_PARSE_E;
31728     }
31729     if (ret == 0) {
31730         /* Store offset of to be signed part. */
31731         dcrl->certBegin = dataASN[CRLASN_IDX_TBS].offset;
31732         /* Store index of signature. */
31733         dcrl->sigIndex = dataASN[CRLASN_IDX_SIGALGO].offset;
31734         /* Store address and length of signature data. */
31735         GetASN_GetRef(&dataASN[CRLASN_IDX_SIGNATURE], &dcrl->signature,
31736                 &dcrl->sigLength);
31737         /* Get the signature OID. */
31738         dcrl->signatureOID = dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum;
31739         /* Get the format/tag of the last and next date. */
31740         dcrl->lastDateFormat = (dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag != 0)
31741                 ? dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag
31742                 : dataASN[CRLASN_IDX_TBS_THISUPDATE_GT].tag;
31743         dcrl->nextDateFormat = (dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag != 0)
31744                 ? dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag
31745                 : dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT].tag;
31746     #ifndef NO_ASN_TIME
31747         if (dcrl->nextDateFormat != 0) {
31748             /* Next date was set, so validate it. */
31749             if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
31750                 WOLFSSL_MSG("CRL after date is no longer valid");
31751                 ret = CRL_CERT_DATE_ERR;
31752             }
31753         }
31754     }
31755     if (ret == 0) {
31756     #endif
31757         /* Calculate the Hash id from the issuer name. */
31758         ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
31759                 GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
31760                 dcrl->issuerHash);
31761         if (ret < 0) {
31762             ret = ASN_PARSE_E;
31763         }
31764     }
31765     if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_REVOKEDCERTS].tag != 0)) {
31766         /* Parse revoked cerificates - starting after SEQUENCE OF. */
31767         ret = ParseCRL_RevokedCerts(dcrl, buff,
31768             GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff),
31769             GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff));
31770     }
31771     if (ret == 0) {
31772         /* Parse the extensions - starting after SEQUENCE OF. */
31773         ret = ParseCRL_Extensions(dcrl, buff,
31774             GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff),
31775             GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff));
31776     }
31777     if (ret == 0) {
31778         /* Find signer and verify signature. */
31779         ret = PaseCRL_CheckSignature(dcrl, buff, cm);
31780     }
31781 
31782     FREE_ASNGETDATA(dataASN, dcrl->heap);
31783     return ret;
31784 #endif /* WOLFSSL_ASN_TEMPLATE */
31785 }
31786 
31787 #endif /* HAVE_CRL */
31788 
31789 
31790 
31791 #ifdef WOLFSSL_CERT_PIV
31792 
31793 #ifdef WOLFSSL_ASN_TEMPLATE
31794 /* Template for PIV. */
31795 static const ASNItem pivASN[] = {
31796 /* CERT        */ { 0, ASN_PIV_CERT, 0, 0, 0 },
31797 /* NONCE       */ { 0, ASN_PIV_NONCE, 0, 0, 1 },
31798 /* SIGNEDNONCE */ { 0, ASN_PIV_SIGNED_NONCE, 0, 0, 1 },
31799 };
31800 enum {
31801     PIVASN_IDX_CERT = 0,
31802     PIVASN_IDX_NONCE,
31803     PIVASN_IDX_SIGNEDNONCE,
31804 };
31805 
31806 #define pivASN_Length (sizeof(pivASN) / sizeof(ASNItem))
31807 
31808 static const ASNItem pivCertASN[] = {
31809                           /* 0x53 = 0x40 | 0x13 */
31810 /* CERT */ { 1, ASN_APPLICATION | 0x13, 0, 1, 0 },
31811                                /* 0x70 = 0x40 | 0x10 + 0x20 (CONSTRUCTED) */
31812 /* X509 */      { 2, ASN_APPLICATION | 0x10, 1, 0, 0 },
31813                                /* 0x71 = 0x40 | 0x11 + 0x20 (CONSTRUCTED) */
31814 /* INFO */      { 2, ASN_APPLICATION | 0x11, 1, 0, 1 },
31815                                /* 0xFE = 0xC0 | 0x1E + 0x20 (CONSTRUCTED) */
31816 /* ERR */      { 2, ASN_PRIVATE | 0x1e, 1, 0, 1 },
31817 };
31818 enum {
31819     PIVCERTASN_IDX_CERT,
31820     PIVCERTASN_IDX_X509,
31821     PIVCERTASN_IDX_INFO,
31822     PIVCERTASN_IDX_ERR,
31823 };
31824 
31825 #define pivCertASN_Length (sizeof(pivCertASN) / sizeof(ASNItem))
31826 #endif
31827 
31828 int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
31829 {
31830 #ifndef WOLFSSL_ASN_TEMPLATE
31831     int length = 0;
31832     word32 idx = 0;
31833 
31834     WOLFSSL_ENTER("wc_ParseCertPIV");
31835 
31836     if (piv == NULL || buf == NULL || totalSz == 0)
31837         return BAD_FUNC_ARG;
31838 
31839     XMEMSET(piv, 0, sizeof(wc_CertPIV));
31840 
31841     /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
31842     /* Certificate (0A 82 05FA) */
31843     if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
31844         /* Identiv Type PIV card */
31845         piv->isIdentiv = 1;
31846 
31847         piv->cert =   &buf[idx];
31848         piv->certSz = length;
31849         idx += length;
31850 
31851         /* Nonce (0B 14) */
31852         if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
31853             piv->nonce =   &buf[idx];
31854             piv->nonceSz = length;
31855             idx += length;
31856         }
31857 
31858         /* Signed Nonce (0C 82 0100) */
31859         if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
31860             piv->signedNonce =   &buf[idx];
31861             piv->signedNonceSz = length;
31862         }
31863 
31864         idx = 0;
31865         buf = piv->cert;
31866         totalSz = piv->certSz;
31867     }
31868 
31869     /* Certificate Buffer Total Size (53 82 05F6) */
31870     if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
31871                                                    &length, totalSz) < 0) {
31872         return ASN_PARSE_E;
31873     }
31874     /* PIV Certificate (70 82 05ED) */
31875     if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
31876                                                          totalSz) < 0) {
31877         return ASN_PARSE_E;
31878     }
31879 
31880     /* Capture certificate buffer pointer and length */
31881     piv->cert =   &buf[idx];
31882     piv->certSz = length;
31883     idx += length;
31884 
31885     /* PIV Certificate Info (71 01 00) */
31886     if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
31887                                                         totalSz) >= 0) {
31888         if (length >= 1) {
31889             piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
31890             piv->isX509 =      ((buf[idx] & ASN_PIV_CERT_INFO_ISX509) != 0);
31891         }
31892         idx += length;
31893     }
31894 
31895     /* PIV Error Detection (FE 00) */
31896     if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
31897                                                         totalSz) >= 0) {
31898         piv->certErrDet =   &buf[idx];
31899         piv->certErrDetSz = length;
31900         idx += length;
31901     }
31902 
31903     return 0;
31904 #else
31905     /* pivCertASN_Length is longer than pivASN_Length */
31906     DECL_ASNGETDATA(dataASN, pivCertASN_Length);
31907     int ret = 0;
31908     word32 idx;
31909     byte info;
31910 
31911     WOLFSSL_ENTER("wc_ParseCertPIV");
31912 
31913     ALLOC_ASNGETDATA(dataASN, pivCertASN_Length, ret, NULL);
31914 
31915     if (ret == 0) {
31916         /* Clear dynamic data. */
31917         XMEMSET(dataASN, 0, sizeof(*dataASN) * pivASN_Length);
31918         /* Start parsing from start of buffer. */
31919         idx = 0;
31920         /* Parse Identiv wrapper. */
31921         ret = GetASN_Items(pivASN, dataASN, pivASN_Length, 1, buf, &idx,
31922                 totalSz);
31923         if (ret == 0) {
31924             /* Identiv wrapper found. */
31925             piv->isIdentiv = 1;
31926             /* Get nonce reference. */
31927             if (dataASN[PIVASN_IDX_NONCE].tag != 0) {
31928                 GetASN_GetConstRef(&dataASN[PIVASN_IDX_NONCE], &piv->nonce,
31929                         &piv->nonceSz);
31930             }
31931             /* Get signedNonce reference. */
31932             if (dataASN[PIVASN_IDX_SIGNEDNONCE].tag != 0) {
31933                 GetASN_GetConstRef(&dataASN[PIVASN_IDX_SIGNEDNONCE],
31934                         &piv->signedNonce, &piv->signedNonceSz);
31935             }
31936             /* Get the certificate data for parsing. */
31937             GetASN_GetConstRef(&dataASN[PIVASN_IDX_CERT], &buf, &totalSz);
31938         }
31939         ret = 0;
31940     }
31941     if (ret == 0) {
31942         /* Clear dynamic data and set variable to put cert info into. */
31943         XMEMSET(dataASN, 0, sizeof(*dataASN) * pivCertASN_Length);
31944         GetASN_Int8Bit(&dataASN[PIVCERTASN_IDX_INFO], &info);
31945         /* Start parsing from start of buffer. */
31946         idx = 0;
31947         /* Parse PIV cetificate data. */
31948         ret = GetASN_Items(pivCertASN, dataASN, pivCertASN_Length, 1, buf, &idx,
31949                 totalSz);
31950         if (ret == 0) {
31951             /* Get X.509 certificate reference. */
31952             GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_X509], &piv->cert,
31953                     &piv->certSz);
31954             /* Set the certificate info if available. */
31955             if (dataASN[PIVCERTASN_IDX_INFO].tag != 0) {
31956                 /* Bits 1 and 2 are compression. */
31957                 piv->compression = info & ASN_PIV_CERT_INFO_COMPRESSED;
31958                 /* Bits 3 is X509 flag. */
31959                 piv->isX509 = ((info & ASN_PIV_CERT_INFO_ISX509) != 0);
31960             }
31961             /* Get X.509 certificate error detection reference. */
31962             GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_ERR], &piv->certErrDet,
31963                      &piv->certErrDetSz);
31964         }
31965         ret = 0;
31966     }
31967 
31968     FREE_ASNGETDATA(dataASN, NULL);
31969     return ret;
31970 #endif /* WOLFSSL_ASN_TEMPLATE */
31971 }
31972 
31973 #endif /* WOLFSSL_CERT_PIV */
31974 
31975 
31976 
31977 #ifdef HAVE_SMIME
31978 
31979 /*****************************************************************************
31980 * wc_MIME_parse_headers - Reads the char array in and parses out MIME headers
31981 * and parameters into headers.  Will continue until in has no more content.
31982 *
31983 * RETURNS:
31984 * returns zero on success, non-zero on error.
31985 */
31986 int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
31987 {
31988     MimeHdr* nextHdr = NULL;
31989     MimeHdr* curHdr = NULL;
31990     MimeParam* nextParam = NULL;
31991     size_t start = 0;
31992     size_t end = 0;
31993     char* nameAttr = NULL;
31994     char* bodyVal = NULL;
31995     MimeTypes mimeType = MIME_HDR;
31996     MimeStatus mimeStatus = MIME_NAMEATTR;
31997     int ret = -1;
31998     size_t pos = 0;
31999     size_t lineLen = 0;
32000     char* curLine = NULL;
32001     char* ptr = NULL;
32002 
32003     if (in == NULL || inLen <= 0 || in[inLen] != '\0' || headers == NULL) {
32004         ret = BAD_FUNC_ARG;
32005         goto error;
32006     }
32007     nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL, DYNAMIC_TYPE_PKCS7);
32008     nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
32009                                     DYNAMIC_TYPE_PKCS7);
32010     if (nextHdr == NULL || nextParam == NULL) {
32011         ret = MEMORY_E;
32012         goto error;
32013     }
32014     XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
32015     XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
32016 
32017     curLine = XSTRTOK(in, "\r\n", &ptr);
32018     if (curLine == NULL) {
32019         ret = ASN_PARSE_E;
32020         goto error;
32021     }
32022 
32023     while (curLine != NULL) {
32024         /* Leftover from previous line, add params to previous header. */
32025         if (curLine[0] == ' ' && curHdr) {
32026             mimeType = MIME_PARAM;
32027         }
32028         else {
32029             mimeType = MIME_HDR;
32030         }
32031         start = 0;
32032         lineLen = XSTRLEN(curLine);
32033         if (lineLen == 0) {
32034             ret = BAD_FUNC_ARG;
32035             goto error;
32036         }
32037 
32038         for (pos = 0; pos < lineLen; pos++) {
32039             char cur = curLine[pos];
32040 
32041             if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
32042                 mimeType == MIME_HDR) || (cur == '=' &&
32043                 mimeType == MIME_PARAM)) && pos >= 1) {
32044                 mimeStatus = MIME_BODYVAL;
32045                 end = pos-1;
32046                 if (nameAttr != NULL)
32047                     XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
32048                 ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
32049                 if (ret) {
32050                     goto error;
32051                 }
32052                 start = pos+1;
32053             }
32054             else if (mimeStatus == MIME_BODYVAL && cur == ';' && pos >= 1) {
32055                 end = pos-1;
32056                 if (bodyVal != NULL)
32057                     XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
32058                 ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
32059                 if (ret) {
32060                     goto error;
32061                 }
32062                 if (mimeType == MIME_HDR) {
32063                     nextHdr->name = nameAttr;
32064                     nameAttr = NULL;
32065                     nextHdr->body = bodyVal;
32066                     bodyVal = NULL;
32067                     nextHdr->next = curHdr;
32068                     curHdr = nextHdr;
32069                     nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
32070                                                 DYNAMIC_TYPE_PKCS7);
32071                     if (nextHdr == NULL) {
32072                         ret = MEMORY_E;
32073                         goto error;
32074                     }
32075                     XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
32076                 }
32077                 else {
32078                     nextParam->attribute = nameAttr;
32079                     nameAttr = NULL;
32080                     nextParam->value = bodyVal;
32081                     bodyVal = NULL;
32082                     nextParam->next = curHdr->params;
32083                     curHdr->params = nextParam;
32084                     nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
32085                                                     DYNAMIC_TYPE_PKCS7);
32086                     if (nextParam == NULL) {
32087                         ret = MEMORY_E;
32088                         goto error;
32089                     }
32090                     XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
32091                 }
32092                 mimeType = MIME_PARAM;
32093                 mimeStatus = MIME_NAMEATTR;
32094                 start = pos+1;
32095             }
32096         }
32097 
32098         end = lineLen-1;
32099         /* Omit newline characters. */
32100         while ((curLine[end] == '\r' || curLine[end] == '\n') && end > 0) {
32101             end--;
32102         }
32103         if (end >= start && mimeStatus == MIME_BODYVAL) {
32104             ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
32105             if (ret) {
32106                 goto error;
32107             }
32108             if (mimeType == MIME_HDR) {
32109                 nextHdr->name = nameAttr;
32110                 nameAttr = NULL;
32111                 nextHdr->body = bodyVal;
32112                 bodyVal = NULL;
32113                 nextHdr->next = curHdr;
32114                 curHdr = nextHdr;
32115                 nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
32116                                             DYNAMIC_TYPE_PKCS7);
32117                 if (nextHdr == NULL) {
32118                     ret = MEMORY_E;
32119                     goto error;
32120                 }
32121                 XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
32122             } else {
32123                 nextParam->attribute = nameAttr;
32124                 nameAttr = NULL;
32125                 nextParam->value = bodyVal;
32126                 bodyVal = NULL;
32127                 nextParam->next = curHdr->params;
32128                 curHdr->params = nextParam;
32129                 nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
32130                                                 DYNAMIC_TYPE_PKCS7);
32131                 if (nextParam == NULL) {
32132                     ret = MEMORY_E;
32133                     goto error;
32134                 }
32135                 XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
32136             }
32137         }
32138 
32139         curLine = XSTRTOK(NULL, "\r\n", &ptr);
32140         mimeStatus = MIME_NAMEATTR;
32141     }
32142 
32143     *headers = curHdr;
32144     ret = 0; /* success if at this point */
32145 
32146 error:
32147     if (ret != 0)
32148         wc_MIME_free_hdrs(curHdr);
32149     wc_MIME_free_hdrs(nextHdr);
32150     if (nameAttr != NULL)
32151         XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
32152     if (bodyVal != NULL)
32153         XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
32154     XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
32155 
32156     return ret;
32157 }
32158 
32159 /*****************************************************************************
32160 * wc_MIME_header_strip - Reads the string in from indices start to end, strips
32161 * out disallowed/separator characters and places the rest into *out.
32162 *
32163 * RETURNS:
32164 * returns zero on success, non-zero on error.
32165 */
32166 int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end)
32167 {
32168     size_t inPos = start;
32169     size_t outPos = 0;
32170     size_t inLen = 0;
32171 
32172     if (end < start || in == NULL || out == NULL) {
32173         return BAD_FUNC_ARG;
32174     }
32175 
32176     inLen = XSTRLEN(in);
32177     if (start > inLen || end > inLen) {
32178         return BAD_FUNC_ARG;
32179     }
32180 
32181     *out = (char*)XMALLOC(((end-start)+2)*sizeof(char), NULL,
32182                           DYNAMIC_TYPE_PKCS7);
32183     if (*out == NULL) {
32184         return MEMORY_E;
32185     }
32186 
32187     while (inPos <= end) {
32188         if (in[inPos] >= MIME_HEADER_ASCII_MIN && in[inPos] <=
32189             MIME_HEADER_ASCII_MAX && in[inPos] != ';' && in[inPos] != '\"') {
32190             (*out)[outPos] = in[inPos];
32191             outPos++;
32192         }
32193         inPos++;
32194     }
32195     (*out)[outPos] = '\0';
32196 
32197     return 0;
32198 }
32199 
32200 /*****************************************************************************
32201 * wc_MIME_find_header_name - Searches through all given headers until a header with
32202 * a name matching the provided name is found.
32203 *
32204 * RETURNS:
32205 * returns a pointer to the found header, if no match was found, returns NULL.
32206 */
32207 MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* header)
32208 {
32209     size_t len = XSTRLEN(name);
32210 
32211     while (header) {
32212         if (!XSTRNCMP(name, header->name, len)) {
32213             return header;
32214         }
32215         header = header->next;
32216     }
32217 
32218     return header;
32219 }
32220 
32221 /*****************************************************************************
32222 * wc_MIME_find_param_attr - Searches through all parameters until a parameter
32223 * with a attribute matching the provided attribute is found.
32224 *
32225 * RETURNS:
32226 * returns a pointer to the found parameter, if no match was found,
32227 * returns NULL.
32228 */
32229 MimeParam* wc_MIME_find_param_attr(const char* attribute,
32230                                     MimeParam* param)
32231 {
32232     size_t len = XSTRLEN(attribute);
32233 
32234     while (param) {
32235         if (!XSTRNCMP(attribute, param->attribute, len)) {
32236             return param;
32237         }
32238         param = param->next;
32239     }
32240 
32241     return param;
32242 }
32243 
32244 /*****************************************************************************
32245 * wc_MIME_canonicalize - Canonicalize a line by converting all line endings
32246 * to CRLF.
32247 *
32248 * RETURNS:
32249 * returns a pointer to a canonicalized line on success, NULL on error.
32250 */
32251 char* wc_MIME_canonicalize(const char* line)
32252 {
32253     size_t end = 0;
32254     char* canonLine = NULL;
32255 
32256     if (line == NULL || XSTRLEN(line) == 0) {
32257         return NULL;
32258     }
32259 
32260     end = XSTRLEN(line);
32261     while (end >= 1 && ((line[end-1] == '\r') || (line[end-1] == '\n'))) {
32262         end--;
32263     }
32264 
32265     /* Need 2 chars for \r\n and 1 for EOL */
32266     canonLine = (char*)XMALLOC((end+3)*sizeof(char), NULL, DYNAMIC_TYPE_PKCS7);
32267     if (canonLine == NULL) {
32268         return NULL;
32269     }
32270 
32271     XSTRNCPY(canonLine, line, end);
32272     canonLine[end] = '\r';
32273     canonLine[end+1] = '\n';
32274     canonLine[end+2] = '\0';
32275 
32276     return canonLine;
32277 }
32278 
32279 /*****************************************************************************
32280 * wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from
32281 * the provided header pointer.
32282 *
32283 * RETURNS:
32284 * returns zero on success, non-zero on error.
32285 */
32286 int wc_MIME_free_hdrs(MimeHdr* head)
32287 {
32288     MimeHdr* curHdr = NULL;
32289     MimeParam* curParam = NULL;
32290 
32291     while (head) {
32292         while (head->params) {
32293             curParam = head->params;
32294             head->params = head->params->next;
32295             XFREE(curParam->attribute, NULL, DYNAMIC_TYPE_PKCS7);
32296             XFREE(curParam->value, NULL, DYNAMIC_TYPE_PKCS7);
32297             XFREE(curParam, NULL, DYNAMIC_TYPE_PKCS7);
32298         }
32299         curHdr = head;
32300         head = head->next;
32301         XFREE(curHdr->name, NULL, DYNAMIC_TYPE_PKCS7);
32302         XFREE(curHdr->body, NULL, DYNAMIC_TYPE_PKCS7);
32303         XFREE(curHdr, NULL, DYNAMIC_TYPE_PKCS7);
32304     }
32305 
32306     return 0;
32307 }
32308 
32309 #endif /* HAVE_SMIME */
32310 
32311 
32312 #undef ERROR_OUT
32313 
32314 #endif /* !NO_ASN */
32315 
32316 #ifdef WOLFSSL_SEP
32317 
32318 
32319 #endif /* WOLFSSL_SEP */
32320