ssh lib

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers asn.c Source File

asn.c

00001 /* asn.c
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfcrypt/settings.h>
00028 
00029 /*
00030 ASN Options:
00031  * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
00032     or wishing to save space.
00033  * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
00034  * ASN_DUMP_OID: Allows dump of OID information for debugging.
00035  * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
00036  * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
00037  * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
00038     restore 3.13.0 behavior.
00039  * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
00040     must still be trusted)
00041  * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
00042     chain is not loaded. This only matches on subject and public key and
00043     does not perform a PKI validation, so it is not a secure solution.
00044     Only enabled for OCSP.
00045  * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
00046     disable checking of OCSP subject hash with issuer hash.
00047  * WOLFSSL_ALT_CERT_CHAINS: Allows matching multiple CA's to validate
00048     chain based on issuer and public key (includes signature confirmation)
00049 */
00050 
00051 #ifndef NO_ASN
00052 
00053 #include <wolfcrypt/asn.h>
00054 #include <wolfcrypt/coding.h>
00055 #include <wolfcrypt/md2.h>
00056 #include <wolfcrypt/hmac.h>
00057 #include <wolfcrypt/error-crypt.h>
00058 #include <wolfcrypt/pwdbased.h>
00059 #include <wolfcrypt/des3.h>
00060 #include <wolfcrypt/aes.h>
00061 #include <wolfcrypt/wc_encrypt.h>
00062 #include <wolfcrypt/logging.h>
00063 
00064 #include <wolfcrypt/random.h>
00065 #include <wolfcrypt/hash.h>
00066 #ifdef NO_INLINE
00067     #include <wolfcrypt/misc.h>
00068 #else
00069     #define WOLFSSL_MISC_INCLUDED
00070     #include <wolfcrypt/src/misc.c>
00071 #endif
00072 
00073 #ifndef NO_PWDBASED
00074     #include <wolfcrypt/aes.h>
00075 #endif
00076 #ifndef NO_RC4
00077     #include <wolfcrypt/arc4.h>
00078 #endif
00079 
00080 #ifdef HAVE_NTRU
00081     #include "libntruencrypt/ntru_crypto.h"
00082 #endif
00083 
00084 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
00085     #include <wolfcrypt/sha512.h>
00086 #endif
00087 
00088 #ifndef NO_SHA256
00089     #include <wolfcrypt/sha256.h>
00090 #endif
00091 
00092 #ifdef HAVE_ECC
00093     #include <wolfcrypt/ecc.h>
00094 #endif
00095 
00096 #ifdef HAVE_ED25519
00097     #include <wolfcrypt/ed25519.h>
00098 #endif
00099 
00100 #ifndef NO_RSA
00101     #include <wolfcrypt/rsa.h>
00102 #endif
00103 
00104 #ifdef WOLFSSL_DEBUG_ENCODING
00105     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00106         #if MQX_USE_IO_OLD
00107             #include <fio.h>
00108         #else
00109             #include <nio.h>
00110         #endif
00111     #else
00112         #include <stdio.h>
00113     #endif
00114 #endif
00115 
00116 
00117 #ifdef _MSC_VER
00118     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
00119     #pragma warning(disable: 4996)
00120 #endif
00121 
00122 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
00123 
00124 WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
00125                            word32 maxIdx)
00126 {
00127     int     length = 0;
00128     word32  idx = *inOutIdx;
00129     byte    b;
00130 
00131     *len = 0;    /* default length */
00132 
00133     if ((idx + 1) > maxIdx) {   /* for first read */
00134         WOLFSSL_MSG("GetLength bad index on input");
00135         return BUFFER_E;
00136     }
00137 
00138     b = input[idx++];
00139     if (b >= ASN_LONG_LENGTH) {
00140         word32 bytes = b & 0x7F;
00141 
00142         if ((idx + bytes) > maxIdx) {   /* for reading bytes */
00143             WOLFSSL_MSG("GetLength bad long length");
00144             return BUFFER_E;
00145         }
00146 
00147         while (bytes--) {
00148             b = input[idx++];
00149             length = (length << 8) | b;
00150         }
00151     }
00152     else
00153         length = b;
00154 
00155     if ((idx + length) > maxIdx) {   /* for user of length */
00156         WOLFSSL_MSG("GetLength value exceeds buffer length");
00157         return BUFFER_E;
00158     }
00159 
00160     *inOutIdx = idx;
00161     if (length > 0)
00162         *len = length;
00163 
00164     return length;
00165 }
00166 
00167 
00168 /* Get the DER/BER encoding of an ASN.1 header.
00169  *
00170  * input     Buffer holding DER/BER encoded data.
00171  * tag       ASN.1 tag value expected in header.
00172  * inOutIdx  Current index into buffer to parse.
00173  * len       The number of bytes in the ASN.1 data.
00174  * maxIdx    Length of data in buffer.
00175  * returns BUFFER_E when there is not enough data to parse.
00176  *         ASN_PARSE_E when the expected tag is not found or length is invalid.
00177  *         Otherwise, the number of bytes in the ASN.1 data.
00178  */
00179 static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
00180                         word32 maxIdx)
00181 {
00182     word32 idx = *inOutIdx;
00183     byte   b;
00184     int    length;
00185 
00186     if ((idx + 1) > maxIdx)
00187         return BUFFER_E;
00188 
00189     b = input[idx++];
00190     if (b != tag)
00191         return ASN_PARSE_E;
00192 
00193     if (GetLength(input, &idx, &length, maxIdx) < 0)
00194         return ASN_PARSE_E;
00195 
00196     *len      = length;
00197     *inOutIdx = idx;
00198     return length;
00199 }
00200 
00201 WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
00202                            word32 maxIdx)
00203 {
00204     return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
00205                         maxIdx);
00206 }
00207 
00208 
00209 WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
00210                         word32 maxIdx)
00211 {
00212     return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
00213                         maxIdx);
00214 }
00215 
00216 /* Get the DER/BER encoded ASN.1 NULL element.
00217  * Ensure that the all fields are as expected and move index past the element.
00218  *
00219  * input     Buffer holding DER/BER encoded data.
00220  * inOutIdx  Current index into buffer to parse.
00221  * maxIdx    Length of data in buffer.
00222  * returns BUFFER_E when there is not enough data to parse.
00223  *         ASN_TAG_NULL_E when the NULL tag is not found.
00224  *         ASN_EXPECT_0_E when the length is not zero.
00225  *         Otherwise, 0 to indicate success.
00226  */
00227 static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
00228 {
00229     word32 idx = *inOutIdx;
00230     byte   b;
00231 
00232     if ((idx + 2) > maxIdx)
00233         return BUFFER_E;
00234 
00235     b = input[idx++];
00236     if (b != ASN_TAG_NULL)
00237         return ASN_TAG_NULL_E;
00238 
00239     if (input[idx++] != 0)
00240         return ASN_EXPECT_0_E;
00241 
00242     *inOutIdx = idx;
00243     return 0;
00244 }
00245 
00246 /* Set the DER/BER encoding of the ASN.1 NULL element.
00247  *
00248  * output  Buffer to write into.
00249  * returns the number of bytes added to the buffer.
00250  */
00251 static int SetASNNull(byte* output)
00252 {
00253     output[0] = ASN_TAG_NULL;
00254     output[1] = 0;
00255 
00256     return 2;
00257 }
00258 
00259 /* Get the DER/BER encoding of an ASN.1 BOOLEAN.
00260  *
00261  * input     Buffer holding DER/BER encoded data.
00262  * inOutIdx  Current index into buffer to parse.
00263  * maxIdx    Length of data in buffer.
00264  * returns BUFFER_E when there is not enough data to parse.
00265  *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
00266  *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
00267  */
00268 static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
00269 {
00270     word32 idx = *inOutIdx;
00271     byte   b;
00272 
00273     if ((idx + 3) > maxIdx)
00274         return BUFFER_E;
00275 
00276     b = input[idx++];
00277     if (b != ASN_BOOLEAN)
00278         return ASN_PARSE_E;
00279 
00280     if (input[idx++] != 1)
00281         return ASN_PARSE_E;
00282 
00283     b = input[idx++] != 0;
00284 
00285     *inOutIdx = idx;
00286     return b;
00287 }
00288 
00289 #ifdef ASN1_SET_BOOLEAN
00290 /* Set the DER/BER encoding of the ASN.1 NULL element.
00291  * Note: Function not required as yet.
00292  *
00293  * val     Boolean value to encode.
00294  * output  Buffer to write into.
00295  * returns the number of bytes added to the buffer.
00296  */
00297 static int SetBoolean(int val, byte* output)
00298 {
00299     output[0] = ASN_BOOLEAN;
00300     output[1] = 1;
00301     output[2] = val ? -1 : 0;
00302 
00303     return 3;
00304 }
00305 #endif
00306 
00307 /* Get the DER/BER encoding of an ASN.1 OCTET_STRING header.
00308  *
00309  * input     Buffer holding DER/BER encoded data.
00310  * inOutIdx  Current index into buffer to parse.
00311  * len       The number of bytes in the ASN.1 data.
00312  * maxIdx    Length of data in buffer.
00313  * returns BUFFER_E when there is not enough data to parse.
00314  *         ASN_PARSE_E when the OCTET_STRING tag is not found or length is
00315  *         invalid.
00316  *         Otherwise, the number of bytes in the ASN.1 data.
00317  */
00318 static int GetOctetString(const byte* input, word32* inOutIdx, int* len,
00319                           word32 maxIdx)
00320 {
00321     return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
00322 }
00323 
00324 /* Get the DER/BER encoding of an ASN.1 INTEGER header.
00325  * Removes the leading zero byte when found.
00326  *
00327  * input     Buffer holding DER/BER encoded data.
00328  * inOutIdx  Current index into buffer to parse.
00329  * len       The number of bytes in the ASN.1 data (excluding any leading zero).
00330  * maxIdx    Length of data in buffer.
00331  * returns BUFFER_E when there is not enough data to parse.
00332  *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
00333  *         or invalid use of or missing leading zero.
00334  *         Otherwise, 0 to indicate success.
00335  */
00336 static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
00337                      word32 maxIdx)
00338 {
00339     int    ret;
00340 
00341     ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
00342     if (ret < 0)
00343         return ret;
00344 
00345     if (*len > 0) {
00346         /* remove leading zero, unless there is only one 0x00 byte */
00347         if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
00348             (*inOutIdx)++;
00349             (*len)--;
00350 
00351             if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
00352                 return ASN_PARSE_E;
00353         }
00354     }
00355 
00356     return 0;
00357 }
00358 
00359 /* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
00360  * 7 bits.
00361  *
00362  * input     Buffer holding DER/BER encoded data.
00363  * inOutIdx  Current index into buffer to parse.
00364  * maxIdx    Length of data in buffer.
00365  * returns BUFFER_E when there is not enough data to parse.
00366  *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
00367  *         Otherwise, the 7-bit value.
00368  */
00369 static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
00370 {
00371     word32 idx = *inOutIdx;
00372     byte   b;
00373 
00374     if ((idx + 3) > maxIdx)
00375         return BUFFER_E;
00376 
00377     if (input[idx++] != ASN_INTEGER)
00378         return ASN_PARSE_E;
00379     if (input[idx++] != 1)
00380         return ASN_PARSE_E;
00381     b = input[idx++];
00382 
00383     *inOutIdx = idx;
00384     return b;
00385 }
00386 
00387 
00388 #if !defined(NO_DSA) && !defined(NO_SHA)
00389 static char sigSha1wDsaName[] = "SHAwDSA";
00390 #endif /* NO_DSA */
00391 #ifndef NO_RSA
00392 #ifdef WOLFSSL_MD2
00393     static char sigMd2wRsaName[] = "MD2wRSA";
00394 #endif
00395 #ifndef NO_MD5
00396     static char sigMd5wRsaName[] = "MD5wRSA";
00397 #endif
00398 #ifndef NO_SHA
00399     static char sigSha1wRsaName[] = "SHAwRSA";
00400 #endif
00401 #ifdef WOLFSSL_SHA224
00402     static char sigSha224wRsaName[] = "SHA224wRSA";
00403 #endif
00404 #ifndef NO_SHA256
00405     static char sigSha256wRsaName[] = "SHA256wRSA";
00406 #endif
00407 #ifdef WOLFSSL_SHA384
00408     static char sigSha384wRsaName[] = "SHA384wRSA";
00409 #endif
00410 #ifdef WOLFSSL_SHA512
00411     static char sigSha512wRsaName[] = "SHA512wRSA";
00412 #endif
00413 #endif /* NO_RSA */
00414 #ifdef HAVE_ECC
00415 #ifndef NO_SHA
00416     static char sigSha1wEcdsaName[] = "SHAwECDSA";
00417 #endif
00418 #ifdef WOLFSSL_SHA224
00419     static char sigSha224wEcdsaName[] = "SHA224wECDSA";
00420 #endif
00421 #ifndef NO_SHA256
00422     static char sigSha256wEcdsaName[] = "SHA256wECDSA";
00423 #endif
00424 #ifdef WOLFSSL_SHA384
00425     static char sigSha384wEcdsaName[] = "SHA384wECDSA";
00426 #endif
00427 #ifdef WOLFSSL_SHA512
00428     static char sigSha512wEcdsaName[] = "SHA512wECDSA";
00429 #endif
00430 #endif /* HAVE_ECC */
00431 static char sigUnknownName[] = "Unknown";
00432 
00433 
00434 /* Get the human readable string for a signature type
00435  *
00436  * oid  Oid value for signature
00437  */
00438 char* GetSigName(int oid) {
00439     switch (oid) {
00440     #if !defined(NO_DSA) && !defined(NO_SHA)
00441         case CTC_SHAwDSA:
00442             return sigSha1wDsaName;
00443     #endif /* NO_DSA && NO_SHA */
00444     #ifndef NO_RSA
00445         #ifdef WOLFSSL_MD2
00446         case CTC_MD2wRSA:
00447             return sigMd2wRsaName;
00448         #endif
00449         #ifndef NO_MD5
00450         case CTC_MD5wRSA:
00451             return sigMd5wRsaName;
00452         #endif
00453         #ifndef NO_SHA
00454         case CTC_SHAwRSA:
00455             return sigSha1wRsaName;
00456         #endif
00457         #ifdef WOLFSSL_SHA224
00458         case CTC_SHA224wRSA:
00459             return sigSha224wRsaName;
00460         #endif
00461         #ifndef NO_SHA256
00462         case CTC_SHA256wRSA:
00463             return sigSha256wRsaName;
00464         #endif
00465         #ifdef WOLFSSL_SHA384
00466         case CTC_SHA384wRSA:
00467             return sigSha384wRsaName;
00468         #endif
00469         #ifdef WOLFSSL_SHA512
00470         case CTC_SHA512wRSA:
00471             return sigSha512wRsaName;
00472         #endif
00473     #endif /* NO_RSA */
00474     #ifdef HAVE_ECC
00475         #ifndef NO_SHA
00476         case CTC_SHAwECDSA:
00477             return sigSha1wEcdsaName;
00478         #endif
00479         #ifdef WOLFSSL_SHA224
00480         case CTC_SHA224wECDSA:
00481             return sigSha224wEcdsaName;
00482         #endif
00483         #ifndef NO_SHA256
00484         case CTC_SHA256wECDSA:
00485             return sigSha256wEcdsaName;
00486         #endif
00487         #ifdef WOLFSSL_SHA384
00488         case CTC_SHA384wECDSA:
00489             return sigSha384wEcdsaName;
00490         #endif
00491         #ifdef WOLFSSL_SHA512
00492         case CTC_SHA512wECDSA:
00493             return sigSha512wEcdsaName;
00494         #endif
00495     #endif /* HAVE_ECC */
00496         default:
00497             return sigUnknownName;
00498     }
00499 }
00500 
00501 
00502 #if !defined(NO_DSA) || defined(HAVE_ECC) || \
00503    (!defined(NO_RSA) && \
00504         (defined(WOLFSSL_CERT_GEN) || \
00505         ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
00506 /* Set the DER/BER encoding of the ASN.1 INTEGER header.
00507  *
00508  * len        Length of data to encode.
00509  * firstByte  First byte of data, most significant byte of integer, to encode.
00510  * output     Buffer to write into.
00511  * returns the number of bytes added to the buffer.
00512  */
00513 static int SetASNInt(int len, byte firstByte, byte* output)
00514 {
00515     word32 idx = 0;
00516 
00517     output[idx++] = ASN_INTEGER;
00518     if (firstByte & 0x80)
00519         len++;
00520     idx += SetLength(len, output + idx);
00521     if (firstByte & 0x80)
00522         output[idx++] = 0x00;
00523 
00524     return idx;
00525 }
00526 #endif
00527 
00528 #if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \
00529     ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
00530 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
00531  * The number is assumed to be positive.
00532  *
00533  * n       Multi-precision integer to encode.
00534  * maxSz   Maximum size of the encoded integer.
00535  *         A negative value indicates no check of length requested.
00536  * output  Buffer to write into.
00537  * returns BUFFER_E when the data is too long for the buffer.
00538  *         MP_TO_E when encoding the integer fails.
00539  *         Otherwise, the number of bytes added to the buffer.
00540  */
00541 static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
00542 {
00543     int idx = 0;
00544     int leadingBit;
00545     int length;
00546     int err;
00547 
00548     leadingBit = mp_leading_bit(n);
00549     length = mp_unsigned_bin_size(n);
00550     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
00551     if (maxSz >= 0 && (idx + length) > maxSz)
00552         return BUFFER_E;
00553 
00554     err = mp_to_unsigned_bin(n, output + idx);
00555     if (err != MP_OKAY)
00556         return MP_TO_E;
00557     idx += length;
00558 
00559     return idx;
00560 }
00561 #endif
00562 
00563 #if !defined(NO_RSA) && defined(HAVE_USER_RSA) && defined(WOLFSSL_CERT_GEN)
00564 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
00565  * an RSA key.
00566  * The number is assumed to be positive.
00567  *
00568  * n       Multi-precision integer to encode.
00569  * output  Buffer to write into.
00570  * returns BUFFER_E when the data is too long for the buffer.
00571  *         MP_TO_E when encoding the integer fails.
00572  *         Otherwise, the number of bytes added to the buffer.
00573  */
00574 static int SetASNIntRSA(mp_int* n, byte* output)
00575 {
00576     int idx = 0;
00577     int leadingBit;
00578     int length;
00579     int err;
00580 
00581     leadingBit = wc_Rsa_leading_bit(n);
00582     length = wc_Rsa_unsigned_bin_size(n);
00583     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
00584     if ((idx + length) > MAX_RSA_INT_SZ)
00585         return BUFFER_E;
00586 
00587     err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
00588     if (err != MP_OKAY)
00589         return MP_TO_E;
00590     idx += length;
00591 
00592     return idx;
00593 }
00594 #endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
00595 
00596 /* Windows header clash for WinCE using GetVersion */
00597 WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
00598                                int* version, word32 maxIdx)
00599 {
00600     word32 idx = *inOutIdx;
00601 
00602     if ((idx + MIN_VERSION_SZ) > maxIdx)
00603         return ASN_PARSE_E;
00604 
00605     if (input[idx++] != ASN_INTEGER)
00606         return ASN_PARSE_E;
00607 
00608     if (input[idx++] != 0x01)
00609         return ASN_VERSION_E;
00610 
00611     *version  = input[idx++];
00612     *inOutIdx = idx;
00613 
00614     return *version;
00615 }
00616 
00617 
00618 #ifndef NO_PWDBASED
00619 /* Get small count integer, 32 bits or less */
00620 int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
00621 {
00622     word32 idx = *inOutIdx;
00623     word32 len;
00624 
00625     *number = 0;
00626 
00627     /* check for type and length bytes */
00628     if ((idx + 2) > maxIdx)
00629         return BUFFER_E;
00630 
00631     if (input[idx++] != ASN_INTEGER)
00632         return ASN_PARSE_E;
00633 
00634     len = input[idx++];
00635     if (len > 4)
00636         return ASN_PARSE_E;
00637 
00638     if (len + idx > maxIdx)
00639         return ASN_PARSE_E;
00640 
00641     while (len--) {
00642         *number  = *number << 8 | input[idx++];
00643     }
00644 
00645     *inOutIdx = idx;
00646 
00647     return *number;
00648 }
00649 
00650 
00651 /* Set small integer, 32 bits or less. DER encoding with no leading 0s
00652  * returns total amount written including ASN tag and length byte on success */
00653 static int SetShortInt(byte* input, word32* inOutIdx, word32 number,
00654         word32 maxIdx)
00655 {
00656     word32 idx = *inOutIdx;
00657     word32 len = 0;
00658     int    i;
00659     byte ar[MAX_LENGTH_SZ];
00660 
00661     /* check for room for type and length bytes */
00662     if ((idx + 2) > maxIdx)
00663         return BUFFER_E;
00664 
00665     input[idx++] = ASN_INTEGER;
00666     idx++; /* place holder for length byte */
00667     if (MAX_LENGTH_SZ + idx > maxIdx)
00668         return ASN_PARSE_E;
00669 
00670     /* find first non zero byte */
00671     XMEMSET(ar, 0, MAX_LENGTH_SZ);
00672     c32toa(number, ar);
00673     for (i = 0; i < MAX_LENGTH_SZ; i++) {
00674         if (ar[i] != 0) {
00675             break;
00676         }
00677     }
00678 
00679     /* handle case of 0 */
00680     if (i == MAX_LENGTH_SZ) {
00681         input[idx++] = 0; len++;
00682     }
00683 
00684     for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
00685         input[idx++] = ar[i]; len++;
00686     }
00687 
00688     /* jump back to beginning of input buffer using unaltered inOutIdx value
00689      * and set number of bytes for integer, then update the index value */
00690     input[*inOutIdx + 1] = (byte)len;
00691     *inOutIdx = idx;
00692 
00693     return len + 2; /* size of integer bytes plus ASN TAG and length byte */
00694 }
00695 #endif /* !NO_PWDBASED */
00696 
00697 /* May not have one, not an error */
00698 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
00699                               word32 maxIdx)
00700 {
00701     word32 idx = *inOutIdx;
00702 
00703     WOLFSSL_ENTER("GetExplicitVersion");
00704 
00705     if ((idx + 1) > maxIdx)
00706         return BUFFER_E;
00707 
00708     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
00709         *inOutIdx = ++idx;  /* skip header */
00710         return GetMyVersion(input, inOutIdx, version, maxIdx);
00711     }
00712 
00713     /* go back as is */
00714     *version = 0;
00715 
00716     return 0;
00717 }
00718 
00719 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
00720 {
00721     word32 idx = *inOutIdx;
00722     int    ret;
00723     int    length;
00724 
00725     ret = GetASNInt(input, &idx, &length, maxIdx);
00726     if (ret != 0)
00727         return ret;
00728 
00729     if (mp_init(mpi) != MP_OKAY)
00730         return MP_INIT_E;
00731 
00732     if (mp_read_unsigned_bin(mpi, (byte*)input + idx, length) != 0) {
00733         mp_clear(mpi);
00734         return ASN_GETINT_E;
00735     }
00736 
00737 #ifdef HAVE_WOLF_BIGINT
00738     if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
00739         mp_clear(mpi);
00740         return ASN_GETINT_E;
00741     }
00742 #endif /* HAVE_WOLF_BIGINT */
00743 
00744     *inOutIdx = idx + length;
00745 
00746     return 0;
00747 }
00748 
00749 #if !defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)
00750 #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
00751 static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
00752 {
00753     word32 idx = *inOutIdx;
00754     int    ret;
00755     int    length;
00756 
00757     ret = GetASNInt(input, &idx, &length, maxIdx);
00758     if (ret != 0)
00759         return ret;
00760 
00761     *inOutIdx = idx + length;
00762 
00763     return 0;
00764 }
00765 #endif
00766 #endif
00767 
00768 static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
00769                           word32 maxIdx, int zeroBits, byte* unusedBits)
00770 {
00771     word32 idx = *inOutIdx;
00772     int    length;
00773     byte   b;
00774 
00775     if ((idx + 1) > maxIdx)
00776         return BUFFER_E;
00777 
00778     if (input[idx++] != ASN_BIT_STRING)
00779         return ASN_BITSTR_E;
00780 
00781     if (GetLength(input, &idx, &length, maxIdx) < 0)
00782         return ASN_PARSE_E;
00783 
00784     /* extra sanity check that length is greater than 0 */
00785     if (length <= 0) {
00786         WOLFSSL_MSG("Error length was 0 in CheckBitString");
00787         return BUFFER_E;
00788     }
00789 
00790     if (idx + 1 > maxIdx) {
00791         WOLFSSL_MSG("Attempted buffer read larger than input buffer");
00792         return BUFFER_E;
00793     }
00794 
00795     b = input[idx];
00796     if (zeroBits && b != 0x00)
00797         return ASN_EXPECT_0_E;
00798     if (b >= 0x08)
00799         return ASN_PARSE_E;
00800     if (b != 0) {
00801         if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
00802             return ASN_PARSE_E;
00803     }
00804     idx++;
00805     length--; /* length has been checked for greater than 0 */
00806 
00807     *inOutIdx = idx;
00808     if (len != NULL)
00809         *len = length;
00810     if (unusedBits != NULL)
00811         *unusedBits = b;
00812 
00813     return 0;
00814 }
00815 
00816 /* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */
00817 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
00818         (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
00819      defined(HAVE_ECC) || \
00820     (defined(HAVE_ED25519) && \
00821         (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
00822 
00823 /* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
00824  *
00825  * len         Length of data to encode.
00826  * unusedBits  The number of unused bits in the last byte of data.
00827  *             That is, the number of least significant zero bits before a one.
00828  *             The last byte is the most-significant non-zero byte of a number.
00829  * output      Buffer to write into.
00830  * returns the number of bytes added to the buffer.
00831  */
00832 static word32 SetBitString(word32 len, byte unusedBits, byte* output)
00833 {
00834     word32 idx = 0;
00835 
00836     output[idx++] = ASN_BIT_STRING;
00837     idx += SetLength(len + 1, output + idx);
00838     output[idx++] = unusedBits;
00839 
00840     return idx;
00841 }
00842 #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
00843 
00844 #ifdef ASN_BER_TO_DER
00845 /* Convert a BER encoding with indefinite length items to DER.
00846  *
00847  * ber    BER encoded data.
00848  * berSz  Length of BER encoded data.
00849  * der    Buffer to hold DER encoded version of data.
00850  *        NULL indicates only the length is required.
00851  * derSz  The size of the buffer to hold the DER encoded data.
00852  *        Will be set if der is NULL, otherwise the value is checked as der is
00853  *        filled.
00854  * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
00855  * derSz are NULL.
00856  */
00857 int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
00858 {
00859     int ret;
00860     word32 i, j, k;
00861     int len, l;
00862     int indef;
00863     int depth = 0;
00864     byte type;
00865     word32 cnt, sz;
00866     word32 outSz;
00867     byte lenBytes[4];
00868 
00869     if (ber == NULL || derSz == NULL)
00870         return BAD_FUNC_ARG;
00871 
00872     outSz = *derSz;
00873 
00874     for (i = 0, j = 0; i < berSz; ) {
00875         /* Check that there is data for an ASN item to parse. */
00876         if (i + 2 > berSz)
00877             return ASN_PARSE_E;
00878 
00879         /* End Of Content (EOC) mark end of indefinite length items.
00880          * EOCs are not encoded in DER.
00881          * Keep track of no. indefinite length items that have not been
00882          * terminated in depth.
00883          */
00884         if (ber[i] == 0 && ber[i+1] == 0) {
00885             if (depth == 0)
00886                 break;
00887             if (--depth == 0)
00888                 break;
00889 
00890             i += 2;
00891             continue;
00892         }
00893 
00894         /* Indefinite length is encoded as: 0x80 */
00895         type = ber[i];
00896         indef = ber[i+1] == ASN_INDEF_LENGTH;
00897         if (indef && (type & 0xC0) == 0 &&
00898                                    ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
00899                                    ber[i] != (ASN_SET      | ASN_CONSTRUCTED)) {
00900             /* Indefinite length OCTET STRING or other simple type.
00901              * Put all the data into one entry.
00902              */
00903 
00904             /* Type no longer constructed. */
00905             type &= ~ASN_CONSTRUCTED;
00906             if (der != NULL) {
00907                 /* Ensure space for type. */
00908                 if (j + 1 >= outSz)
00909                     return BUFFER_E;
00910                 der[j] = type;
00911             }
00912             i++; j++;
00913             /* Skip indefinite length. */
00914             i++;
00915 
00916             /* There must be further ASN1 items to combine. */
00917             if (i + 2 > berSz)
00918                 return ASN_PARSE_E;
00919 
00920             /* Calculate length of combined data. */
00921             len = 0;
00922             k = i;
00923             while (ber[k] != 0x00) {
00924                 /* Each ASN item must be the same type as the constructed. */
00925                 if (ber[k] != type)
00926                     return ASN_PARSE_E;
00927                 k++;
00928 
00929                 ret = GetLength(ber, &k, &l, berSz);
00930                 if (ret < 0)
00931                     return ASN_PARSE_E;
00932                 k += l;
00933                 len += l;
00934 
00935                 /* Must at least have terminating EOC. */
00936                 if (k + 2 > berSz)
00937                     return ASN_PARSE_E;
00938             }
00939             /* Ensure a valid EOC ASN item. */
00940             if (ber[k+1] != 0x00)
00941                 return ASN_PARSE_E;
00942 
00943             if (der == NULL) {
00944                 /* Add length of ASN item length encoding and data. */
00945                 j += SetLength(len, lenBytes);
00946                 j += len;
00947             }
00948             else {
00949                 /* Check space for encoded length. */
00950                 if (SetLength(len, lenBytes) > outSz - j)
00951                     return BUFFER_E;
00952                 /* Encode new length. */
00953                 j += SetLength(len, der + j);
00954 
00955                 /* Encode data in single item. */
00956                 k = i;
00957                 while (ber[k] != 0x00) {
00958                     /* Skip ASN type. */
00959                     k++;
00960 
00961                     /* Find length of data in ASN item. */
00962                     ret = GetLength(ber, &k, &l, berSz);
00963                     if (ret < 0)
00964                         return ASN_PARSE_E;
00965 
00966                     /* Ensure space for data and copy in. */
00967                     if (j + l > outSz)
00968                         return BUFFER_E;
00969                     XMEMCPY(der + j, ber + k, l);
00970                     k += l; j += l;
00971                 }
00972             }
00973             /* Continue conversion after EOC. */
00974             i = k + 2;
00975 
00976             continue;
00977         }
00978 
00979         if (der != NULL) {
00980             /* Ensure space for type and at least one byte of length. */
00981             if (j + 1 >= outSz)
00982                 return BUFFER_E;
00983             /* Put in type. */
00984             der[j] = ber[i];
00985         }
00986         i++; j++;
00987 
00988         if (indef) {
00989             /* Skip indefinite length. */
00990             i++;
00991             /* Calculate the size of the data inside constructed. */
00992             ret = wc_BerToDer(ber + i, berSz - i, NULL, &sz);
00993             if (ret != LENGTH_ONLY_E)
00994                 return ret;
00995 
00996             if (der != NULL) {
00997                 /* Ensure space for encoded length. */
00998                 if (SetLength(sz, lenBytes) > outSz - j)
00999                     return BUFFER_E;
01000                 /* Encode real length. */
01001                 j += SetLength(sz, der + j);
01002             }
01003             else {
01004                 /* Add size of encoded length. */
01005                 j += SetLength(sz, lenBytes);
01006             }
01007 
01008             /* Another EOC to find. */
01009             depth++;
01010         }
01011         else {
01012             /* Get the size of the encode length and length value. */
01013             cnt = i;
01014             ret = GetLength(ber, &cnt, &len, berSz);
01015             if (ret < 0)
01016                 return ASN_PARSE_E;
01017             cnt -= i;
01018 
01019             /* Check there is enough data to copy out. */
01020             if (i + cnt + len > berSz)
01021                 return ASN_PARSE_E;
01022 
01023             if (der != NULL) {
01024                 /* Ensure space in DER buffer. */
01025                 if (j + cnt + len > outSz)
01026                     return BUFFER_E;
01027                 /* Copy length and data into DER buffer. */
01028                 XMEMCPY(der + j, ber + i, cnt + len);
01029             }
01030             /* Continue conversion after this ASN item. */
01031             i += cnt + len;
01032             j += cnt + len;
01033         }
01034     }
01035 
01036     if (depth >= 1)
01037         return ASN_PARSE_E;
01038 
01039     /* Return length if no buffer to write to. */
01040     if (der == NULL) {
01041         *derSz = j;
01042         return LENGTH_ONLY_E;
01043     }
01044 
01045     return 0;
01046 }
01047 #endif
01048 
01049 #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)
01050 
01051 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \
01052     defined(HAVE_ECC) || defined(HAVE_ED25519)
01053 
01054 #ifdef WOLFSSL_CERT_EXT
01055 /* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
01056  *
01057  * val         16-bit value to encode.
01058  * output      Buffer to write into.
01059  * returns the number of bytes added to the buffer.
01060  */
01061 static word32 SetBitString16Bit(word16 val, byte* output)
01062 {
01063     word32 idx;
01064     int    len;
01065     byte   lastByte;
01066     byte   unusedBits = 0;
01067 
01068     if ((val >> 8) != 0) {
01069         len = 2;
01070         lastByte = (byte)(val >> 8);
01071     }
01072     else {
01073         len = 1;
01074         lastByte = (byte)val;
01075     }
01076 
01077     while (((lastByte >> unusedBits) & 0x01) == 0x00)
01078         unusedBits++;
01079 
01080     idx = SetBitString(len, unusedBits, output);
01081     output[idx++] = (byte)val;
01082     if (len > 1)
01083         output[idx++] = (byte)(val >> 8);
01084 
01085     return idx;
01086 }
01087 #endif /* WOLFSSL_CERT_EXT */
01088 #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
01089 #endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */
01090 
01091 
01092 
01093 /* hashType */
01094 #ifdef WOLFSSL_MD2
01095     static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
01096 #endif
01097 #ifndef NO_MD5
01098     static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
01099 #endif
01100 #ifndef NO_SHA
01101     static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
01102 #endif
01103 #ifdef WOLFSSL_SHA224
01104     static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
01105 #endif
01106 #ifndef NO_SHA256
01107     static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
01108 #endif
01109 #ifdef WOLFSSL_SHA384
01110     static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
01111 #endif
01112 #ifdef WOLFSSL_SHA512
01113     static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
01114 #endif
01115 
01116 /* hmacType */
01117 #ifndef NO_HMAC
01118     #ifdef WOLFSSL_SHA224
01119     static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
01120     #endif
01121     #ifndef NO_SHA256
01122     static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
01123     #endif
01124     #ifdef WOLFSSL_SHA384
01125     static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
01126     #endif
01127     #ifdef WOLFSSL_SHA512
01128     static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
01129     #endif
01130 #endif
01131 
01132 /* sigType */
01133 #if !defined(NO_DSA) && !defined(NO_SHA)
01134     static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
01135 #endif /* NO_DSA */
01136 #ifndef NO_RSA
01137     #ifdef WOLFSSL_MD2
01138     static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
01139     #endif
01140     #ifndef NO_MD5
01141     static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
01142     #endif
01143     #ifndef NO_SHA
01144     static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
01145     #endif
01146     #ifdef WOLFSSL_SHA224
01147     static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
01148     #endif
01149     #ifndef NO_SHA256
01150     static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
01151     #endif
01152     #ifdef WOLFSSL_SHA384
01153     static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
01154     #endif
01155     #ifdef WOLFSSL_SHA512
01156     static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
01157     #endif
01158 #endif /* NO_RSA */
01159 #ifdef HAVE_ECC
01160     #ifndef NO_SHA
01161     static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
01162     #endif
01163     #ifdef WOLFSSL_SHA224
01164     static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
01165     #endif
01166     #ifndef NO_SHA256
01167     static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
01168     #endif
01169     #ifdef WOLFSSL_SHA384
01170     static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
01171     #endif
01172     #ifdef WOLFSSL_SHA512
01173     static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
01174     #endif
01175 #endif /* HAVE_ECC */
01176 #ifdef HAVE_ED25519
01177     static const byte sigEd25519Oid[] = {43, 101, 112};
01178 #endif /* HAVE_ED25519 */
01179 
01180 /* keyType */
01181 #ifndef NO_DSA
01182     static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
01183 #endif /* NO_DSA */
01184 #ifndef NO_RSA
01185     static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
01186 #endif /* NO_RSA */
01187 #ifdef HAVE_NTRU
01188     static const byte keyNtruOid[] = {43, 6, 1, 4, 1, 193, 22, 1, 1, 1, 1};
01189 #endif /* HAVE_NTRU */
01190 #ifdef HAVE_ECC
01191     static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
01192 #endif /* HAVE_ECC */
01193 #ifdef HAVE_ED25519
01194     static const byte keyEd25519Oid[] = {43, 101, 112};
01195 #endif /* HAVE_ED25519 */
01196 
01197 /* curveType */
01198 #ifdef HAVE_ECC
01199     /* See "ecc_sets" table in ecc.c */
01200 #endif /* HAVE_ECC */
01201 
01202 #ifdef HAVE_AES_CBC
01203 /* blkType */
01204     #ifdef WOLFSSL_AES_128
01205     static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
01206     #endif
01207     #ifdef WOLFSSL_AES_192
01208     static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
01209     #endif
01210     #ifdef WOLFSSL_AES_256
01211     static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
01212     #endif
01213 #endif /* HAVE_AES_CBC */
01214 
01215 #ifndef NO_DES3
01216     static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
01217     static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
01218 #endif
01219 
01220 /* keyWrapType */
01221 #ifdef WOLFSSL_AES_128
01222     static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
01223 #endif
01224 #ifdef WOLFSSL_AES_192
01225     static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
01226 #endif
01227 #ifdef WOLFSSL_AES_256
01228     static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
01229 #endif
01230 
01231 /* cmsKeyAgreeType */
01232 #ifndef NO_SHA
01233     static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
01234                                           {43, 129, 5, 16, 134, 72, 63, 0, 2};
01235 #endif
01236 #ifdef WOLFSSL_SHA224
01237     static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
01238 #endif
01239 #ifndef NO_SHA256
01240     static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
01241 #endif
01242 #ifdef WOLFSSL_SHA384
01243     static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
01244 #endif
01245 #ifdef WOLFSSL_SHA512
01246     static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
01247 #endif
01248 
01249 /* ocspType */
01250 #ifdef HAVE_OCSP
01251     static const byte ocspBasicOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 1};
01252     static const byte ocspNonceOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 2};
01253 #endif /* HAVE_OCSP */
01254 
01255 /* certExtType */
01256 static const byte extBasicCaOid[] = {85, 29, 19};
01257 static const byte extAltNamesOid[] = {85, 29, 17};
01258 static const byte extCrlDistOid[] = {85, 29, 31};
01259 static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
01260 static const byte extAuthKeyOid[] = {85, 29, 35};
01261 static const byte extSubjKeyOid[] = {85, 29, 14};
01262 static const byte extCertPolicyOid[] = {85, 29, 32};
01263 static const byte extKeyUsageOid[] = {85, 29, 15};
01264 static const byte extInhibitAnyOid[] = {85, 29, 54};
01265 static const byte extExtKeyUsageOid[] = {85, 29, 37};
01266 #ifndef IGNORE_NAME_CONSTRAINTS
01267     static const byte extNameConsOid[] = {85, 29, 30};
01268 #endif
01269 
01270 /* certAuthInfoType */
01271 #ifdef HAVE_OCSP
01272     static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
01273 #endif
01274 static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
01275 
01276 /* certPolicyType */
01277 static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
01278 
01279 /* certKeyUseType */
01280 static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
01281 
01282 /* certKeyUseType */
01283 static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
01284 static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
01285 static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
01286 static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
01287 static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
01288 static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
01289 static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
01290 
01291 /* kdfType */
01292 static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
01293 
01294 /* PKCS5 */
01295 #if !defined(NO_DES3) && !defined(NO_SHA)
01296 static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
01297 #endif
01298 
01299 /* PKCS12 */
01300 #if !defined(NO_RC4) && !defined(NO_SHA)
01301 static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
01302 #endif
01303 #if !defined(NO_DES3) && !defined(NO_SHA)
01304 static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
01305 #endif
01306 
01307 
01308 /* returns a pointer to the OID string on success and NULL on fail */
01309 const byte* OidFromId(word32 id, word32 type, word32* oidSz)
01310 {
01311     const byte* oid = NULL;
01312 
01313     *oidSz = 0;
01314 
01315     switch (type) {
01316 
01317         case oidHashType:
01318             switch (id) {
01319             #ifdef WOLFSSL_MD2
01320                 case MD2h:
01321                     oid = hashMd2hOid;
01322                     *oidSz = sizeof(hashMd2hOid);
01323                     break;
01324             #endif
01325             #ifndef NO_MD5
01326                 case MD5h:
01327                     oid = hashMd5hOid;
01328                     *oidSz = sizeof(hashMd5hOid);
01329                     break;
01330             #endif
01331             #ifndef NO_SHA
01332                 case SHAh:
01333                     oid = hashSha1hOid;
01334                     *oidSz = sizeof(hashSha1hOid);
01335                     break;
01336             #endif
01337             #ifdef WOLFSSL_SHA224
01338                 case SHA224h:
01339                     oid = hashSha224hOid;
01340                     *oidSz = sizeof(hashSha224hOid);
01341                     break;
01342             #endif
01343             #ifndef NO_SHA256
01344                 case SHA256h:
01345                     oid = hashSha256hOid;
01346                     *oidSz = sizeof(hashSha256hOid);
01347                     break;
01348             #endif
01349             #ifdef WOLFSSL_SHA384
01350                 case SHA384h:
01351                     oid = hashSha384hOid;
01352                     *oidSz = sizeof(hashSha384hOid);
01353                     break;
01354             #endif
01355             #ifdef WOLFSSL_SHA512
01356                 case SHA512h:
01357                     oid = hashSha512hOid;
01358                     *oidSz = sizeof(hashSha512hOid);
01359                     break;
01360             #endif
01361             }
01362             break;
01363 
01364         case oidSigType:
01365             switch (id) {
01366                 #if !defined(NO_DSA) && !defined(NO_SHA)
01367                 case CTC_SHAwDSA:
01368                     oid = sigSha1wDsaOid;
01369                     *oidSz = sizeof(sigSha1wDsaOid);
01370                     break;
01371                 #endif /* NO_DSA */
01372                 #ifndef NO_RSA
01373                 #ifdef WOLFSSL_MD2
01374                 case CTC_MD2wRSA:
01375                     oid = sigMd2wRsaOid;
01376                     *oidSz = sizeof(sigMd2wRsaOid);
01377                     break;
01378                 #endif
01379                 #ifndef NO_MD5
01380                 case CTC_MD5wRSA:
01381                     oid = sigMd5wRsaOid;
01382                     *oidSz = sizeof(sigMd5wRsaOid);
01383                     break;
01384                 #endif
01385                 #ifndef NO_SHA
01386                 case CTC_SHAwRSA:
01387                     oid = sigSha1wRsaOid;
01388                     *oidSz = sizeof(sigSha1wRsaOid);
01389                     break;
01390                 #endif
01391                 #ifdef WOLFSSL_SHA224
01392                 case CTC_SHA224wRSA:
01393                     oid = sigSha224wRsaOid;
01394                     *oidSz = sizeof(sigSha224wRsaOid);
01395                     break;
01396                 #endif
01397                 #ifndef NO_SHA256
01398                 case CTC_SHA256wRSA:
01399                     oid = sigSha256wRsaOid;
01400                     *oidSz = sizeof(sigSha256wRsaOid);
01401                     break;
01402                 #endif
01403                 #ifdef WOLFSSL_SHA384
01404                 case CTC_SHA384wRSA:
01405                     oid = sigSha384wRsaOid;
01406                     *oidSz = sizeof(sigSha384wRsaOid);
01407                     break;
01408                 #endif
01409                 #ifdef WOLFSSL_SHA512
01410                 case CTC_SHA512wRSA:
01411                     oid = sigSha512wRsaOid;
01412                     *oidSz = sizeof(sigSha512wRsaOid);
01413                     break;
01414                 #endif /* WOLFSSL_SHA512 */
01415                 #endif /* NO_RSA */
01416                 #ifdef HAVE_ECC
01417                 #ifndef NO_SHA
01418                 case CTC_SHAwECDSA:
01419                     oid = sigSha1wEcdsaOid;
01420                     *oidSz = sizeof(sigSha1wEcdsaOid);
01421                     break;
01422                 #endif
01423                 #ifdef WOLFSSL_SHA224
01424                 case CTC_SHA224wECDSA:
01425                     oid = sigSha224wEcdsaOid;
01426                     *oidSz = sizeof(sigSha224wEcdsaOid);
01427                     break;
01428                 #endif
01429                 #ifndef NO_SHA256
01430                 case CTC_SHA256wECDSA:
01431                     oid = sigSha256wEcdsaOid;
01432                     *oidSz = sizeof(sigSha256wEcdsaOid);
01433                     break;
01434                 #endif
01435                 #ifdef WOLFSSL_SHA384
01436                 case CTC_SHA384wECDSA:
01437                     oid = sigSha384wEcdsaOid;
01438                     *oidSz = sizeof(sigSha384wEcdsaOid);
01439                     break;
01440                 #endif
01441                 #ifdef WOLFSSL_SHA512
01442                 case CTC_SHA512wECDSA:
01443                     oid = sigSha512wEcdsaOid;
01444                     *oidSz = sizeof(sigSha512wEcdsaOid);
01445                     break;
01446                 #endif
01447                 #endif /* HAVE_ECC */
01448                 #ifdef HAVE_ED25519
01449                 case CTC_ED25519:
01450                     oid = sigEd25519Oid;
01451                     *oidSz = sizeof(sigEd25519Oid);
01452                     break;
01453                 #endif
01454                 default:
01455                     break;
01456             }
01457             break;
01458 
01459         case oidKeyType:
01460             switch (id) {
01461                 #ifndef NO_DSA
01462                 case DSAk:
01463                     oid = keyDsaOid;
01464                     *oidSz = sizeof(keyDsaOid);
01465                     break;
01466                 #endif /* NO_DSA */
01467                 #ifndef NO_RSA
01468                 case RSAk:
01469                     oid = keyRsaOid;
01470                     *oidSz = sizeof(keyRsaOid);
01471                     break;
01472                 #endif /* NO_RSA */
01473                 #ifdef HAVE_NTRU
01474                 case NTRUk:
01475                     oid = keyNtruOid;
01476                     *oidSz = sizeof(keyNtruOid);
01477                     break;
01478                 #endif /* HAVE_NTRU */
01479                 #ifdef HAVE_ECC
01480                 case ECDSAk:
01481                     oid = keyEcdsaOid;
01482                     *oidSz = sizeof(keyEcdsaOid);
01483                     break;
01484                 #endif /* HAVE_ECC */
01485                 #ifdef HAVE_ED25519
01486                 case ED25519k:
01487                     oid = keyEd25519Oid;
01488                     *oidSz = sizeof(keyEd25519Oid);
01489                     break;
01490                 #endif /* HAVE_ED25519 */
01491                 default:
01492                     break;
01493             }
01494             break;
01495 
01496         #ifdef HAVE_ECC
01497         case oidCurveType:
01498             if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
01499                 WOLFSSL_MSG("ECC OID not found");
01500             }
01501             break;
01502         #endif /* HAVE_ECC */
01503 
01504         case oidBlkType:
01505             switch (id) {
01506     #ifdef HAVE_AES_CBC
01507         #ifdef WOLFSSL_AES_128
01508                 case AES128CBCb:
01509                     oid = blkAes128CbcOid;
01510                     *oidSz = sizeof(blkAes128CbcOid);
01511                     break;
01512         #endif
01513         #ifdef WOLFSSL_AES_192
01514                 case AES192CBCb:
01515                     oid = blkAes192CbcOid;
01516                     *oidSz = sizeof(blkAes192CbcOid);
01517                     break;
01518         #endif
01519         #ifdef WOLFSSL_AES_256
01520                 case AES256CBCb:
01521                     oid = blkAes256CbcOid;
01522                     *oidSz = sizeof(blkAes256CbcOid);
01523                     break;
01524         #endif
01525     #endif /* HAVE_AES_CBC */
01526     #ifndef NO_DES3
01527                 case DESb:
01528                     oid = blkDesCbcOid;
01529                     *oidSz = sizeof(blkDesCbcOid);
01530                     break;
01531                 case DES3b:
01532                     oid = blkDes3CbcOid;
01533                     *oidSz = sizeof(blkDes3CbcOid);
01534                     break;
01535     #endif /* !NO_DES3 */
01536             }
01537             break;
01538 
01539         #ifdef HAVE_OCSP
01540         case oidOcspType:
01541             switch (id) {
01542                 case OCSP_BASIC_OID:
01543                     oid = ocspBasicOid;
01544                     *oidSz = sizeof(ocspBasicOid);
01545                     break;
01546                 case OCSP_NONCE_OID:
01547                     oid = ocspNonceOid;
01548                     *oidSz = sizeof(ocspNonceOid);
01549                     break;
01550             }
01551             break;
01552         #endif /* HAVE_OCSP */
01553 
01554         case oidCertExtType:
01555             switch (id) {
01556                 case BASIC_CA_OID:
01557                     oid = extBasicCaOid;
01558                     *oidSz = sizeof(extBasicCaOid);
01559                     break;
01560                 case ALT_NAMES_OID:
01561                     oid = extAltNamesOid;
01562                     *oidSz = sizeof(extAltNamesOid);
01563                     break;
01564                 case CRL_DIST_OID:
01565                     oid = extCrlDistOid;
01566                     *oidSz = sizeof(extCrlDistOid);
01567                     break;
01568                 case AUTH_INFO_OID:
01569                     oid = extAuthInfoOid;
01570                     *oidSz = sizeof(extAuthInfoOid);
01571                     break;
01572                 case AUTH_KEY_OID:
01573                     oid = extAuthKeyOid;
01574                     *oidSz = sizeof(extAuthKeyOid);
01575                     break;
01576                 case SUBJ_KEY_OID:
01577                     oid = extSubjKeyOid;
01578                     *oidSz = sizeof(extSubjKeyOid);
01579                     break;
01580                 case CERT_POLICY_OID:
01581                     oid = extCertPolicyOid;
01582                     *oidSz = sizeof(extCertPolicyOid);
01583                     break;
01584                 case KEY_USAGE_OID:
01585                     oid = extKeyUsageOid;
01586                     *oidSz = sizeof(extKeyUsageOid);
01587                     break;
01588                 case INHIBIT_ANY_OID:
01589                     oid = extInhibitAnyOid;
01590                     *oidSz = sizeof(extInhibitAnyOid);
01591                     break;
01592                 case EXT_KEY_USAGE_OID:
01593                     oid = extExtKeyUsageOid;
01594                     *oidSz = sizeof(extExtKeyUsageOid);
01595                     break;
01596             #ifndef IGNORE_NAME_CONSTRAINTS
01597                 case NAME_CONS_OID:
01598                     oid = extNameConsOid;
01599                     *oidSz = sizeof(extNameConsOid);
01600                     break;
01601             #endif
01602             }
01603             break;
01604 
01605         case oidCertAuthInfoType:
01606             switch (id) {
01607             #ifdef HAVE_OCSP
01608                 case AIA_OCSP_OID:
01609                     oid = extAuthInfoOcspOid;
01610                     *oidSz = sizeof(extAuthInfoOcspOid);
01611                     break;
01612             #endif
01613                 case AIA_CA_ISSUER_OID:
01614                     oid = extAuthInfoCaIssuerOid;
01615                     *oidSz = sizeof(extAuthInfoCaIssuerOid);
01616                     break;
01617             }
01618             break;
01619 
01620         case oidCertPolicyType:
01621             switch (id) {
01622                 case CP_ANY_OID:
01623                     oid = extCertPolicyAnyOid;
01624                     *oidSz = sizeof(extCertPolicyAnyOid);
01625                     break;
01626             }
01627             break;
01628 
01629         case oidCertAltNameType:
01630             switch (id) {
01631                 case HW_NAME_OID:
01632                     oid = extAltNamesHwNameOid;
01633                     *oidSz = sizeof(extAltNamesHwNameOid);
01634                     break;
01635             }
01636             break;
01637 
01638         case oidCertKeyUseType:
01639             switch (id) {
01640                 case EKU_ANY_OID:
01641                     oid = extExtKeyUsageAnyOid;
01642                     *oidSz = sizeof(extExtKeyUsageAnyOid);
01643                     break;
01644                 case EKU_SERVER_AUTH_OID:
01645                     oid = extExtKeyUsageServerAuthOid;
01646                     *oidSz = sizeof(extExtKeyUsageServerAuthOid);
01647                     break;
01648                 case EKU_CLIENT_AUTH_OID:
01649                     oid = extExtKeyUsageClientAuthOid;
01650                     *oidSz = sizeof(extExtKeyUsageClientAuthOid);
01651                     break;
01652                 case EKU_CODESIGNING_OID:
01653                     oid = extExtKeyUsageCodeSigningOid;
01654                     *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
01655                     break;
01656                 case EKU_EMAILPROTECT_OID:
01657                     oid = extExtKeyUsageEmailProtectOid;
01658                     *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
01659                     break;
01660                 case EKU_TIMESTAMP_OID:
01661                     oid = extExtKeyUsageTimestampOid;
01662                     *oidSz = sizeof(extExtKeyUsageTimestampOid);
01663                     break;
01664                 case EKU_OCSP_SIGN_OID:
01665                     oid = extExtKeyUsageOcspSignOid;
01666                     *oidSz = sizeof(extExtKeyUsageOcspSignOid);
01667                     break;
01668             }
01669             break;
01670 
01671         case oidKdfType:
01672             switch (id) {
01673                 case PBKDF2_OID:
01674                     oid = pbkdf2Oid;
01675                     *oidSz = sizeof(pbkdf2Oid);
01676                     break;
01677             }
01678             break;
01679 
01680         case oidPBEType:
01681             switch (id) {
01682         #if !defined(NO_SHA) && !defined(NO_RC4)
01683                 case PBE_SHA1_RC4_128:
01684                     oid = pbeSha1RC4128;
01685                     *oidSz = sizeof(pbeSha1RC4128);
01686                     break;
01687         #endif
01688         #if !defined(NO_SHA) && !defined(NO_DES3)
01689                 case PBE_SHA1_DES:
01690                     oid = pbeSha1Des;
01691                     *oidSz = sizeof(pbeSha1Des);
01692                     break;
01693 
01694         #endif
01695         #if !defined(NO_SHA) && !defined(NO_DES3)
01696                 case PBE_SHA1_DES3:
01697                     oid = pbeSha1Des3;
01698                     *oidSz = sizeof(pbeSha1Des3);
01699                     break;
01700         #endif
01701             }
01702             break;
01703 
01704         case oidKeyWrapType:
01705             switch (id) {
01706             #ifdef WOLFSSL_AES_128
01707                 case AES128_WRAP:
01708                     oid = wrapAes128Oid;
01709                     *oidSz = sizeof(wrapAes128Oid);
01710                     break;
01711             #endif
01712             #ifdef WOLFSSL_AES_192
01713                 case AES192_WRAP:
01714                     oid = wrapAes192Oid;
01715                     *oidSz = sizeof(wrapAes192Oid);
01716                     break;
01717             #endif
01718             #ifdef WOLFSSL_AES_256
01719                 case AES256_WRAP:
01720                     oid = wrapAes256Oid;
01721                     *oidSz = sizeof(wrapAes256Oid);
01722                     break;
01723             #endif
01724             }
01725             break;
01726 
01727         case oidCmsKeyAgreeType:
01728             switch (id) {
01729             #ifndef NO_SHA
01730                 case dhSinglePass_stdDH_sha1kdf_scheme:
01731                     oid = dhSinglePass_stdDH_sha1kdf_Oid;
01732                     *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
01733                     break;
01734             #endif
01735             #ifdef WOLFSSL_SHA224
01736                 case dhSinglePass_stdDH_sha224kdf_scheme:
01737                     oid = dhSinglePass_stdDH_sha224kdf_Oid;
01738                     *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
01739                     break;
01740             #endif
01741             #ifndef NO_SHA256
01742                 case dhSinglePass_stdDH_sha256kdf_scheme:
01743                     oid = dhSinglePass_stdDH_sha256kdf_Oid;
01744                     *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
01745                     break;
01746             #endif
01747             #ifdef WOLFSSL_SHA384
01748                 case dhSinglePass_stdDH_sha384kdf_scheme:
01749                     oid = dhSinglePass_stdDH_sha384kdf_Oid;
01750                     *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
01751                     break;
01752             #endif
01753             #ifdef WOLFSSL_SHA512
01754                 case dhSinglePass_stdDH_sha512kdf_scheme:
01755                     oid = dhSinglePass_stdDH_sha512kdf_Oid;
01756                     *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
01757                     break;
01758             #endif
01759             }
01760             break;
01761 
01762 #ifndef NO_HMAC
01763         case oidHmacType:
01764             switch (id) {
01765         #ifdef WOLFSSL_SHA224
01766                 case HMAC_SHA224_OID:
01767                     oid = hmacSha224Oid;
01768                     *oidSz = sizeof(hmacSha224Oid);
01769                     break;
01770         #endif
01771         #ifndef NO_SHA256
01772                 case HMAC_SHA256_OID:
01773                     oid = hmacSha256Oid;
01774                     *oidSz = sizeof(hmacSha256Oid);
01775                     break;
01776         #endif
01777         #ifdef WOLFSSL_SHA384
01778                 case HMAC_SHA384_OID:
01779                     oid = hmacSha384Oid;
01780                     *oidSz = sizeof(hmacSha384Oid);
01781                     break;
01782         #endif
01783         #ifdef WOLFSSL_SHA512
01784                 case HMAC_SHA512_OID:
01785                     oid = hmacSha512Oid;
01786                     *oidSz = sizeof(hmacSha512Oid);
01787                     break;
01788         #endif
01789             }
01790             break;
01791 #endif /* !NO_HMAC */
01792 
01793         case oidIgnoreType:
01794         default:
01795             break;
01796     }
01797 
01798     return oid;
01799 }
01800 
01801 #ifdef HAVE_OID_ENCODING
01802 int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
01803 {
01804     int i, x, len;
01805     word32 d, t;
01806 
01807     /* check args */
01808     if (in == NULL || outSz == NULL) {
01809         return BAD_FUNC_ARG;
01810     }
01811 
01812     /* compute length of encoded OID */
01813     d = (in[0] * 40) + in[1];
01814     len = 0;
01815     for (i = 1; i < (int)inSz; i++) {
01816         x = 0;
01817         t = d;
01818         while (t) {
01819             x++;
01820             t >>= 1;
01821         }
01822         len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
01823 
01824         if (i < (int)inSz - 1) {
01825             d = in[i + 1];
01826         }
01827     }
01828 
01829     if (out) {
01830         /* verify length */
01831         if ((int)*outSz < len) {
01832             return BUFFER_E; /* buffer provided is not large enough */
01833         }
01834 
01835         /* calc first byte */
01836         d = (in[0] * 40) + in[1];
01837 
01838         /* encode bytes */
01839         x = 0;
01840         for (i = 1; i < (int)inSz; i++) {
01841             if (d) {
01842                 int y = x, z;
01843                 byte mask = 0;
01844                 while (d) {
01845                     out[x++] = (byte)((d & 0x7F) | mask);
01846                     d     >>= 7;
01847                     mask  |= 0x80;  /* upper bit is set on all but the last byte */
01848                 }
01849                 /* now swap bytes y...x-1 */
01850                 z = x - 1;
01851                 while (y < z) {
01852                     mask = out[y];
01853                     out[y] = out[z];
01854                     out[z] = mask;
01855                     ++y;
01856                     --z;
01857                 }
01858             }
01859             else {
01860               out[x++] = 0x00; /* zero value */
01861             }
01862 
01863             /* next word */
01864             if (i < (int)inSz - 1) {
01865                 d = in[i + 1];
01866             }
01867         }
01868     }
01869 
01870     /* return length */
01871     *outSz = len;
01872 
01873     return 0;
01874 }
01875 #endif /* HAVE_OID_ENCODING */
01876 
01877 #ifdef HAVE_OID_DECODING
01878 int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
01879 {
01880     int x = 0, y = 0;
01881     word32 t = 0;
01882 
01883     /* check args */
01884     if (in == NULL || outSz == NULL) {
01885         return BAD_FUNC_ARG;
01886     }
01887 
01888     /* decode bytes */
01889     while (inSz--) {
01890         t = (t << 7) | (in[x] & 0x7F);
01891         if (!(in[x] & 0x80)) {
01892             if (y >= (int)*outSz) {
01893                 return BUFFER_E;
01894             }
01895             if (y == 0) {
01896                 out[0] = (t / 40);
01897                 out[1] = (t % 40);
01898                 y = 2;
01899             }
01900             else {
01901                 out[y++] = t;
01902             }
01903             t = 0; /* reset tmp */
01904         }
01905         x++;
01906     }
01907 
01908     /* return length */
01909     *outSz = y;
01910 
01911     return 0;
01912 }
01913 #endif /* HAVE_OID_DECODING */
01914 
01915 /* Get the DER/BER encoding of an ASN.1 OBJECT_ID header.
01916  *
01917  * input     Buffer holding DER/BER encoded data.
01918  * inOutIdx  Current index into buffer to parse.
01919  * len       The number of bytes in the ASN.1 data.
01920  * maxIdx    Length of data in buffer.
01921  * returns BUFFER_E when there is not enough data to parse.
01922  *         ASN_OBJECt_ID_E when the OBJECT_ID tag is not found.
01923  *         ASN_PARSE_E when length is invalid.
01924  *         Otherwise, 0 to indicate success.
01925  */
01926 static int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
01927                           word32 maxIdx)
01928 {
01929     word32 idx = *inOutIdx;
01930     byte   b;
01931     int    length;
01932 
01933     if ((idx + 1) > maxIdx)
01934         return BUFFER_E;
01935 
01936     b = input[idx++];
01937     if (b != ASN_OBJECT_ID)
01938         return ASN_OBJECT_ID_E;
01939 
01940     if (GetLength(input, &idx, &length, maxIdx) < 0)
01941         return ASN_PARSE_E;
01942 
01943     *len = length;
01944     *inOutIdx = idx;
01945     return 0;
01946 }
01947 
01948 /* Set the DER/BER encoding of the ASN.1 OBJECT_ID header.
01949  *
01950  * len         Length of the OBJECT_ID data.
01951  * output      Buffer to write into.
01952  * returns the number of bytes added to the buffer.
01953  */
01954 static int SetObjectId(int len, byte* output)
01955 {
01956     int idx = 0;
01957 
01958     output[idx++] = ASN_OBJECT_ID;
01959     idx += SetLength(len, output + idx);
01960 
01961     return idx;
01962 }
01963 
01964 int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
01965                                   word32 oidType, word32 maxIdx)
01966 {
01967     int    ret = 0, length;
01968     word32 idx = *inOutIdx;
01969 #ifndef NO_VERIFY_OID
01970     word32 actualOidSz = 0;
01971     const byte* actualOid;
01972 #endif /* NO_VERIFY_OID */
01973 
01974     (void)oidType;
01975     WOLFSSL_ENTER("GetObjectId()");
01976     *oid = 0;
01977 
01978     ret = GetASNObjectId(input, &idx, &length, maxIdx);
01979     if (ret != 0)
01980         return ret;
01981 
01982 #ifndef NO_VERIFY_OID
01983     actualOid = &input[idx];
01984     if (length > 0)
01985         actualOidSz = (word32)length;
01986 #endif /* NO_VERIFY_OID */
01987 
01988     while (length--) {
01989         /* odd HC08 compiler behavior here when input[idx++] */
01990         *oid += (word32)input[idx];
01991         idx++;
01992     }
01993     /* just sum it up for now */
01994 
01995     *inOutIdx = idx;
01996 
01997 #ifndef NO_VERIFY_OID
01998     {
01999         const byte* checkOid = NULL;
02000         word32 checkOidSz;
02001     #ifdef ASN_DUMP_OID
02002         word32 i;
02003     #endif
02004 
02005         if (oidType != oidIgnoreType) {
02006             checkOid = OidFromId(*oid, oidType, &checkOidSz);
02007 
02008         #ifdef ASN_DUMP_OID
02009             /* support for dumping OID information */
02010             printf("OID (Type %d, Sz %d, Sum %d): ", oidType, actualOidSz, *oid);
02011             for (i=0; i<actualOidSz; i++) {
02012                 printf("%d, ", actualOid[i]);
02013             }
02014             printf("\n");
02015             #ifdef HAVE_OID_DECODING
02016             {
02017                 word16 decOid[16];
02018                 word32 decOidSz = sizeof(decOid);
02019                 ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);
02020                 if (ret == 0) {
02021                     printf("  Decoded (Sz %d): ", decOidSz);
02022                     for (i=0; i<decOidSz; i++) {
02023                         printf("%d.", decOid[i]);
02024                     }
02025                     printf("\n");
02026                 }
02027                 else {
02028                     printf("DecodeObjectId failed: %d\n", ret);
02029                 }
02030             }
02031             #endif /* HAVE_OID_DECODING */
02032         #endif /* ASN_DUMP_OID */
02033 
02034             if (checkOid != NULL &&
02035                 (checkOidSz != actualOidSz ||
02036                     XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) {
02037                 WOLFSSL_MSG("OID Check Failed");
02038                 return ASN_UNKNOWN_OID_E;
02039             }
02040         }
02041     }
02042 #endif /* NO_VERIFY_OID */
02043 
02044     return ret;
02045 }
02046 
02047 static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
02048 {
02049     word32 idx = *inOutIdx;
02050     int    length;
02051     int ret;
02052 
02053     ret = GetASNObjectId(input, &idx, &length, maxIdx);
02054     if (ret != 0)
02055         return ret;
02056 
02057     idx += length;
02058     *inOutIdx = idx;
02059 
02060     return 0;
02061 }
02062 
02063 WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
02064                      word32 oidType, word32 maxIdx)
02065 {
02066     int    length;
02067     word32 idx = *inOutIdx;
02068     int    ret;
02069     *oid = 0;
02070 
02071     WOLFSSL_ENTER("GetAlgoId");
02072 
02073     if (GetSequence(input, &idx, &length, maxIdx) < 0)
02074         return ASN_PARSE_E;
02075 
02076     if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
02077         return ASN_OBJECT_ID_E;
02078 
02079     /* could have NULL tag and 0 terminator, but may not */
02080     if (idx < maxIdx && input[idx] == ASN_TAG_NULL) {
02081         ret = GetASNNull(input, &idx, maxIdx);
02082         if (ret != 0)
02083             return ret;
02084     }
02085 
02086     *inOutIdx = idx;
02087 
02088     return 0;
02089 }
02090 
02091 #ifndef NO_RSA
02092 
02093 #ifndef HAVE_USER_RSA
02094 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
02095                         word32 inSz)
02096 {
02097     int version, length;
02098 
02099     if (inOutIdx == NULL) {
02100         return BAD_FUNC_ARG;
02101     }
02102     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02103         return ASN_PARSE_E;
02104 
02105     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
02106         return ASN_PARSE_E;
02107 
02108     key->type = RSA_PRIVATE;
02109 
02110     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
02111         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
02112         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
02113         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
02114         GetInt(&key->q,  input, inOutIdx, inSz) < 0)   return ASN_RSA_KEY_E;
02115 #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
02116     if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
02117         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
02118         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
02119 #else
02120     if (SkipInt(input, inOutIdx, inSz) < 0 ||
02121         SkipInt(input, inOutIdx, inSz) < 0 ||
02122         SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
02123 #endif
02124 
02125 #ifdef WOLFSSL_XILINX_CRYPT
02126     if (wc_InitRsaHw(key) != 0) {
02127         return BAD_STATE_E;
02128     }
02129 #endif
02130 
02131     return 0;
02132 }
02133 #endif /* HAVE_USER_RSA */
02134 #endif /* NO_RSA */
02135 
02136 /* Remove PKCS8 header, place inOutIdx at beginning of traditional,
02137  * return traditional length on success, negative on error */
02138 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
02139 {
02140     word32 idx, oid;
02141     int    version, length;
02142     int    ret;
02143 
02144     if (input == NULL || inOutIdx == NULL)
02145         return BAD_FUNC_ARG;
02146 
02147     idx = *inOutIdx;
02148 
02149     if (GetSequence(input, &idx, &length, sz) < 0)
02150         return ASN_PARSE_E;
02151 
02152     if (GetMyVersion(input, &idx, &version, sz) < 0)
02153         return ASN_PARSE_E;
02154 
02155     if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
02156         return ASN_PARSE_E;
02157 
02158     if (input[idx] == ASN_OBJECT_ID) {
02159         if (SkipObjectId(input, &idx, sz) < 0)
02160             return ASN_PARSE_E;
02161     }
02162 
02163     ret = GetOctetString(input, &idx, &length, sz);
02164     if (ret < 0)
02165         return ret;
02166 
02167     *inOutIdx = idx;
02168 
02169     return length;
02170 }
02171 
02172 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
02173 int ToTraditional(byte* input, word32 sz)
02174 {
02175     word32 inOutIdx = 0;
02176     int    length;
02177 
02178     if (input == NULL)
02179         return BAD_FUNC_ARG;
02180 
02181     length = ToTraditionalInline(input, &inOutIdx, sz);
02182     if (length < 0)
02183         return length;
02184 
02185     XMEMMOVE(input, input + inOutIdx, length);
02186 
02187     return length;
02188 }
02189 
02190 
02191 /* find beginning of traditional key inside PKCS#8 unencrypted buffer
02192  * return traditional length on success, with inOutIdx at beginning of
02193  * traditional
02194  * return negative on failure/error */
02195 int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
02196 {
02197     int length;
02198 
02199     if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
02200         return BAD_FUNC_ARG;
02201 
02202     length = ToTraditionalInline(input, inOutIdx, sz);
02203 
02204     return length;
02205 }
02206 
02207 
02208 /* PKCS#8 from RFC 5208
02209  * This function takes in a DER key and converts it to PKCS#8 format. Used
02210  * in creating PKCS#12 shrouded key bags.
02211  * Reverse of ToTraditional
02212  *
02213  * PrivateKeyInfo ::= SEQUENCE {
02214  *  version Version,
02215  *  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
02216  *  privateKey          PrivateKey,
02217  *  attributes          optional
02218  *  }
02219  *  Version ::= INTEGER
02220  *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
02221  *  PrivateKey ::= OCTET STRING
02222  *
02223  * out      buffer to place result in
02224  * outSz    size of out buffer
02225  * key      buffer with DER key
02226  * keySz    size of key buffer
02227  * algoID   algorithm ID i.e. RSAk
02228  * curveOID ECC curve oid if used. Should be NULL for RSA keys.
02229  * oidSz    size of curve oid. Is set to 0 if curveOID is NULL.
02230  *
02231  * Returns the size of PKCS#8 placed into out. In error cases returns negative
02232  * values.
02233  */
02234 int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
02235         int algoID, const byte* curveOID, word32 oidSz)
02236 {
02237         word32 keyIdx = 0;
02238         word32 tmpSz  = 0;
02239         word32 sz;
02240 
02241 
02242         /* If out is NULL then return the max size needed
02243          * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
02244         if (out == NULL && outSz != NULL) {
02245             *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
02246                      + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
02247 
02248             if (curveOID != NULL)
02249                 *outSz += oidSz + MAX_LENGTH_SZ + 1;
02250 
02251             WOLFSSL_MSG("Checking size of PKCS8");
02252 
02253             return LENGTH_ONLY_E;
02254         }
02255 
02256         WOLFSSL_ENTER("wc_CreatePKCS8Key()");
02257 
02258         if (key == NULL || out == NULL || outSz == NULL) {
02259             return BAD_FUNC_ARG;
02260         }
02261 
02262         /* check the buffer has enough room for largest possible size */
02263         if (curveOID != NULL) {
02264             if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
02265                    + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
02266                 return BUFFER_E;
02267         }
02268         else {
02269             oidSz = 0; /* with no curveOID oid size must be 0 */
02270             if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
02271                       + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
02272                 return BUFFER_E;
02273         }
02274 
02275         /* PrivateKeyInfo ::= SEQUENCE */
02276         keyIdx += MAX_SEQ_SZ; /* save room for sequence */
02277 
02278         /*  version Version
02279          *  no header information just INTEGER */
02280         sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
02281         tmpSz += sz; keyIdx += sz;
02282 
02283         /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
02284         sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
02285         if (curveOID != NULL && oidSz > 0) {
02286             byte buf[MAX_LENGTH_SZ];
02287             sz = SetLength(oidSz, buf);
02288             sz += 1; /* plus one for ASN object id */
02289         }
02290         sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
02291         tmpSz += sz; keyIdx += sz;
02292 
02293         /*  privateKey          PrivateKey *
02294          * pkcs8 ecc uses slightly different format. Places curve oid in
02295          * buffer */
02296         if (curveOID != NULL && oidSz > 0) {
02297             sz = SetObjectId(oidSz, out + keyIdx);
02298             keyIdx += sz; tmpSz += sz;
02299             XMEMCPY(out + keyIdx, curveOID, oidSz);
02300             keyIdx += oidSz; tmpSz += oidSz;
02301         }
02302 
02303         sz = SetOctetString(keySz, out + keyIdx);
02304         keyIdx += sz; tmpSz += sz;
02305         XMEMCPY(out + keyIdx, key, keySz);
02306         tmpSz += keySz;
02307 
02308         /*  attributes          optional
02309          * No attributes currently added */
02310 
02311         /* rewind and add sequence */
02312         sz = SetSequence(tmpSz, out);
02313         XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
02314 
02315         return tmpSz + sz;
02316 }
02317 
02318 
02319 /* check that the private key is a pair for the public key in certificate
02320  * return 1 (true) on match
02321  * return 0 or negative value on failure/error
02322  *
02323  * key   : buffer holding DER fromat key
02324  * keySz : size of key buffer
02325  * der   : a initialized and parsed DecodedCert holding a certificate */
02326 int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
02327 {
02328     int ret;
02329     (void)keySz;
02330 
02331     if (key == NULL || der == NULL) {
02332         return BAD_FUNC_ARG;
02333     }
02334 
02335     #if !defined(NO_RSA)
02336     /* test if RSA key */
02337     if (der->keyOID == RSAk) {
02338     #ifdef WOLFSSL_SMALL_STACK
02339         RsaKey* a = NULL;
02340         RsaKey* b = NULL;
02341     #else
02342         RsaKey a[1], b[1];
02343     #endif
02344         word32 keyIdx = 0;
02345 
02346     #ifdef WOLFSSL_SMALL_STACK
02347         a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
02348         if (a == NULL)
02349             return MEMORY_E;
02350         b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
02351         if (b == NULL) {
02352             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
02353             return MEMORY_E;
02354         }
02355     #endif
02356 
02357         if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
02358     #ifdef WOLFSSL_SMALL_STACK
02359             XFREE(b, NULL, DYNAMIC_TYPE_RSA);
02360             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
02361     #endif
02362             return ret;
02363         }
02364         if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
02365             wc_FreeRsaKey(a);
02366     #ifdef WOLFSSL_SMALL_STACK
02367             XFREE(b, NULL, DYNAMIC_TYPE_RSA);
02368             XFREE(a, NULL, DYNAMIC_TYPE_RSA);
02369     #endif
02370             return ret;
02371         }
02372         if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
02373             WOLFSSL_MSG("Checking RSA key pair");
02374             keyIdx = 0; /* reset to 0 for parsing public key */
02375 
02376             if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
02377                                                        der->pubKeySize)) == 0) {
02378                 /* limit for user RSA crypto because of RsaKey
02379                  * dereference. */
02380             #if defined(HAVE_USER_RSA)
02381                 WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
02382                 ret = 1; /* return first RSA cert as match */
02383             #else
02384                 /* both keys extracted successfully now check n and e
02385                  * values are the same. This is dereferencing RsaKey */
02386                 if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
02387                     mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
02388                     ret = MP_CMP_E;
02389                 }
02390                 else
02391                     ret = 1;
02392             #endif
02393             }
02394         }
02395         wc_FreeRsaKey(b);
02396         wc_FreeRsaKey(a);
02397     #ifdef WOLFSSL_SMALL_STACK
02398         XFREE(b, NULL, DYNAMIC_TYPE_RSA);
02399         XFREE(a, NULL, DYNAMIC_TYPE_RSA);
02400     #endif
02401     }
02402     else
02403     #endif /* NO_RSA */
02404 
02405     #ifdef HAVE_ECC
02406     if (der->keyOID == ECDSAk) {
02407     #ifdef WOLFSSL_SMALL_STACK
02408         ecc_key* key_pair = NULL;
02409         byte*    privDer;
02410     #else
02411         ecc_key  key_pair[1];
02412         byte     privDer[MAX_ECC_BYTES];
02413     #endif
02414         word32   privSz = MAX_ECC_BYTES;
02415         word32   keyIdx = 0;
02416 
02417     #ifdef WOLFSSL_SMALL_STACK
02418         key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
02419         if (key_pair == NULL)
02420             return MEMORY_E;
02421         privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02422         if (privDer == NULL) {
02423             XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
02424             return MEMORY_E;
02425         }
02426     #endif
02427 
02428         if ((ret = wc_ecc_init(key_pair)) < 0) {
02429     #ifdef WOLFSSL_SMALL_STACK
02430             XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02431             XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
02432     #endif
02433             return ret;
02434         }
02435 
02436         if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
02437                                                                  keySz)) == 0) {
02438             WOLFSSL_MSG("Checking ECC key pair");
02439 
02440             if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
02441                                                                          == 0) {
02442                 wc_ecc_free(key_pair);
02443                 ret = wc_ecc_init(key_pair);
02444                 if (ret == 0) {
02445                     ret = wc_ecc_import_private_key((const byte*)privDer,
02446                                             privSz, (const byte*)der->publicKey,
02447                                             der->pubKeySize, key_pair);
02448                 }
02449 
02450                 /* public and private extracted successfuly now check if is
02451                  * a pair and also do sanity checks on key. wc_ecc_check_key
02452                  * checks that private * base generator equals pubkey */
02453                 if (ret == 0) {
02454                     if ((ret = wc_ecc_check_key(key_pair)) == 0) {
02455                         ret = 1;
02456                     }
02457                 }
02458                 ForceZero(privDer, privSz);
02459             }
02460         }
02461         wc_ecc_free(key_pair);
02462     #ifdef WOLFSSL_SMALL_STACK
02463         XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02464         XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
02465     #endif
02466     }
02467     else
02468     #endif /* HAVE_ECC */
02469 
02470     #ifdef HAVE_ED25519
02471     if (der->keyOID == ED25519k) {
02472     #ifdef WOLFSSL_SMALL_STACK
02473         ed25519_key* key_pair = NULL;
02474     #else
02475         ed25519_key  key_pair[1];
02476     #endif
02477         word32       keyIdx = 0;
02478 
02479     #ifdef WOLFSSL_SMALL_STACK
02480         key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
02481                                                           DYNAMIC_TYPE_ED25519);
02482         if (key_pair == NULL)
02483             return MEMORY_E;
02484     #endif
02485 
02486         if ((ret = wc_ed25519_init(key_pair)) < 0) {
02487     #ifdef WOLFSSL_SMALL_STACK
02488             XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
02489     #endif
02490             return ret;
02491         }
02492         if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
02493                                                                  keySz)) == 0) {
02494             WOLFSSL_MSG("Checking ED25519 key pair");
02495             keyIdx = 0;
02496             if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
02497                                                               key_pair)) == 0) {
02498                 /* public and private extracted successfuly no check if is
02499                  * a pair and also do sanity checks on key. wc_ecc_check_key
02500                  * checks that private * base generator equals pubkey */
02501                 if ((ret = wc_ed25519_check_key(key_pair)) == 0)
02502                     ret = 1;
02503             }
02504         }
02505         wc_ed25519_free(key_pair);
02506     #ifdef WOLFSSL_SMALL_STACK
02507         XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
02508     #endif
02509     }
02510     else
02511     #endif
02512     {
02513         ret = 0;
02514     }
02515 
02516     (void)keySz;
02517 
02518     return ret;
02519 }
02520 
02521 #ifndef NO_PWDBASED
02522 
02523 /* Check To see if PKCS version algo is supported, set id if it is return 0
02524    < 0 on error */
02525 static int CheckAlgo(int first, int second, int* id, int* version)
02526 {
02527     *id      = ALGO_ID_E;
02528     *version = PKCS5;   /* default */
02529 
02530     if (first == 1) {
02531         switch (second) {
02532 #if !defined(NO_SHA)
02533     #ifndef NO_RC4
02534         case PBE_SHA1_RC4_128:
02535             *id = PBE_SHA1_RC4_128;
02536             *version = PKCS12v1;
02537             return 0;
02538     #endif
02539     #ifndef NO_DES3
02540         case PBE_SHA1_DES3:
02541             *id = PBE_SHA1_DES3;
02542             *version = PKCS12v1;
02543             return 0;
02544     #endif
02545 #endif /* !NO_SHA */
02546         default:
02547             return ALGO_ID_E;
02548         }
02549     }
02550 
02551     if (first != PKCS5)
02552         return ASN_INPUT_E;  /* VERSION ERROR */
02553 
02554     if (second == PBES2) {
02555         *version = PKCS5v2;
02556         return 0;
02557     }
02558 
02559     switch (second) {
02560 #ifndef NO_DES3
02561     #ifndef NO_MD5
02562     case 3:                   /* see RFC 2898 for ids */
02563         *id = PBE_MD5_DES;
02564         return 0;
02565     #endif
02566     #ifndef NO_SHA
02567     case 10:
02568         *id = PBE_SHA1_DES;
02569         return 0;
02570     #endif
02571 #endif /* !NO_DES3 */
02572     default:
02573         return ALGO_ID_E;
02574 
02575     }
02576 }
02577 
02578 
02579 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
02580    < 0 on error */
02581 static int CheckAlgoV2(int oid, int* id)
02582 {
02583     (void)id; /* not used if AES and DES3 disabled */
02584     switch (oid) {
02585 #if !defined(NO_DES3) && !defined(NO_SHA)
02586     case DESb:
02587         *id = PBE_SHA1_DES;
02588         return 0;
02589     case DES3b:
02590         *id = PBE_SHA1_DES3;
02591         return 0;
02592 #endif
02593 #ifdef WOLFSSL_AES_256
02594     case AES256CBCb:
02595         *id = PBE_AES256_CBC;
02596         return 0;
02597 #endif
02598     default:
02599         return ALGO_ID_E;
02600 
02601     }
02602 }
02603 
02604 
02605 int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
02606         int* algoID, void* heap)
02607 {
02608     word32 tmpIdx = 0;
02609 
02610     if (key == NULL || algoID == NULL)
02611         return BAD_FUNC_ARG;
02612 
02613     *algoID = 0;
02614 
02615     #ifndef NO_RSA
02616     {
02617         RsaKey rsa;
02618 
02619         wc_InitRsaKey(&rsa, heap);
02620         if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
02621             *algoID = RSAk;
02622         }
02623         else {
02624             WOLFSSL_MSG("Not RSA DER key");
02625         }
02626         wc_FreeRsaKey(&rsa);
02627     }
02628     #endif /* NO_RSA */
02629     #ifdef HAVE_ECC
02630     if (*algoID == 0) {
02631         ecc_key ecc;
02632 
02633         tmpIdx = 0;
02634         wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);
02635         if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
02636             *algoID = ECDSAk;
02637 
02638             /* now find oid */
02639             if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
02640                 WOLFSSL_MSG("Error getting ECC curve OID");
02641                 wc_ecc_free(&ecc);
02642                 return BAD_FUNC_ARG;
02643             }
02644         }
02645         else {
02646             WOLFSSL_MSG("Not ECC DER key either");
02647         }
02648         wc_ecc_free(&ecc);
02649     }
02650 #endif /* HAVE_ECC */
02651 #ifdef HAVE_ED25519
02652     if (*algoID != RSAk && *algoID != ECDSAk) {
02653         ed25519_key ed25519;
02654 
02655         tmpIdx = 0;
02656         if (wc_ed25519_init(&ed25519) == 0) {
02657             if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
02658                                                                          == 0) {
02659                 *algoID = ED25519k;
02660             }
02661             else {
02662                 WOLFSSL_MSG("Not ED25519 DER key");
02663             }
02664             wc_ed25519_free(&ed25519);
02665         }
02666         else {
02667             WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
02668         }
02669     }
02670 #endif
02671 
02672     /* if flag is not set then is neither RSA or ECC key that could be
02673      * found */
02674     if (*algoID == 0) {
02675         WOLFSSL_MSG("Bad key DER or compile options");
02676         return BAD_FUNC_ARG;
02677     }
02678 
02679     (void)curveOID;
02680     (void)oidSz;
02681 
02682     return 1;
02683 }
02684 
02685 
02686 /*
02687  * Used when creating PKCS12 shrouded key bags
02688  * vPKCS is the version of PKCS to use
02689  * vAlgo is the algorithm version to use
02690  *
02691  * if salt is NULL a random number is generated
02692  *
02693  * returns the size of encrypted data on success
02694  */
02695 int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
02696         const char* password,int passwordSz, int vPKCS, int vAlgo,
02697         byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
02698 {
02699     int algoID = 0;
02700     byte*  tmp;
02701     word32 tmpSz = 0;
02702     word32 sz;
02703     word32 seqSz;
02704     word32 inOutIdx = 0;
02705     word32 totalSz = 0;
02706     int    version, id;
02707     int    ret;
02708 
02709     const byte* curveOID = NULL;
02710     word32 oidSz   = 0;
02711 
02712 #ifdef WOLFSSL_SMALL_STACK
02713     byte*  saltTmp = NULL;
02714     byte*  cbcIv   = NULL;
02715 #else
02716     byte   saltTmp[MAX_IV_SIZE];
02717     byte   cbcIv[MAX_IV_SIZE];
02718 #endif
02719 
02720     WOLFSSL_ENTER("UnTraditionalEnc()");
02721 
02722     if (saltSz > MAX_SALT_SIZE)
02723         return ASN_PARSE_E;
02724 
02725 
02726     inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */
02727     if (CheckAlgo(vPKCS, vAlgo, &id, &version) < 0) {
02728         WOLFSSL_MSG("Bad/Unsupported algorithm ID");
02729         return ASN_INPUT_E;  /* Algo ID error */
02730     }
02731 
02732     if (out != NULL) {
02733         if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +
02734                 MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)
02735                 return BUFFER_E;
02736 
02737         if (version == PKCS5v2) {
02738             WOLFSSL_MSG("PKCS5v2 Not supported yet\n");
02739             return ASN_VERSION_E;
02740         }
02741 
02742         if (salt == NULL || saltSz <= 0) {
02743             saltSz = 8;
02744         #ifdef WOLFSSL_SMALL_STACK
02745             saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
02746             if (saltTmp == NULL)
02747                 return MEMORY_E;
02748         #endif
02749             salt = saltTmp;
02750 
02751             if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
02752                 WOLFSSL_MSG("Error generating random salt");
02753             #ifdef WOLFSSL_SMALL_STACK
02754                 if (saltTmp != NULL)
02755                     XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02756             #endif
02757                 return ret;
02758             }
02759         }
02760 
02761 
02762         /* leave room for a sequence (contains salt and iterations int) */
02763         inOutIdx += MAX_SEQ_SZ; sz = 0;
02764         inOutIdx += MAX_ALGO_SZ;
02765 
02766         /* place salt in buffer */
02767         out[inOutIdx++] = ASN_OCTET_STRING; sz++;
02768         tmpSz = SetLength(saltSz, out + inOutIdx);
02769         inOutIdx += tmpSz; sz += tmpSz;
02770         XMEMCPY(out + inOutIdx, salt, saltSz);
02771         inOutIdx += saltSz; sz += saltSz;
02772 
02773         /* place iteration count in buffer */
02774         ret = SetShortInt(out, &inOutIdx, itt, *outSz);
02775         if (ret < 0) {
02776             return ret;
02777         }
02778         sz += (word32)ret;
02779 
02780         /* wind back index and set sequence then clean up buffer */
02781         inOutIdx -= (sz + MAX_SEQ_SZ);
02782         tmpSz = SetSequence(sz, out + inOutIdx);
02783         XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);
02784         totalSz += tmpSz + sz; sz += tmpSz;
02785 
02786         /* add in algo ID */
02787         inOutIdx -= MAX_ALGO_SZ;
02788         tmpSz =  SetAlgoID(id, out + inOutIdx, oidPBEType, sz);
02789         XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);
02790         totalSz += tmpSz; inOutIdx += tmpSz + sz;
02791 
02792         /* octet string containing encrypted key */
02793         out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;
02794     }
02795 
02796     /* check key type and get OID if ECC */
02797     if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {
02798             return ret;
02799     }
02800 
02801     /* PKCS#8 wrapping around key */
02802     if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)
02803             != LENGTH_ONLY_E) {
02804     #ifdef WOLFSSL_SMALL_STACK
02805         if (saltTmp != NULL)
02806             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02807     #endif
02808         return MEMORY_E;
02809     }
02810 
02811     /* check if should return max size */
02812     if (out == NULL) {
02813         /* account for salt size */
02814         if (salt == NULL || saltSz <= 0) {
02815             tmpSz += MAX_SALT_SIZE;
02816         }
02817         else {
02818             tmpSz += saltSz;
02819         }
02820 
02821         /* plus 3 for tags */
02822         *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ
02823             + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;
02824         return LENGTH_ONLY_E;
02825     }
02826 
02827     tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
02828     if (tmp == NULL) {
02829     #ifdef WOLFSSL_SMALL_STACK
02830         if (saltTmp != NULL)
02831             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02832     #endif
02833         return MEMORY_E;
02834     }
02835 
02836     if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,
02837                     oidSz)) < 0) {
02838         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02839         WOLFSSL_MSG("Error wrapping key with PKCS#8");
02840     #ifdef WOLFSSL_SMALL_STACK
02841         if (saltTmp != NULL)
02842             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02843     #endif
02844         return ret;
02845     }
02846     tmpSz = ret;
02847 
02848 #ifdef WOLFSSL_SMALL_STACK
02849     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
02850     if (cbcIv == NULL) {
02851         if (saltTmp != NULL)
02852             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02853         XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);
02854         return MEMORY_E;
02855     }
02856 #endif
02857 
02858     /* encrypt PKCS#8 wrapped key */
02859     if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
02860                tmp, tmpSz, version, cbcIv, 1)) < 0) {
02861         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02862         WOLFSSL_MSG("Error encrypting key");
02863     #ifdef WOLFSSL_SMALL_STACK
02864         if (saltTmp != NULL)
02865             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02866         if (cbcIv != NULL)
02867             XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
02868     #endif
02869         return ret;  /* encryption failure */
02870     }
02871     totalSz += tmpSz;
02872 
02873 #ifdef WOLFSSL_SMALL_STACK
02874     if (saltTmp != NULL)
02875         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02876     if (cbcIv != NULL)
02877         XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
02878 #endif
02879 
02880     if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {
02881         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02882         return BUFFER_E;
02883     }
02884 
02885     /* set length of key and copy over encrypted key */
02886     seqSz = SetLength(tmpSz, out + inOutIdx);
02887     inOutIdx += seqSz; totalSz += seqSz;
02888     XMEMCPY(out + inOutIdx, tmp, tmpSz);
02889     XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
02890 
02891     /* set total size at begining */
02892     sz = SetSequence(totalSz, out);
02893     XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);
02894 
02895     return totalSz + sz;
02896 }
02897 
02898 
02899 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
02900    of input */
02901 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
02902 {
02903     word32 inOutIdx = 0, seqEnd, oid;
02904     int    ret = 0, first, second, length = 0, version, saltSz, id;
02905     int    iterations = 0, keySz = 0;
02906 #ifdef WOLFSSL_SMALL_STACK
02907     byte*  salt = NULL;
02908     byte*  cbcIv = NULL;
02909 #else
02910     byte   salt[MAX_SALT_SIZE];
02911     byte   cbcIv[MAX_IV_SIZE];
02912 #endif
02913 
02914     if (passwordSz < 0) {
02915         WOLFSSL_MSG("Bad password size");
02916         return BAD_FUNC_ARG;
02917     }
02918 
02919     if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
02920         ERROR_OUT(ASN_PARSE_E, exit_tte);
02921     }
02922 
02923     if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
02924         ERROR_OUT(ASN_PARSE_E, exit_tte);
02925     }
02926 
02927     first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
02928     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
02929 
02930     if (CheckAlgo(first, second, &id, &version) < 0) {
02931         ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */
02932     }
02933 
02934     if (version == PKCS5v2) {
02935         if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
02936             ERROR_OUT(ASN_PARSE_E, exit_tte);
02937         }
02938 
02939         if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
02940             ERROR_OUT(ASN_PARSE_E, exit_tte);
02941         }
02942 
02943         if (oid != PBKDF2_OID) {
02944             ERROR_OUT(ASN_PARSE_E, exit_tte);
02945         }
02946     }
02947 
02948     if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
02949         ERROR_OUT(ASN_PARSE_E, exit_tte);
02950     }
02951     /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
02952      * DEFAULT items. */
02953     seqEnd = inOutIdx + length;
02954 
02955     ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
02956     if (ret < 0)
02957         goto exit_tte;
02958 
02959     if (saltSz > MAX_SALT_SIZE) {
02960         ERROR_OUT(ASN_PARSE_E, exit_tte);
02961     }
02962 
02963 #ifdef WOLFSSL_SMALL_STACK
02964     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02965     if (salt == NULL) {
02966         ERROR_OUT(MEMORY_E, exit_tte);
02967     }
02968 #endif
02969 
02970     XMEMCPY(salt, &input[inOutIdx], saltSz);
02971     inOutIdx += saltSz;
02972 
02973     if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
02974         ERROR_OUT(ASN_PARSE_E, exit_tte);
02975     }
02976 
02977     /* OPTIONAL key length */
02978     if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
02979         if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
02980             ERROR_OUT(ASN_PARSE_E, exit_tte);
02981         }
02982     }
02983 
02984     /* DEFAULT HMAC is SHA-1 */
02985     if (seqEnd > inOutIdx) {
02986         if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
02987             ERROR_OUT(ASN_PARSE_E, exit_tte);
02988         }
02989     }
02990 
02991 #ifdef WOLFSSL_SMALL_STACK
02992     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02993     if (cbcIv == NULL) {
02994         ERROR_OUT(MEMORY_E, exit_tte);
02995     }
02996 #endif
02997 
02998     if (version == PKCS5v2) {
02999         /* get encryption algo */
03000         if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
03001             ERROR_OUT(ASN_PARSE_E, exit_tte);
03002         }
03003 
03004         if (CheckAlgoV2(oid, &id) < 0) {
03005             ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */
03006         }
03007 
03008         ret = GetOctetString(input, &inOutIdx, &length, sz);
03009         if (ret < 0)
03010             goto exit_tte;
03011 
03012         if (length > MAX_IV_SIZE) {
03013             ERROR_OUT(ASN_PARSE_E, exit_tte);
03014         }
03015 
03016         XMEMCPY(cbcIv, &input[inOutIdx], length);
03017         inOutIdx += length;
03018     }
03019 
03020     ret = GetOctetString(input, &inOutIdx, &length, sz);
03021     if (ret < 0)
03022         goto exit_tte;
03023 
03024     ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
03025                    input + inOutIdx, length, version, cbcIv, 0);
03026 
03027 exit_tte:
03028 #ifdef WOLFSSL_SMALL_STACK
03029     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
03030     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03031 #endif
03032 
03033     if (ret == 0) {
03034         XMEMMOVE(input, input + inOutIdx, length);
03035         ret = ToTraditional(input, length);
03036     }
03037 
03038     return ret;
03039 }
03040 
03041 
03042 /* encrypt PKCS 12 content
03043  *
03044  * NOTE: if out is NULL then outSz is set with the total buffer size needed and
03045  *       the error value LENGTH_ONLY_E is returned.
03046  *
03047  * input      data to encrypt
03048  * inputSz    size of input buffer
03049  * out        buffer to hold the result
03050  * outSz      size of out buffer
03051  * password   password if used. Can be NULL for no password
03052  * passwordSz size of password buffer
03053  * vPKCS      version of PKCS i.e. PKCS5v2
03054  * vAlgo      algorithm version
03055  * salt       buffer holding salt if used. If NULL then a random salt is created
03056  * saltSz     size of salt buffer if it is not NULL
03057  * itt        number of iterations used
03058  * rng        random number generator to use
03059  * heap       possible heap hint for mallocs/frees
03060  *
03061  * returns the total size of encrypted content on success.
03062  */
03063 int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
03064         const char* password, int passwordSz, int vPKCS, int vAlgo,
03065         byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
03066 {
03067     word32 sz;
03068     word32 inOutIdx = 0;
03069     word32 tmpIdx   = 0;
03070     word32 totalSz  = 0;
03071     word32 seqSz;
03072     int    ret;
03073     int    version, id;
03074 #ifdef WOLFSSL_SMALL_STACK
03075     byte*  saltTmp = NULL;
03076     byte*  cbcIv   = NULL;
03077 #else
03078     byte   saltTmp[MAX_SALT_SIZE];
03079     byte   cbcIv[MAX_IV_SIZE];
03080 #endif
03081 
03082     (void)heap;
03083 
03084     WOLFSSL_ENTER("EncryptContent()");
03085 
03086     if (CheckAlgo(vPKCS, vAlgo, &id, &version) < 0)
03087         return ASN_INPUT_E;  /* Algo ID error */
03088 
03089     if (version == PKCS5v2) {
03090         WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
03091         return BAD_FUNC_ARG;
03092     }
03093 
03094     if (saltSz > MAX_SALT_SIZE)
03095         return ASN_PARSE_E;
03096 
03097     if (outSz == NULL) {
03098         return BAD_FUNC_ARG;
03099     }
03100 
03101     if (out == NULL) {
03102         sz = inputSz;
03103         switch (id) {
03104         #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA))
03105             case PBE_MD5_DES:
03106             case PBE_SHA1_DES:
03107             case PBE_SHA1_DES3:
03108                 /* set to block size of 8 for DES operations. This rounds up
03109                  * to the nearset multiple of 8 */
03110                 sz &= 0xfffffff8;
03111                 sz += 8;
03112                 break;
03113         #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */
03114         #if !defined(NO_RC4) && !defined(NO_SHA)
03115             case PBE_SHA1_RC4_128:
03116                 break;
03117         #endif
03118             case -1:
03119                 break;
03120 
03121             default:
03122                 return ALGO_ID_E;
03123         }
03124 
03125         if (saltSz <= 0) {
03126             sz += MAX_SALT_SIZE;
03127         }
03128         else {
03129             sz += saltSz;
03130         }
03131 
03132         /* add 2 for tags */
03133         *outSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
03134             MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2;
03135 
03136         return LENGTH_ONLY_E;
03137     }
03138 
03139     if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz)
03140         return BUFFER_E;
03141 
03142     sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0);
03143     inOutIdx += sz; totalSz += sz;
03144     tmpIdx = inOutIdx;
03145     tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */
03146     out[tmpIdx++] = ASN_OCTET_STRING;
03147 
03148     /* create random salt if one not provided */
03149     if (salt == NULL || saltSz <= 0) {
03150         saltSz = 8;
03151     #ifdef WOLFSSL_SMALL_STACK
03152         saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
03153         if (saltTmp == NULL)
03154             return MEMORY_E;
03155     #endif
03156         salt = saltTmp;
03157 
03158         if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
03159             WOLFSSL_MSG("Error generating random salt");
03160         #ifdef WOLFSSL_SMALL_STACK
03161             XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03162         #endif
03163             return ret;
03164         }
03165     }
03166 
03167     if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) {
03168     #ifdef WOLFSSL_SMALL_STACK
03169         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03170     #endif
03171         return BUFFER_E;
03172     }
03173 
03174     sz = SetLength(saltSz, out + tmpIdx);
03175     tmpIdx += sz;
03176 
03177     XMEMCPY(out + tmpIdx, salt, saltSz);
03178     tmpIdx += saltSz;
03179 
03180     /* place itteration setting in buffer */
03181     ret = SetShortInt(out, &tmpIdx, itt, *outSz);
03182     if (ret < 0) {
03183     #ifdef WOLFSSL_SMALL_STACK
03184         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03185     #endif
03186         return ret;
03187     }
03188 
03189     /* rewind and place sequence */
03190     sz = tmpIdx - inOutIdx - MAX_SEQ_SZ;
03191     seqSz = SetSequence(sz, out + inOutIdx);
03192     XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz);
03193     inOutIdx += seqSz; totalSz += seqSz;
03194     inOutIdx += sz; totalSz += sz;
03195 
03196 #ifdef WOLFSSL_SMALL_STACK
03197     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
03198     if (cbcIv == NULL) {
03199         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03200         return MEMORY_E;
03201     }
03202 #endif
03203 
03204     if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
03205                    input, inputSz, version, cbcIv, 1)) < 0) {
03206 
03207     #ifdef WOLFSSL_SMALL_STACK
03208         XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
03209         XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03210     #endif
03211         return ret;  /* encrypt failure */
03212     }
03213 
03214 #ifdef WOLFSSL_SMALL_STACK
03215     XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
03216     XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
03217 #endif
03218 
03219     if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)
03220         return BUFFER_E;
03221 
03222     out[inOutIdx++] = ASN_LONG_LENGTH; totalSz++;
03223     sz = SetLength(inputSz, out + inOutIdx);
03224     inOutIdx += sz; totalSz += sz;
03225     XMEMCPY(out + inOutIdx, input, inputSz);
03226     totalSz += inputSz;
03227 
03228     return totalSz;
03229 }
03230 
03231 
03232 /* decrypt PKCS
03233  *
03234  * NOTE: input buffer is overwritten with decrypted data!
03235  *
03236  * input[in/out] data to decrypt and results are written to
03237  * sz            size of input buffer
03238  * password      password if used. Can be NULL for no password
03239  * passwordSz    size of password buffer
03240  *
03241  * returns the total size of decrypted content on success.
03242  */
03243 int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
03244 {
03245     word32 inOutIdx = 0, seqEnd, oid;
03246     int    ret = 0;
03247     int    first, second, length = 0, version, saltSz, id;
03248     int    iterations = 0, keySz = 0;
03249 #ifdef WOLFSSL_SMALL_STACK
03250     byte*  salt = NULL;
03251     byte*  cbcIv = NULL;
03252 #else
03253     byte   salt[MAX_SALT_SIZE];
03254     byte   cbcIv[MAX_IV_SIZE];
03255 #endif
03256 
03257     if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
03258         ERROR_OUT(ASN_PARSE_E, exit_dc);
03259     }
03260 
03261     first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
03262     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
03263 
03264     if (CheckAlgo(first, second, &id, &version) < 0) {
03265         ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
03266     }
03267 
03268     if (version == PKCS5v2) {
03269         if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
03270             ERROR_OUT(ASN_PARSE_E, exit_dc);
03271         }
03272 
03273         if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
03274             ERROR_OUT(ASN_PARSE_E, exit_dc);
03275         }
03276 
03277         if (oid != PBKDF2_OID) {
03278             ERROR_OUT(ASN_PARSE_E, exit_dc);
03279         }
03280     }
03281 
03282     if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
03283         ERROR_OUT(ASN_PARSE_E, exit_dc);
03284     }
03285     /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
03286      * DEFAULT items. */
03287     seqEnd = inOutIdx + length;
03288 
03289     ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
03290     if (ret < 0)
03291         goto exit_dc;
03292 
03293     if (saltSz > MAX_SALT_SIZE) {
03294         ERROR_OUT(ASN_PARSE_E, exit_dc);
03295     }
03296 
03297 #ifdef WOLFSSL_SMALL_STACK
03298     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03299     if (salt == NULL) {
03300         ERROR_OUT(MEMORY_E, exit_dc);
03301     }
03302 #endif
03303 
03304     XMEMCPY(salt, &input[inOutIdx], saltSz);
03305     inOutIdx += saltSz;
03306 
03307     if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
03308         ERROR_OUT(ASN_PARSE_E, exit_dc);
03309     }
03310 
03311     /* OPTIONAL key length */
03312     if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
03313         if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
03314             ERROR_OUT(ASN_PARSE_E, exit_dc);
03315         }
03316     }
03317 
03318     /* DEFAULT HMAC is SHA-1 */
03319     if (seqEnd > inOutIdx) {
03320         if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
03321             ERROR_OUT(ASN_PARSE_E, exit_dc);
03322         }
03323     }
03324 
03325 #ifdef WOLFSSL_SMALL_STACK
03326     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03327     if (cbcIv == NULL) {
03328         ERROR_OUT(MEMORY_E, exit_dc);
03329     }
03330 #endif
03331 
03332     if (version == PKCS5v2) {
03333         /* get encryption algo */
03334         if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
03335             ERROR_OUT(ASN_PARSE_E, exit_dc);
03336         }
03337 
03338         if (CheckAlgoV2(oid, &id) < 0) {
03339             ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
03340         }
03341 
03342         ret = GetOctetString(input, &inOutIdx, &length, sz);
03343         if (ret < 0)
03344             goto exit_dc;
03345 
03346         if (length > MAX_IV_SIZE) {
03347             ERROR_OUT(ASN_PARSE_E, exit_dc);
03348         }
03349 
03350         XMEMCPY(cbcIv, &input[inOutIdx], length);
03351         inOutIdx += length;
03352     }
03353 
03354     if (input[inOutIdx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
03355         ERROR_OUT(ASN_PARSE_E, exit_dc);
03356     }
03357 
03358     if (GetLength(input, &inOutIdx, &length, sz) < 0) {
03359         ERROR_OUT(ASN_PARSE_E, exit_dc);
03360     }
03361 
03362     ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
03363                    input + inOutIdx, length, version, cbcIv, 0);
03364 
03365 exit_dc:
03366 
03367 #ifdef WOLFSSL_SMALL_STACK
03368     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
03369     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03370 #endif
03371 
03372     if (ret == 0) {
03373         XMEMMOVE(input, input + inOutIdx, length);
03374         ret = length;
03375     }
03376 
03377     return ret;
03378 }
03379 #endif /* NO_PWDBASED */
03380 
03381 #ifndef NO_RSA
03382 
03383 #ifndef HAVE_USER_RSA
03384 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
03385                        word32 inSz)
03386 {
03387     int  length;
03388 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
03389     byte b;
03390 #endif
03391     int ret;
03392 
03393     if (input == NULL || inOutIdx == NULL || key == NULL)
03394         return BAD_FUNC_ARG;
03395 
03396     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03397         return ASN_PARSE_E;
03398 
03399     key->type = RSA_PUBLIC;
03400 
03401 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
03402     if ((*inOutIdx + 1) > inSz)
03403         return BUFFER_E;
03404 
03405     b = input[*inOutIdx];
03406     if (b != ASN_INTEGER) {
03407         /* not from decoded cert, will have algo id, skip past */
03408         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03409             return ASN_PARSE_E;
03410 
03411         if (SkipObjectId(input, inOutIdx, inSz) < 0)
03412             return ASN_PARSE_E;
03413 
03414         /* Option NULL ASN.1 tag */
03415         if (*inOutIdx  >= inSz) {
03416             return BUFFER_E;
03417         }
03418         if (input[*inOutIdx] == ASN_TAG_NULL) {
03419             ret = GetASNNull(input, inOutIdx, inSz);
03420             if (ret != 0)
03421                 return ret;
03422         }
03423 
03424         /* should have bit tag length and seq next */
03425         ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
03426         if (ret != 0)
03427             return ret;
03428 
03429         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03430             return ASN_PARSE_E;
03431     }
03432 #endif /* OPENSSL_EXTRA */
03433 
03434     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0)
03435         return ASN_RSA_KEY_E;
03436     if (GetInt(&key->e,  input, inOutIdx, inSz) < 0) {
03437         mp_clear(&key->n);
03438         return ASN_RSA_KEY_E;
03439     }
03440 
03441 #ifdef WOLFSSL_XILINX_CRYPT
03442     if (wc_InitRsaHw(key) != 0) {
03443         return BAD_STATE_E;
03444     }
03445 #endif
03446 
03447     return 0;
03448 }
03449 
03450 /* import RSA public key elements (n, e) into RsaKey structure (key) */
03451 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
03452                              word32 eSz, RsaKey* key)
03453 {
03454     if (n == NULL || e == NULL || key == NULL)
03455         return BAD_FUNC_ARG;
03456 
03457     key->type = RSA_PUBLIC;
03458 
03459     if (mp_init(&key->n) != MP_OKAY)
03460         return MP_INIT_E;
03461 
03462     if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
03463         mp_clear(&key->n);
03464         return ASN_GETINT_E;
03465     }
03466 
03467     if (mp_init(&key->e) != MP_OKAY) {
03468         mp_clear(&key->n);
03469         return MP_INIT_E;
03470     }
03471 
03472     if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
03473         mp_clear(&key->n);
03474         mp_clear(&key->e);
03475         return ASN_GETINT_E;
03476     }
03477 
03478 #ifdef WOLFSSL_XILINX_CRYPT
03479     if (wc_InitRsaHw(key) != 0) {
03480         return BAD_STATE_E;
03481     }
03482 #endif
03483 
03484     return 0;
03485 }
03486 #endif /* HAVE_USER_RSA */
03487 #endif
03488 
03489 #ifndef NO_DH
03490 
03491 int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
03492 {
03493     int    length;
03494 
03495     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03496         return ASN_PARSE_E;
03497 
03498     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
03499         GetInt(&key->g,  input, inOutIdx, inSz) < 0) {
03500         return ASN_DH_KEY_E;
03501     }
03502 
03503     return 0;
03504 }
03505 
03506 
03507 int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
03508                  byte* g, word32* gInOutSz)
03509 {
03510     word32 idx = 0;
03511     int    ret;
03512     int    length;
03513 
03514     if (GetSequence(input, &idx, &length, inSz) <= 0)
03515         return ASN_PARSE_E;
03516 
03517     ret = GetASNInt(input, &idx, &length, inSz);
03518     if (ret != 0)
03519         return ret;
03520 
03521     if (length <= (int)*pInOutSz) {
03522         XMEMCPY(p, &input[idx], length);
03523         *pInOutSz = length;
03524     }
03525     else {
03526         return BUFFER_E;
03527     }
03528     idx += length;
03529 
03530     ret = GetASNInt(input, &idx, &length, inSz);
03531     if (ret != 0)
03532         return ret;
03533 
03534     if (length <= (int)*gInOutSz) {
03535         XMEMCPY(g, &input[idx], length);
03536         *gInOutSz = length;
03537     }
03538     else {
03539         return BUFFER_E;
03540     }
03541 
03542     return 0;
03543 }
03544 
03545 #endif /* NO_DH */
03546 
03547 
03548 #ifndef NO_DSA
03549 
03550 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
03551                         word32 inSz)
03552 {
03553     int    length;
03554 
03555     if (input == NULL || inOutIdx == NULL || key == NULL) {
03556         return BAD_FUNC_ARG;
03557     }
03558 
03559     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03560         return ASN_PARSE_E;
03561 
03562     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
03563         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
03564         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
03565         GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
03566         return ASN_DH_KEY_E;
03567 
03568     key->type = DSA_PUBLIC;
03569     return 0;
03570 }
03571 
03572 
03573 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
03574                         word32 inSz)
03575 {
03576     int    length, version;
03577 
03578     /* Sanity checks on input */
03579     if (input == NULL || inOutIdx == NULL || key == NULL) {
03580         return BAD_FUNC_ARG;
03581     }
03582 
03583     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
03584         return ASN_PARSE_E;
03585 
03586     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
03587         return ASN_PARSE_E;
03588 
03589     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
03590         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
03591         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
03592         GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
03593         GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
03594         return ASN_DH_KEY_E;
03595 
03596     key->type = DSA_PRIVATE;
03597     return 0;
03598 }
03599 
03600 static mp_int* GetDsaInt(DsaKey* key, int idx)
03601 {
03602     if (idx == 0)
03603         return &key->p;
03604     if (idx == 1)
03605         return &key->q;
03606     if (idx == 2)
03607         return &key->g;
03608     if (idx == 3)
03609         return &key->y;
03610     if (idx == 4)
03611         return &key->x;
03612 
03613     return NULL;
03614 }
03615 
03616 /* Release Tmp DSA resources */
03617 static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
03618 {
03619     int i;
03620 
03621     for (i = 0; i < DSA_INTS; i++)
03622         XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
03623 
03624     (void)heap;
03625 }
03626 
03627 /* Convert DsaKey key to DER format, write to output (inLen), return bytes
03628  written */
03629 int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
03630 {
03631     word32 seqSz, verSz, rawLen, intTotalLen = 0;
03632     word32 sizes[DSA_INTS];
03633     int    i, j, outLen, ret = 0, mpSz;
03634 
03635     byte  seq[MAX_SEQ_SZ];
03636     byte  ver[MAX_VERSION_SZ];
03637     byte* tmps[DSA_INTS];
03638 
03639     if (!key || !output)
03640         return BAD_FUNC_ARG;
03641 
03642     if (key->type != DSA_PRIVATE)
03643         return BAD_FUNC_ARG;
03644 
03645     for (i = 0; i < DSA_INTS; i++)
03646         tmps[i] = NULL;
03647 
03648     /* write all big ints from key to DER tmps */
03649     for (i = 0; i < DSA_INTS; i++) {
03650         mp_int* keyInt = GetDsaInt(key, i);
03651 
03652         rawLen = mp_unsigned_bin_size(keyInt) + 1;
03653         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
03654                                                               DYNAMIC_TYPE_DSA);
03655         if (tmps[i] == NULL) {
03656             ret = MEMORY_E;
03657             break;
03658         }
03659 
03660         mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
03661         if (mpSz < 0) {
03662             ret = mpSz;
03663             break;
03664         }
03665         intTotalLen += (sizes[i] = mpSz);
03666     }
03667 
03668     if (ret != 0) {
03669         FreeTmpDsas(tmps, key->heap);
03670         return ret;
03671     }
03672 
03673     /* make headers */
03674     verSz = SetMyVersion(0, ver, FALSE);
03675     seqSz = SetSequence(verSz + intTotalLen, seq);
03676 
03677     outLen = seqSz + verSz + intTotalLen;
03678     if (outLen > (int)inLen)
03679         return BAD_FUNC_ARG;
03680 
03681     /* write to output */
03682     XMEMCPY(output, seq, seqSz);
03683     j = seqSz;
03684     XMEMCPY(output + j, ver, verSz);
03685     j += verSz;
03686 
03687     for (i = 0; i < DSA_INTS; i++) {
03688         XMEMCPY(output + j, tmps[i], sizes[i]);
03689         j += sizes[i];
03690     }
03691     FreeTmpDsas(tmps, key->heap);
03692 
03693     return outLen;
03694 }
03695 
03696 #endif /* NO_DSA */
03697 
03698 
03699 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
03700 {
03701     if (cert != NULL) {
03702         XMEMSET(cert, 0, sizeof(DecodedCert));
03703 
03704         cert->subjectCNEnc    = CTC_UTF8;
03705         cert->issuer[0]       = '\0';
03706         cert->subject[0]      = '\0';
03707         cert->source          = source;  /* don't own */
03708         cert->maxIdx          = inSz;    /* can't go over this index */
03709         cert->heap            = heap;
03710     #ifdef WOLFSSL_CERT_GEN
03711         cert->subjectSNEnc    = CTC_UTF8;
03712         cert->subjectCEnc     = CTC_PRINTABLE;
03713         cert->subjectLEnc     = CTC_UTF8;
03714         cert->subjectSTEnc    = CTC_UTF8;
03715         cert->subjectOEnc     = CTC_UTF8;
03716         cert->subjectOUEnc    = CTC_UTF8;
03717     #endif /* WOLFSSL_CERT_GEN */
03718 
03719         InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
03720     }
03721 }
03722 
03723 
03724 void FreeAltNames(DNS_entry* altNames, void* heap)
03725 {
03726     (void)heap;
03727 
03728     while (altNames) {
03729         DNS_entry* tmp = altNames->next;
03730 
03731         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
03732         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
03733         altNames = tmp;
03734     }
03735 }
03736 
03737 #ifndef IGNORE_NAME_CONSTRAINTS
03738 
03739 void FreeNameSubtrees(Base_entry* names, void* heap)
03740 {
03741     (void)heap;
03742 
03743     while (names) {
03744         Base_entry* tmp = names->next;
03745 
03746         XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
03747         XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
03748         names = tmp;
03749     }
03750 }
03751 
03752 #endif /* IGNORE_NAME_CONSTRAINTS */
03753 
03754 void FreeDecodedCert(DecodedCert* cert)
03755 {
03756     if (cert->subjectCNStored == 1)
03757         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
03758     if (cert->pubKeyStored == 1)
03759         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
03760     if (cert->weOwnAltNames && cert->altNames)
03761         FreeAltNames(cert->altNames, cert->heap);
03762 #ifndef IGNORE_NAME_CONSTRAINTS
03763     if (cert->altEmailNames)
03764         FreeAltNames(cert->altEmailNames, cert->heap);
03765     if (cert->permittedNames)
03766         FreeNameSubtrees(cert->permittedNames, cert->heap);
03767     if (cert->excludedNames)
03768         FreeNameSubtrees(cert->excludedNames, cert->heap);
03769 #endif /* IGNORE_NAME_CONSTRAINTS */
03770 #ifdef WOLFSSL_SEP
03771     XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
03772     XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
03773     XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
03774 #endif /* WOLFSSL_SEP */
03775 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
03776     if (cert->issuerName.fullName != NULL)
03777         XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
03778     if (cert->subjectName.fullName != NULL)
03779         XFREE(cert->subjectName.fullName, cert->heap, DYNAMIC_TYPE_X509);
03780 #endif /* OPENSSL_EXTRA */
03781     FreeSignatureCtx(&cert->sigCtx);
03782 }
03783 
03784 static int GetCertHeader(DecodedCert* cert)
03785 {
03786     int ret = 0, len;
03787 
03788     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
03789         return ASN_PARSE_E;
03790 
03791     cert->certBegin = cert->srcIdx;
03792 
03793     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
03794         return ASN_PARSE_E;
03795     cert->sigIndex = len + cert->srcIdx;
03796 
03797     if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
03798                                                               cert->maxIdx) < 0)
03799         return ASN_PARSE_E;
03800 
03801     if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
03802                                         &cert->serialSz, cert->maxIdx) < 0)
03803         return ASN_PARSE_E;
03804 
03805     return ret;
03806 }
03807 
03808 #if !defined(NO_RSA)
03809 /* Store Rsa Key, may save later, Dsa could use in future */
03810 static int StoreRsaKey(DecodedCert* cert)
03811 {
03812     int    length;
03813     word32 recvd = cert->srcIdx;
03814 
03815     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
03816         return ASN_PARSE_E;
03817 
03818     recvd = cert->srcIdx - recvd;
03819     length += recvd;
03820 
03821     while (recvd--)
03822        cert->srcIdx--;
03823 
03824     cert->pubKeySize = length;
03825     cert->publicKey = cert->source + cert->srcIdx;
03826     cert->srcIdx += length;
03827 
03828     return 0;
03829 }
03830 #endif /* !NO_RSA */
03831 
03832 #ifdef HAVE_ECC
03833 
03834     /* return 0 on success if the ECC curve oid sum is supported */
03835     static int CheckCurve(word32 oid)
03836     {
03837         int ret = 0;
03838         word32 oidSz = 0;
03839 
03840         ret = wc_ecc_get_oid(oid, NULL, &oidSz);
03841         if (ret < 0 || oidSz <= 0) {
03842             WOLFSSL_MSG("CheckCurve not found");
03843             ret = ALGO_ID_E;
03844         }
03845 
03846         return ret;
03847     }
03848 
03849 #endif /* HAVE_ECC */
03850 
03851 static int GetKey(DecodedCert* cert)
03852 {
03853     int length;
03854 #if defined(HAVE_ECC) || defined(HAVE_NTRU)
03855     int tmpIdx = cert->srcIdx;
03856 #endif
03857 
03858     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
03859         return ASN_PARSE_E;
03860 
03861     if (GetAlgoId(cert->source, &cert->srcIdx,
03862                   &cert->keyOID, oidKeyType, cert->maxIdx) < 0)
03863         return ASN_PARSE_E;
03864 
03865     switch (cert->keyOID) {
03866    #ifndef NO_RSA
03867         case RSAk:
03868         {
03869             int ret;
03870             ret = CheckBitString(cert->source, &cert->srcIdx, NULL,
03871                                  cert->maxIdx, 1, NULL);
03872             if (ret != 0)
03873                 return ret;
03874 
03875             return StoreRsaKey(cert);
03876         }
03877 
03878     #endif /* NO_RSA */
03879     #ifdef HAVE_NTRU
03880         case NTRUk:
03881         {
03882             const byte* key = &cert->source[tmpIdx];
03883             byte*       next = (byte*)key;
03884             word16      keyLen;
03885             word32      rc;
03886             word32      remaining = cert->maxIdx - cert->srcIdx;
03887 #ifdef WOLFSSL_SMALL_STACK
03888             byte*       keyBlob = NULL;
03889 #else
03890             byte        keyBlob[MAX_NTRU_KEY_SZ];
03891 #endif
03892             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
03893                                 &keyLen, NULL, &next, &remaining);
03894             if (rc != NTRU_OK)
03895                 return ASN_NTRU_KEY_E;
03896             if (keyLen > MAX_NTRU_KEY_SZ)
03897                 return ASN_NTRU_KEY_E;
03898 
03899 #ifdef WOLFSSL_SMALL_STACK
03900             keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,
03901                                      DYNAMIC_TYPE_TMP_BUFFER);
03902             if (keyBlob == NULL)
03903                 return MEMORY_E;
03904 #endif
03905 
03906             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
03907                                 &keyLen, keyBlob, &next, &remaining);
03908             if (rc != NTRU_OK) {
03909 #ifdef WOLFSSL_SMALL_STACK
03910                 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
03911 #endif
03912                 return ASN_NTRU_KEY_E;
03913             }
03914 
03915             if ( (next - key) < 0) {
03916 #ifdef WOLFSSL_SMALL_STACK
03917                 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
03918 #endif
03919                 return ASN_NTRU_KEY_E;
03920             }
03921 
03922             cert->srcIdx = tmpIdx + (int)(next - key);
03923 
03924             cert->publicKey = (byte*)XMALLOC(keyLen, cert->heap,
03925                                              DYNAMIC_TYPE_PUBLIC_KEY);
03926             if (cert->publicKey == NULL) {
03927 #ifdef WOLFSSL_SMALL_STACK
03928                 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
03929 #endif
03930                 return MEMORY_E;
03931             }
03932             XMEMCPY(cert->publicKey, keyBlob, keyLen);
03933             cert->pubKeyStored = 1;
03934             cert->pubKeySize   = keyLen;
03935 
03936 #ifdef WOLFSSL_SMALL_STACK
03937             XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
03938 #endif
03939 
03940             return 0;
03941         }
03942     #endif /* HAVE_NTRU */
03943     #ifdef HAVE_ECC
03944         case ECDSAk:
03945         {
03946             int ret;
03947             byte seq[5];
03948             int pubLen = length + 1 + SetLength(length, seq);
03949 
03950             if (cert->source[cert->srcIdx] !=
03951                                              (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
03952                 if (GetObjectId(cert->source, &cert->srcIdx,
03953                             &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
03954                     return ASN_PARSE_E;
03955 
03956                 if (CheckCurve(cert->pkCurveOID) < 0)
03957                     return ECC_CURVE_OID_E;
03958 
03959                 /* key header */
03960                 ret = CheckBitString(cert->source, &cert->srcIdx, &length,
03961                                                          cert->maxIdx, 1, NULL);
03962                 if (ret != 0)
03963                     return ret;
03964             }
03965 
03966             cert->publicKey = (byte*)XMALLOC(pubLen, cert->heap,
03967                                              DYNAMIC_TYPE_PUBLIC_KEY);
03968             if (cert->publicKey == NULL)
03969                 return MEMORY_E;
03970             XMEMCPY(cert->publicKey, &cert->source[tmpIdx], pubLen);
03971             cert->pubKeyStored = 1;
03972             cert->pubKeySize   = pubLen;
03973 
03974             cert->srcIdx = tmpIdx + pubLen;
03975 
03976             return 0;
03977         }
03978     #endif /* HAVE_ECC */
03979     #ifdef HAVE_ED25519
03980         case ED25519k:
03981         {
03982             int ret;
03983 
03984             cert->pkCurveOID = ED25519k;
03985 
03986             ret = CheckBitString(cert->source, &cert->srcIdx, &length,
03987                                  cert->maxIdx, 1, NULL);
03988             if (ret != 0)
03989                 return ret;
03990 
03991             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
03992                                               DYNAMIC_TYPE_PUBLIC_KEY);
03993             if (cert->publicKey == NULL)
03994                 return MEMORY_E;
03995             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
03996             cert->pubKeyStored = 1;
03997             cert->pubKeySize   = length;
03998 
03999             cert->srcIdx += length;
04000 
04001             return 0;
04002         }
04003     #endif /* HAVE_ED25519 */
04004         default:
04005             return ASN_UNKNOWN_OID_E;
04006     }
04007 }
04008 
04009 /* process NAME, either issuer or subject */
04010 static int GetName(DecodedCert* cert, int nameType)
04011 {
04012     int    length;  /* length of all distinguished names */
04013     int    dummy;
04014     int    ret;
04015     char*  full;
04016     byte*  hash;
04017     word32 idx;
04018     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04019         DecodedName* dName =
04020                   (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
04021         int dcnum = 0;
04022     #endif /* OPENSSL_EXTRA */
04023 
04024     WOLFSSL_MSG("Getting Cert Name");
04025 
04026     if (nameType == ISSUER) {
04027         full = cert->issuer;
04028         hash = cert->issuerHash;
04029     }
04030     else {
04031         full = cert->subject;
04032         hash = cert->subjectHash;
04033     }
04034 
04035     if (cert->srcIdx >= cert->maxIdx) {
04036         return BUFFER_E;
04037     }
04038 
04039     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
04040         WOLFSSL_MSG("Trying optional prefix...");
04041 
04042         if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0)
04043             return ASN_PARSE_E;
04044         WOLFSSL_MSG("Got optional prefix");
04045     }
04046 
04047     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
04048      * calculated over the entire DER encoding of the Name field, including
04049      * the tag and length. */
04050     idx = cert->srcIdx;
04051     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
04052         return ASN_PARSE_E;
04053 
04054 #ifdef NO_SHA
04055     ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
04056 #else
04057     ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
04058 #endif
04059     if (ret != 0)
04060         return ret;
04061 
04062     length += cert->srcIdx;
04063     idx = 0;
04064 
04065 #ifdef HAVE_PKCS7
04066     /* store pointer to raw issuer */
04067     if (nameType == ISSUER) {
04068         cert->issuerRaw = &cert->source[cert->srcIdx];
04069         cert->issuerRawLen = length - cert->srcIdx;
04070     }
04071 #endif
04072 #ifndef IGNORE_NAME_CONSTRAINTS
04073     if (nameType == SUBJECT) {
04074         cert->subjectRaw = &cert->source[cert->srcIdx];
04075         cert->subjectRawLen = length - cert->srcIdx;
04076     }
04077 #endif
04078 
04079     while (cert->srcIdx < (word32)length) {
04080         byte   b;
04081         byte   joint[2];
04082         byte   tooBig = FALSE;
04083         int    oidSz;
04084 
04085         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
04086             WOLFSSL_MSG("Cert name lacks set header, trying sequence");
04087         }
04088 
04089         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) <= 0)
04090             return ASN_PARSE_E;
04091 
04092         ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx);
04093         if (ret != 0)
04094             return ret;
04095 
04096         /* make sure there is room for joint */
04097         if ((cert->srcIdx + sizeof(joint)) > cert->maxIdx)
04098             return ASN_PARSE_E;
04099 
04100         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
04101 
04102         /* v1 name types */
04103         if (joint[0] == 0x55 && joint[1] == 0x04) {
04104             const char*  copy = NULL;
04105             int    strLen;
04106             byte   id;
04107 
04108             cert->srcIdx += 2;
04109             id = cert->source[cert->srcIdx++];
04110             b  = cert->source[cert->srcIdx++]; /* encoding */
04111 
04112             if (GetLength(cert->source, &cert->srcIdx, &strLen,
04113                           cert->maxIdx) < 0)
04114                 return ASN_PARSE_E;
04115 
04116             if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
04117                 /* include biggest pre fix header too 4 = "/serialNumber=" */
04118                 WOLFSSL_MSG("ASN Name too big, skipping");
04119                 tooBig = TRUE;
04120             }
04121 
04122             if (id == ASN_COMMON_NAME) {
04123                 if (nameType == SUBJECT) {
04124                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
04125                     cert->subjectCNLen = strLen;
04126                     cert->subjectCNEnc = b;
04127                 }
04128 
04129                 copy = WOLFSSL_COMMON_NAME;
04130                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04131                     dName->cnIdx = cert->srcIdx;
04132                     dName->cnLen = strLen;
04133                 #endif /* OPENSSL_EXTRA */
04134             }
04135             else if (id == ASN_SUR_NAME) {
04136                 copy = WOLFSSL_SUR_NAME;
04137                 #ifdef WOLFSSL_CERT_GEN
04138                     if (nameType == SUBJECT) {
04139                         cert->subjectSN = (char*)&cert->source[cert->srcIdx];
04140                         cert->subjectSNLen = strLen;
04141                         cert->subjectSNEnc = b;
04142                     }
04143                 #endif /* WOLFSSL_CERT_GEN */
04144                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04145                     dName->snIdx = cert->srcIdx;
04146                     dName->snLen = strLen;
04147                 #endif /* OPENSSL_EXTRA */
04148             }
04149             else if (id == ASN_COUNTRY_NAME) {
04150                 copy = WOLFSSL_COUNTRY_NAME;
04151                 #ifdef WOLFSSL_CERT_GEN
04152                     if (nameType == SUBJECT) {
04153                         cert->subjectC = (char*)&cert->source[cert->srcIdx];
04154                         cert->subjectCLen = strLen;
04155                         cert->subjectCEnc = b;
04156                     }
04157                 #endif /* WOLFSSL_CERT_GEN */
04158                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04159                     dName->cIdx = cert->srcIdx;
04160                     dName->cLen = strLen;
04161                 #endif /* OPENSSL_EXTRA */
04162             }
04163             else if (id == ASN_LOCALITY_NAME) {
04164                 copy = WOLFSSL_LOCALITY_NAME;
04165                 #ifdef WOLFSSL_CERT_GEN
04166                     if (nameType == SUBJECT) {
04167                         cert->subjectL = (char*)&cert->source[cert->srcIdx];
04168                         cert->subjectLLen = strLen;
04169                         cert->subjectLEnc = b;
04170                     }
04171                 #endif /* WOLFSSL_CERT_GEN */
04172                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04173                     dName->lIdx = cert->srcIdx;
04174                     dName->lLen = strLen;
04175                 #endif /* OPENSSL_EXTRA */
04176             }
04177             else if (id == ASN_STATE_NAME) {
04178                 copy = WOLFSSL_STATE_NAME;
04179                 #ifdef WOLFSSL_CERT_GEN
04180                     if (nameType == SUBJECT) {
04181                         cert->subjectST = (char*)&cert->source[cert->srcIdx];
04182                         cert->subjectSTLen = strLen;
04183                         cert->subjectSTEnc = b;
04184                     }
04185                 #endif /* WOLFSSL_CERT_GEN */
04186                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04187                     dName->stIdx = cert->srcIdx;
04188                     dName->stLen = strLen;
04189                 #endif /* OPENSSL_EXTRA */
04190             }
04191             else if (id == ASN_ORG_NAME) {
04192                 copy = WOLFSSL_ORG_NAME;
04193                 #ifdef WOLFSSL_CERT_GEN
04194                     if (nameType == SUBJECT) {
04195                         cert->subjectO = (char*)&cert->source[cert->srcIdx];
04196                         cert->subjectOLen = strLen;
04197                         cert->subjectOEnc = b;
04198                     }
04199                 #endif /* WOLFSSL_CERT_GEN */
04200                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04201                     dName->oIdx = cert->srcIdx;
04202                     dName->oLen = strLen;
04203                 #endif /* OPENSSL_EXTRA */
04204             }
04205             else if (id == ASN_ORGUNIT_NAME) {
04206                 copy = WOLFSSL_ORGUNIT_NAME;
04207                 #ifdef WOLFSSL_CERT_GEN
04208                     if (nameType == SUBJECT) {
04209                         cert->subjectOU = (char*)&cert->source[cert->srcIdx];
04210                         cert->subjectOULen = strLen;
04211                         cert->subjectOUEnc = b;
04212                     }
04213                 #endif /* WOLFSSL_CERT_GEN */
04214                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04215                     dName->ouIdx = cert->srcIdx;
04216                     dName->ouLen = strLen;
04217                 #endif /* OPENSSL_EXTRA */
04218             }
04219             else if (id == ASN_SERIAL_NUMBER) {
04220                 copy = WOLFSSL_SERIAL_NUMBER;
04221                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04222                     dName->snIdx = cert->srcIdx;
04223                     dName->snLen = strLen;
04224                 #endif /* OPENSSL_EXTRA */
04225             }
04226             if (copy && !tooBig) {
04227                 XMEMCPY(&full[idx], copy, XSTRLEN(copy));
04228                 idx += (word32)XSTRLEN(copy);
04229             #ifdef WOLFSSL_WPAS
04230                 full[idx] = '=';
04231                 idx++;
04232             #endif
04233                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
04234                 idx += strLen;
04235             }
04236 
04237             cert->srcIdx += strLen;
04238         }
04239         else {
04240             /* skip */
04241             byte email = FALSE;
04242             byte pilot = FALSE;
04243             byte id    = 0;
04244             int  adv;
04245 
04246             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
04247                 email = TRUE;
04248 
04249             if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
04250                 /* last value of OID is the type of pilot attribute */
04251                 id    = cert->source[cert->srcIdx + oidSz - 1];
04252                 pilot = TRUE;
04253             }
04254 
04255             cert->srcIdx += oidSz + 1;
04256 
04257             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
04258                 return ASN_PARSE_E;
04259 
04260             if (adv > (int)(ASN_NAME_MAX - idx)) {
04261                 WOLFSSL_MSG("ASN name too big, skipping");
04262                 tooBig = TRUE;
04263             }
04264 
04265             if (email) {
04266                 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
04267                     WOLFSSL_MSG("ASN name too big, skipping");
04268                     tooBig = TRUE;
04269                 }
04270                 if (!tooBig) {
04271                     XMEMCPY(&full[idx], "/emailAddress=", 14);
04272                     idx += 14;
04273                 }
04274 
04275                 #ifdef WOLFSSL_CERT_GEN
04276                     if (nameType == SUBJECT) {
04277                         cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
04278                         cert->subjectEmailLen = adv;
04279                     }
04280                 #endif /* WOLFSSL_CERT_GEN */
04281                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04282                     dName->emailIdx = cert->srcIdx;
04283                     dName->emailLen = adv;
04284                 #endif /* OPENSSL_EXTRA */
04285                 #ifndef IGNORE_NAME_CONSTRAINTS
04286                     {
04287                         DNS_entry* emailName = NULL;
04288 
04289                         emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
04290                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
04291                         if (emailName == NULL) {
04292                             WOLFSSL_MSG("\tOut of Memory");
04293                             return MEMORY_E;
04294                         }
04295                         emailName->type = 0;
04296                         emailName->name = (char*)XMALLOC(adv + 1,
04297                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
04298                         if (emailName->name == NULL) {
04299                             WOLFSSL_MSG("\tOut of Memory");
04300                             XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
04301                             return MEMORY_E;
04302                         }
04303                         emailName->len = adv;
04304                         XMEMCPY(emailName->name,
04305                                               &cert->source[cert->srcIdx], adv);
04306                         emailName->name[adv] = '\0';
04307 
04308                         emailName->next = cert->altEmailNames;
04309                         cert->altEmailNames = emailName;
04310                     }
04311                 #endif /* IGNORE_NAME_CONSTRAINTS */
04312                 if (!tooBig) {
04313                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
04314                     idx += adv;
04315                 }
04316             }
04317 
04318             if (pilot) {
04319                 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
04320                     WOLFSSL_MSG("ASN name too big, skipping");
04321                     tooBig = TRUE;
04322                 }
04323                 if (!tooBig) {
04324                     switch (id) {
04325                         case ASN_USER_ID:
04326                             XMEMCPY(&full[idx], "/UID=", 5);
04327                             idx += 5;
04328                         #if defined(OPENSSL_EXTRA) || \
04329                             defined(OPENSSL_EXTRA_X509_SMALL)
04330                             dName->uidIdx = cert->srcIdx;
04331                             dName->uidLen = adv;
04332                         #endif /* OPENSSL_EXTRA */
04333                             break;
04334 
04335                         case ASN_DOMAIN_COMPONENT:
04336                             XMEMCPY(&full[idx], "/DC=", 4);
04337                             idx += 4;
04338                         #if defined(OPENSSL_EXTRA) || \
04339                             defined(OPENSSL_EXTRA_X509_SMALL)
04340                             dName->dcIdx[dcnum] = cert->srcIdx;
04341                             dName->dcLen[dcnum] = adv;
04342                             dName->dcNum = dcnum + 1;
04343                             dcnum++;
04344                         #endif /* OPENSSL_EXTRA */
04345                             break;
04346 
04347                         default:
04348                             WOLFSSL_MSG("Unknown pilot attribute type");
04349                             return ASN_PARSE_E;
04350                     }
04351                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
04352                     idx += adv;
04353                 }
04354             }
04355 
04356             cert->srcIdx += adv;
04357         }
04358     }
04359     full[idx++] = 0;
04360 
04361     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
04362     {
04363         int totalLen = 0;
04364         int i = 0;
04365 
04366         if (dName->cnLen != 0)
04367             totalLen += dName->cnLen + 4;
04368         if (dName->snLen != 0)
04369             totalLen += dName->snLen + 4;
04370         if (dName->cLen != 0)
04371             totalLen += dName->cLen + 3;
04372         if (dName->lLen != 0)
04373             totalLen += dName->lLen + 3;
04374         if (dName->stLen != 0)
04375             totalLen += dName->stLen + 4;
04376         if (dName->oLen != 0)
04377             totalLen += dName->oLen + 3;
04378         if (dName->ouLen != 0)
04379             totalLen += dName->ouLen + 4;
04380         if (dName->emailLen != 0)
04381             totalLen += dName->emailLen + 14;
04382         if (dName->uidLen != 0)
04383             totalLen += dName->uidLen + 5;
04384         if (dName->serialLen != 0)
04385             totalLen += dName->serialLen + 14;
04386         if (dName->dcNum != 0){
04387             for (i = 0;i < dName->dcNum;i++)
04388                 totalLen += dName->dcLen[i] + 4;
04389         }
04390 
04391         dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
04392                                                              DYNAMIC_TYPE_X509);
04393         if (dName->fullName != NULL) {
04394             idx = 0;
04395 
04396             if (dName->cnLen != 0) {
04397                 dName->entryCount++;
04398                 XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);
04399                 idx += 4;
04400                 XMEMCPY(&dName->fullName[idx],
04401                                      &cert->source[dName->cnIdx], dName->cnLen);
04402                 dName->cnIdx = idx;
04403                 idx += dName->cnLen;
04404             }
04405             if (dName->snLen != 0) {
04406                 dName->entryCount++;
04407                 XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);
04408                 idx += 4;
04409                 XMEMCPY(&dName->fullName[idx],
04410                                      &cert->source[dName->snIdx], dName->snLen);
04411                 dName->snIdx = idx;
04412                 idx += dName->snLen;
04413             }
04414             if (dName->cLen != 0) {
04415                 dName->entryCount++;
04416                 XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);
04417                 idx += 3;
04418                 XMEMCPY(&dName->fullName[idx],
04419                                        &cert->source[dName->cIdx], dName->cLen);
04420                 dName->cIdx = idx;
04421                 idx += dName->cLen;
04422             }
04423             if (dName->lLen != 0) {
04424                 dName->entryCount++;
04425                 XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);
04426                 idx += 3;
04427                 XMEMCPY(&dName->fullName[idx],
04428                                        &cert->source[dName->lIdx], dName->lLen);
04429                 dName->lIdx = idx;
04430                 idx += dName->lLen;
04431             }
04432             if (dName->stLen != 0) {
04433                 dName->entryCount++;
04434                 XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);
04435                 idx += 4;
04436                 XMEMCPY(&dName->fullName[idx],
04437                                      &cert->source[dName->stIdx], dName->stLen);
04438                 dName->stIdx = idx;
04439                 idx += dName->stLen;
04440             }
04441             if (dName->oLen != 0) {
04442                 dName->entryCount++;
04443                 XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);
04444                 idx += 3;
04445                 XMEMCPY(&dName->fullName[idx],
04446                                        &cert->source[dName->oIdx], dName->oLen);
04447                 dName->oIdx = idx;
04448                 idx += dName->oLen;
04449             }
04450             if (dName->ouLen != 0) {
04451                 dName->entryCount++;
04452                 XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);
04453                 idx += 4;
04454                 XMEMCPY(&dName->fullName[idx],
04455                                      &cert->source[dName->ouIdx], dName->ouLen);
04456                 dName->ouIdx = idx;
04457                 idx += dName->ouLen;
04458             }
04459             if (dName->emailLen != 0) {
04460                 dName->entryCount++;
04461                 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
04462                 idx += 14;
04463                 XMEMCPY(&dName->fullName[idx],
04464                                &cert->source[dName->emailIdx], dName->emailLen);
04465                 dName->emailIdx = idx;
04466                 idx += dName->emailLen;
04467             }
04468             for (i = 0;i < dName->dcNum;i++){
04469                 if (dName->dcLen[i] != 0) {
04470                     dName->entryCount++;
04471                     XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);
04472                     idx += 4;
04473                     XMEMCPY(&dName->fullName[idx],
04474                                     &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
04475                     dName->dcIdx[i] = idx;
04476                     idx += dName->dcLen[i];
04477                 }
04478             }
04479             if (dName->uidLen != 0) {
04480                 dName->entryCount++;
04481                 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
04482                 idx += 5;
04483                 XMEMCPY(&dName->fullName[idx],
04484                                    &cert->source[dName->uidIdx], dName->uidLen);
04485                 dName->uidIdx = idx;
04486                 idx += dName->uidLen;
04487             }
04488             if (dName->serialLen != 0) {
04489                 dName->entryCount++;
04490                 XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);
04491                 idx += 14;
04492                 XMEMCPY(&dName->fullName[idx],
04493                              &cert->source[dName->serialIdx], dName->serialLen);
04494                 dName->serialIdx = idx;
04495                 idx += dName->serialLen;
04496             }
04497             dName->fullName[idx] = '\0';
04498             dName->fullNameLen = totalLen;
04499         }
04500     }
04501     #endif /* OPENSSL_EXTRA */
04502 
04503     return 0;
04504 }
04505 
04506 
04507 #ifndef NO_ASN_TIME
04508 
04509 /* two byte date/time, add to value */
04510 static WC_INLINE void GetTime(int* value, const byte* date, int* idx)
04511 {
04512     int i = *idx;
04513 
04514     *value += btoi(date[i++]) * 10;
04515     *value += btoi(date[i++]);
04516 
04517     *idx = i;
04518 }
04519 
04520 int ExtractDate(const unsigned char* date, unsigned char format,
04521                                                   struct tm* certTime, int* idx)
04522 {
04523     XMEMSET(certTime, 0, sizeof(certTime));
04524 
04525     if (format == ASN_UTC_TIME) {
04526         /*if (btoi(date[0]) >= 5)
04527             certTime->tm_year = 1900;
04528         else
04529             certTime->tm_year = 2000;*/
04530     }
04531     else  { /* format == GENERALIZED_TIME */
04532         //certTime->tm_year += btoi(date[*idx]) * 1000; *idx = *idx + 1;
04533         //certTime->tm_year += btoi(date[*idx]) * 100;  *idx = *idx + 1;
04534     }
04535 
04536     /* adjust tm_year, tm_mon */
04537     /*GetTime((int*)&certTime->tm_year, date, idx); certTime->tm_year -= 1900;
04538     GetTime((int*)&certTime->tm_mon,  date, idx); certTime->tm_mon  -= 1;
04539     GetTime((int*)&certTime->tm_mday, date, idx);
04540     GetTime((int*)&certTime->tm_hour, date, idx);
04541     GetTime((int*)&certTime->tm_min,  date, idx);
04542     GetTime((int*)&certTime->tm_sec,  date, idx);*/
04543 
04544     return 1;
04545 }
04546 
04547 
04548 #if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
04549     defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
04550 int GetTimeString(byte* date, int format, char* buf, int len)
04551 {
04552     struct tm t;
04553     int idx = 0;
04554 
04555     if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
04556         return 0;
04557     }
04558 
04559     if (date[idx] != 'Z') {
04560         WOLFSSL_MSG("UTCtime, not Zulu") ;
04561         return 0;
04562     }
04563 
04564     /* place month in buffer */
04565     buf[0] = '\0';
04566     switch(t.tm_mon) {
04567         case 0:  XSTRNCAT(buf, "Jan ", 4); break;
04568         case 1:  XSTRNCAT(buf, "Feb ", 4); break;
04569         case 2:  XSTRNCAT(buf, "Mar ", 4); break;
04570         case 3:  XSTRNCAT(buf, "Apr ", 4); break;
04571         case 4:  XSTRNCAT(buf, "May ", 4); break;
04572         case 5:  XSTRNCAT(buf, "Jun ", 4); break;
04573         case 6:  XSTRNCAT(buf, "Jul ", 4); break;
04574         case 7:  XSTRNCAT(buf, "Aug ", 4); break;
04575         case 8:  XSTRNCAT(buf, "Sep ", 4); break;
04576         case 9:  XSTRNCAT(buf, "Oct ", 4); break;
04577         case 10: XSTRNCAT(buf, "Nov ", 4); break;
04578         case 11: XSTRNCAT(buf, "Dec ", 4); break;
04579         default:
04580             return 0;
04581 
04582     }
04583     idx = 4; /* use idx now for char buffer */
04584     buf[idx] = ' ';
04585 
04586     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
04587               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
04588 
04589     return 1;
04590 }
04591 #endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
04592 
04593 
04594 #if defined(USE_WOLF_VALIDDATE)
04595 
04596 /* to the second */
04597 static int DateGreaterThan(const struct tm* a, const struct tm* b)
04598 {
04599     /*if (a->tm_year > b->tm_year)
04600         return 1;
04601 
04602     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
04603         return 1;
04604 
04605     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
04606            a->tm_mday > b->tm_mday)
04607         return 1;
04608 
04609     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
04610         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
04611         return 1;
04612 
04613     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
04614         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
04615         a->tm_min > b->tm_min)
04616         return 1;
04617 
04618     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
04619         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
04620         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
04621         return 1;*/
04622 
04623     return 0; /* false */
04624 }
04625 
04626 
04627 static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
04628 {
04629     return DateGreaterThan(b,a);
04630 }
04631 
04632 /* like atoi but only use first byte */
04633 /* Make sure before and after dates are valid */
04634 int ValidateDate(const byte* date, byte format, int dateType)
04635 {
04636     time_t ltime;
04637     struct tm  certTime;
04638     struct tm* localTime;
04639     struct tm* tmpTime = NULL;
04640     int    i = 0;
04641     int    timeDiff = 0 ;
04642     int    diffHH = 0 ; int diffMM = 0 ;
04643     int    diffSign = 0 ;
04644 
04645 #if defined(NEED_TMP_TIME)
04646     struct tm tmpTimeStorage;
04647     tmpTime = &tmpTimeStorage;
04648 #else
04649     (void)tmpTime;
04650 #endif
04651 
04652     ltime = XTIME(0);
04653 
04654 #ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
04655     if (dateType == BEFORE) {
04656         WOLFSSL_MSG("Skewing local time for before date check");
04657         ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
04658     }
04659 #endif
04660 
04661 #ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
04662     if (dateType == AFTER) {
04663         WOLFSSL_MSG("Skewing local time for after date check");
04664         ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
04665     }
04666 #endif
04667 
04668     if (!ExtractDate(date, format, &certTime, &i)) {
04669         WOLFSSL_MSG("Error extracting the date");
04670         return 0;
04671     }
04672 
04673     if ((date[i] == '+') || (date[i] == '-')) {
04674         WOLFSSL_MSG("Using time differential, not Zulu") ;
04675         diffSign = date[i++] == '+' ? 1 : -1 ;
04676         GetTime(&diffHH, date, &i);
04677         GetTime(&diffMM, date, &i);
04678         timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
04679     } else if (date[i] != 'Z') {
04680         WOLFSSL_MSG("UTCtime, niether Zulu or time differential") ;
04681         return 0;
04682     }
04683 
04684     ltime -= (time_t)timeDiff ;
04685     localTime = XGMTIME(&ltime, tmpTime);
04686 
04687     if (localTime == NULL) {
04688         WOLFSSL_MSG("XGMTIME failed");
04689         return 0;
04690     }
04691 
04692     if (dateType == BEFORE) {
04693         if (DateLessThan(localTime, &certTime)) {
04694             WOLFSSL_MSG("Date BEFORE check failed");
04695             return 0;
04696         }
04697     }
04698     else {  /* dateType == AFTER */
04699         if (DateGreaterThan(localTime, &certTime)) {
04700             WOLFSSL_MSG("Date AFTER check failed");
04701             return 0;
04702         }
04703     }
04704 
04705     return 1;
04706 }
04707 #endif /* USE_WOLF_VALIDDATE */
04708 
04709 int wc_GetTime(void* timePtr, word32 timeSize)
04710 {
04711     time_t* ltime = (time_t*)timePtr;
04712 
04713     if (timePtr == NULL) {
04714         return BAD_FUNC_ARG;
04715     }
04716 
04717     if ((word32)sizeof(time_t) > timeSize) {
04718         return BUFFER_E;
04719     }
04720 
04721     *ltime = XTIME(0);
04722 
04723     return 0;
04724 }
04725 
04726 #endif /* !NO_ASN_TIME */
04727 
04728 
04729 /* Get date buffer, format and length. Returns 0=success or error */
04730 static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
04731                         byte* pFormat, int* pLength, word32 maxIdx)
04732 {
04733     int length;
04734     byte format;
04735 
04736     if (source == NULL || idx == NULL)
04737         return BAD_FUNC_ARG;
04738 
04739     /* get ASN format header */
04740     if (*idx+1 > maxIdx)
04741         return BUFFER_E;
04742     format = source[*idx];
04743     *idx += 1;
04744     if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
04745         return ASN_TIME_E;
04746 
04747     /* get length */
04748     if (GetLength(source, idx, &length, maxIdx) < 0)
04749         return ASN_PARSE_E;
04750     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
04751         return ASN_DATE_SZ_E;
04752 
04753     /* return format, date and length */
04754     if (pFormat)
04755         *pFormat = format;
04756     if (pDate)
04757         *pDate = &source[*idx];
04758     if (pLength)
04759         *pLength = length;
04760 
04761     *idx += length;
04762 
04763     return 0;
04764 }
04765 
04766 static int GetDate(DecodedCert* cert, int dateType, int verify)
04767 {
04768     int    ret, length;
04769     const byte *datePtr = NULL;
04770     byte   date[MAX_DATE_SIZE];
04771     byte   format;
04772     word32 startIdx = 0;
04773 
04774     if (dateType == BEFORE)
04775         cert->beforeDate = &cert->source[cert->srcIdx];
04776     else
04777         cert->afterDate = &cert->source[cert->srcIdx];
04778     startIdx = cert->srcIdx;
04779 
04780     ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
04781                       &length, cert->maxIdx);
04782     if (ret < 0)
04783         return ret;
04784 
04785     XMEMSET(date, 0, MAX_DATE_SIZE);
04786     XMEMCPY(date, datePtr, length);
04787 
04788     if (dateType == BEFORE)
04789         cert->beforeDateLen = cert->srcIdx - startIdx;
04790     else
04791         cert->afterDateLen  = cert->srcIdx - startIdx;
04792 
04793 #ifndef NO_ASN_TIME
04794     if (verify != NO_VERIFY && !XVALIDATE_DATE(date, format, dateType)) {
04795         if (dateType == BEFORE)
04796             return ASN_BEFORE_DATE_E;
04797         else
04798             return ASN_AFTER_DATE_E;
04799     }
04800 #else
04801     (void)verify;
04802 #endif
04803 
04804     return 0;
04805 }
04806 
04807 static int GetValidity(DecodedCert* cert, int verify)
04808 {
04809     int length;
04810     int badDate = 0;
04811 
04812     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
04813         return ASN_PARSE_E;
04814 
04815     if (GetDate(cert, BEFORE, verify) < 0)
04816         badDate = ASN_BEFORE_DATE_E; /* continue parsing */
04817 
04818     if (GetDate(cert, AFTER, verify) < 0)
04819         return ASN_AFTER_DATE_E;
04820 
04821     if (badDate != 0)
04822         return badDate;
04823 
04824     return 0;
04825 }
04826 
04827 
04828 int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
04829     byte* format, int* length)
04830 {
04831     int ret;
04832     word32 idx = 0;
04833 
04834     ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
04835     if (ret < 0)
04836         return ret;
04837 
04838     return 0;
04839 }
04840 
04841 #ifndef NO_ASN_TIME
04842 int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
04843     struct tm* timearg)
04844 {
04845     int idx = 0;
04846     (void)length;
04847     if (!ExtractDate(date, format, timearg, &idx))
04848         return ASN_TIME_E;
04849     return 0;
04850 }
04851 
04852 #if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
04853 int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
04854 {
04855     int ret = 0;
04856     const byte* date;
04857     byte format;
04858     int length;
04859 
04860     if (cert == NULL)
04861         return BAD_FUNC_ARG;
04862 
04863     if (before && cert->beforeDateSz > 0) {
04864         ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
04865                              &format, &length);
04866         if (ret == 0)
04867             ret = wc_GetDateAsCalendarTime(date, length, format, before);
04868     }
04869     if (after && cert->afterDateSz > 0) {
04870         ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
04871                              &format, &length);
04872         if (ret == 0)
04873             ret = wc_GetDateAsCalendarTime(date, length, format, after);
04874     }
04875 
04876     return ret;
04877 }
04878 #endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
04879 #endif /* !NO_ASN_TIME */
04880 
04881 
04882 int DecodeToKey(DecodedCert* cert, int verify)
04883 {
04884     int badDate = 0;
04885     int ret;
04886 
04887     if ( (ret = GetCertHeader(cert)) < 0)
04888         return ret;
04889 
04890     WOLFSSL_MSG("Got Cert Header");
04891 
04892     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
04893                           oidSigType, cert->maxIdx)) < 0)
04894         return ret;
04895 
04896     WOLFSSL_MSG("Got Algo ID");
04897 
04898     if ( (ret = GetName(cert, ISSUER)) < 0)
04899         return ret;
04900 
04901     if ( (ret = GetValidity(cert, verify)) < 0)
04902         badDate = ret;
04903 
04904     if ( (ret = GetName(cert, SUBJECT)) < 0)
04905         return ret;
04906 
04907     WOLFSSL_MSG("Got Subject Name");
04908 
04909     if ( (ret = GetKey(cert)) < 0)
04910         return ret;
04911 
04912     WOLFSSL_MSG("Got Key");
04913 
04914     if (badDate != 0)
04915         return badDate;
04916 
04917     return ret;
04918 }
04919 
04920 static int GetSignature(DecodedCert* cert)
04921 {
04922     int length;
04923     int ret;
04924     ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
04925                          NULL);
04926     if (ret != 0)
04927         return ret;
04928 
04929     cert->sigLength = length;
04930     cert->signature = &cert->source[cert->srcIdx];
04931     cert->srcIdx += cert->sigLength;
04932 
04933     return 0;
04934 }
04935 
04936 static word32 SetOctetString8Bit(word32 len, byte* output)
04937 {
04938     output[0] = ASN_OCTET_STRING;
04939     output[1] = (byte)len;
04940     return 2;
04941 }
04942 
04943 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
04944 {
04945     word32 idx = SetOctetString8Bit(digSz, output);
04946     XMEMCPY(&output[idx], digest, digSz);
04947 
04948     return idx + digSz;
04949 }
04950 
04951 
04952 static word32 BytePrecision(word32 value)
04953 {
04954     word32 i;
04955     for (i = sizeof(value); i; --i)
04956         if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
04957             break;
04958 
04959     return i;
04960 }
04961 
04962 
04963 WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)
04964 {
04965     word32 i = 0, j;
04966 
04967     if (length < ASN_LONG_LENGTH)
04968         output[i++] = (byte)length;
04969     else {
04970         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
04971 
04972         for (j = BytePrecision(length); j; --j) {
04973             output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
04974             i++;
04975         }
04976     }
04977 
04978     return i;
04979 }
04980 
04981 
04982 WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)
04983 {
04984     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
04985     return SetLength(len, output + 1) + 1;
04986 }
04987 
04988 WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)
04989 {
04990     output[0] = ASN_OCTET_STRING;
04991     return SetLength(len, output + 1) + 1;
04992 }
04993 
04994 /* Write a set header to output */
04995 WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)
04996 {
04997     output[0] = ASN_SET | ASN_CONSTRUCTED;
04998     return SetLength(len, output + 1) + 1;
04999 }
05000 
05001 WOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
05002 {
05003 
05004     output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
05005                     | ASN_CONTEXT_SPECIFIC | number;
05006     return SetLength(len, output + 1) + 1;
05007 }
05008 
05009 WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
05010 {
05011     output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
05012     return SetLength(len, output + 1) + 1;
05013 }
05014 
05015 
05016 #if defined(HAVE_ECC)
05017 
05018 static int SetCurve(ecc_key* key, byte* output)
05019 {
05020 #ifdef HAVE_OID_ENCODING
05021     int ret;
05022 #endif
05023     int idx = 0;
05024     word32 oidSz = 0;
05025 
05026     /* validate key */
05027     if (key == NULL || key->dp == NULL) {
05028         return BAD_FUNC_ARG;
05029     }
05030 
05031 #ifdef HAVE_OID_ENCODING
05032     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
05033     if (ret != 0) {
05034         return ret;
05035     }
05036 #else
05037     oidSz = key->dp->oidSz;
05038 #endif
05039 
05040     idx += SetObjectId(oidSz, output);
05041 
05042 #ifdef HAVE_OID_ENCODING
05043     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
05044     if (ret != 0) {
05045         return ret;
05046     }
05047 #else
05048     XMEMCPY(output+idx, key->dp->oid, oidSz);
05049 #endif
05050     idx += oidSz;
05051 
05052     return idx;
05053 }
05054 
05055 #endif /* HAVE_ECC */
05056 
05057 
05058 #ifdef HAVE_ECC
05059 static WC_INLINE int IsSigAlgoECDSA(int algoOID)
05060 {
05061     /* ECDSA sigAlgo must not have ASN1 NULL parameters */
05062     if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
05063         algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
05064         return 1;
05065     }
05066 
05067     return 0;
05068 }
05069 #endif
05070 
05071 WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
05072 {
05073     word32 tagSz, idSz, seqSz, algoSz = 0;
05074     const  byte* algoName = 0;
05075     byte   ID_Length[1 + MAX_LENGTH_SZ];
05076     byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
05077 
05078     tagSz = (type == oidHashType ||
05079              (type == oidSigType
05080         #ifdef HAVE_ECC
05081               && !IsSigAlgoECDSA(algoOID)
05082         #endif
05083         #ifdef HAVE_ED25519
05084               && algoOID != ED25519k
05085         #endif
05086               ) ||
05087              (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
05088 
05089     algoName = OidFromId(algoOID, type, &algoSz);
05090 
05091     if (algoName == NULL) {
05092         WOLFSSL_MSG("Unknown Algorithm");
05093         return 0;
05094     }
05095 
05096     idSz  = SetObjectId(algoSz, ID_Length);
05097     seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
05098 
05099     XMEMCPY(output, seqArray, seqSz);
05100     XMEMCPY(output + seqSz, ID_Length, idSz);
05101     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
05102     if (tagSz == 2)
05103         SetASNNull(&output[seqSz + idSz + algoSz]);
05104 
05105     return seqSz + idSz + algoSz + tagSz;
05106 
05107 }
05108 
05109 
05110 word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
05111                           int hashOID)
05112 {
05113     byte digArray[MAX_ENCODED_DIG_SZ];
05114     byte algoArray[MAX_ALGO_SZ];
05115     byte seqArray[MAX_SEQ_SZ];
05116     word32 encDigSz, algoSz, seqSz;
05117 
05118     encDigSz = SetDigest(digest, digSz, digArray);
05119     algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
05120     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
05121 
05122     XMEMCPY(out, seqArray, seqSz);
05123     XMEMCPY(out + seqSz, algoArray, algoSz);
05124     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
05125 
05126     return encDigSz + algoSz + seqSz;
05127 }
05128 
05129 
05130 int wc_GetCTC_HashOID(int type)
05131 {
05132     int ret;
05133     enum wc_HashType hType;
05134 
05135     hType = wc_HashTypeConvert(type);
05136     ret = wc_HashGetOID(hType);
05137     if (ret < 0)
05138         ret = 0; /* backwards compatibility */
05139 
05140     return ret;
05141 }
05142 
05143 void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
05144 {
05145     if (sigCtx) {
05146         XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
05147         sigCtx->devId = devId;
05148         sigCtx->heap = heap;
05149     }
05150 }
05151 
05152 void FreeSignatureCtx(SignatureCtx* sigCtx)
05153 {
05154     if (sigCtx == NULL)
05155         return;
05156 
05157     if (sigCtx->digest) {
05158         XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
05159         sigCtx->digest = NULL;
05160     }
05161 #ifndef NO_RSA
05162     if (sigCtx->plain) {
05163         XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
05164         sigCtx->plain = NULL;
05165     }
05166 #endif
05167     if (sigCtx->key.ptr) {
05168         switch (sigCtx->keyOID) {
05169         #ifndef NO_RSA
05170             case RSAk:
05171                 wc_FreeRsaKey(sigCtx->key.rsa);
05172                 XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);
05173                 break;
05174         #endif /* !NO_RSA */
05175         #ifdef HAVE_ECC
05176             case ECDSAk:
05177                 wc_ecc_free(sigCtx->key.ecc);
05178                 XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
05179                 break;
05180         #endif /* HAVE_ECC */
05181         #ifdef HAVE_ED25519
05182             case ED25519k:
05183                 wc_ed25519_free(sigCtx->key.ed25519);
05184                 XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
05185                 break;
05186         #endif /* HAVE_ED25519 */
05187             default:
05188                 break;
05189         } /* switch (keyOID) */
05190         sigCtx->key.ptr = NULL;
05191     }
05192 
05193     /* reset state, we are done */
05194     sigCtx->state = SIG_STATE_BEGIN;
05195 }
05196 
05197 static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
05198                             byte* digest, int* typeH, int* digestSz, int verify)
05199 {
05200     int ret = 0;
05201 
05202     (void)verify;
05203 
05204     switch (sigOID) {
05205     #if defined(WOLFSSL_MD2)
05206         case CTC_MD2wRSA:
05207             if (!verify) {
05208                 ret = HASH_TYPE_E;
05209                 WOLFSSL_MSG("MD2 not supported for signing");
05210             }
05211             else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
05212                 *typeH    = MD2h;
05213                 *digestSz = MD2_DIGEST_SIZE;
05214             }
05215         break;
05216     #endif
05217     #ifndef NO_MD5
05218         case CTC_MD5wRSA:
05219             if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
05220                 *typeH    = MD5h;
05221                 *digestSz = WC_MD5_DIGEST_SIZE;
05222             }
05223             break;
05224     #endif
05225     #ifndef NO_SHA
05226         case CTC_SHAwRSA:
05227         case CTC_SHAwDSA:
05228         case CTC_SHAwECDSA:
05229             if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
05230                 *typeH    = SHAh;
05231                 *digestSz = WC_SHA_DIGEST_SIZE;
05232             }
05233             break;
05234     #endif
05235     #ifdef WOLFSSL_SHA224
05236         case CTC_SHA224wRSA:
05237         case CTC_SHA224wECDSA:
05238             if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
05239                 *typeH    = SHA224h;
05240                 *digestSz = WC_SHA224_DIGEST_SIZE;
05241             }
05242             break;
05243     #endif
05244     #ifndef NO_SHA256
05245         case CTC_SHA256wRSA:
05246         case CTC_SHA256wECDSA:
05247             if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
05248                 *typeH    = SHA256h;
05249                 *digestSz = WC_SHA256_DIGEST_SIZE;
05250             }
05251             break;
05252     #endif
05253     #ifdef WOLFSSL_SHA384
05254         case CTC_SHA384wRSA:
05255         case CTC_SHA384wECDSA:
05256             if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
05257                 *typeH    = SHA384h;
05258                 *digestSz = WC_SHA384_DIGEST_SIZE;
05259             }
05260             break;
05261     #endif
05262     #ifdef WOLFSSL_SHA512
05263         case CTC_SHA512wRSA:
05264         case CTC_SHA512wECDSA:
05265             if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
05266                 *typeH    = SHA512h;
05267                 *digestSz = WC_SHA512_DIGEST_SIZE;
05268             }
05269             break;
05270     #endif
05271         case CTC_ED25519:
05272             /* Hashes done in signing operation.
05273              * Two dependent hashes with prefixes performed.
05274              */
05275             break;
05276         default:
05277             ret = HASH_TYPE_E;
05278             WOLFSSL_MSG("Hash for Signature has unsupported type");
05279     }
05280 
05281     return ret;
05282 }
05283 
05284 /* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
05285 static int ConfirmSignature(SignatureCtx* sigCtx,
05286     const byte* buf, word32 bufSz,
05287     const byte* key, word32 keySz, word32 keyOID,
05288     const byte* sig, word32 sigSz, word32 sigOID)
05289 {
05290     int ret = 0;
05291 
05292     if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
05293         keySz == 0 || sig == NULL || sigSz == 0) {
05294         return BAD_FUNC_ARG;
05295     }
05296 
05297     (void)key;
05298     (void)keySz;
05299     (void)sig;
05300     (void)sigSz;
05301 
05302     WOLFSSL_ENTER("ConfirmSignature");
05303 
05304     switch (sigCtx->state) {
05305         case SIG_STATE_BEGIN:
05306         {
05307             sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
05308                                                     DYNAMIC_TYPE_DIGEST);
05309             if (sigCtx->digest == NULL) {
05310                 ERROR_OUT(MEMORY_E, exit_cs);
05311             }
05312 
05313             sigCtx->state = SIG_STATE_HASH;
05314         } /* SIG_STATE_BEGIN */
05315         FALL_THROUGH;
05316 
05317         case SIG_STATE_HASH:
05318         {
05319             ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
05320                                    &sigCtx->typeH, &sigCtx->digestSz, 1);
05321             if (ret != 0) {
05322                 goto exit_cs;
05323             }
05324 
05325             sigCtx->state = SIG_STATE_KEY;
05326         } /* SIG_STATE_HASH */
05327         FALL_THROUGH;
05328 
05329         case SIG_STATE_KEY:
05330         {
05331             sigCtx->keyOID = keyOID;
05332 
05333             switch (keyOID) {
05334             #ifndef NO_RSA
05335                 case RSAk:
05336                 {
05337                     word32 idx = 0;
05338 
05339                     sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
05340                                                 sigCtx->heap, DYNAMIC_TYPE_RSA);
05341                     sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
05342                                          sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
05343                     if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) {
05344                         ERROR_OUT(MEMORY_E, exit_cs);
05345                     }
05346                     if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
05347                                                         sigCtx->devId)) != 0) {
05348                         goto exit_cs;
05349                     }
05350                     if (sigSz > MAX_ENCODED_SIG_SZ) {
05351                         WOLFSSL_MSG("Verify Signature is too big");
05352                         ERROR_OUT(BUFFER_E, exit_cs);
05353                     }
05354                     if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
05355                                                                  keySz)) != 0) {
05356                         WOLFSSL_MSG("ASN Key decode error RSA");
05357                         goto exit_cs;
05358                     }
05359                     XMEMCPY(sigCtx->plain, sig, sigSz);
05360                     sigCtx->out = NULL;
05361 
05362                 #ifdef WOLFSSL_ASYNC_CRYPT
05363                     sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
05364                 #endif
05365                     break;
05366                 }
05367             #endif /* !NO_RSA */
05368             #ifdef HAVE_ECC
05369                 case ECDSAk:
05370                 {
05371                     word32 idx = 0;
05372 
05373                     sigCtx->verify = 0;
05374                     sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
05375                                                 sigCtx->heap, DYNAMIC_TYPE_ECC);
05376                     if (sigCtx->key.ecc == NULL) {
05377                         ERROR_OUT(MEMORY_E, exit_cs);
05378                     }
05379                     if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
05380                                                           sigCtx->devId)) < 0) {
05381                         goto exit_cs;
05382                     }
05383                     ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
05384                                                                          keySz);
05385                     if (ret < 0) {
05386                         WOLFSSL_MSG("ASN Key import error ECC");
05387                         goto exit_cs;
05388                     }
05389                 #ifdef WOLFSSL_ASYNC_CRYPT
05390                     sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
05391                 #endif
05392                     break;
05393                 }
05394             #endif /* HAVE_ECC */
05395             #ifdef HAVE_ED25519
05396                 case ED25519k:
05397                 {
05398                     sigCtx->verify = 0;
05399                     sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
05400                                               sizeof(ed25519_key), sigCtx->heap,
05401                                               DYNAMIC_TYPE_ED25519);
05402                     if (sigCtx->key.ed25519 == NULL) {
05403                         ERROR_OUT(MEMORY_E, exit_cs);
05404                     }
05405                     if ((ret = wc_ed25519_init(sigCtx->key.ed25519)) < 0) {
05406                         goto exit_cs;
05407                     }
05408                     if ((ret = wc_ed25519_import_public(key, keySz,
05409                                                     sigCtx->key.ed25519)) < 0) {
05410                         WOLFSSL_MSG("ASN Key import error ED25519");
05411                         goto exit_cs;
05412                     }
05413                 #ifdef WOLFSSL_ASYNC_CRYPT
05414                     sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
05415                 #endif
05416                     break;
05417                 }
05418             #endif
05419                 default:
05420                     WOLFSSL_MSG("Verify Key type unknown");
05421                     ret = ASN_UNKNOWN_OID_E;
05422                     break;
05423             } /* switch (keyOID) */
05424 
05425             if (ret != 0) {
05426                 goto exit_cs;
05427             }
05428 
05429             sigCtx->state = SIG_STATE_DO;
05430 
05431         #ifdef WOLFSSL_ASYNC_CRYPT
05432             if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
05433                 /* make sure event is intialized */
05434                 WOLF_EVENT* event = &sigCtx->asyncDev->event;
05435                 ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
05436                     sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
05437             }
05438         #endif
05439         } /* SIG_STATE_KEY */
05440         FALL_THROUGH;
05441 
05442         case SIG_STATE_DO:
05443         {
05444             switch (keyOID) {
05445             #ifndef NO_RSA
05446                 case RSAk:
05447                 {
05448                 #ifdef HAVE_PK_CALLBACKS
05449                     if (sigCtx->pkCbRsa) {
05450                         ret = sigCtx->pkCbRsa(
05451                                 sigCtx->plain, sigSz, &sigCtx->out,
05452                                 key, keySz,
05453                                 sigCtx->pkCtxRsa);
05454                     }
05455                     else
05456                 #endif /* HAVE_PK_CALLBACKS */
05457                     {
05458                         ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
05459                                                  &sigCtx->out, sigCtx->key.rsa);
05460                     }
05461                     break;
05462                 }
05463             #endif /* !NO_RSA */
05464             #ifdef HAVE_ECC
05465                 case ECDSAk:
05466                 {
05467                 #ifdef HAVE_PK_CALLBACKS
05468                     if (sigCtx->pkCbEcc) {
05469                         ret = sigCtx->pkCbEcc(
05470                                 sig, sigSz,
05471                                 sigCtx->digest, sigCtx->digestSz,
05472                                 key, keySz, &sigCtx->verify,
05473                                 sigCtx->pkCtxEcc);
05474                     }
05475                     else
05476                 #endif /* HAVE_PK_CALLBACKS */
05477                     {
05478                         ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
05479                                             sigCtx->digestSz, &sigCtx->verify,
05480                                             sigCtx->key.ecc);
05481                     }
05482                     break;
05483                 }
05484             #endif /* HAVE_ECC */
05485             #ifdef HAVE_ED25519
05486                 case ED25519k:
05487                 {
05488                     ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
05489                                           &sigCtx->verify, sigCtx->key.ed25519);
05490                     break;
05491                 }
05492             #endif
05493                 default:
05494                     break;
05495             }  /* switch (keyOID) */
05496 
05497             if (ret < 0) {
05498                 /* treat all non async RSA errors as ASN_SIG_CONFIRM_E */
05499                 if (ret != WC_PENDING_E)
05500                     ret = ASN_SIG_CONFIRM_E;
05501                 goto exit_cs;
05502             }
05503 
05504             sigCtx->state = SIG_STATE_CHECK;
05505         } /* SIG_STATE_DO */
05506         FALL_THROUGH;
05507 
05508         case SIG_STATE_CHECK:
05509         {
05510             switch (keyOID) {
05511             #ifndef NO_RSA
05512                 case RSAk:
05513                 {
05514                     int encodedSigSz, verifySz;
05515                 #ifdef WOLFSSL_SMALL_STACK
05516                     byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
05517                                         sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
05518                     if (encodedSig == NULL) {
05519                         ERROR_OUT(MEMORY_E, exit_cs);
05520                     }
05521                 #else
05522                     byte encodedSig[MAX_ENCODED_SIG_SZ];
05523                 #endif
05524 
05525                     verifySz = ret;
05526 
05527                     /* make sure we're right justified */
05528                     encodedSigSz = wc_EncodeSignature(encodedSig,
05529                             sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
05530                     if (encodedSigSz == verifySz && sigCtx->out != NULL &&
05531                         XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
05532                         ret = 0;
05533                     }
05534                     else {
05535                         WOLFSSL_MSG("RSA SSL verify match encode error");
05536                         ret = ASN_SIG_CONFIRM_E;
05537                     }
05538 
05539                 #ifdef WOLFSSL_SMALL_STACK
05540                     XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
05541                 #endif
05542                     break;
05543                 }
05544             #endif /* NO_RSA */
05545             #ifdef HAVE_ECC
05546                 case ECDSAk:
05547                 {
05548                     if (sigCtx->verify == 1) {
05549                         ret = 0;
05550                     }
05551                     else {
05552                         WOLFSSL_MSG("ECC Verify didn't match");
05553                         ret = ASN_SIG_CONFIRM_E;
05554                     }
05555                     break;
05556                 }
05557             #endif /* HAVE_ECC */
05558             #ifdef HAVE_ED25519
05559                 case ED25519k:
05560                 {
05561                     if (sigCtx->verify == 1) {
05562                         ret = 0;
05563                     }
05564                     else {
05565                         WOLFSSL_MSG("ED25519 Verify didn't match");
05566                         ret = ASN_SIG_CONFIRM_E;
05567                     }
05568                     break;
05569                 }
05570             #endif /* HAVE_ED25519 */
05571                 default:
05572                     break;
05573             }  /* switch (keyOID) */
05574 
05575             break;
05576         } /* SIG_STATE_CHECK */
05577     } /* switch (sigCtx->state) */
05578 
05579 exit_cs:
05580 
05581     WOLFSSL_LEAVE("ConfirmSignature", ret);
05582 
05583     if (ret != WC_PENDING_E) {
05584         FreeSignatureCtx(sigCtx);
05585     }
05586 
05587     return ret;
05588 }
05589 
05590 
05591 #ifndef IGNORE_NAME_CONSTRAINTS
05592 
05593 static int MatchBaseName(int type, const char* name, int nameSz,
05594                          const char* base, int baseSz)
05595 {
05596     if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
05597             name[0] == '.' || nameSz < baseSz ||
05598             (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
05599         return 0;
05600 
05601     /* If an email type, handle special cases where the base is only
05602      * a domain, or is an email address itself. */
05603     if (type == ASN_RFC822_TYPE) {
05604         const char* p = NULL;
05605         int count = 0;
05606 
05607         if (base[0] != '.') {
05608             p = base;
05609             count = 0;
05610 
05611             /* find the '@' in the base */
05612             while (*p != '@' && count < baseSz) {
05613                 count++;
05614                 p++;
05615             }
05616 
05617             /* No '@' in base, reset p to NULL */
05618             if (count >= baseSz)
05619                 p = NULL;
05620         }
05621 
05622         if (p == NULL) {
05623             /* Base isn't an email address, it is a domain name,
05624              * wind the name forward one character past its '@'. */
05625             p = name;
05626             count = 0;
05627             while (*p != '@' && count < baseSz) {
05628                 count++;
05629                 p++;
05630             }
05631 
05632             if (count < baseSz && *p == '@') {
05633                 name = p + 1;
05634                 nameSz -= count + 1;
05635             }
05636         }
05637     }
05638 
05639     if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
05640         int szAdjust = nameSz - baseSz;
05641         name += szAdjust;
05642         nameSz -= szAdjust;
05643     }
05644 
05645     while (nameSz > 0) {
05646         if (XTOLOWER((unsigned char)*name++) !=
05647                                                XTOLOWER((unsigned char)*base++))
05648             return 0;
05649         nameSz--;
05650     }
05651 
05652     return 1;
05653 }
05654 
05655 
05656 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
05657 {
05658     if (signer == NULL || cert == NULL)
05659         return 0;
05660 
05661     /* Check against the excluded list */
05662     if (signer->excludedNames) {
05663         Base_entry* base = signer->excludedNames;
05664 
05665         while (base != NULL) {
05666             switch (base->type) {
05667                 case ASN_DNS_TYPE:
05668                 {
05669                     DNS_entry* name = cert->altNames;
05670                     while (name != NULL) {
05671                         if (MatchBaseName(ASN_DNS_TYPE,
05672                                           name->name, name->len,
05673                                           base->name, base->nameSz)) {
05674                             return 0;
05675                         }
05676                         name = name->next;
05677                     }
05678                     break;
05679                 }
05680                 case ASN_RFC822_TYPE:
05681                 {
05682                     DNS_entry* name = cert->altEmailNames;
05683                     while (name != NULL) {
05684                         if (MatchBaseName(ASN_RFC822_TYPE,
05685                                           name->name, name->len,
05686                                           base->name, base->nameSz)) {
05687                             return 0;
05688                         }
05689                         name = name->next;
05690                     }
05691                     break;
05692                 }
05693                 case ASN_DIR_TYPE:
05694                 {
05695                     /* allow permitted dirName smaller than actual subject */
05696                     if (cert->subjectRawLen >= base->nameSz &&
05697                         XMEMCMP(cert->subjectRaw, base->name,
05698                                                         base->nameSz) == 0) {
05699                         return 0;
05700                     }
05701                     break;
05702                 }
05703             }; /* switch */
05704             base = base->next;
05705         }
05706     }
05707 
05708     /* Check against the permitted list */
05709     if (signer->permittedNames != NULL) {
05710         int needDns = 0;
05711         int matchDns = 0;
05712         int needEmail = 0;
05713         int matchEmail = 0;
05714         int needDir = 0;
05715         int matchDir = 0;
05716         Base_entry* base = signer->permittedNames;
05717 
05718         while (base != NULL) {
05719             switch (base->type) {
05720                 case ASN_DNS_TYPE:
05721                 {
05722                     DNS_entry* name = cert->altNames;
05723 
05724                     if (name != NULL)
05725                         needDns = 1;
05726 
05727                     while (name != NULL) {
05728                         matchDns = MatchBaseName(ASN_DNS_TYPE,
05729                                           name->name, name->len,
05730                                           base->name, base->nameSz);
05731                         name = name->next;
05732                     }
05733                     break;
05734                 }
05735                 case ASN_RFC822_TYPE:
05736                 {
05737                     DNS_entry* name = cert->altEmailNames;
05738 
05739                     if (name != NULL)
05740                         needEmail = 1;
05741 
05742                     while (name != NULL) {
05743                         matchEmail = MatchBaseName(ASN_DNS_TYPE,
05744                                           name->name, name->len,
05745                                           base->name, base->nameSz);
05746                         name = name->next;
05747                     }
05748                     break;
05749                 }
05750                 case ASN_DIR_TYPE:
05751                 {
05752                     /* allow permitted dirName smaller than actual subject */
05753                     needDir = 1;
05754                     if (cert->subjectRaw != NULL &&
05755                         cert->subjectRawLen >= base->nameSz &&
05756                         XMEMCMP(cert->subjectRaw, base->name,
05757                                                         base->nameSz) == 0) {
05758                         matchDir = 1;
05759                     }
05760                     break;
05761                 }
05762             } /* switch */
05763             base = base->next;
05764         }
05765 
05766         if ((needDns   && !matchDns) ||
05767             (needEmail && !matchEmail) ||
05768             (needDir   && !matchDir)) {
05769             return 0;
05770         }
05771     }
05772 
05773     return 1;
05774 }
05775 
05776 #endif /* IGNORE_NAME_CONSTRAINTS */
05777 
05778 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
05779 {
05780     word32 idx = 0;
05781     int length = 0;
05782 
05783     WOLFSSL_ENTER("DecodeAltNames");
05784 
05785     if (GetSequence(input, &idx, &length, sz) < 0) {
05786         WOLFSSL_MSG("\tBad Sequence");
05787         return ASN_PARSE_E;
05788     }
05789 
05790     cert->weOwnAltNames = 1;
05791 
05792     while (length > 0) {
05793         byte b = input[idx++];
05794 
05795         length--;
05796 
05797         /* Save DNS Type names in the altNames list. */
05798         /* Save Other Type names in the cert's OidMap */
05799         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
05800             DNS_entry* dnsEntry;
05801             int strLen;
05802             word32 lenStartIdx = idx;
05803 
05804             if (GetLength(input, &idx, &strLen, sz) < 0) {
05805                 WOLFSSL_MSG("\tfail: str length");
05806                 return ASN_PARSE_E;
05807             }
05808             length -= (idx - lenStartIdx);
05809 
05810             dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
05811                                         DYNAMIC_TYPE_ALTNAME);
05812             if (dnsEntry == NULL) {
05813                 WOLFSSL_MSG("\tOut of Memory");
05814                 return MEMORY_E;
05815             }
05816 
05817             dnsEntry->type = ASN_DNS_TYPE;
05818             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
05819                                          DYNAMIC_TYPE_ALTNAME);
05820             if (dnsEntry->name == NULL) {
05821                 WOLFSSL_MSG("\tOut of Memory");
05822                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
05823                 return MEMORY_E;
05824             }
05825             dnsEntry->len = strLen;
05826             XMEMCPY(dnsEntry->name, &input[idx], strLen);
05827             dnsEntry->name[strLen] = '\0';
05828 
05829             dnsEntry->next = cert->altNames;
05830             cert->altNames = dnsEntry;
05831 
05832             length -= strLen;
05833             idx    += strLen;
05834         }
05835     #ifndef IGNORE_NAME_CONSTRAINTS
05836         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
05837             DNS_entry* emailEntry;
05838             int strLen;
05839             word32 lenStartIdx = idx;
05840 
05841             if (GetLength(input, &idx, &strLen, sz) < 0) {
05842                 WOLFSSL_MSG("\tfail: str length");
05843                 return ASN_PARSE_E;
05844             }
05845             length -= (idx - lenStartIdx);
05846 
05847             emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
05848                                         DYNAMIC_TYPE_ALTNAME);
05849             if (emailEntry == NULL) {
05850                 WOLFSSL_MSG("\tOut of Memory");
05851                 return MEMORY_E;
05852             }
05853 
05854             emailEntry->type = ASN_RFC822_TYPE;
05855             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
05856                                          DYNAMIC_TYPE_ALTNAME);
05857             if (emailEntry->name == NULL) {
05858                 WOLFSSL_MSG("\tOut of Memory");
05859                 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
05860                 return MEMORY_E;
05861             }
05862             emailEntry->len = strLen;
05863             XMEMCPY(emailEntry->name, &input[idx], strLen);
05864             emailEntry->name[strLen] = '\0';
05865 
05866             emailEntry->next = cert->altEmailNames;
05867             cert->altEmailNames = emailEntry;
05868 
05869             length -= strLen;
05870             idx    += strLen;
05871         }
05872         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
05873             DNS_entry* uriEntry;
05874             int strLen;
05875             word32 lenStartIdx = idx;
05876 
05877             WOLFSSL_MSG("\tPutting URI into list but not using");
05878             if (GetLength(input, &idx, &strLen, sz) < 0) {
05879                 WOLFSSL_MSG("\tfail: str length");
05880                 return ASN_PARSE_E;
05881             }
05882             length -= (idx - lenStartIdx);
05883 
05884             /* check that strLen at index is not past input buffer */
05885             if (strLen + (int)idx > sz) {
05886                 return BUFFER_E;
05887             }
05888 
05889         #ifndef WOLFSSL_NO_ASN_STRICT
05890             /* Verify RFC 5280 Sec 4.2.1.6 rule:
05891                 "The name MUST NOT be a relative URI" */
05892 
05893             {
05894                 int i;
05895 
05896                 /* skip past scheme (i.e http,ftp,...) finding first ':' char */
05897                 for (i = 0; i < strLen; i++) {
05898                     if (input[idx + i] == ':') {
05899                         break;
05900                     }
05901                     if (input[idx + i] == '/') {
05902                         i = strLen; /* error, found relative path since '/' was
05903                                      * encountered before ':'. Returning error
05904                                      * value in next if statement. */
05905                     }
05906                 }
05907 
05908                 /* test if no ':' char was found and test that the next two
05909                  * chars are // to match the pattern "://" */
05910                 if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
05911                                         input[idx + i + 2] != '/')) {
05912                     WOLFSSL_MSG("\tAlt Name must be absolute URI");
05913                     return ASN_ALT_NAME_E;
05914                 }
05915             }
05916         #endif
05917 
05918             uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
05919                                         DYNAMIC_TYPE_ALTNAME);
05920             if (uriEntry == NULL) {
05921                 WOLFSSL_MSG("\tOut of Memory");
05922                 return MEMORY_E;
05923             }
05924 
05925             uriEntry->type = ASN_URI_TYPE;
05926             uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
05927                                          DYNAMIC_TYPE_ALTNAME);
05928             if (uriEntry->name == NULL) {
05929                 WOLFSSL_MSG("\tOut of Memory");
05930                 XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
05931                 return MEMORY_E;
05932             }
05933             uriEntry->len = strLen;
05934             XMEMCPY(uriEntry->name, &input[idx], strLen);
05935             uriEntry->name[strLen] = '\0';
05936 
05937             uriEntry->next = cert->altNames;
05938             cert->altNames = uriEntry;
05939 
05940             length -= strLen;
05941             idx    += strLen;
05942         }
05943 #endif /* IGNORE_NAME_CONSTRAINTS */
05944 #ifdef WOLFSSL_SEP
05945         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
05946         {
05947             int strLen;
05948             word32 lenStartIdx = idx;
05949             word32 oid = 0;
05950             int    ret;
05951 
05952             if (GetLength(input, &idx, &strLen, sz) < 0) {
05953                 WOLFSSL_MSG("\tfail: other name length");
05954                 return ASN_PARSE_E;
05955             }
05956             /* Consume the rest of this sequence. */
05957             length -= (strLen + idx - lenStartIdx);
05958 
05959             if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
05960                 WOLFSSL_MSG("\tbad OID");
05961                 return ASN_PARSE_E;
05962             }
05963 
05964             if (oid != HW_NAME_OID) {
05965                 WOLFSSL_MSG("\tincorrect OID");
05966                 return ASN_PARSE_E;
05967             }
05968 
05969             if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
05970                 WOLFSSL_MSG("\twrong type");
05971                 return ASN_PARSE_E;
05972             }
05973 
05974             if (GetLength(input, &idx, &strLen, sz) < 0) {
05975                 WOLFSSL_MSG("\tfail: str len");
05976                 return ASN_PARSE_E;
05977             }
05978 
05979             if (GetSequence(input, &idx, &strLen, sz) < 0) {
05980                 WOLFSSL_MSG("\tBad Sequence");
05981                 return ASN_PARSE_E;
05982             }
05983 
05984             ret = GetASNObjectId(input, &idx, &strLen, sz);
05985             if (ret != 0) {
05986                 WOLFSSL_MSG("\tbad OID");
05987                 return ret;
05988             }
05989 
05990             cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
05991                                           DYNAMIC_TYPE_X509_EXT);
05992             if (cert->hwType == NULL) {
05993                 WOLFSSL_MSG("\tOut of Memory");
05994                 return MEMORY_E;
05995             }
05996 
05997             XMEMCPY(cert->hwType, &input[idx], strLen);
05998             cert->hwTypeSz = strLen;
05999             idx += strLen;
06000 
06001             ret = GetOctetString(input, &idx, &strLen, sz);
06002             if (ret < 0)
06003                 return ret;
06004 
06005             cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
06006                                                DYNAMIC_TYPE_X509_EXT);
06007             if (cert->hwSerialNum == NULL) {
06008                 WOLFSSL_MSG("\tOut of Memory");
06009                 return MEMORY_E;
06010             }
06011 
06012             XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
06013             cert->hwSerialNum[strLen] = '\0';
06014             cert->hwSerialNumSz = strLen;
06015             idx += strLen;
06016         }
06017     #endif /* WOLFSSL_SEP */
06018         else {
06019             int strLen;
06020             word32 lenStartIdx = idx;
06021 
06022             WOLFSSL_MSG("\tUnsupported name type, skipping");
06023 
06024             if (GetLength(input, &idx, &strLen, sz) < 0) {
06025                 WOLFSSL_MSG("\tfail: unsupported name length");
06026                 return ASN_PARSE_E;
06027             }
06028             length -= (strLen + idx - lenStartIdx);
06029             idx += strLen;
06030         }
06031     }
06032     return 0;
06033 }
06034 
06035 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
06036 {
06037     word32 idx = 0;
06038     int length = 0;
06039     int ret;
06040 
06041     WOLFSSL_ENTER("DecodeBasicCaConstraint");
06042 
06043     if (GetSequence(input, &idx, &length, sz) < 0) {
06044         WOLFSSL_MSG("\tfail: bad SEQUENCE");
06045         return ASN_PARSE_E;
06046     }
06047 
06048     if (length == 0)
06049         return 0;
06050 
06051     /* If the basic ca constraint is false, this extension may be named, but
06052      * left empty. So, if the length is 0, just return. */
06053 
06054     ret = GetBoolean(input, &idx, sz);
06055     if (ret < 0) {
06056         WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN");
06057         return ret;
06058     }
06059 
06060     cert->isCA = (byte)ret;
06061 
06062     /* If there isn't any more data, return. */
06063     if (idx >= (word32)sz)
06064         return 0;
06065 
06066     ret = GetInteger7Bit(input, &idx, sz);
06067     if (ret < 0)
06068         return ret;
06069 
06070     cert->pathLength = (byte)ret;
06071     cert->pathLengthSet = 1;
06072 
06073     return 0;
06074 }
06075 
06076 
06077 #define CRLDP_FULL_NAME 0
06078     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
06079 #define GENERALNAME_URI 6
06080     /* From RFC3280 SS4.2.1.7, GeneralName */
06081 
06082 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
06083 {
06084     word32 idx = 0;
06085     int length = 0;
06086 
06087     WOLFSSL_ENTER("DecodeCrlDist");
06088 
06089     /* Unwrap the list of Distribution Points*/
06090     if (GetSequence(input, &idx, &length, sz) < 0)
06091         return ASN_PARSE_E;
06092 
06093     /* Unwrap a single Distribution Point */
06094     if (GetSequence(input, &idx, &length, sz) < 0)
06095         return ASN_PARSE_E;
06096 
06097     /* The Distribution Point has three explicit optional members
06098      *  First check for a DistributionPointName
06099      */
06100     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
06101     {
06102         idx++;
06103         if (GetLength(input, &idx, &length, sz) < 0)
06104             return ASN_PARSE_E;
06105 
06106         if (input[idx] ==
06107                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
06108         {
06109             idx++;
06110             if (GetLength(input, &idx, &length, sz) < 0)
06111                 return ASN_PARSE_E;
06112 
06113             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
06114             {
06115                 idx++;
06116                 if (GetLength(input, &idx, &length, sz) < 0)
06117                     return ASN_PARSE_E;
06118 
06119                 cert->extCrlInfoSz = length;
06120                 cert->extCrlInfo = input + idx;
06121                 idx += length;
06122             }
06123             else
06124                 /* This isn't a URI, skip it. */
06125                 idx += length;
06126         }
06127         else {
06128             /* This isn't a FULLNAME, skip it. */
06129             idx += length;
06130         }
06131     }
06132 
06133     /* Check for reasonFlags */
06134     if (idx < (word32)sz &&
06135         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
06136     {
06137         idx++;
06138         if (GetLength(input, &idx, &length, sz) < 0)
06139             return ASN_PARSE_E;
06140         idx += length;
06141     }
06142 
06143     /* Check for cRLIssuer */
06144     if (idx < (word32)sz &&
06145         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
06146     {
06147         idx++;
06148         if (GetLength(input, &idx, &length, sz) < 0)
06149             return ASN_PARSE_E;
06150         idx += length;
06151     }
06152 
06153     if (idx < (word32)sz)
06154     {
06155         WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
06156                    "but we only use the first one.");
06157     }
06158 
06159     return 0;
06160 }
06161 
06162 
06163 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
06164 /*
06165  *  Read the first of the Authority Information Access records. If there are
06166  *  any issues, return without saving the record.
06167  */
06168 {
06169     word32 idx = 0;
06170     int length = 0;
06171     byte b;
06172     word32 oid;
06173 
06174     WOLFSSL_ENTER("DecodeAuthInfo");
06175 
06176     /* Unwrap the list of AIAs */
06177     if (GetSequence(input, &idx, &length, sz) < 0)
06178         return ASN_PARSE_E;
06179 
06180     while (idx < (word32)sz) {
06181         /* Unwrap a single AIA */
06182         if (GetSequence(input, &idx, &length, sz) < 0)
06183             return ASN_PARSE_E;
06184 
06185         oid = 0;
06186         if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
06187             return ASN_PARSE_E;
06188 
06189 
06190         /* Only supporting URIs right now. */
06191         b = input[idx++];
06192         if (GetLength(input, &idx, &length, sz) < 0)
06193             return ASN_PARSE_E;
06194 
06195         if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
06196             oid == AIA_OCSP_OID)
06197         {
06198             cert->extAuthInfoSz = length;
06199             cert->extAuthInfo = input + idx;
06200             break;
06201         }
06202         idx += length;
06203     }
06204 
06205     return 0;
06206 }
06207 
06208 
06209 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
06210 {
06211     word32 idx = 0;
06212     int length = 0, ret = 0;
06213 
06214     WOLFSSL_ENTER("DecodeAuthKeyId");
06215 
06216     if (GetSequence(input, &idx, &length, sz) < 0) {
06217         WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
06218         return ASN_PARSE_E;
06219     }
06220 
06221     if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
06222         WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
06223         return 0;
06224     }
06225 
06226     if (GetLength(input, &idx, &length, sz) <= 0) {
06227         WOLFSSL_MSG("\tfail: extension data length");
06228         return ASN_PARSE_E;
06229     }
06230 
06231 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06232     cert->extAuthKeyIdSrc = &input[idx];
06233     cert->extAuthKeyIdSz = length;
06234 #endif /* OPENSSL_EXTRA */
06235 
06236     if (length == KEYID_SIZE) {
06237         XMEMCPY(cert->extAuthKeyId, input + idx, length);
06238     }
06239     else {
06240     #ifdef NO_SHA
06241         ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
06242     #else
06243         ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
06244     #endif
06245     }
06246 
06247     return ret;
06248 }
06249 
06250 
06251 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
06252 {
06253     word32 idx = 0;
06254     int length = 0, ret = 0;
06255 
06256     WOLFSSL_ENTER("DecodeSubjKeyId");
06257 
06258     if (sz <= 0)
06259         return ASN_PARSE_E;
06260 
06261     ret = GetOctetString(input, &idx, &length, sz);
06262     if (ret < 0)
06263         return ret;
06264 
06265     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06266         cert->extSubjKeyIdSrc = &input[idx];
06267         cert->extSubjKeyIdSz = length;
06268     #endif /* OPENSSL_EXTRA */
06269 
06270     if (length == SIGNER_DIGEST_SIZE) {
06271         XMEMCPY(cert->extSubjKeyId, input + idx, length);
06272     }
06273     else {
06274     #ifdef NO_SHA
06275         ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
06276     #else
06277         ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
06278     #endif
06279     }
06280 
06281     return ret;
06282 }
06283 
06284 
06285 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
06286 {
06287     word32 idx = 0;
06288     int length;
06289     int ret;
06290     WOLFSSL_ENTER("DecodeKeyUsage");
06291 
06292     ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
06293     if (ret != 0)
06294         return ret;
06295 
06296     cert->extKeyUsage = (word16)(input[idx]);
06297     if (length == 2)
06298         cert->extKeyUsage |= (word16)(input[idx+1] << 8);
06299 
06300     return 0;
06301 }
06302 
06303 
06304 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
06305 {
06306     word32 idx = 0, oid;
06307     int length;
06308 
06309     WOLFSSL_ENTER("DecodeExtKeyUsage");
06310 
06311     if (GetSequence(input, &idx, &length, sz) < 0) {
06312         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
06313         return ASN_PARSE_E;
06314     }
06315 
06316 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06317     cert->extExtKeyUsageSrc = input + idx;
06318     cert->extExtKeyUsageSz = length;
06319 #endif
06320 
06321     while (idx < (word32)sz) {
06322         if (GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz) < 0)
06323             return ASN_PARSE_E;
06324 
06325         switch (oid) {
06326             case EKU_ANY_OID:
06327                 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
06328                 break;
06329             case EKU_SERVER_AUTH_OID:
06330                 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
06331                 break;
06332             case EKU_CLIENT_AUTH_OID:
06333                 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
06334                 break;
06335             case EKU_CODESIGNING_OID:
06336                 cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
06337                 break;
06338             case EKU_EMAILPROTECT_OID:
06339                 cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
06340                 break;
06341             case EKU_TIMESTAMP_OID:
06342                 cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
06343                 break;
06344             case EKU_OCSP_SIGN_OID:
06345                 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
06346                 break;
06347         }
06348 
06349     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06350         cert->extExtKeyUsageCount++;
06351     #endif
06352     }
06353 
06354     return 0;
06355 }
06356 
06357 
06358 #ifndef IGNORE_NAME_CONSTRAINTS
06359 #define ASN_TYPE_MASK 0xF
06360 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
06361 {
06362     word32 idx = 0;
06363 
06364     (void)heap;
06365 
06366     while (idx < (word32)sz) {
06367         int seqLength, strLength;
06368         word32 nameIdx;
06369         byte b, bType;
06370 
06371         if (GetSequence(input, &idx, &seqLength, sz) < 0) {
06372             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
06373             return ASN_PARSE_E;
06374         }
06375         nameIdx = idx;
06376         b = input[nameIdx++];
06377 
06378         if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
06379             WOLFSSL_MSG("\tinvalid length");
06380             return ASN_PARSE_E;
06381         }
06382 
06383         /* Get type, LSB 4-bits */
06384         bType = (b & ASN_TYPE_MASK);
06385 
06386         if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
06387                                                         bType == ASN_DIR_TYPE) {
06388             Base_entry* entry;
06389 
06390             /* if constructed has leading sequence */
06391             if (b & ASN_CONSTRUCTED) {
06392                 if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
06393                     WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
06394                     return ASN_PARSE_E;
06395                 }
06396             }
06397 
06398             entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
06399                                                           DYNAMIC_TYPE_ALTNAME);
06400             if (entry == NULL) {
06401                 WOLFSSL_MSG("allocate error");
06402                 return MEMORY_E;
06403             }
06404 
06405             entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
06406             if (entry->name == NULL) {
06407                 WOLFSSL_MSG("allocate error");
06408                 XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
06409                 return MEMORY_E;
06410             }
06411 
06412             XMEMCPY(entry->name, &input[nameIdx], strLength);
06413             entry->nameSz = strLength;
06414             entry->type = bType;
06415 
06416             entry->next = *head;
06417             *head = entry;
06418         }
06419 
06420         idx += seqLength;
06421     }
06422 
06423     return 0;
06424 }
06425 
06426 
06427 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
06428 {
06429     word32 idx = 0;
06430     int length = 0;
06431 
06432     WOLFSSL_ENTER("DecodeNameConstraints");
06433 
06434     if (GetSequence(input, &idx, &length, sz) < 0) {
06435         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
06436         return ASN_PARSE_E;
06437     }
06438 
06439     while (idx < (word32)sz) {
06440         byte b = input[idx++];
06441         Base_entry** subtree = NULL;
06442 
06443         if (GetLength(input, &idx, &length, sz) <= 0) {
06444             WOLFSSL_MSG("\tinvalid length");
06445             return ASN_PARSE_E;
06446         }
06447 
06448         if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
06449             subtree = &cert->permittedNames;
06450         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
06451             subtree = &cert->excludedNames;
06452         else {
06453             WOLFSSL_MSG("\tinvalid subtree");
06454             return ASN_PARSE_E;
06455         }
06456 
06457         DecodeSubtree(input + idx, length, subtree, cert->heap);
06458 
06459         idx += length;
06460     }
06461 
06462     return 0;
06463 }
06464 #endif /* IGNORE_NAME_CONSTRAINTS */
06465 
06466 #if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)
06467 
06468 static int Word32ToString(char* d, word32 number)
06469 {
06470     int i = 0;
06471 
06472     if (d != NULL) {
06473         word32 order = 1000000000;
06474         word32 digit;
06475 
06476         if (number == 0) {
06477             d[i++] = '0';
06478         }
06479         else {
06480             while (order) {
06481                 digit = number / order;
06482                 if (i > 0 || digit != 0) {
06483                     d[i++] = (char)digit + '0';
06484                 }
06485                 if (digit != 0)
06486                     number %= digit * order;
06487                 if (order > 1)
06488                     order /= 10;
06489                 else
06490                     order = 0;
06491             }
06492         }
06493         d[i] = 0;
06494     }
06495 
06496     return i;
06497 }
06498 
06499 
06500 /* Decode ITU-T X.690 OID format to a string representation
06501  * return string length */
06502 int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
06503 {
06504     word32 val, idx = 0, nb_bytes;
06505     size_t w_bytes = 0;
06506 
06507     if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
06508         return BAD_FUNC_ARG;
06509 
06510     /* first two byte must be interpreted as : 40 * int1 + int2 */
06511     val = (word16)in[idx++];
06512 
06513     w_bytes = Word32ToString(out, val / 40);
06514     out[w_bytes++] = '.';
06515     w_bytes += Word32ToString(out+w_bytes, val % 40);
06516 
06517     while (idx < inSz) {
06518         /* init value */
06519         val = 0;
06520         nb_bytes = 0;
06521 
06522         /* check that output size is ok */
06523         if (w_bytes > (outSz - 3))
06524             return BUFFER_E;
06525 
06526         /* first bit is used to set if value is coded on 1 or multiple bytes */
06527         while ((in[idx+nb_bytes] & 0x80))
06528             nb_bytes++;
06529 
06530         if (!nb_bytes)
06531             val = (word32)(in[idx++] & 0x7f);
06532         else {
06533             word32 base = 1, tmp = nb_bytes;
06534 
06535             while (tmp != 0) {
06536                 val += (word32)(in[idx+tmp] & 0x7f) * base;
06537                 base *= 128;
06538                 tmp--;
06539             }
06540             val += (word32)(in[idx++] & 0x7f) * base;
06541 
06542             idx += nb_bytes;
06543         }
06544 
06545         out[w_bytes++] = '.';
06546         w_bytes += Word32ToString(out+w_bytes, val);
06547     }
06548 
06549     return (int)w_bytes;
06550 }
06551 #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
06552 
06553 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
06554     /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
06555     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
06556     {
06557         word32 idx = 0;
06558         word32 oldIdx;
06559         int ret;
06560         int total_length = 0, policy_length = 0, length = 0;
06561     #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
06562         !defined(WOLFSSL_DUP_CERTPOL)
06563         int i;
06564     #endif
06565 
06566         WOLFSSL_ENTER("DecodeCertPolicy");
06567 
06568         if (GetSequence(input, &idx, &total_length, sz) < 0) {
06569             WOLFSSL_MSG("\tGet CertPolicy total seq failed");
06570             return ASN_PARSE_E;
06571         }
06572 
06573         /* Validate total length */
06574         if (total_length > (sz - (int)idx)) {
06575             WOLFSSL_MSG("\tCertPolicy length mismatch");
06576             return ASN_PARSE_E;
06577         }
06578 
06579         /* Unwrap certificatePolicies */
06580         do {
06581             if (GetSequence(input, &idx, &policy_length, sz) < 0) {
06582                 WOLFSSL_MSG("\tGet CertPolicy seq failed");
06583                 return ASN_PARSE_E;
06584             }
06585 
06586             oldIdx = idx;
06587             ret = GetASNObjectId(input, &idx, &length, sz);
06588             if (ret != 0)
06589                 return ret;
06590             policy_length -= idx - oldIdx;
06591 
06592             if (length > 0) {
06593                 /* Verify length won't overrun buffer */
06594                 if (length > (sz - (int)idx)) {
06595                     WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
06596                     return ASN_PARSE_E;
06597                 }
06598 
06599         #if defined(WOLFSSL_SEP)
06600                 cert->deviceType = (byte*)XMALLOC(length, cert->heap,
06601                                                   DYNAMIC_TYPE_X509_EXT);
06602                 if (cert->deviceType == NULL) {
06603                     WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
06604                     return MEMORY_E;
06605                 }
06606                 cert->deviceTypeSz = length;
06607                 XMEMCPY(cert->deviceType, input + idx, length);
06608                 break;
06609         #elif defined(WOLFSSL_CERT_EXT)
06610                 /* decode cert policy */
06611                 if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
06612                                     input + idx, length) <= 0) {
06613                     WOLFSSL_MSG("\tCouldn't decode CertPolicy");
06614                     return ASN_PARSE_E;
06615                 }
06616             #ifndef WOLFSSL_DUP_CERTPOL
06617                 /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
06618                  * NOT appear more than once in a certificate policies
06619                  * extension". This is a sanity check for duplicates.
06620                  * extCertPolicies should only have OID values, additional
06621                  * qualifiers need to be stored in a seperate array. */
06622                 for (i = 0; i < cert->extCertPoliciesNb; i++) {
06623                     if (XMEMCMP(cert->extCertPolicies[i],
06624                             cert->extCertPolicies[cert->extCertPoliciesNb],
06625                             MAX_CERTPOL_SZ) == 0) {
06626                             WOLFSSL_MSG("Duplicate policy OIDs not allowed");
06627                             WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
06628                             return CERTPOLICIES_E;
06629                     }
06630                 }
06631             #endif /* !WOLFSSL_DUP_CERTPOL */
06632                 cert->extCertPoliciesNb++;
06633         #else
06634                 WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
06635                 return 0;
06636         #endif
06637             }
06638             idx += policy_length;
06639         } while((int)idx < total_length
06640     #if defined(WOLFSSL_CERT_EXT)
06641             && cert->extCertPoliciesNb < MAX_CERTPOL_NB
06642     #endif
06643         );
06644 
06645         WOLFSSL_LEAVE("DecodeCertPolicy", 0);
06646         return 0;
06647     }
06648 #endif /* WOLFSSL_SEP */
06649 
06650 /* Macro to check if bit is set, if not sets and return success.
06651     Otherwise returns failure */
06652 /* Macro required here because bit-field operation */
06653 #ifndef WOLFSSL_NO_ASN_STRICT
06654     #define VERIFY_AND_SET_OID(bit) \
06655         if (bit == 0) \
06656             bit = 1; \
06657         else \
06658             return ASN_OBJECT_ID_E;
06659 #else
06660     /* With no strict defined, the verify is skipped */
06661 #define VERIFY_AND_SET_OID(bit) bit = 1;
06662 #endif
06663 
06664 static int DecodeCertExtensions(DecodedCert* cert)
06665 /*
06666  *  Processing the Certificate Extensions. This does not modify the current
06667  *  index. It is works starting with the recorded extensions pointer.
06668  */
06669 {
06670     int ret = 0;
06671     word32 idx = 0;
06672     int sz = cert->extensionsSz;
06673     byte* input = cert->extensions;
06674     int length;
06675     word32 oid;
06676     byte critical = 0;
06677     byte criticalFail = 0;
06678 
06679     WOLFSSL_ENTER("DecodeCertExtensions");
06680 
06681     if (input == NULL || sz == 0)
06682         return BAD_FUNC_ARG;
06683 
06684     if (input[idx++] != ASN_EXTENSIONS) {
06685         WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
06686         return ASN_PARSE_E;
06687     }
06688 
06689     if (GetLength(input, &idx, &length, sz) < 0) {
06690         WOLFSSL_MSG("\tfail: invalid length");
06691         return ASN_PARSE_E;
06692     }
06693 
06694     if (GetSequence(input, &idx, &length, sz) < 0) {
06695         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
06696         return ASN_PARSE_E;
06697     }
06698 
06699     while (idx < (word32)sz) {
06700         if (GetSequence(input, &idx, &length, sz) < 0) {
06701             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
06702             return ASN_PARSE_E;
06703         }
06704 
06705         oid = 0;
06706         if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
06707             WOLFSSL_MSG("\tfail: OBJECT ID");
06708             return ret;
06709         }
06710 
06711         /* check for critical flag */
06712         critical = 0;
06713         if (input[idx] == ASN_BOOLEAN) {
06714             ret = GetBoolean(input, &idx, sz);
06715             if (ret < 0) {
06716                 WOLFSSL_MSG("\tfail: critical boolean");
06717                 return ret;
06718             }
06719 
06720             critical = (byte)ret;
06721         }
06722 
06723         /* process the extension based on the OID */
06724         ret = GetOctetString(input, &idx, &length, sz);
06725         if (ret < 0) {
06726             WOLFSSL_MSG("\tfail: bad OCTET STRING");
06727             return ret;
06728         }
06729 
06730         switch (oid) {
06731             case BASIC_CA_OID:
06732                 VERIFY_AND_SET_OID(cert->extBasicConstSet);
06733                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06734                     cert->extBasicConstCrit = critical;
06735                 #endif
06736                 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
06737                     return ASN_PARSE_E;
06738                 break;
06739 
06740             case CRL_DIST_OID:
06741                 VERIFY_AND_SET_OID(cert->extCRLdistSet);
06742                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06743                     cert->extCRLdistCrit = critical;
06744                 #endif
06745                 if (DecodeCrlDist(&input[idx], length, cert) < 0)
06746                     return ASN_PARSE_E;
06747                 break;
06748 
06749             case AUTH_INFO_OID:
06750                 VERIFY_AND_SET_OID(cert->extAuthInfoSet);
06751                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06752                     cert->extAuthInfoCrit = critical;
06753                 #endif
06754                 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
06755                     return ASN_PARSE_E;
06756                 break;
06757 
06758             case ALT_NAMES_OID:
06759                 VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
06760                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06761                     cert->extSubjAltNameCrit = critical;
06762                 #endif
06763                 ret = DecodeAltNames(&input[idx], length, cert);
06764                 if (ret < 0)
06765                     return ret;
06766                 break;
06767 
06768             case AUTH_KEY_OID:
06769                 VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
06770                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06771                     cert->extAuthKeyIdCrit = critical;
06772                 #endif
06773                 #ifndef WOLFSSL_ALLOW_CRIT_SKID
06774                     /* This check is added due to RFC 5280 section 4.2.1.1
06775                      * stating that conforming CA's must mark this extension
06776                      * as non-critical. When parsing extensions check that
06777                      * certificate was made in compliance with this. */
06778                     if (critical) {
06779                         WOLFSSL_MSG("Critical Auth Key ID is not allowed");
06780                         WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
06781                         return ASN_CRIT_EXT_E;
06782                     }
06783                 #endif
06784                 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
06785                     return ASN_PARSE_E;
06786                 break;
06787 
06788             case SUBJ_KEY_OID:
06789                 VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
06790                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06791                     cert->extSubjKeyIdCrit = critical;
06792                 #endif
06793                 #ifndef WOLFSSL_ALLOW_CRIT_SKID
06794                     /* This check is added due to RFC 5280 section 4.2.1.2
06795                      * stating that conforming CA's must mark this extension
06796                      * as non-critical. When parsing extensions check that
06797                      * certificate was made in compliance with this. */
06798                     if (critical) {
06799                         WOLFSSL_MSG("Critical Subject Key ID is not allowed");
06800                         WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
06801                         return ASN_CRIT_EXT_E;
06802                     }
06803                 #endif
06804 
06805                 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
06806                     return ASN_PARSE_E;
06807                 break;
06808 
06809             case CERT_POLICY_OID:
06810                 #ifdef WOLFSSL_SEP
06811                     VERIFY_AND_SET_OID(cert->extCertPolicySet);
06812                     #if defined(OPENSSL_EXTRA) || \
06813                         defined(OPENSSL_EXTRA_X509_SMALL)
06814                         cert->extCertPolicyCrit = critical;
06815                     #endif
06816                 #endif
06817                 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
06818                     if (DecodeCertPolicy(&input[idx], length, cert) < 0) {
06819                         return ASN_PARSE_E;
06820                     }
06821                 #else
06822                     WOLFSSL_MSG("Certificate Policy extension not supported yet.");
06823                 #endif
06824                 break;
06825 
06826             case KEY_USAGE_OID:
06827                 VERIFY_AND_SET_OID(cert->extKeyUsageSet);
06828                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06829                     cert->extKeyUsageCrit = critical;
06830                 #endif
06831                 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
06832                     return ASN_PARSE_E;
06833                 break;
06834 
06835             case EXT_KEY_USAGE_OID:
06836                 VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
06837                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06838                     cert->extExtKeyUsageCrit = critical;
06839                 #endif
06840                 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
06841                     return ASN_PARSE_E;
06842                 break;
06843 
06844             #ifndef IGNORE_NAME_CONSTRAINTS
06845             case NAME_CONS_OID:
06846             #ifndef WOLFSSL_NO_ASN_STRICT
06847                 /* Verify RFC 5280 Sec 4.2.1.10 rule:
06848                     "The name constraints extension,
06849                     which MUST be used only in a CA certificate" */
06850                 if (!cert->isCA) {
06851                     WOLFSSL_MSG("Name constraints allowed only for CA certs");
06852                     return ASN_NAME_INVALID_E;
06853                 }
06854             #endif
06855                 VERIFY_AND_SET_OID(cert->extNameConstraintSet);
06856                 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
06857                     cert->extNameConstraintCrit = critical;
06858                 #endif
06859                 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
06860                     return ASN_PARSE_E;
06861                 break;
06862             #endif /* IGNORE_NAME_CONSTRAINTS */
06863 
06864             case INHIBIT_ANY_OID:
06865                 VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
06866                 WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
06867                 break;
06868 
06869             default:
06870                 /* While it is a failure to not support critical extensions,
06871                  * still parse the certificate ignoring the unsupported
06872                  * extension to allow caller to accept it with the verify
06873                  * callback. */
06874                 if (critical)
06875                     criticalFail = 1;
06876                 break;
06877         }
06878         idx += length;
06879     }
06880 
06881     return criticalFail ? ASN_CRIT_EXT_E : 0;
06882 }
06883 
06884 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
06885 {
06886     int   ret;
06887     char* ptr;
06888 
06889     ret = ParseCertRelative(cert, type, verify, cm);
06890     if (ret < 0)
06891         return ret;
06892 
06893     if (cert->subjectCNLen > 0) {
06894         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
06895                               DYNAMIC_TYPE_SUBJECT_CN);
06896         if (ptr == NULL)
06897             return MEMORY_E;
06898         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
06899         ptr[cert->subjectCNLen] = '\0';
06900         cert->subjectCN = ptr;
06901         cert->subjectCNStored = 1;
06902     }
06903 
06904     if (cert->keyOID == RSAk &&
06905                           cert->publicKey != NULL  && cert->pubKeySize > 0) {
06906         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
06907                               DYNAMIC_TYPE_PUBLIC_KEY);
06908         if (ptr == NULL)
06909             return MEMORY_E;
06910         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
06911         cert->publicKey = (byte *)ptr;
06912         cert->pubKeyStored = 1;
06913     }
06914 
06915     return ret;
06916 }
06917 
06918 /* from SSL proper, for locking can't do find here anymore */
06919 #ifdef __cplusplus
06920     extern "C" {
06921 #endif
06922     WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);
06923     #ifndef NO_SKID
06924         WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
06925     #endif
06926 #ifdef __cplusplus
06927     }
06928 #endif
06929 
06930 
06931 #if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS)
06932 
06933 /* dummy functions, not using wolfSSL so don't need actual ones */
06934 Signer* GetCA(void* signers, byte* hash)
06935 {
06936     (void)hash;
06937 
06938     return (Signer*)signers;
06939 }
06940 
06941 #ifndef NO_SKID
06942 Signer* GetCAByName(void* signers, byte* hash)
06943 {
06944     (void)hash;
06945 
06946     return (Signer*)signers;
06947 }
06948 #endif /* NO_SKID */
06949 
06950 #endif /* WOLFCRYPT_ONLY || NO_CERTS */
06951 
06952 #if (defined(WOLFSSL_ALT_CERT_CHAINS) || \
06953     defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY)) && !defined(NO_SKID)
06954 static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
06955 {
06956     Signer* ca = NULL;
06957     if (cert->extSubjKeyIdSet)
06958         ca = GetCA(cm, cert->extSubjKeyId);
06959     if (ca == NULL)
06960         ca = GetCAByName(cm, cert->subjectHash);
06961     if (ca) {
06962         if ((ca->pubKeySize == cert->pubKeySize) &&
06963                (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
06964             return ca;
06965         }
06966     }
06967     return NULL;
06968 }
06969 #endif
06970 
06971 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
06972 {
06973     int    ret = 0;
06974     int    badDate = 0;
06975     int    criticalExt = 0;
06976     word32 confirmOID;
06977     int    selfSigned = 0;
06978 
06979     if (cert == NULL) {
06980         return BAD_FUNC_ARG;
06981     }
06982 
06983     if (cert->sigCtx.state == SIG_STATE_BEGIN) {
06984         if ((ret = DecodeToKey(cert, verify)) < 0) {
06985             if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
06986                 badDate = ret;
06987             else
06988                 return ret;
06989         }
06990 
06991         WOLFSSL_MSG("Parsed Past Key");
06992 
06993         if (cert->srcIdx < cert->sigIndex) {
06994         #ifndef ALLOW_V1_EXTENSIONS
06995             if (cert->version < 2) {
06996                 WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
06997                 return ASN_VERSION_E;
06998             }
06999         #endif
07000 
07001             /* save extensions */
07002             cert->extensions    = &cert->source[cert->srcIdx];
07003             cert->extensionsSz  = cert->sigIndex - cert->srcIdx;
07004             cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
07005 
07006             if ((ret = DecodeCertExtensions(cert)) < 0) {
07007                 if (ret == ASN_CRIT_EXT_E)
07008                     criticalExt = ret;
07009                 else
07010                     return ret;
07011             }
07012 
07013             /* advance past extensions */
07014             cert->srcIdx = cert->sigIndex;
07015         }
07016 
07017         if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
07018                              oidSigType, cert->maxIdx)) < 0)
07019             return ret;
07020 
07021         if ((ret = GetSignature(cert)) < 0)
07022             return ret;
07023 
07024         if (confirmOID != cert->signatureOID)
07025             return ASN_SIG_OID_E;
07026 
07027     #ifndef NO_SKID
07028         if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
07029                                                         cert->pubKeySize > 0) {
07030         #ifdef NO_SHA
07031             ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
07032                                                             cert->extSubjKeyId);
07033         #else
07034             ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
07035                                                             cert->extSubjKeyId);
07036         #endif /* NO_SHA */
07037             if (ret != 0)
07038                 return ret;
07039         }
07040     #endif /* !NO_SKID */
07041 
07042         if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
07043             cert->ca = NULL;
07044     #ifndef NO_SKID
07045             if (cert->extAuthKeyIdSet)
07046                 cert->ca = GetCA(cm, cert->extAuthKeyId);
07047             if (cert->ca == NULL)
07048                 cert->ca = GetCAByName(cm, cert->issuerHash);
07049 
07050             /* OCSP Only: alt lookup using subject and pub key w/o sig check */
07051         #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
07052             if (cert->ca == NULL && verify == VERIFY_OCSP) {
07053                 cert->ca = GetCABySubjectAndPubKey(cert, cm);
07054                 if (cert->ca) {
07055                     ret = 0; /* success */
07056                     goto exit_pcr;
07057                 }
07058             }
07059         #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
07060 
07061             /* alt lookup using subject and public key */
07062         #ifdef WOLFSSL_ALT_CERT_CHAINS
07063             if (cert->ca == NULL)
07064                 cert->ca = GetCABySubjectAndPubKey(cert, cm);
07065         #endif
07066     #else
07067             cert->ca = GetCA(cm, cert->issuerHash);
07068             if (XMEMCMP(cert->issuerHash, cert->subjectHash, KEYID_SIZE) == 0)
07069                 selfSigned = 1;
07070     #endif /* !NO_SKID */
07071 
07072             WOLFSSL_MSG("About to verify certificate signature");
07073             if (cert->ca) {
07074                 if (cert->isCA && cert->ca->pathLengthSet) {
07075                     if (selfSigned) {
07076                         if (cert->ca->pathLength != 0) {
07077                            WOLFSSL_MSG("Root CA with path length > 0");
07078                            return ASN_PATHLEN_INV_E;
07079                         }
07080                     }
07081                     else {
07082                         if (cert->ca->pathLength == 0) {
07083                             WOLFSSL_MSG("CA with path length 0 signing a CA");
07084                             return ASN_PATHLEN_INV_E;
07085                         }
07086                         else if (cert->pathLength >= cert->ca->pathLength) {
07087 
07088                             WOLFSSL_MSG("CA signing CA with longer path length");
07089                             return ASN_PATHLEN_INV_E;
07090                         }
07091                     }
07092                 }
07093 
07094         #ifdef HAVE_OCSP
07095                 /* Need the CA's public key hash for OCSP */
07096             #ifdef NO_SHA
07097                 ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
07098                                                            cert->issuerKeyHash);
07099             #else
07100                 ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
07101                                                            cert->issuerKeyHash);
07102             #endif /* NO_SHA */
07103                 if (ret != 0)
07104                     return ret;
07105         #endif /* HAVE_OCSP */
07106             }
07107         }
07108     }
07109 
07110     if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
07111         if (cert->ca) {
07112             if (verify == VERIFY || verify == VERIFY_OCSP) {
07113                 /* try to confirm/verify signature */
07114                 if ((ret = ConfirmSignature(&cert->sigCtx,
07115                         cert->source + cert->certBegin,
07116                         cert->sigIndex - cert->certBegin,
07117                         cert->ca->publicKey, cert->ca->pubKeySize,
07118                         cert->ca->keyOID, cert->signature,
07119                         cert->sigLength, cert->signatureOID)) != 0) {
07120                     if (ret != WC_PENDING_E) {
07121                         WOLFSSL_MSG("Confirm signature failed");
07122                     }
07123                     return ret;
07124                 }
07125             #ifndef IGNORE_NAME_CONSTRAINTS
07126                 /* check that this cert's name is permitted by the signer's
07127                  * name constraints */
07128                 if (!ConfirmNameConstraints(cert->ca, cert)) {
07129                     WOLFSSL_MSG("Confirm name constraint failed");
07130                     return ASN_NAME_INVALID_E;
07131                 }
07132             #endif /* IGNORE_NAME_CONSTRAINTS */
07133             }
07134         }
07135         else {
07136             /* no signer */
07137             WOLFSSL_MSG("No CA signer to verify with");
07138             return ASN_NO_SIGNER_E;
07139         }
07140     }
07141 
07142 #if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
07143 exit_pcr:
07144 #endif
07145 
07146     if (badDate != 0)
07147         return badDate;
07148 
07149     if (criticalExt != 0)
07150         return criticalExt;
07151 
07152     return ret;
07153 }
07154 
07155 /* Create and init an new signer */
07156 Signer* MakeSigner(void* heap)
07157 {
07158     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
07159                                        DYNAMIC_TYPE_SIGNER);
07160     if (signer) {
07161         signer->pubKeySize = 0;
07162         signer->keyOID     = 0;
07163         signer->publicKey  = NULL;
07164         signer->nameLen    = 0;
07165         signer->name       = NULL;
07166     #ifndef IGNORE_NAME_CONSTRAINTS
07167         signer->permittedNames = NULL;
07168         signer->excludedNames = NULL;
07169     #endif /* IGNORE_NAME_CONSTRAINTS */
07170         signer->pathLengthSet = 0;
07171         signer->pathLength = 0;
07172     #ifdef WOLFSSL_SIGNER_DER_CERT
07173         signer->derCert    = NULL;
07174     #endif
07175         signer->next       = NULL;
07176     }
07177     (void)heap;
07178 
07179     return signer;
07180 }
07181 
07182 
07183 /* Free an individual signer */
07184 void FreeSigner(Signer* signer, void* heap)
07185 {
07186     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
07187     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
07188 #ifndef IGNORE_NAME_CONSTRAINTS
07189     if (signer->permittedNames)
07190         FreeNameSubtrees(signer->permittedNames, heap);
07191     if (signer->excludedNames)
07192         FreeNameSubtrees(signer->excludedNames, heap);
07193 #endif
07194 #ifdef WOLFSSL_SIGNER_DER_CERT
07195     FreeDer(&signer->derCert);
07196 #endif
07197     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
07198 
07199     (void)heap;
07200 }
07201 
07202 
07203 /* Free the whole singer table with number of rows */
07204 void FreeSignerTable(Signer** table, int rows, void* heap)
07205 {
07206     int i;
07207 
07208     for (i = 0; i < rows; i++) {
07209         Signer* signer = table[i];
07210         while (signer) {
07211             Signer* next = signer->next;
07212             FreeSigner(signer, heap);
07213             signer = next;
07214         }
07215         table[i] = NULL;
07216     }
07217 }
07218 
07219 #ifdef WOLFSSL_TRUST_PEER_CERT
07220 /* Free an individual trusted peer cert */
07221 void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
07222 {
07223     if (tp == NULL) {
07224         return;
07225     }
07226 
07227     if (tp->name) {
07228         XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
07229     }
07230 
07231     if (tp->sig) {
07232         XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
07233     }
07234 #ifndef IGNORE_NAME_CONSTRAINTS
07235     if (tp->permittedNames)
07236         FreeNameSubtrees(tp->permittedNames, heap);
07237     if (tp->excludedNames)
07238         FreeNameSubtrees(tp->excludedNames, heap);
07239 #endif
07240     XFREE(tp, heap, DYNAMIC_TYPE_CERT);
07241 
07242     (void)heap;
07243 }
07244 
07245 /* Free the whole Trusted Peer linked list */
07246 void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
07247 {
07248     int i;
07249 
07250     for (i = 0; i < rows; i++) {
07251         TrustedPeerCert* tp = table[i];
07252         while (tp) {
07253             TrustedPeerCert* next = tp->next;
07254             FreeTrustedPeer(tp, heap);
07255             tp = next;
07256         }
07257         table[i] = NULL;
07258     }
07259 }
07260 #endif /* WOLFSSL_TRUST_PEER_CERT */
07261 
07262 WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
07263 {
07264     int i = 0;
07265 
07266     if (output == NULL)
07267         return BAD_FUNC_ARG;
07268 
07269     if (header) {
07270         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
07271         output[i++] = 3;
07272     }
07273     output[i++] = ASN_INTEGER;
07274     output[i++] = 0x01;
07275     output[i++] = (byte)version;
07276 
07277     return i;
07278 }
07279 
07280 
07281 WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
07282     int maxSnSz)
07283 {
07284     int i = 0;
07285     int snSzInt = (int)snSz;
07286 
07287     if (sn == NULL || output == NULL || snSzInt < 0)
07288         return BAD_FUNC_ARG;
07289 
07290     /* remove leading zeros */
07291     while (snSzInt > 0 && sn[0] == 0) {
07292         snSzInt--;
07293         sn++;
07294     }
07295 
07296     /* truncate if input is too long */
07297     if (snSzInt > maxSnSz)
07298         snSzInt = maxSnSz;
07299 
07300     /* encode ASN Integer, with length and value */
07301     output[i++] = ASN_INTEGER;
07302 
07303     /* handle MSB, to make sure value is positive */
07304     if (sn[0] & 0x80) {
07305         /* make room for zero pad */
07306         if (snSzInt > maxSnSz-1)
07307             snSzInt = maxSnSz-1;
07308 
07309         /* add zero pad */
07310         i += SetLength(snSzInt+1, &output[i]);
07311         output[i++] = 0x00;
07312         XMEMCPY(&output[i], sn, snSzInt);
07313     }
07314     else {
07315         i += SetLength(snSzInt, &output[i]);
07316         XMEMCPY(&output[i], sn, snSzInt);
07317     }
07318 
07319     /* compute final length */
07320     i += snSzInt;
07321 
07322     return i;
07323 }
07324 
07325 WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
07326     byte* serial, int* serialSz, word32 maxIdx)
07327 {
07328     int result = 0;
07329     int ret;
07330 
07331     WOLFSSL_ENTER("GetSerialNumber");
07332 
07333     if (serial == NULL || input == NULL || serialSz == NULL) {
07334         return BAD_FUNC_ARG;
07335     }
07336 
07337     /* First byte is ASN type */
07338     if ((*inOutIdx+1) > maxIdx) {
07339         WOLFSSL_MSG("Bad idx first");
07340         return BUFFER_E;
07341     }
07342 
07343     ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
07344     if (ret != 0)
07345         return ret;
07346 
07347     if (*serialSz > EXTERNAL_SERIAL_SIZE) {
07348         WOLFSSL_MSG("Serial size bad");
07349         return ASN_PARSE_E;
07350     }
07351 
07352     /* return serial */
07353     XMEMCPY(serial, &input[*inOutIdx], *serialSz);
07354     *inOutIdx += *serialSz;
07355 
07356     return result;
07357 }
07358 
07359 
07360 int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
07361 {
07362     int ret = BAD_FUNC_ARG;
07363     if (pDer) {
07364         int dynType = 0;
07365         DerBuffer* der;
07366 
07367         /* Determine dynamic type */
07368         switch (type) {
07369             case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
07370             case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
07371             case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
07372             case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
07373             case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
07374             case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
07375             default:        dynType = DYNAMIC_TYPE_KEY;  break;
07376         }
07377 
07378         /* Setup new buffer */
07379         *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
07380         if (*pDer == NULL) {
07381             return MEMORY_E;
07382         }
07383         XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
07384 
07385         der = *pDer;
07386         der->type = type;
07387         der->dynType = dynType; /* Cache this for FreeDer */
07388         der->heap = heap;
07389         der->buffer = (byte*)der + sizeof(DerBuffer);
07390         der->length = length;
07391         ret = 0; /* Success */
07392     }
07393     return ret;
07394 }
07395 
07396 void FreeDer(DerBuffer** pDer)
07397 {
07398     if (pDer && *pDer)
07399     {
07400         DerBuffer* der = (DerBuffer*)*pDer;
07401 
07402         /* ForceZero private keys */
07403         if (der->type == PRIVATEKEY_TYPE) {
07404             ForceZero(der->buffer, der->length);
07405         }
07406         der->buffer = NULL;
07407         der->length = 0;
07408         XFREE(der, der->heap, der->dynType);
07409 
07410         *pDer = NULL;
07411     }
07412 }
07413 
07414 
07415 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
07416 
07417 /* Max X509 header length indicates the max length + 2 ('\n', '\0') */
07418 #define MAX_X509_HEADER_SZ  (37 + 2)
07419 
07420 const char* const BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
07421 const char* const END_CERT             = "-----END CERTIFICATE-----";
07422 #ifdef WOLFSSL_CERT_REQ
07423     const char* const BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
07424     const char* const END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
07425 #endif
07426 #ifndef NO_DH
07427     const char* const BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
07428     const char* const END_DH_PARAM     = "-----END DH PARAMETERS-----";
07429 #endif
07430 #ifndef NO_DSA
07431     const char* const BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
07432     const char* const END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
07433 #endif
07434 const char* const BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
07435 const char* const END_X509_CRL         = "-----END X509 CRL-----";
07436 const char* const BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
07437 const char* const END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
07438 const char* const BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
07439 const char* const END_PRIV_KEY         = "-----END PRIVATE KEY-----";
07440 const char* const BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
07441 const char* const END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
07442 #ifdef HAVE_ECC
07443     const char* const BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
07444     const char* const END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
07445 #endif
07446 #if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA)
07447     const char* const BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
07448     const char* const END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
07449 #endif
07450 const char* const BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
07451 const char* const END_PUB_KEY          = "-----END PUBLIC KEY-----";
07452 #ifdef HAVE_ED25519
07453     const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
07454     const char* const END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
07455 #endif
07456 #ifdef HAVE_CRL
07457     const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----";
07458     const char* const END_CRL   = "-----END X509 CRL-----";
07459 #endif
07460 
07461 
07462 
07463 int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
07464 {
07465     int ret = BAD_FUNC_ARG;
07466 
07467     switch (type) {
07468         case CA_TYPE:       /* same as below */
07469         case TRUSTED_PEER_TYPE:
07470         case CERT_TYPE:
07471             if (header) *header = BEGIN_CERT;
07472             if (footer) *footer = END_CERT;
07473             ret = 0;
07474             break;
07475 
07476         case CRL_TYPE:
07477             if (header) *header = BEGIN_X509_CRL;
07478             if (footer) *footer = END_X509_CRL;
07479             ret = 0;
07480             break;
07481     #ifndef NO_DH
07482         case DH_PARAM_TYPE:
07483             if (header) *header = BEGIN_DH_PARAM;
07484             if (footer) *footer = END_DH_PARAM;
07485             ret = 0;
07486             break;
07487     #endif
07488     #ifndef NO_DSA
07489         case DSA_PARAM_TYPE:
07490             if (header) *header = BEGIN_DSA_PARAM;
07491             if (footer) *footer = END_DSA_PARAM;
07492             ret = 0;
07493             break;
07494     #endif
07495     #ifdef WOLFSSL_CERT_REQ
07496         case CERTREQ_TYPE:
07497             if (header) *header = BEGIN_CERT_REQ;
07498             if (footer) *footer = END_CERT_REQ;
07499             ret = 0;
07500             break;
07501     #endif
07502     #ifndef NO_DSA
07503         case DSA_TYPE:
07504         case DSA_PRIVATEKEY_TYPE:
07505             if (header) *header = BEGIN_DSA_PRIV;
07506             if (footer) *footer = END_DSA_PRIV;
07507             ret = 0;
07508             break;
07509     #endif
07510     #ifdef HAVE_ECC
07511         case ECC_TYPE:
07512         case ECC_PRIVATEKEY_TYPE:
07513             if (header) *header = BEGIN_EC_PRIV;
07514             if (footer) *footer = END_EC_PRIV;
07515             ret = 0;
07516             break;
07517     #endif
07518         case RSA_TYPE:
07519         case PRIVATEKEY_TYPE:
07520             if (header) *header = BEGIN_RSA_PRIV;
07521             if (footer) *footer = END_RSA_PRIV;
07522             ret = 0;
07523             break;
07524     #ifdef HAVE_ED25519
07525         case ED25519_TYPE:
07526         case EDDSA_PRIVATEKEY_TYPE:
07527             if (header) *header = BEGIN_EDDSA_PRIV;
07528             if (footer) *footer = END_EDDSA_PRIV;
07529             ret = 0;
07530             break;
07531     #endif
07532         case PUBLICKEY_TYPE:
07533             if (header) *header = BEGIN_PUB_KEY;
07534             if (footer) *footer = END_PUB_KEY;
07535             ret = 0;
07536             break;
07537         default:
07538             break;
07539     }
07540     return ret;
07541 }
07542 
07543 #ifdef WOLFSSL_ENCRYPTED_KEYS
07544 
07545 static const char* const kProcTypeHeader = "Proc-Type";
07546 static const char* const kDecInfoHeader = "DEK-Info";
07547 
07548 #ifdef WOLFSSL_PEM_TO_DER
07549 #ifndef NO_DES3
07550     static const char* const kEncTypeDes = "DES-CBC";
07551     static const char* const kEncTypeDes3 = "DES-EDE3-CBC";
07552 #endif
07553 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
07554     static const char* const kEncTypeAesCbc128 = "AES-128-CBC";
07555 #endif
07556 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
07557     static const char* const kEncTypeAesCbc192 = "AES-192-CBC";
07558 #endif
07559 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
07560     static const char* const kEncTypeAesCbc256 = "AES-256-CBC";
07561 #endif
07562 
07563 int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
07564 {
07565     int ret = 0;
07566 
07567     if (info == NULL || cipherInfo == NULL)
07568         return BAD_FUNC_ARG;
07569 
07570     /* determine cipher information */
07571 #ifndef NO_DES3
07572     if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
07573         info->cipherType = WC_CIPHER_DES;
07574         info->keySz = DES_KEY_SIZE;
07575         if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
07576     }
07577     else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
07578         info->cipherType = WC_CIPHER_DES3;
07579         info->keySz = DES3_KEY_SIZE;
07580         if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
07581     }
07582     else
07583 #endif /* !NO_DES3 */
07584 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
07585     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
07586         info->cipherType = WC_CIPHER_AES_CBC;
07587         info->keySz = AES_128_KEY_SIZE;
07588         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
07589     }
07590     else
07591 #endif
07592 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
07593     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
07594         info->cipherType = WC_CIPHER_AES_CBC;
07595         info->keySz = AES_192_KEY_SIZE;
07596         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
07597     }
07598     else
07599 #endif
07600 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
07601     if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
07602         info->cipherType = WC_CIPHER_AES_CBC;
07603         info->keySz = AES_256_KEY_SIZE;
07604         if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
07605     }
07606     else
07607 #endif
07608     {
07609         ret = NOT_COMPILED_IN;
07610     }
07611     return ret;
07612 }
07613 
07614 static int wc_EncryptedInfoParse(EncryptedInfo* info,
07615     char** pBuffer, size_t bufSz)
07616 {
07617     int err = 0;
07618     char*  bufferStart;
07619     char*  bufferEnd;
07620     char*  line;
07621     word32 lineSz;
07622     char*  finish;
07623     word32 finishSz;
07624     char*  start = NULL;
07625     word32 startSz;
07626     char*  newline = NULL;
07627 
07628     if (info == NULL || pBuffer == NULL || bufSz == 0)
07629         return BAD_FUNC_ARG;
07630 
07631     bufferStart = *pBuffer;
07632     bufferEnd = bufferStart + bufSz;
07633 
07634     /* find encrypted info marker */
07635     line = XSTRNSTR(bufferStart, kProcTypeHeader,
07636                     min((word32)bufSz, PEM_LINE_LEN));
07637     if (line != NULL) {
07638         if (line >= bufferEnd) {
07639             return BUFFER_E;
07640         }
07641 
07642         lineSz = (word32)(bufferEnd - line);
07643 
07644         /* find DEC-Info marker */
07645         start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
07646 
07647         if (start == NULL)
07648             return BUFFER_E;
07649 
07650         /* skip dec-info and ": " */
07651         start += XSTRLEN(kDecInfoHeader);
07652         if (start >= bufferEnd)
07653             return BUFFER_E;
07654 
07655         if (start[0] == ':') {
07656             start++;
07657             if (start >= bufferEnd)
07658                 return BUFFER_E;
07659         }
07660         if (start[0] == ' ')
07661             start++;
07662 
07663         startSz = (word32)(bufferEnd - start);
07664         finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
07665 
07666         if ((start != NULL) && (finish != NULL) && (start < finish)) {
07667             if (finish >= bufferEnd) {
07668                 return BUFFER_E;
07669             }
07670 
07671             finishSz = (word32)(bufferEnd - finish);
07672             newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
07673 
07674             /* get cipher name */
07675             if (NAME_SZ < (finish - start)) /* buffer size of info->name */
07676                 return BUFFER_E;
07677             if (XMEMCPY(info->name, start, finish - start) == NULL)
07678                 return BUFFER_E;
07679             info->name[finish - start] = '\0'; /* null term */
07680 
07681             /* get IV */
07682             if (finishSz < sizeof(info->iv) + 1)
07683                 return BUFFER_E;
07684             if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
07685                 return BUFFER_E;
07686 
07687             if (newline == NULL)
07688                 newline = XSTRNSTR(finish, "\n", min(finishSz,
07689                                                      PEM_LINE_LEN));
07690             if ((newline != NULL) && (newline > finish)) {
07691                 info->ivSz = (word32)(newline - (finish + 1));
07692                 info->set = 1;
07693             }
07694             else
07695                 return BUFFER_E;
07696         }
07697         else
07698             return BUFFER_E;
07699 
07700         /* eat blank line */
07701         while (newline < bufferEnd &&
07702                 (*newline == '\r' || *newline == '\n')) {
07703             newline++;
07704         }
07705 
07706         /* return new headerEnd */
07707         if (pBuffer)
07708             *pBuffer = newline;
07709 
07710         /* populate info */
07711         err = wc_EncryptedInfoGet(info, info->name);
07712     }
07713 
07714     return err;
07715 }
07716 #endif /* WOLFSSL_PEM_TO_DER */
07717 
07718 #ifdef WOLFSSL_DER_TO_PEM
07719 static int wc_EncryptedInfoAppend(char* dest, char* cipherInfo)
07720 {
07721     if (cipherInfo != NULL) {
07722         size_t cipherInfoStrLen = XSTRLEN(cipherInfo);
07723         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
07724             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
07725 
07726         XSTRNCAT(dest, kProcTypeHeader, 9);
07727         XSTRNCAT(dest, ": 4,ENCRYPTED\n", 14);
07728         XSTRNCAT(dest, kDecInfoHeader, 8);
07729         XSTRNCAT(dest, ": ", 2);
07730         XSTRNCAT(dest, cipherInfo, cipherInfoStrLen);
07731         XSTRNCAT(dest, "\n\n", 3);
07732     }
07733     return 0;
07734 }
07735 #endif /* WOLFSSL_DER_TO_PEM */
07736 #endif /* WOLFSSL_ENCRYPTED_KEYS */
07737 
07738 #ifdef WOLFSSL_DER_TO_PEM
07739 
07740 /* Used for compatibility API */
07741 int wc_DerToPem(const byte* der, word32 derSz,
07742                 byte* output, word32 outSz, int type)
07743 {
07744     return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
07745 }
07746 
07747 /* convert der buffer to pem into output, can't do inplace, der and output
07748    need to be different */
07749 int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
07750              byte *cipher_info, int type)
07751 {
07752     const char* headerStr = NULL;
07753     const char* footerStr = NULL;
07754 #ifdef WOLFSSL_SMALL_STACK
07755     char* header = NULL;
07756     char* footer = NULL;
07757 #else
07758     char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
07759     char footer[MAX_X509_HEADER_SZ];
07760 #endif
07761     int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
07762     int footerLen = MAX_X509_HEADER_SZ;
07763     int i;
07764     int err;
07765     int outLen;   /* return length or error */
07766 
07767     (void)cipher_info;
07768 
07769     if (der == output)      /* no in place conversion */
07770         return BAD_FUNC_ARG;
07771 
07772     err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
07773     if (err != 0)
07774         return err;
07775 
07776 #ifdef WOLFSSL_SMALL_STACK
07777     header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07778     if (header == NULL)
07779         return MEMORY_E;
07780 
07781     footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07782     if (footer == NULL) {
07783         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07784         return MEMORY_E;
07785     }
07786 #endif
07787 
07788     /* null term and leave room for newline */
07789     header[--headerLen] = '\0'; header[--headerLen] = '\0';
07790     footer[--footerLen] = '\0'; footer[--footerLen] = '\0';
07791 
07792     /* build header and footer based on type */
07793     XSTRNCPY(header, headerStr, headerLen);
07794     XSTRNCPY(footer, footerStr, footerLen);
07795 
07796     /* add new line to end */
07797     XSTRNCAT(header, "\n", 2);
07798     XSTRNCAT(footer, "\n", 2);
07799 
07800 #ifdef WOLFSSL_ENCRYPTED_KEYS
07801     err = wc_EncryptedInfoAppend(header, (char*)cipher_info);
07802     if (err != 0) {
07803     #ifdef WOLFSSL_SMALL_STACK
07804         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07805         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07806     #endif
07807         return err;
07808     }
07809 #endif
07810 
07811     headerLen = (int)XSTRLEN(header);
07812     footerLen = (int)XSTRLEN(footer);
07813 
07814     /* if null output and 0 size passed in then return size needed */
07815     if (!output && outSz == 0) {
07816 #ifdef WOLFSSL_SMALL_STACK
07817         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07818         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07819 #endif
07820         outLen = 0;
07821         if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
07822                 != LENGTH_ONLY_E) {
07823             return err;
07824         }
07825         return headerLen + footerLen + outLen;
07826     }
07827 
07828     if (!der || !output) {
07829 #ifdef WOLFSSL_SMALL_STACK
07830         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07831         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07832 #endif
07833         return BAD_FUNC_ARG;
07834     }
07835 
07836     /* don't even try if outSz too short */
07837     if (outSz < headerLen + footerLen + derSz) {
07838 #ifdef WOLFSSL_SMALL_STACK
07839         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07840         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07841 #endif
07842         return BAD_FUNC_ARG;
07843     }
07844 
07845     /* header */
07846     XMEMCPY(output, header, headerLen);
07847     i = headerLen;
07848 
07849 #ifdef WOLFSSL_SMALL_STACK
07850     XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07851 #endif
07852 
07853     /* body */
07854     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
07855     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
07856 #ifdef WOLFSSL_SMALL_STACK
07857         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07858 #endif
07859         return err;
07860     }
07861     i += outLen;
07862 
07863     /* footer */
07864     if ( (i + footerLen) > (int)outSz) {
07865 #ifdef WOLFSSL_SMALL_STACK
07866         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07867 #endif
07868         return BAD_FUNC_ARG;
07869     }
07870     XMEMCPY(output + i, footer, footerLen);
07871 
07872 #ifdef WOLFSSL_SMALL_STACK
07873     XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07874 #endif
07875 
07876     return outLen + headerLen + footerLen;
07877 }
07878 
07879 #endif /* WOLFSSL_DER_TO_PEM */
07880 
07881 #ifdef WOLFSSL_PEM_TO_DER
07882 
07883 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
07884    info->consumed tracks of PEM bytes consumed in case multiple parts */
07885 int PemToDer(const unsigned char* buff, long longSz, int type,
07886               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
07887 {
07888     const char* header      = NULL;
07889     const char* footer      = NULL;
07890     char*       headerEnd;
07891     char*       footerEnd;
07892     char*       consumedEnd;
07893     char*       bufferEnd   = (char*)(buff + longSz);
07894     long        neededSz;
07895     int         ret         = 0;
07896     int         sz          = (int)longSz;
07897     int         encrypted_key = 0;
07898     DerBuffer*  der;
07899 
07900     WOLFSSL_ENTER("PemToDer");
07901 
07902     /* get PEM header and footer based on type */
07903     ret = wc_PemGetHeaderFooter(type, &header, &footer);
07904     if (ret != 0)
07905         return ret;
07906 
07907     /* map header if not found for type */
07908     for (;;) {
07909         headerEnd = XSTRNSTR((char*)buff, header, sz);
07910 
07911         if (headerEnd || type != PRIVATEKEY_TYPE) {
07912             break;
07913         } else
07914         if (header == BEGIN_RSA_PRIV) {
07915             header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
07916         } else
07917         if (header == BEGIN_PRIV_KEY) {
07918             header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
07919         } else
07920 #ifdef HAVE_ECC
07921         if (header == BEGIN_ENC_PRIV_KEY) {
07922             header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
07923         } else
07924         if (header == BEGIN_EC_PRIV) {
07925             header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
07926         } else
07927 #endif
07928 #ifdef HAVE_ED25519
07929     #ifdef HAVE_ECC
07930         if (header == BEGIN_DSA_PRIV)
07931     #else
07932         if (header == BEGIN_ENC_PRIV_KEY)
07933     #endif
07934         {
07935             header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;
07936         } else
07937 #endif
07938 #ifdef HAVE_CRL
07939         if (type == CRL_TYPE) {
07940             header =  BEGIN_CRL;        footer = END_CRL;
07941         } else
07942 #endif
07943         {
07944             break;
07945         }
07946     }
07947 
07948     if (!headerEnd) {
07949         WOLFSSL_MSG("Couldn't find PEM header");
07950         return ASN_NO_PEM_HEADER;
07951     }
07952 
07953     headerEnd += XSTRLEN(header);
07954 
07955     if ((headerEnd + 1) >= bufferEnd)
07956         return BUFFER_E;
07957 
07958     /* eat end of line */
07959     if (headerEnd[0] == '\n')
07960         headerEnd++;
07961     else if (headerEnd[1] == '\n')
07962         headerEnd += 2;
07963     else {
07964         if (info)
07965             info->consumed = (long)(headerEnd+2 - (char*)buff);
07966         return BUFFER_E;
07967     }
07968 
07969     if (type == PRIVATEKEY_TYPE) {
07970         if (eccKey) {
07971         #ifdef HAVE_ECC
07972             *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0;
07973         #else
07974             *eccKey = 0;
07975         #endif
07976         }
07977     }
07978 
07979 #ifdef WOLFSSL_ENCRYPTED_KEYS
07980     if (info) {
07981         ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
07982         if (ret < 0)
07983             return ret;
07984         if (info->set)
07985             encrypted_key = 1;
07986     }
07987 #endif /* WOLFSSL_ENCRYPTED_KEYS */
07988 
07989     /* find footer */
07990     footerEnd = XSTRNSTR((char*)buff, footer, sz);
07991     if (!footerEnd) {
07992         if (info)
07993             info->consumed = longSz; /* No more certs if no footer */
07994         return BUFFER_E;
07995     }
07996 
07997     consumedEnd = footerEnd + XSTRLEN(footer);
07998 
07999     if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
08000         /* eat end of line */
08001         if (consumedEnd[0] == '\n')
08002             consumedEnd++;
08003         else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
08004             consumedEnd += 2;
08005         else {
08006             if (info)
08007                 info->consumed = (long)(consumedEnd+2 - (char*)buff);
08008             return BUFFER_E;
08009         }
08010     }
08011 
08012     if (info)
08013         info->consumed = (long)(consumedEnd - (char*)buff);
08014 
08015     /* set up der buffer */
08016     neededSz = (long)(footerEnd - headerEnd);
08017     if (neededSz > sz || neededSz <= 0)
08018         return BUFFER_E;
08019 
08020     ret = AllocDer(pDer, (word32)neededSz, type, heap);
08021     if (ret < 0) {
08022         return ret;
08023     }
08024     der = *pDer;
08025 
08026     if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
08027                       der->buffer, &der->length) < 0)
08028         return BUFFER_E;
08029 
08030     if (header == BEGIN_PRIV_KEY && !encrypted_key) {
08031         /* pkcs8 key, convert and adjust length */
08032         if ((ret = ToTraditional(der->buffer, der->length)) < 0)
08033             return ret;
08034 
08035         der->length = ret;
08036         return 0;
08037     }
08038 
08039 #ifdef WOLFSSL_ENCRYPTED_KEYS
08040     if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
08041         int   passwordSz = NAME_SZ;
08042     #ifdef WOLFSSL_SMALL_STACK
08043         char* password = NULL;
08044     #else
08045         char  password[NAME_SZ];
08046     #endif
08047 
08048         if (!info || !info->passwd_cb) {
08049             WOLFSSL_MSG("No password callback set");
08050             return NO_PASSWORD;
08051         }
08052 
08053     #ifdef WOLFSSL_SMALL_STACK
08054         password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
08055         if (password == NULL)
08056             return MEMORY_E;
08057     #endif
08058 
08059         /* get password */
08060         ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
08061             info->passwd_userdata);
08062         if (ret >= 0) {
08063             passwordSz = ret;
08064 
08065             /* convert and adjust length */
08066             if (header == BEGIN_ENC_PRIV_KEY) {
08067             #ifndef NO_PWDBASED
08068                 ret = ToTraditionalEnc(der->buffer, der->length,
08069                                        password, passwordSz);
08070 
08071                 if (ret >= 0) {
08072                     der->length = ret;
08073                 }
08074             #else
08075                 ret = NOT_COMPILED_IN;
08076             #endif
08077             }
08078             /* decrypt the key */
08079             else {
08080                 ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
08081                     (byte*)password, passwordSz, WC_MD5);
08082             }
08083             ForceZero(password, passwordSz);
08084         }
08085 
08086     #ifdef WOLFSSL_SMALL_STACK
08087         XFREE(password, heap, DYNAMIC_TYPE_STRING);
08088     #endif
08089     }
08090 #endif /* WOLFSSL_ENCRYPTED_KEYS */
08091 
08092     return ret;
08093 }
08094 
08095 int wc_PemToDer(const unsigned char* buff, long longSz, int type,
08096               DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
08097 {
08098     return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
08099 }
08100 
08101 
08102 /* our KeyPemToDer password callback, password in userData */
08103 static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
08104 {
08105     (void)rw;
08106 
08107     if (userdata == NULL)
08108         return 0;
08109 
08110     XSTRNCPY(passwd, (char*)userdata, sz);
08111     return min((word32)sz, (word32)XSTRLEN((char*)userdata));
08112 }
08113 
08114 /* Return bytes written to buff or < 0 for error */
08115 int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
08116                         unsigned char* buff, int buffSz, const char* pass)
08117 {
08118     int            eccKey = 0;
08119     int            ret;
08120     DerBuffer*     der = NULL;
08121 #ifdef WOLFSSL_SMALL_STACK
08122     EncryptedInfo* info = NULL;
08123 #else
08124     EncryptedInfo  info[1];
08125 #endif
08126 
08127     WOLFSSL_ENTER("wc_KeyPemToDer");
08128 
08129     if (pem == NULL || buff == NULL || buffSz <= 0) {
08130         WOLFSSL_MSG("Bad pem der args");
08131         return BAD_FUNC_ARG;
08132     }
08133 
08134 #ifdef WOLFSSL_SMALL_STACK
08135     info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
08136                                    DYNAMIC_TYPE_ENCRYPTEDINFO);
08137     if (info == NULL)
08138         return MEMORY_E;
08139 #endif
08140 
08141     XMEMSET(info, 0, sizeof(EncryptedInfo));
08142     info->passwd_cb = OurPasswordCb;
08143     info->passwd_userdata = (void*)pass;
08144 
08145     ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
08146 
08147 #ifdef WOLFSSL_SMALL_STACK
08148     XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
08149 #endif
08150 
08151     if (ret < 0) {
08152         WOLFSSL_MSG("Bad Pem To Der");
08153     }
08154     else {
08155         if (der->length <= (word32)buffSz) {
08156             XMEMCPY(buff, der->buffer, der->length);
08157             ret = der->length;
08158         }
08159         else {
08160             WOLFSSL_MSG("Bad der length");
08161             ret = BAD_FUNC_ARG;
08162         }
08163     }
08164 
08165     FreeDer(&der);
08166     return ret;
08167 }
08168 
08169 
08170 /* Return bytes written to buff or < 0 for error */
08171 int wc_CertPemToDer(const unsigned char* pem, int pemSz,
08172                         unsigned char* buff, int buffSz, int type)
08173 {
08174     int            eccKey = 0;
08175     int            ret;
08176     DerBuffer*     der = NULL;
08177 
08178     WOLFSSL_ENTER("wc_CertPemToDer");
08179 
08180     if (pem == NULL || buff == NULL || buffSz <= 0) {
08181         WOLFSSL_MSG("Bad pem der args");
08182         return BAD_FUNC_ARG;
08183     }
08184 
08185     if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
08186         WOLFSSL_MSG("Bad cert type");
08187         return BAD_FUNC_ARG;
08188     }
08189 
08190 
08191     ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
08192     if (ret < 0) {
08193         WOLFSSL_MSG("Bad Pem To Der");
08194     }
08195     else {
08196         if (der->length <= (word32)buffSz) {
08197             XMEMCPY(buff, der->buffer, der->length);
08198             ret = der->length;
08199         }
08200         else {
08201             WOLFSSL_MSG("Bad der length");
08202             ret = BAD_FUNC_ARG;
08203         }
08204     }
08205 
08206     FreeDer(&der);
08207     return ret;
08208 }
08209 
08210 #endif /* WOLFSSL_PEM_TO_DER */
08211 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
08212 
08213 
08214 #ifdef WOLFSSL_PEM_TO_DER
08215 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
08216 /* Return bytes written to buff or < 0 for error */
08217 int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
08218                            unsigned char* buff, int buffSz)
08219 {
08220     int ret;
08221     DerBuffer* der = NULL;
08222 
08223     WOLFSSL_ENTER("wc_PubKeyPemToDer");
08224 
08225     if (pem == NULL || buff == NULL || buffSz <= 0) {
08226         WOLFSSL_MSG("Bad pem der args");
08227         return BAD_FUNC_ARG;
08228     }
08229 
08230     ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
08231     if (ret < 0) {
08232         WOLFSSL_MSG("Bad Pem To Der");
08233     }
08234     else {
08235         if (der->length <= (word32)buffSz) {
08236             XMEMCPY(buff, der->buffer, der->length);
08237             ret = der->length;
08238         }
08239         else {
08240             WOLFSSL_MSG("Bad der length");
08241             ret = BAD_FUNC_ARG;
08242         }
08243     }
08244 
08245     FreeDer(&der);
08246     return ret;
08247 }
08248 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
08249 #endif /* WOLFSSL_PEM_TO_DER */
08250 
08251 #ifndef NO_FILESYSTEM
08252 
08253 #ifdef WOLFSSL_CERT_GEN
08254 /* load pem cert from file into der buffer, return der size or error */
08255 int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
08256 {
08257 #ifdef WOLFSSL_SMALL_STACK
08258     byte   staticBuffer[1]; /* force XMALLOC */
08259 #else
08260     byte   staticBuffer[FILE_BUFFER_SIZE];
08261 #endif
08262     byte*  fileBuf = staticBuffer;
08263     int    dynamic = 0;
08264     int    ret     = 0;
08265     long   sz      = 0;
08266     XFILE  file    = XFOPEN(fileName, "rb");
08267     DerBuffer* converted = NULL;
08268 
08269     WOLFSSL_ENTER("wc_PemCertToDer");
08270 
08271     if (file == XBADFILE) {
08272         ret = BUFFER_E;
08273     }
08274     else {
08275         XFSEEK(file, 0, XSEEK_END);
08276         sz = XFTELL(file);
08277         XREWIND(file);
08278 
08279         if (sz <= 0) {
08280             ret = BUFFER_E;
08281         }
08282         else if (sz > (long)sizeof(staticBuffer)) {
08283         #ifdef WOLFSSL_STATIC_MEMORY
08284             WOLFSSL_MSG("File was larger then static buffer");
08285             return MEMORY_E;
08286         #endif
08287             fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
08288             if (fileBuf == NULL)
08289                 ret = MEMORY_E;
08290             else
08291                 dynamic = 1;
08292         }
08293 
08294         if (ret == 0) {
08295             if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
08296                 ret = BUFFER_E;
08297             }
08298         #ifdef WOLFSSL_PEM_TO_DER
08299             else {
08300                 ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,  0, NULL,NULL);
08301             }
08302         #endif
08303 
08304             if (ret == 0) {
08305                 if (converted->length < (word32)derSz) {
08306                     XMEMCPY(derBuf, converted->buffer, converted->length);
08307                     ret = converted->length;
08308                 }
08309                 else
08310                     ret = BUFFER_E;
08311             }
08312 
08313             FreeDer(&converted);
08314         }
08315 
08316         XFCLOSE(file);
08317         if (dynamic)
08318             XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
08319     }
08320 
08321     return ret;
08322 }
08323 #endif /* WOLFSSL_CERT_GEN */
08324 
08325 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
08326 /* load pem public key from file into der buffer, return der size or error */
08327 int wc_PemPubKeyToDer(const char* fileName,
08328                            unsigned char* derBuf, int derSz)
08329 {
08330 #ifdef WOLFSSL_SMALL_STACK
08331     byte   staticBuffer[1]; /* force XMALLOC */
08332 #else
08333     byte   staticBuffer[FILE_BUFFER_SIZE];
08334 #endif
08335     byte*  fileBuf = staticBuffer;
08336     int    dynamic = 0;
08337     int    ret     = 0;
08338     long   sz      = 0;
08339     XFILE  file    = XFOPEN(fileName, "rb");
08340     DerBuffer* converted = NULL;
08341 
08342     WOLFSSL_ENTER("wc_PemPubKeyToDer");
08343 
08344     if (file == XBADFILE) {
08345         ret = BUFFER_E;
08346     }
08347     else {
08348         XFSEEK(file, 0, XSEEK_END);
08349         sz = XFTELL(file);
08350         XREWIND(file);
08351 
08352         if (sz <= 0) {
08353             ret = BUFFER_E;
08354         }
08355         else if (sz > (long)sizeof(staticBuffer)) {
08356         #ifdef WOLFSSL_STATIC_MEMORY
08357             WOLFSSL_MSG("File was larger then static buffer");
08358             return MEMORY_E;
08359         #endif
08360             fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
08361             if (fileBuf == NULL)
08362                 ret = MEMORY_E;
08363             else
08364                 dynamic = 1;
08365         }
08366         if (ret == 0) {
08367             if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
08368                 ret = BUFFER_E;
08369             }
08370         #ifdef WOLFSSL_PEM_TO_DER
08371             else {
08372                 ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
08373                                0, NULL, NULL);
08374             }
08375         #endif
08376 
08377             if (ret == 0) {
08378                 if (converted->length < (word32)derSz) {
08379                     XMEMCPY(derBuf, converted->buffer, converted->length);
08380                     ret = converted->length;
08381                 }
08382                 else
08383                     ret = BUFFER_E;
08384             }
08385 
08386             FreeDer(&converted);
08387         }
08388 
08389         XFCLOSE(file);
08390         if (dynamic)
08391             XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
08392     }
08393 
08394     return ret;
08395 }
08396 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
08397 
08398 #endif /* !NO_FILESYSTEM */
08399 
08400 
08401 #if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
08402     ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
08403 /* USER RSA ifdef portions used instead of refactor in consideration for
08404    possible fips build */
08405 /* Write a public RSA key to output */
08406 static int SetRsaPublicKey(byte* output, RsaKey* key,
08407                            int outLen, int with_header)
08408 {
08409 #ifdef WOLFSSL_SMALL_STACK
08410     byte* n = NULL;
08411     byte* e = NULL;
08412 #else
08413     byte n[MAX_RSA_INT_SZ];
08414     byte e[MAX_RSA_E_SZ];
08415 #endif
08416     byte seq[MAX_SEQ_SZ];
08417     byte bitString[1 + MAX_LENGTH_SZ + 1];
08418     int  nSz;
08419     int  eSz;
08420     int  seqSz;
08421     int  bitStringSz;
08422     int  idx;
08423 
08424     if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
08425         return BAD_FUNC_ARG;
08426 
08427     /* n */
08428 #ifdef WOLFSSL_SMALL_STACK
08429     n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08430     if (n == NULL)
08431         return MEMORY_E;
08432 #endif
08433 
08434 #ifdef HAVE_USER_RSA
08435     nSz = SetASNIntRSA(key->n, n);
08436 #else
08437     nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);
08438 #endif
08439     if (nSz < 0) {
08440 #ifdef WOLFSSL_SMALL_STACK
08441         XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08442 #endif
08443         return nSz;
08444     }
08445 
08446     /* e */
08447 #ifdef WOLFSSL_SMALL_STACK
08448     e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08449     if (e == NULL) {
08450 #ifdef WOLFSSL_SMALL_STACK
08451         XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08452 #endif
08453         return MEMORY_E;
08454     }
08455 #endif
08456 
08457 #ifdef HAVE_USER_RSA
08458     eSz = SetASNIntRSA(key->e, e);
08459 #else
08460     eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);
08461 #endif
08462     if (eSz < 0) {
08463 #ifdef WOLFSSL_SMALL_STACK
08464         XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08465         XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08466 #endif
08467         return eSz;
08468     }
08469 
08470     seqSz  = SetSequence(nSz + eSz, seq);
08471 
08472     /* check output size */
08473     if ( (seqSz + nSz + eSz) > outLen) {
08474 #ifdef WOLFSSL_SMALL_STACK
08475         XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08476         XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08477 #endif
08478         return BUFFER_E;
08479     }
08480 
08481     /* headers */
08482     if (with_header) {
08483         int  algoSz;
08484 #ifdef WOLFSSL_SMALL_STACK
08485         byte* algo = NULL;
08486 
08487         algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08488         if (algo == NULL) {
08489             XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08490             XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08491             return MEMORY_E;
08492         }
08493 #else
08494         byte algo[MAX_ALGO_SZ];
08495 #endif
08496         algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
08497         bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
08498 
08499         idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);
08500 
08501         /* check output size */
08502         if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
08503             #ifdef WOLFSSL_SMALL_STACK
08504                 XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08505                 XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08506                 XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08507             #endif
08508 
08509             return BUFFER_E;
08510         }
08511 
08512         /* algo */
08513         XMEMCPY(output + idx, algo, algoSz);
08514         idx += algoSz;
08515         /* bit string */
08516         XMEMCPY(output + idx, bitString, bitStringSz);
08517         idx += bitStringSz;
08518 #ifdef WOLFSSL_SMALL_STACK
08519         XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08520 #endif
08521     }
08522     else
08523         idx = 0;
08524 
08525     /* seq */
08526     XMEMCPY(output + idx, seq, seqSz);
08527     idx += seqSz;
08528     /* n */
08529     XMEMCPY(output + idx, n, nSz);
08530     idx += nSz;
08531     /* e */
08532     XMEMCPY(output + idx, e, eSz);
08533     idx += eSz;
08534 
08535 #ifdef WOLFSSL_SMALL_STACK
08536     XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08537     XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08538 #endif
08539 
08540     return idx;
08541 }
08542 
08543 int RsaPublicKeyDerSize(RsaKey* key, int with_header)
08544 {
08545     byte* dummy = NULL;
08546     byte seq[MAX_SEQ_SZ];
08547     byte bitString[1 + MAX_LENGTH_SZ + 1];
08548     int  nSz;
08549     int  eSz;
08550     int  seqSz;
08551     int  bitStringSz;
08552     int  idx;
08553 
08554     if (key == NULL)
08555         return BAD_FUNC_ARG;
08556 
08557     /* n */
08558     dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08559     if (dummy == NULL)
08560         return MEMORY_E;
08561 
08562 #ifdef HAVE_USER_RSA
08563     nSz = SetASNIntRSA(key->n, dummy);
08564 #else
08565     nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, dummy);
08566 #endif
08567     XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08568     if (nSz < 0) {
08569         return nSz;
08570     }
08571 
08572     /* e */
08573     dummy = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08574     if (dummy == NULL) {
08575         XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08576         return MEMORY_E;
08577     }
08578 
08579 #ifdef HAVE_USER_RSA
08580     eSz = SetASNIntRSA(key->e, dummy);
08581 #else
08582     eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, dummy);
08583 #endif
08584     XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08585     if (eSz < 0) {
08586         return eSz;
08587     }
08588 
08589     seqSz  = SetSequence(nSz + eSz, seq);
08590 
08591     /* headers */
08592     if (with_header) {
08593         int  algoSz;
08594         dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08595         if (dummy == NULL)
08596             return MEMORY_E;
08597 
08598         algoSz = SetAlgoID(RSAk, dummy, oidKeyType, 0);
08599         bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
08600 
08601         idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, dummy);
08602         XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08603 
08604         /* algo */
08605         idx += algoSz;
08606         /* bit string */
08607         idx += bitStringSz;
08608     }
08609     else
08610         idx = 0;
08611 
08612     /* seq */
08613     idx += seqSz;
08614     /* n */
08615     idx += nSz;
08616     /* e */
08617     idx += eSz;
08618 
08619     return idx;
08620 }
08621 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
08622                                            !HAVE_USER_RSA))) */
08623 
08624 
08625 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
08626 
08627 
08628 static mp_int* GetRsaInt(RsaKey* key, int idx)
08629 {
08630     if (idx == 0)
08631         return &key->n;
08632     if (idx == 1)
08633         return &key->e;
08634     if (idx == 2)
08635         return &key->d;
08636     if (idx == 3)
08637         return &key->p;
08638     if (idx == 4)
08639         return &key->q;
08640     if (idx == 5)
08641         return &key->dP;
08642     if (idx == 6)
08643         return &key->dQ;
08644     if (idx == 7)
08645         return &key->u;
08646 
08647     return NULL;
08648 }
08649 
08650 
08651 /* Release Tmp RSA resources */
08652 static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
08653 {
08654     int i;
08655 
08656     (void)heap;
08657 
08658     for (i = 0; i < RSA_INTS; i++)
08659         XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
08660 }
08661 
08662 
08663 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
08664    written */
08665 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
08666 {
08667     word32 seqSz, verSz, rawLen, intTotalLen = 0;
08668     word32 sizes[RSA_INTS];
08669     int    i, j, outLen, ret = 0, mpSz;
08670 
08671     byte  seq[MAX_SEQ_SZ];
08672     byte  ver[MAX_VERSION_SZ];
08673     byte* tmps[RSA_INTS];
08674 
08675     if (!key || !output)
08676         return BAD_FUNC_ARG;
08677 
08678     if (key->type != RSA_PRIVATE)
08679         return BAD_FUNC_ARG;
08680 
08681     for (i = 0; i < RSA_INTS; i++)
08682         tmps[i] = NULL;
08683 
08684     /* write all big ints from key to DER tmps */
08685     for (i = 0; i < RSA_INTS; i++) {
08686         mp_int* keyInt = GetRsaInt(key, i);
08687 
08688         rawLen = mp_unsigned_bin_size(keyInt) + 1;
08689         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
08690                                  DYNAMIC_TYPE_RSA);
08691         if (tmps[i] == NULL) {
08692             ret = MEMORY_E;
08693             break;
08694         }
08695 
08696         mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
08697         if (mpSz < 0) {
08698             ret = mpSz;
08699             break;
08700         }
08701         intTotalLen += (sizes[i] = mpSz);
08702     }
08703 
08704     if (ret != 0) {
08705         FreeTmpRsas(tmps, key->heap);
08706         return ret;
08707     }
08708 
08709     /* make headers */
08710     verSz = SetMyVersion(0, ver, FALSE);
08711     seqSz = SetSequence(verSz + intTotalLen, seq);
08712 
08713     outLen = seqSz + verSz + intTotalLen;
08714     if (outLen > (int)inLen) {
08715         FreeTmpRsas(tmps, key->heap);
08716         return BAD_FUNC_ARG;
08717     }
08718 
08719     /* write to output */
08720     XMEMCPY(output, seq, seqSz);
08721     j = seqSz;
08722     XMEMCPY(output + j, ver, verSz);
08723     j += verSz;
08724 
08725     for (i = 0; i < RSA_INTS; i++) {
08726         XMEMCPY(output + j, tmps[i], sizes[i]);
08727         j += sizes[i];
08728     }
08729     FreeTmpRsas(tmps, key->heap);
08730 
08731     return outLen;
08732 }
08733 #endif
08734 
08735 #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
08736 /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
08737    written */
08738 int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
08739 {
08740     return SetRsaPublicKey(output, key, inLen, 1);
08741 }
08742 
08743 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
08744 
08745 
08746 #ifdef WOLFSSL_CERT_GEN
08747 
08748 /* Initialize and Set Certificate defaults:
08749    version    = 3 (0x2)
08750    serial     = 0
08751    sigType    = SHA_WITH_RSA
08752    issuer     = blank
08753    daysValid  = 500
08754    selfSigned = 1 (true) use subject as issuer
08755    subject    = blank
08756 */
08757 int wc_InitCert(Cert* cert)
08758 {
08759 #ifdef WOLFSSL_MULTI_ATTRIB
08760     int i = 0;
08761 #endif
08762     if (cert == NULL) {
08763         return BAD_FUNC_ARG;
08764     }
08765 
08766     XMEMSET(cert, 0, sizeof(Cert));
08767 
08768     cert->version    = 2;   /* version 3 is hex 2 */
08769 #ifndef NO_SHA
08770     cert->sigType    = CTC_SHAwRSA;
08771 #elif !defined(NO_SHA256)
08772     cert->sigType    = CTC_SHA256wRSA;
08773 #else
08774     cert->sigType    = 0;
08775 #endif
08776     cert->daysValid  = 500;
08777     cert->selfSigned = 1;
08778     cert->keyType    = RSA_KEY;
08779 
08780     cert->issuer.countryEnc = CTC_PRINTABLE;
08781     cert->issuer.stateEnc = CTC_UTF8;
08782     cert->issuer.localityEnc = CTC_UTF8;
08783     cert->issuer.surEnc = CTC_UTF8;
08784     cert->issuer.orgEnc = CTC_UTF8;
08785     cert->issuer.unitEnc = CTC_UTF8;
08786     cert->issuer.commonNameEnc = CTC_UTF8;
08787 
08788     cert->subject.countryEnc = CTC_PRINTABLE;
08789     cert->subject.stateEnc = CTC_UTF8;
08790     cert->subject.localityEnc = CTC_UTF8;
08791     cert->subject.surEnc = CTC_UTF8;
08792     cert->subject.orgEnc = CTC_UTF8;
08793     cert->subject.unitEnc = CTC_UTF8;
08794     cert->subject.commonNameEnc = CTC_UTF8;
08795 
08796 #ifdef WOLFSSL_MULTI_ATTRIB
08797     for (i = 0; i < CTC_MAX_ATTRIB; i++) {
08798         cert->issuer.name[i].type   = CTC_UTF8;
08799         cert->subject.name[i].type  = CTC_UTF8;
08800     }
08801 #endif /* WOLFSSL_MULTI_ATTRIB */
08802 
08803 #ifdef WOLFSSL_HEAP_TEST
08804     cert->heap = (void*)WOLFSSL_HEAP_TEST;
08805 #endif
08806 
08807     return 0;
08808 }
08809 
08810 
08811 /* DER encoded x509 Certificate */
08812 typedef struct DerCert {
08813     byte size[MAX_LENGTH_SZ];          /* length encoded */
08814     byte version[MAX_VERSION_SZ];      /* version encoded */
08815     byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
08816     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
08817     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
08818     byte subject[ASN_NAME_MAX];        /* subject encoded */
08819     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
08820     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
08821     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
08822     byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
08823 #ifdef WOLFSSL_CERT_EXT
08824     byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
08825     byte akid[MAX_KID_SZ];             /* Authority Key Identifier extension */
08826     byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
08827     byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
08828     byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
08829 #endif
08830 #ifdef WOLFSSL_CERT_REQ
08831     byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
08832 #endif
08833 #ifdef WOLFSSL_ALT_NAMES
08834     byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
08835 #endif
08836     int  sizeSz;                       /* encoded size length */
08837     int  versionSz;                    /* encoded version length */
08838     int  serialSz;                     /* encoded serial length */
08839     int  sigAlgoSz;                    /* encoded sig alog length */
08840     int  issuerSz;                     /* encoded issuer length */
08841     int  subjectSz;                    /* encoded subject length */
08842     int  validitySz;                   /* encoded validity length */
08843     int  publicKeySz;                  /* encoded public key length */
08844     int  caSz;                         /* encoded CA extension length */
08845 #ifdef WOLFSSL_CERT_EXT
08846     int  skidSz;                       /* encoded SKID extension length */
08847     int  akidSz;                       /* encoded SKID extension length */
08848     int  keyUsageSz;                   /* encoded KeyUsage extension length */
08849     int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
08850     int  certPoliciesSz;               /* encoded CertPolicies extension length*/
08851 #endif
08852 #ifdef WOLFSSL_ALT_NAMES
08853     int  altNamesSz;                   /* encoded AltNames extension length */
08854 #endif
08855     int  extensionsSz;                 /* encoded extensions total length */
08856     int  total;                        /* total encoded lengths */
08857 #ifdef WOLFSSL_CERT_REQ
08858     int  attribSz;
08859 #endif
08860 } DerCert;
08861 
08862 
08863 #ifdef WOLFSSL_CERT_REQ
08864 
08865 /* Write a set header to output */
08866 static word32 SetUTF8String(word32 len, byte* output)
08867 {
08868     output[0] = ASN_UTF8STRING;
08869     return SetLength(len, output + 1) + 1;
08870 }
08871 
08872 #endif /* WOLFSSL_CERT_REQ */
08873 
08874 #endif /*WOLFSSL_CERT_GEN */
08875 
08876 #if defined(HAVE_ECC)
08877 
08878 /* Write a public ECC key to output */
08879 static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
08880 {
08881     byte bitString[1 + MAX_LENGTH_SZ + 1];
08882     int  algoSz;
08883     int  curveSz;
08884     int  bitStringSz;
08885     int  idx;
08886     word32 pubSz = ECC_BUFSIZE;
08887 #ifdef WOLFSSL_SMALL_STACK
08888     byte* algo = NULL;
08889     byte* curve = NULL;
08890     byte* pub = NULL;
08891 #else
08892     byte algo[MAX_ALGO_SZ];
08893     byte curve[MAX_ALGO_SZ];
08894     byte pub[ECC_BUFSIZE];
08895 #endif
08896     int ret;
08897 
08898 #ifdef WOLFSSL_SMALL_STACK
08899     pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08900     if (pub == NULL)
08901         return MEMORY_E;
08902 #endif
08903 
08904     ret = wc_ecc_export_x963(key, pub, &pubSz);
08905     if (ret != 0) {
08906 #ifdef WOLFSSL_SMALL_STACK
08907         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08908 #endif
08909         return ret;
08910     }
08911 
08912     /* headers */
08913     if (with_header) {
08914 #ifdef WOLFSSL_SMALL_STACK
08915         curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08916         if (curve == NULL) {
08917             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08918             return MEMORY_E;
08919         }
08920 #endif
08921         curveSz = SetCurve(key, curve);
08922         if (curveSz <= 0) {
08923 #ifdef WOLFSSL_SMALL_STACK
08924             XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08925             XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08926 #endif
08927             return curveSz;
08928         }
08929 
08930 #ifdef WOLFSSL_SMALL_STACK
08931         algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08932         if (algo == NULL) {
08933             XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08934             XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08935             return MEMORY_E;
08936         }
08937 #endif
08938         algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
08939 
08940         bitStringSz = SetBitString(pubSz, 0, bitString);
08941 
08942         idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
08943         /* algo */
08944         XMEMCPY(output + idx, algo, algoSz);
08945         idx += algoSz;
08946        /* curve */
08947         XMEMCPY(output + idx, curve, curveSz);
08948         idx += curveSz;
08949         /* bit string */
08950         XMEMCPY(output + idx, bitString, bitStringSz);
08951         idx += bitStringSz;
08952     }
08953     else
08954         idx = 0;
08955 
08956     /* pub */
08957     XMEMCPY(output + idx, pub, pubSz);
08958     idx += pubSz;
08959 
08960 #ifdef WOLFSSL_SMALL_STACK
08961     if (with_header) {
08962         XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08963         XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08964     }
08965     XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
08966 #endif
08967 
08968     return idx;
08969 }
08970 
08971 
08972 /* returns the size of buffer used, the public ECC key in DER format is stored
08973    in output buffer
08974    with_AlgCurve is a flag for when to include a header that has the Algorithm
08975    and Curve infromation */
08976 int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
08977                                                               int with_AlgCurve)
08978 {
08979     word32 infoSz = 0;
08980     word32 keySz  = 0;
08981     int ret;
08982 
08983     if (output == NULL || key == NULL) {
08984         return BAD_FUNC_ARG;
08985     }
08986 
08987     if (with_AlgCurve) {
08988         /* buffer space for algorithm/curve */
08989         infoSz += MAX_SEQ_SZ;
08990         infoSz += 2 * MAX_ALGO_SZ;
08991 
08992         /* buffer space for public key sequence */
08993         infoSz += MAX_SEQ_SZ;
08994         infoSz += TRAILING_ZERO;
08995     }
08996 
08997     if ((ret = wc_ecc_export_x963(key, NULL, &keySz)) != LENGTH_ONLY_E) {
08998         WOLFSSL_MSG("Error in getting ECC public key size");
08999         return ret;
09000     }
09001 
09002     if (inLen < keySz + infoSz) {
09003         return BUFFER_E;
09004     }
09005 
09006     return SetEccPublicKey(output, key, with_AlgCurve);
09007 }
09008 #endif /* HAVE_ECC */
09009 
09010 #if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \
09011                               defined(WOLFSSL_KEY_GEN))
09012 
09013 /* Write a public ECC key to output */
09014 static int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header)
09015 {
09016     byte bitString[1 + MAX_LENGTH_SZ + 1];
09017     int  algoSz;
09018     int  bitStringSz;
09019     int  idx;
09020     word32 pubSz = ED25519_PUB_KEY_SIZE;
09021 #ifdef WOLFSSL_SMALL_STACK
09022     byte* algo = NULL;
09023     byte* pub = NULL;
09024 #else
09025     byte algo[MAX_ALGO_SZ];
09026     byte pub[ED25519_PUB_KEY_SIZE];
09027 #endif
09028 
09029 #ifdef WOLFSSL_SMALL_STACK
09030     pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09031     if (pub == NULL)
09032         return MEMORY_E;
09033 #endif
09034 
09035     int ret = wc_ed25519_export_public(key, pub, &pubSz);
09036     if (ret != 0) {
09037 #ifdef WOLFSSL_SMALL_STACK
09038         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09039 #endif
09040         return ret;
09041     }
09042 
09043     /* headers */
09044     if (with_header) {
09045 #ifdef WOLFSSL_SMALL_STACK
09046         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09047         if (algo == NULL) {
09048             XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09049             return MEMORY_E;
09050         }
09051 #endif
09052         algoSz  = SetAlgoID(ED25519k, algo, oidKeyType, 0);
09053 
09054         bitStringSz = SetBitString(pubSz, 0, bitString);
09055 
09056         idx = SetSequence(pubSz + bitStringSz + algoSz, output);
09057         /* algo */
09058         XMEMCPY(output + idx, algo, algoSz);
09059         idx += algoSz;
09060         /* bit string */
09061         XMEMCPY(output + idx, bitString, bitStringSz);
09062         idx += bitStringSz;
09063     }
09064     else
09065         idx = 0;
09066 
09067     /* pub */
09068     XMEMCPY(output + idx, pub, pubSz);
09069     idx += pubSz;
09070 
09071 #ifdef WOLFSSL_SMALL_STACK
09072     if (with_header) {
09073         XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09074     }
09075     XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09076 #endif
09077 
09078     return idx;
09079 }
09080 
09081 int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
09082                                                                     int withAlg)
09083 {
09084     word32 infoSz = 0;
09085     word32 keySz  = 0;
09086     int ret;
09087 
09088     if (output == NULL || key == NULL) {
09089         return BAD_FUNC_ARG;
09090     }
09091 
09092     if (withAlg) {
09093         /* buffer space for algorithm */
09094         infoSz += MAX_SEQ_SZ;
09095         infoSz += MAX_ALGO_SZ;
09096 
09097         /* buffer space for public key sequence */
09098         infoSz += MAX_SEQ_SZ;
09099         infoSz += TRAILING_ZERO;
09100     }
09101 
09102     if ((ret = wc_ed25519_export_public(key, output, &keySz)) != BUFFER_E) {
09103         WOLFSSL_MSG("Error in getting ECC public key size");
09104         return ret;
09105     }
09106 
09107     if (inLen < keySz + infoSz) {
09108         return BUFFER_E;
09109     }
09110 
09111     return SetEd25519PublicKey(output, key, withAlg);
09112 }
09113 #endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
09114 
09115 
09116 #ifdef WOLFSSL_CERT_GEN
09117 
09118 static WC_INLINE byte itob(int number)
09119 {
09120     return (byte)number + 0x30;
09121 }
09122 
09123 
09124 /* write time to output, format */
09125 static void SetTime(struct tm* date, byte* output)
09126 {
09127     int i = 0;
09128 
09129     output[i++] = itob((date->tm_year % 10000) / 1000);
09130     output[i++] = itob((date->tm_year % 1000)  /  100);
09131     output[i++] = itob((date->tm_year % 100)   /   10);
09132     output[i++] = itob( date->tm_year % 10);
09133 
09134     output[i++] = itob(date->tm_mon / 10);
09135     output[i++] = itob(date->tm_mon % 10);
09136 
09137     output[i++] = itob(date->tm_mday / 10);
09138     output[i++] = itob(date->tm_mday % 10);
09139 
09140     output[i++] = itob(date->tm_hour / 10);
09141     output[i++] = itob(date->tm_hour % 10);
09142 
09143     output[i++] = itob(date->tm_min / 10);
09144     output[i++] = itob(date->tm_min % 10);
09145 
09146     output[i++] = itob(date->tm_sec / 10);
09147     output[i++] = itob(date->tm_sec % 10);
09148 
09149     output[i] = 'Z';  /* Zulu profile */
09150 }
09151 
09152 
09153 #ifdef WOLFSSL_ALT_NAMES
09154 
09155 /* Copy Dates from cert, return bytes written */
09156 static int CopyValidity(byte* output, Cert* cert)
09157 {
09158     int seqSz;
09159 
09160     WOLFSSL_ENTER("CopyValidity");
09161 
09162     /* headers and output */
09163     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
09164     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
09165     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
09166                                                  cert->afterDateSz);
09167     return seqSz + cert->beforeDateSz + cert->afterDateSz;
09168 }
09169 
09170 #endif
09171 
09172 
09173 /* Set Date validity from now until now + daysValid
09174  * return size in bytes written to output, 0 on error */
09175 static int SetValidity(byte* output, int daysValid)
09176 {
09177     byte before[MAX_DATE_SIZE];
09178     byte  after[MAX_DATE_SIZE];
09179 
09180     int beforeSz;
09181     int afterSz;
09182     int seqSz;
09183 
09184     time_t now;
09185     time_t then;
09186     struct tm* tmpTime = NULL;
09187     struct tm* expandedTime;
09188     struct tm localTime;
09189 
09190 #if defined(NEED_TMP_TIME)
09191     /* for use with gmtime_r */
09192     struct tm tmpTimeStorage;
09193     tmpTime = &tmpTimeStorage;
09194 #else
09195     (void)tmpTime;
09196 #endif
09197 
09198     now = XTIME(0);
09199 
09200     /* before now */
09201     before[0] = ASN_GENERALIZED_TIME;
09202     beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
09203 
09204     /* subtract 1 day of seconds for more compliance */
09205     then = now - 86400;
09206     expandedTime = XGMTIME(&then, tmpTime);
09207     if (expandedTime == NULL) {
09208         WOLFSSL_MSG("XGMTIME failed");
09209         return 0;   /* error */
09210     }
09211     localTime = *expandedTime;
09212 
09213     /* adjust */
09214     localTime.tm_year += 1900;
09215     localTime.tm_mon +=    1;
09216 
09217     SetTime(&localTime, before + beforeSz);
09218     beforeSz += ASN_GEN_TIME_SZ;
09219 
09220     after[0] = ASN_GENERALIZED_TIME;
09221     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
09222 
09223     /* add daysValid of seconds */
09224     then = now + (daysValid * 3600);
09225     expandedTime = XGMTIME(&then, tmpTime);
09226     if (expandedTime == NULL) {
09227         WOLFSSL_MSG("XGMTIME failed");
09228         return 0;   /* error */
09229     }
09230     localTime = *expandedTime;
09231 
09232     /* adjust */
09233     localTime.tm_year += 1900;
09234     localTime.tm_mon  +=    1;
09235 
09236     SetTime(&localTime, after + afterSz);
09237     afterSz += ASN_GEN_TIME_SZ;
09238 
09239     /* headers and output */
09240     seqSz = SetSequence(beforeSz + afterSz, output);
09241     XMEMCPY(output + seqSz, before, beforeSz);
09242     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
09243 
09244     return seqSz + beforeSz + afterSz;
09245 }
09246 
09247 
09248 /* ASN Encoded Name field */
09249 typedef struct EncodedName {
09250     int  nameLen;                /* actual string value length */
09251     int  totalLen;               /* total encoded length */
09252     int  type;                   /* type of name */
09253     int  used;                   /* are we actually using this one */
09254     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
09255 } EncodedName;
09256 
09257 
09258 /* Get Which Name from index */
09259 static const char* GetOneName(CertName* name, int idx)
09260 {
09261     switch (idx) {
09262     case 0:
09263        return name->country;
09264 
09265     case 1:
09266        return name->state;
09267 
09268     case 2:
09269        return name->locality;
09270 
09271     case 3:
09272        return name->sur;
09273 
09274     case 4:
09275        return name->org;
09276 
09277     case 5:
09278        return name->unit;
09279 
09280     case 6:
09281        return name->commonName;
09282 
09283     case 7:
09284        return name->email;
09285 
09286     default:
09287        return 0;
09288     }
09289 }
09290 
09291 
09292 /* Get Which Name Encoding from index */
09293 static char GetNameType(CertName* name, int idx)
09294 {
09295     switch (idx) {
09296     case 0:
09297        return name->countryEnc;
09298 
09299     case 1:
09300        return name->stateEnc;
09301 
09302     case 2:
09303        return name->localityEnc;
09304 
09305     case 3:
09306        return name->surEnc;
09307 
09308     case 4:
09309        return name->orgEnc;
09310 
09311     case 5:
09312        return name->unitEnc;
09313 
09314     case 6:
09315        return name->commonNameEnc;
09316 
09317     default:
09318        return 0;
09319     }
09320 }
09321 
09322 
09323 /* Get ASN Name from index */
09324 static byte GetNameId(int idx)
09325 {
09326     switch (idx) {
09327     case 0:
09328        return ASN_COUNTRY_NAME;
09329 
09330     case 1:
09331        return ASN_STATE_NAME;
09332 
09333     case 2:
09334        return ASN_LOCALITY_NAME;
09335 
09336     case 3:
09337        return ASN_SUR_NAME;
09338 
09339     case 4:
09340        return ASN_ORG_NAME;
09341 
09342     case 5:
09343        return ASN_ORGUNIT_NAME;
09344 
09345     case 6:
09346        return ASN_COMMON_NAME;
09347 
09348     case 7:
09349        return ASN_EMAIL_NAME;
09350 
09351     default:
09352        return 0;
09353     }
09354 }
09355 
09356 /*
09357  Extensions ::= SEQUENCE OF Extension
09358 
09359  Extension ::= SEQUENCE {
09360  extnId     OBJECT IDENTIFIER,
09361  critical   BOOLEAN DEFAULT FALSE,
09362  extnValue  OCTET STRING }
09363  */
09364 
09365 /* encode all extensions, return total bytes written */
09366 static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
09367                          const byte* ext, int extSz)
09368 {
09369     if (out == NULL || IdxInOut == NULL || ext == NULL)
09370         return BAD_FUNC_ARG;
09371 
09372     if (outSz < (word32)(*IdxInOut+extSz))
09373         return BUFFER_E;
09374 
09375     XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
09376     *IdxInOut += extSz;
09377 
09378     return *IdxInOut;
09379 }
09380 
09381 /* encode extensions header, return total bytes written */
09382 static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
09383 {
09384     byte sequence[MAX_SEQ_SZ];
09385     byte len[MAX_LENGTH_SZ];
09386     int seqSz, lenSz, idx = 0;
09387 
09388     if (out == NULL)
09389         return BAD_FUNC_ARG;
09390 
09391     if (outSz < 3)
09392         return BUFFER_E;
09393 
09394     seqSz = SetSequence(extSz, sequence);
09395 
09396     /* encode extensions length provided */
09397     lenSz = SetLength(extSz+seqSz, len);
09398 
09399     if (outSz < (word32)(lenSz+seqSz+1))
09400         return BUFFER_E;
09401 
09402     out[idx++] = ASN_EXTENSIONS; /* extensions id */
09403     XMEMCPY(&out[idx], len, lenSz);  /* length */
09404     idx += lenSz;
09405 
09406     XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
09407     idx += seqSz;
09408 
09409     return idx;
09410 }
09411 
09412 
09413 /* encode CA basic constraint true, return total bytes written */
09414 static int SetCa(byte* out, word32 outSz)
09415 {
09416     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
09417                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
09418 
09419     if (out == NULL)
09420         return BAD_FUNC_ARG;
09421 
09422     if (outSz < sizeof(ca))
09423         return BUFFER_E;
09424 
09425     XMEMCPY(out, ca, sizeof(ca));
09426 
09427     return (int)sizeof(ca);
09428 }
09429 
09430 
09431 #ifdef WOLFSSL_CERT_EXT
09432 /* encode OID and associated value, return total bytes written */
09433 static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
09434                        byte *in, word32 inSz)
09435 {
09436     int idx = 0;
09437 
09438     if (out == NULL || oid == NULL || in == NULL)
09439         return BAD_FUNC_ARG;
09440 
09441     if (outSz < 3)
09442         return BUFFER_E;
09443 
09444     /* sequence,  + 1 => byte to put value size */
09445     idx = SetSequence(inSz + oidSz + 1, out);
09446 
09447     if ((idx + inSz + oidSz + 1) > outSz)
09448         return BUFFER_E;
09449 
09450     XMEMCPY(out+idx, oid, oidSz);
09451     idx += oidSz;
09452     out[idx++] = (byte)inSz;
09453     XMEMCPY(out+idx, in, inSz);
09454 
09455     return (idx+inSz);
09456 }
09457 
09458 /* encode Subject Key Identifier, return total bytes written
09459  * RFC5280 : non-critical */
09460 static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
09461 {
09462     byte skid_len[1 + MAX_LENGTH_SZ];
09463     byte skid_enc_len[MAX_LENGTH_SZ];
09464     int idx = 0, skid_lenSz, skid_enc_lenSz;
09465     static const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
09466 
09467     if (output == NULL || input == NULL)
09468         return BAD_FUNC_ARG;
09469 
09470     /* Octet String header */
09471     skid_lenSz = SetOctetString(length, skid_len);
09472 
09473     /* length of encoded value */
09474     skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
09475 
09476     if (outSz < 3)
09477         return BUFFER_E;
09478 
09479     idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
09480                       output);
09481 
09482     if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
09483         return BUFFER_E;
09484 
09485     /* put oid */
09486     XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
09487     idx += sizeof(skid_oid);
09488 
09489     /* put encoded len */
09490     XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
09491     idx += skid_enc_lenSz;
09492 
09493     /* put octet header */
09494     XMEMCPY(output+idx, skid_len, skid_lenSz);
09495     idx += skid_lenSz;
09496 
09497     /* put value */
09498     XMEMCPY(output+idx, input, length);
09499     idx += length;
09500 
09501     return idx;
09502 }
09503 
09504 /* encode Authority Key Identifier, return total bytes written
09505  * RFC5280 : non-critical */
09506 static int SetAKID(byte* output, word32 outSz,
09507                                          byte *input, word32 length, void* heap)
09508 {
09509     byte    *enc_val;
09510     int     ret, enc_valSz;
09511     static const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04 };
09512     static const byte akid_cs[] = { 0x80 };
09513 
09514     if (output == NULL || input == NULL)
09515         return BAD_FUNC_ARG;
09516 
09517     enc_valSz = length + 3 + sizeof(akid_cs);
09518     enc_val = (byte *)XMALLOC(enc_valSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
09519     if (enc_val == NULL)
09520         return MEMORY_E;
09521 
09522     /* sequence for ContentSpec & value */
09523     ret = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
09524                       input, length);
09525     if (ret > 0) {
09526         enc_valSz = ret;
09527 
09528         ret = SetOidValue(output, outSz, akid_oid, sizeof(akid_oid),
09529                           enc_val, enc_valSz);
09530     }
09531 
09532     XFREE(enc_val, heap, DYNAMIC_TYPE_TMP_BUFFER);
09533     return ret;
09534 }
09535 
09536 /* encode Key Usage, return total bytes written
09537  * RFC5280 : critical */
09538 static int SetKeyUsage(byte* output, word32 outSz, word16 input)
09539 {
09540     byte ku[5];
09541     int  idx;
09542     static const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
09543                                          0x01, 0x01, 0xff, 0x04};
09544     if (output == NULL)
09545         return BAD_FUNC_ARG;
09546 
09547     idx = SetBitString16Bit(input, ku);
09548     return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
09549                        ku, idx);
09550 }
09551 
09552 static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
09553     const byte* oid, word32 oidSz)
09554 {
09555     /* verify room */
09556     if (*idx + 2 + oidSz >= outSz)
09557         return ASN_PARSE_E;
09558 
09559     *idx += SetObjectId(oidSz, &output[*idx]);
09560     XMEMCPY(&output[*idx], oid, oidSz);
09561     *idx += oidSz;
09562 
09563     return 0;
09564 }
09565 
09566 /* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
09567 static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
09568 {
09569     int idx = 0, oidListSz = 0, totalSz, ret = 0;
09570     static const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
09571 
09572     if (output == NULL)
09573         return BAD_FUNC_ARG;
09574 
09575     /* Skip to OID List */
09576     totalSz = 2 + sizeof(extkeyusage_oid) + 4;
09577     idx = totalSz;
09578 
09579     /* Build OID List */
09580     /* If any set, then just use it */
09581     if (input & EXTKEYUSE_ANY) {
09582         ret |= SetOjectIdValue(output, outSz, &idx,
09583             extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
09584     }
09585     else {
09586         if (input & EXTKEYUSE_SERVER_AUTH)
09587             ret |= SetOjectIdValue(output, outSz, &idx,
09588                 extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
09589         if (input & EXTKEYUSE_CLIENT_AUTH)
09590             ret |= SetOjectIdValue(output, outSz, &idx,
09591                 extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
09592         if (input & EXTKEYUSE_CODESIGN)
09593             ret |= SetOjectIdValue(output, outSz, &idx,
09594                 extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
09595         if (input & EXTKEYUSE_EMAILPROT)
09596             ret |= SetOjectIdValue(output, outSz, &idx,
09597                 extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
09598         if (input & EXTKEYUSE_TIMESTAMP)
09599             ret |= SetOjectIdValue(output, outSz, &idx,
09600                 extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
09601         if (input & EXTKEYUSE_OCSP_SIGN)
09602             ret |= SetOjectIdValue(output, outSz, &idx,
09603                 extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
09604     #ifdef WOLFSSL_EKU_OID
09605         /* iterate through OID values */
09606         if (input & EXTKEYUSE_USER) {
09607             int i, sz;
09608             for (i = 0; i < CTC_MAX_EKU_NB; i++) {
09609                 sz = cert->extKeyUsageOIDSz[i];
09610                 if (sz > 0) {
09611                     ret |= SetOjectIdValue(output, outSz, &idx,
09612                         cert->extKeyUsageOID[i], sz);
09613                 }
09614             }
09615         }
09616     #endif /* WOLFSSL_EKU_OID */
09617     }
09618     if (ret != 0)
09619         return ASN_PARSE_E;
09620 
09621     /* Calculate Sizes */
09622     oidListSz = idx - totalSz;
09623     totalSz = idx - 2; /* exclude first seq/len (2) */
09624 
09625     /* 1. Seq + Total Len (2) */
09626     idx = SetSequence(totalSz, output);
09627 
09628     /* 2. Object ID (2) */
09629     XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
09630     idx += sizeof(extkeyusage_oid);
09631 
09632     /* 3. Octect String (2) */
09633     idx += SetOctetString(totalSz - idx, &output[idx]);
09634 
09635     /* 4. Seq + OidListLen (2) */
09636     idx += SetSequence(oidListSz, &output[idx]);
09637 
09638     /* 5. Oid List (already set in-place above) */
09639     idx += oidListSz;
09640 
09641     (void)cert;
09642     return idx;
09643 }
09644 
09645 /* Encode OID string representation to ITU-T X.690 format */
09646 static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
09647 {
09648     word32 val, idx = 0, nb_val;
09649     char *token, *str, *ptr;
09650     word32 len;
09651 
09652     if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
09653         return BAD_FUNC_ARG;
09654 
09655     len = (word32)XSTRLEN(in);
09656 
09657     str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
09658     if (str == NULL)
09659         return MEMORY_E;
09660 
09661     XSTRNCPY(str, in, len);
09662     str[len] = '\0';
09663 
09664     nb_val = 0;
09665 
09666     /* parse value, and set corresponding Policy OID value */
09667     token = XSTRTOK(str, ".", &ptr);
09668     while (token != NULL)
09669     {
09670         val = (word32)atoi(token);
09671 
09672         if (nb_val == 0) {
09673             if (val > 2) {
09674                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
09675                 return ASN_OBJECT_ID_E;
09676             }
09677 
09678             out[idx] = (byte)(40 * val);
09679         }
09680         else if (nb_val == 1) {
09681             if (val > 127) {
09682                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
09683                 return ASN_OBJECT_ID_E;
09684             }
09685 
09686             if (idx > *outSz) {
09687                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
09688                 return BUFFER_E;
09689             }
09690 
09691             out[idx++] += (byte)val;
09692         }
09693         else {
09694             word32  tb = 0, x;
09695             int     i = 0;
09696             byte    oid[MAX_OID_SZ];
09697 
09698             while (val >= 128) {
09699                 x = val % 128;
09700                 val /= 128;
09701                 oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
09702             }
09703 
09704             if ((idx+(word32)i) > *outSz) {
09705                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
09706                 return BUFFER_E;
09707             }
09708 
09709             oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
09710 
09711             /* push value in the right order */
09712             while (i >= 0)
09713                 out[idx++] = oid[i--];
09714         }
09715 
09716         token = XSTRTOK(NULL, ".", &ptr);
09717         nb_val++;
09718     }
09719 
09720     *outSz = idx;
09721 
09722     XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
09723     return 0;
09724 }
09725 
09726 /* encode Certificate Policies, return total bytes written
09727  * each input value must be ITU-T X.690 formatted : a.b.c...
09728  * input must be an array of values with a NULL terminated for the latest
09729  * RFC5280 : non-critical */
09730 static int SetCertificatePolicies(byte *output,
09731                                   word32 outputSz,
09732                                   char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
09733                                   word16 nb_certpol,
09734                                   void* heap)
09735 {
09736     byte    oid[MAX_OID_SZ],
09737             der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],
09738             out[MAX_CERTPOL_SZ];
09739     word32  oidSz;
09740     word32  outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];
09741     int     ret;
09742 
09743     static const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
09744     static const byte oid_oid[] = { 0x06 };
09745 
09746     if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
09747         return BAD_FUNC_ARG;
09748 
09749     for (i = 0; i < nb_certpol; i++) {
09750         oidSz = sizeof(oid);
09751         XMEMSET(oid, 0, oidSz);
09752 
09753         ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
09754         if (ret != 0)
09755             return ret;
09756 
09757         /* compute sequence value for the oid */
09758         ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
09759                           sizeof(oid_oid), oid, oidSz);
09760         if (ret <= 0)
09761             return ret;
09762         else
09763             der_oidSz[i] = (word32)ret;
09764     }
09765 
09766     /* concatenate oid, keep two byte for sequence/size of the created value */
09767     for (i = 0, outSz = 2; i < nb_certpol; i++) {
09768         XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
09769         outSz += der_oidSz[i];
09770     }
09771 
09772     /* add sequence */
09773     ret = SetSequence(outSz-2, out);
09774     if (ret <= 0)
09775         return ret;
09776 
09777     /* add Policy OID to compute final value */
09778     return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
09779                       out, outSz);
09780 }
09781 #endif /* WOLFSSL_CERT_EXT */
09782 
09783 #ifdef WOLFSSL_ALT_NAMES
09784 /* encode Alternative Names, return total bytes written */
09785 static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
09786 {
09787     if (out == NULL || input == NULL)
09788         return BAD_FUNC_ARG;
09789 
09790     if (outSz < length)
09791         return BUFFER_E;
09792 
09793     /* Alternative Names come from certificate or computed by
09794      * external function, so already encoded. Just copy value */
09795     XMEMCPY(out, input, length);
09796     return length;
09797 }
09798 #endif /* WOLFSL_ALT_NAMES */
09799 
09800 /* Encodes one attribute of the name (issuer/subject)
09801  *
09802  * name     structure to hold result of encoding
09803  * nameStr  value to be encoded
09804  * nameType type of encoding i.e CTC_UTF8
09805  * type     id of attribute i.e ASN_COMMON_NAME
09806  *
09807  * returns length on success
09808  */
09809 static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
09810         byte type)
09811 {
09812     word32 idx = 0;
09813 
09814     if (nameStr) {
09815         /* bottom up */
09816         byte firstLen[1 + MAX_LENGTH_SZ];
09817         byte secondLen[MAX_LENGTH_SZ];
09818         byte sequence[MAX_SEQ_SZ];
09819         byte set[MAX_SET_SZ];
09820 
09821         int strLen  = (int)XSTRLEN(nameStr);
09822         int thisLen = strLen;
09823         int firstSz, secondSz, seqSz, setSz;
09824 
09825         if (strLen == 0) { /* no user data for this item */
09826             name->used = 0;
09827             return 0;
09828         }
09829 
09830         /* Restrict country code size */
09831         if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
09832             return ASN_COUNTRY_SIZE_E;
09833         }
09834 
09835         secondSz = SetLength(strLen, secondLen);
09836         thisLen += secondSz;
09837         switch (type) {
09838             case ASN_EMAIL_NAME: /* email */
09839                 thisLen += EMAIL_JOINT_LEN;
09840                 firstSz  = EMAIL_JOINT_LEN;
09841                 break;
09842 
09843             case ASN_DOMAIN_COMPONENT:
09844                 thisLen += PILOT_JOINT_LEN;
09845                 firstSz  = PILOT_JOINT_LEN;
09846                 break;
09847 
09848             default:
09849                 thisLen++;                                 /* str type */
09850                 thisLen += JOINT_LEN;
09851                 firstSz  = JOINT_LEN + 1;
09852         }
09853         thisLen++; /* id  type */
09854         firstSz  = SetObjectId(firstSz, firstLen);
09855         thisLen += firstSz;
09856 
09857         seqSz = SetSequence(thisLen, sequence);
09858         thisLen += seqSz;
09859         setSz = SetSet(thisLen, set);
09860         thisLen += setSz;
09861 
09862         if (thisLen > (int)sizeof(name->encoded)) {
09863             return BUFFER_E;
09864         }
09865 
09866         /* store it */
09867         idx = 0;
09868         /* set */
09869         XMEMCPY(name->encoded, set, setSz);
09870         idx += setSz;
09871         /* seq */
09872         XMEMCPY(name->encoded + idx, sequence, seqSz);
09873         idx += seqSz;
09874         /* asn object id */
09875         XMEMCPY(name->encoded + idx, firstLen, firstSz);
09876         idx += firstSz;
09877         switch (type) {
09878             case ASN_EMAIL_NAME:
09879                 {
09880                     const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
09881                                        0x01, 0x09, 0x01, 0x16 };
09882                     /* email joint id */
09883                     XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
09884                     idx += (int)sizeof(EMAIL_OID);
09885                 }
09886                 break;
09887 
09888             case ASN_DOMAIN_COMPONENT:
09889                 {
09890                     const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
09891                                     0x93, 0xF2, 0x2C, 0x64, 0x01
09892                     };
09893 
09894                     XMEMCPY(name->encoded + idx, PILOT_OID,
09895                                                      sizeof(PILOT_OID));
09896                     idx += (int)sizeof(PILOT_OID);
09897                     /* id type */
09898                     name->encoded[idx++] = type;
09899                     /* str type */
09900                     name->encoded[idx++] = nameType;
09901                 }
09902                 break;
09903 
09904             default:
09905                 name->encoded[idx++] = 0x55;
09906                 name->encoded[idx++] = 0x04;
09907                 /* id type */
09908                 name->encoded[idx++] = type;
09909                 /* str type */
09910                 name->encoded[idx++] = nameType;
09911         }
09912         /* second length */
09913         XMEMCPY(name->encoded + idx, secondLen, secondSz);
09914         idx += secondSz;
09915         /* str value */
09916         XMEMCPY(name->encoded + idx, nameStr, strLen);
09917         idx += strLen;
09918 
09919         name->type = type;
09920         name->totalLen = idx;
09921         name->used = 1;
09922     }
09923     else
09924         name->used = 0;
09925 
09926     return idx;
09927 }
09928 
09929 /* encode CertName into output, return total bytes written */
09930 int SetName(byte* output, word32 outputSz, CertName* name)
09931 {
09932     int          totalBytes = 0, i, idx;
09933 #ifdef WOLFSSL_SMALL_STACK
09934     EncodedName* names = NULL;
09935 #else
09936     EncodedName  names[NAME_ENTRIES];
09937 #endif
09938 #ifdef WOLFSSL_MULTI_ATTRIB
09939     EncodedName addNames[CTC_MAX_ATTRIB];
09940     int j, type;
09941 #endif
09942 
09943     if (output == NULL || name == NULL)
09944         return BAD_FUNC_ARG;
09945 
09946     if (outputSz < 3)
09947         return BUFFER_E;
09948 
09949 #ifdef WOLFSSL_SMALL_STACK
09950     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
09951                                                        DYNAMIC_TYPE_TMP_BUFFER);
09952     if (names == NULL)
09953         return MEMORY_E;
09954 #endif
09955 
09956     for (i = 0; i < NAME_ENTRIES; i++) {
09957         int ret;
09958         const char* nameStr = GetOneName(name, i);
09959 
09960         ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
09961                           GetNameId(i));
09962         if (ret < 0) {
09963         #ifdef WOLFSSL_SMALL_STACK
09964                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09965         #endif
09966                 return BUFFER_E;
09967         }
09968         totalBytes += ret;
09969     }
09970 #ifdef WOLFSSL_MULTI_ATTRIB
09971     for (i = 0; i < CTC_MAX_ATTRIB; i++) {
09972         if (name->name[i].sz > 0) {
09973             int ret;
09974             ret = wc_EncodeName(&addNames[i], name->name[i].value,
09975                         name->name[i].type, name->name[i].id);
09976             if (ret < 0) {
09977             #ifdef WOLFSSL_SMALL_STACK
09978                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09979             #endif
09980                 return BUFFER_E;
09981             }
09982             totalBytes += ret;
09983         }
09984         else {
09985             addNames[i].used = 0;
09986         }
09987     }
09988 #endif /* WOLFSSL_MULTI_ATTRIB */
09989 
09990     /* header */
09991     idx = SetSequence(totalBytes, output);
09992     totalBytes += idx;
09993     if (totalBytes > ASN_NAME_MAX) {
09994 #ifdef WOLFSSL_SMALL_STACK
09995         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09996 #endif
09997         return BUFFER_E;
09998     }
09999 
10000     for (i = 0; i < NAME_ENTRIES; i++) {
10001     #ifdef WOLFSSL_MULTI_ATTRIB
10002         type = GetNameId(i);
10003 
10004         /* list all DC values before OUs */
10005         if (type == ASN_ORGUNIT_NAME) {
10006             type = ASN_DOMAIN_COMPONENT;
10007             for (j = 0; j < CTC_MAX_ATTRIB; j++) {
10008                 if (name->name[j].sz > 0 && type == name->name[j].id) {
10009                     if (outputSz < (word32)(idx+addNames[j].totalLen)) {
10010                     #ifdef WOLFSSL_SMALL_STACK
10011                         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10012                     #endif
10013                         return BUFFER_E;
10014                     }
10015 
10016                     XMEMCPY(output + idx, addNames[j].encoded,
10017                             addNames[j].totalLen);
10018                     idx += addNames[j].totalLen;
10019                 }
10020             }
10021             type = ASN_ORGUNIT_NAME;
10022         }
10023 
10024         /* write all similar types to the buffer */
10025         for (j = 0; j < CTC_MAX_ATTRIB; j++) {
10026             if (name->name[j].sz > 0 && type == name->name[j].id) {
10027                 if (outputSz < (word32)(idx+addNames[j].totalLen)) {
10028                 #ifdef WOLFSSL_SMALL_STACK
10029                     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10030                 #endif
10031                     return BUFFER_E;
10032                 }
10033 
10034                 XMEMCPY(output + idx, addNames[j].encoded,
10035                         addNames[j].totalLen);
10036                 idx += addNames[j].totalLen;
10037             }
10038         }
10039     #endif /* WOLFSSL_MULTI_ATTRIB */
10040 
10041         if (names[i].used) {
10042             if (outputSz < (word32)(idx+names[i].totalLen)) {
10043 #ifdef WOLFSSL_SMALL_STACK
10044                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10045 #endif
10046                 return BUFFER_E;
10047             }
10048 
10049             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
10050             idx += names[i].totalLen;
10051         }
10052     }
10053 
10054 #ifdef WOLFSSL_SMALL_STACK
10055     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10056 #endif
10057 
10058     return totalBytes;
10059 }
10060 
10061 /* encode info from cert into DER encoded format */
10062 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
10063                       WC_RNG* rng, const byte* ntruKey, word16 ntruSz,
10064                       ed25519_key* ed25519Key)
10065 {
10066     int ret;
10067 
10068     if (cert == NULL || der == NULL || rng == NULL)
10069         return BAD_FUNC_ARG;
10070 
10071     /* make sure at least one key type is provided */
10072     if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && ntruKey == NULL)
10073         return PUBLIC_KEY_E;
10074 
10075     /* init */
10076     XMEMSET(der, 0, sizeof(DerCert));
10077 
10078     /* version */
10079     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
10080 
10081     /* serial number (must be positive) */
10082     if (cert->serialSz == 0) {
10083         /* generate random serial */
10084         cert->serialSz = CTC_SERIAL_SIZE;
10085         ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
10086         if (ret != 0)
10087             return ret;
10088     }
10089     der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,
10090         CTC_SERIAL_SIZE);
10091     if (der->serialSz < 0)
10092         return der->serialSz;
10093 
10094     /* signature algo */
10095     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
10096     if (der->sigAlgoSz <= 0)
10097         return ALGO_ID_E;
10098 
10099     /* public key */
10100 #ifndef NO_RSA
10101     if (cert->keyType == RSA_KEY) {
10102         if (rsaKey == NULL)
10103             return PUBLIC_KEY_E;
10104         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
10105                                            sizeof(der->publicKey), 1);
10106     }
10107 #endif
10108 
10109 #ifdef HAVE_ECC
10110     if (cert->keyType == ECC_KEY) {
10111         if (eccKey == NULL)
10112             return PUBLIC_KEY_E;
10113         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
10114     }
10115 #endif
10116 
10117 #ifdef HAVE_ED25519
10118     if (cert->keyType == ED25519_KEY) {
10119         if (ed25519Key == NULL)
10120             return PUBLIC_KEY_E;
10121         der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
10122     }
10123 #endif
10124 
10125 #ifdef HAVE_NTRU
10126     if (cert->keyType == NTRU_KEY) {
10127         word32 rc;
10128         word16 encodedSz;
10129 
10130         if (ntruKey == NULL)
10131             return PUBLIC_KEY_E;
10132 
10133         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
10134                                                    ntruKey, &encodedSz, NULL);
10135         if (rc != NTRU_OK)
10136             return PUBLIC_KEY_E;
10137         if (encodedSz > MAX_PUBLIC_KEY_SZ)
10138             return PUBLIC_KEY_E;
10139 
10140         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
10141                                          ntruKey, &encodedSz, der->publicKey);
10142         if (rc != NTRU_OK)
10143             return PUBLIC_KEY_E;
10144 
10145         der->publicKeySz = encodedSz;
10146     }
10147 #else
10148     (void)ntruSz;
10149 #endif /* HAVE_NTRU */
10150 
10151     if (der->publicKeySz <= 0)
10152         return PUBLIC_KEY_E;
10153 
10154     der->validitySz = 0;
10155 #ifdef WOLFSSL_ALT_NAMES
10156     /* date validity copy ? */
10157     if (cert->beforeDateSz && cert->afterDateSz) {
10158         der->validitySz = CopyValidity(der->validity, cert);
10159         if (der->validitySz <= 0)
10160             return DATE_E;
10161     }
10162 #endif
10163 
10164     /* date validity */
10165     if (der->validitySz == 0) {
10166         der->validitySz = SetValidity(der->validity, cert->daysValid);
10167         if (der->validitySz <= 0)
10168             return DATE_E;
10169     }
10170 
10171     /* subject name */
10172     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
10173     if (der->subjectSz <= 0)
10174         return SUBJECT_E;
10175 
10176     /* issuer name */
10177     der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
10178              &cert->subject : &cert->issuer);
10179     if (der->issuerSz <= 0)
10180         return ISSUER_E;
10181 
10182     /* set the extensions */
10183     der->extensionsSz = 0;
10184 
10185     /* CA */
10186     if (cert->isCA) {
10187         der->caSz = SetCa(der->ca, sizeof(der->ca));
10188         if (der->caSz <= 0)
10189             return CA_TRUE_E;
10190 
10191         der->extensionsSz += der->caSz;
10192     }
10193     else
10194         der->caSz = 0;
10195 
10196 #ifdef WOLFSSL_ALT_NAMES
10197     /* Alternative Name */
10198     if (cert->altNamesSz) {
10199         der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
10200                                       cert->altNames, cert->altNamesSz);
10201         if (der->altNamesSz <= 0)
10202             return ALT_NAME_E;
10203 
10204         der->extensionsSz += der->altNamesSz;
10205     }
10206     else
10207         der->altNamesSz = 0;
10208 #endif
10209 
10210 #ifdef WOLFSSL_CERT_EXT
10211     /* SKID */
10212     if (cert->skidSz) {
10213         /* check the provided SKID size */
10214         if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
10215             return SKID_E;
10216 
10217         /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
10218             cert (CTC_MAX_SKID_SIZE). */
10219         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
10220                               cert->skid, cert->skidSz);
10221         if (der->skidSz <= 0)
10222             return SKID_E;
10223 
10224         der->extensionsSz += der->skidSz;
10225     }
10226     else
10227         der->skidSz = 0;
10228 
10229     /* AKID */
10230     if (cert->akidSz) {
10231         /* check the provided AKID size */
10232         if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
10233             return AKID_E;
10234 
10235         der->akidSz = SetAKID(der->akid, sizeof(der->akid),
10236                               cert->akid, cert->akidSz, cert->heap);
10237         if (der->akidSz <= 0)
10238             return AKID_E;
10239 
10240         der->extensionsSz += der->akidSz;
10241     }
10242     else
10243         der->akidSz = 0;
10244 
10245     /* Key Usage */
10246     if (cert->keyUsage != 0){
10247         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
10248                                       cert->keyUsage);
10249         if (der->keyUsageSz <= 0)
10250             return KEYUSAGE_E;
10251 
10252         der->extensionsSz += der->keyUsageSz;
10253     }
10254     else
10255         der->keyUsageSz = 0;
10256 
10257     /* Extended Key Usage */
10258     if (cert->extKeyUsage != 0){
10259         der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
10260                                 sizeof(der->extKeyUsage), cert->extKeyUsage);
10261         if (der->extKeyUsageSz <= 0)
10262             return EXTKEYUSAGE_E;
10263 
10264         der->extensionsSz += der->extKeyUsageSz;
10265     }
10266     else
10267         der->extKeyUsageSz = 0;
10268 
10269     /* Certificate Policies */
10270     if (cert->certPoliciesNb != 0) {
10271         der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
10272                                                      sizeof(der->certPolicies),
10273                                                      cert->certPolicies,
10274                                                      cert->certPoliciesNb,
10275                                                      cert->heap);
10276         if (der->certPoliciesSz <= 0)
10277             return CERTPOLICIES_E;
10278 
10279         der->extensionsSz += der->certPoliciesSz;
10280     }
10281     else
10282         der->certPoliciesSz = 0;
10283 #endif /* WOLFSSL_CERT_EXT */
10284 
10285     /* put extensions */
10286     if (der->extensionsSz > 0) {
10287 
10288         /* put the start of extensions sequence (ID, Size) */
10289         der->extensionsSz = SetExtensionsHeader(der->extensions,
10290                                                 sizeof(der->extensions),
10291                                                 der->extensionsSz);
10292         if (der->extensionsSz <= 0)
10293             return EXTENSIONS_E;
10294 
10295         /* put CA */
10296         if (der->caSz) {
10297             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10298                                 &der->extensionsSz,
10299                                 der->ca, der->caSz);
10300             if (ret == 0)
10301                 return EXTENSIONS_E;
10302         }
10303 
10304 #ifdef WOLFSSL_ALT_NAMES
10305         /* put Alternative Names */
10306         if (der->altNamesSz) {
10307             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10308                                 &der->extensionsSz,
10309                                 der->altNames, der->altNamesSz);
10310             if (ret <= 0)
10311                 return EXTENSIONS_E;
10312         }
10313 #endif
10314 
10315 #ifdef WOLFSSL_CERT_EXT
10316         /* put SKID */
10317         if (der->skidSz) {
10318             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10319                                 &der->extensionsSz,
10320                                 der->skid, der->skidSz);
10321             if (ret <= 0)
10322                 return EXTENSIONS_E;
10323         }
10324 
10325         /* put AKID */
10326         if (der->akidSz) {
10327             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10328                                 &der->extensionsSz,
10329                                 der->akid, der->akidSz);
10330             if (ret <= 0)
10331                 return EXTENSIONS_E;
10332         }
10333 
10334         /* put KeyUsage */
10335         if (der->keyUsageSz) {
10336             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10337                                 &der->extensionsSz,
10338                                 der->keyUsage, der->keyUsageSz);
10339             if (ret <= 0)
10340                 return EXTENSIONS_E;
10341         }
10342 
10343         /* put ExtendedKeyUsage */
10344         if (der->extKeyUsageSz) {
10345             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10346                                 &der->extensionsSz,
10347                                 der->extKeyUsage, der->extKeyUsageSz);
10348             if (ret <= 0)
10349                 return EXTENSIONS_E;
10350         }
10351 
10352         /* put Certificate Policies */
10353         if (der->certPoliciesSz) {
10354             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10355                                 &der->extensionsSz,
10356                                 der->certPolicies, der->certPoliciesSz);
10357             if (ret <= 0)
10358                 return EXTENSIONS_E;
10359         }
10360 #endif /* WOLFSSL_CERT_EXT */
10361     }
10362 
10363     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
10364         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
10365         der->extensionsSz;
10366 
10367     return 0;
10368 }
10369 
10370 
10371 /* write DER encoded cert to buffer, size already checked */
10372 static int WriteCertBody(DerCert* der, byte* buffer)
10373 {
10374     int idx;
10375 
10376     /* signed part header */
10377     idx = SetSequence(der->total, buffer);
10378     /* version */
10379     XMEMCPY(buffer + idx, der->version, der->versionSz);
10380     idx += der->versionSz;
10381     /* serial */
10382     XMEMCPY(buffer + idx, der->serial, der->serialSz);
10383     idx += der->serialSz;
10384     /* sig algo */
10385     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
10386     idx += der->sigAlgoSz;
10387     /* issuer */
10388     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
10389     idx += der->issuerSz;
10390     /* validity */
10391     XMEMCPY(buffer + idx, der->validity, der->validitySz);
10392     idx += der->validitySz;
10393     /* subject */
10394     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
10395     idx += der->subjectSz;
10396     /* public key */
10397     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
10398     idx += der->publicKeySz;
10399     if (der->extensionsSz) {
10400         /* extensions */
10401         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
10402                                                    (int)sizeof(der->extensions)));
10403         idx += der->extensionsSz;
10404     }
10405 
10406     return idx;
10407 }
10408 
10409 
10410 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
10411 static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz,
10412     byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
10413     ed25519_key* ed25519Key, WC_RNG* rng, int sigAlgoType, void* heap)
10414 {
10415     int digestSz = 0, typeH = 0, ret = 0;
10416 
10417     (void)digestSz;
10418     (void)typeH;
10419     (void)buffer;
10420     (void)sz;
10421     (void)sig;
10422     (void)sigSz;
10423     (void)rsaKey;
10424     (void)eccKey;
10425     (void)ed25519Key;
10426     (void)rng;
10427 
10428     switch (certSignCtx->state) {
10429     case CERTSIGN_STATE_BEGIN:
10430     case CERTSIGN_STATE_DIGEST:
10431 
10432         certSignCtx->state = CERTSIGN_STATE_DIGEST;
10433         certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
10434             DYNAMIC_TYPE_TMP_BUFFER);
10435         if (certSignCtx->digest == NULL) {
10436             ret = MEMORY_E; goto exit_ms;
10437         }
10438 
10439         ret = HashForSignature(buffer, sz, sigAlgoType, certSignCtx->digest,
10440                                &typeH, &digestSz, 0);
10441         /* set next state, since WC_PENDING rentry for these are not "call again" */
10442         certSignCtx->state = CERTSIGN_STATE_ENCODE;
10443         if (ret != 0) {
10444             goto exit_ms;
10445         }
10446         FALL_THROUGH;
10447 
10448     case CERTSIGN_STATE_ENCODE:
10449     #ifndef NO_RSA
10450         if (rsaKey) {
10451             certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
10452                 DYNAMIC_TYPE_TMP_BUFFER);
10453             if (certSignCtx->encSig == NULL) {
10454                 ret = MEMORY_E; goto exit_ms;
10455             }
10456 
10457             /* signature */
10458             certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
10459                                           certSignCtx->digest, digestSz, typeH);
10460         }
10461     #endif /* !NO_RSA */
10462         FALL_THROUGH;
10463 
10464     case CERTSIGN_STATE_DO:
10465         certSignCtx->state = CERTSIGN_STATE_DO;
10466         ret = ALGO_ID_E; /* default to error */
10467 
10468     #ifndef NO_RSA
10469         if (rsaKey) {
10470             /* signature */
10471             ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
10472                                  sig, sigSz, rsaKey, rng);
10473         }
10474     #endif /* !NO_RSA */
10475 
10476     #ifdef HAVE_ECC
10477         if (!rsaKey && eccKey) {
10478             word32 outSz = sigSz;
10479 
10480             ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
10481                                    sig, &outSz, rng, eccKey);
10482             if (ret == 0)
10483                 ret = outSz;
10484         }
10485     #endif /* HAVE_ECC */
10486 
10487     #ifdef HAVE_ED25519
10488         if (!rsaKey && !eccKey && ed25519Key) {
10489             word32 outSz = sigSz;
10490 
10491             ret = wc_ed25519_sign_msg(buffer, sz, sig, &outSz, ed25519Key);
10492             if (ret == 0)
10493                 ret = outSz;
10494         }
10495     #endif /* HAVE_ECC */
10496         break;
10497     }
10498 
10499 exit_ms:
10500 
10501     if (ret == WC_PENDING_E) {
10502         return ret;
10503     }
10504 
10505 #ifndef NO_RSA
10506     if (rsaKey) {
10507         XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
10508     }
10509 #endif /* !NO_RSA */
10510 
10511     XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
10512     certSignCtx->digest = NULL;
10513 
10514     /* reset state */
10515     certSignCtx->state = CERTSIGN_STATE_BEGIN;
10516 
10517     return ret;
10518 }
10519 
10520 
10521 /* add signature to end of buffer, size of buffer assumed checked, return
10522    new length */
10523 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
10524                         int sigAlgoType)
10525 {
10526     byte seq[MAX_SEQ_SZ];
10527     int  idx = bodySz, seqSz;
10528 
10529     /* algo */
10530     idx += SetAlgoID(sigAlgoType, buffer + idx, oidSigType, 0);
10531     /* bit string */
10532     idx += SetBitString(sigSz, 0, buffer + idx);
10533     /* signature */
10534     XMEMCPY(buffer + idx, sig, sigSz);
10535     idx += sigSz;
10536 
10537     /* make room for overall header */
10538     seqSz = SetSequence(idx, seq);
10539     XMEMMOVE(buffer + seqSz, buffer, idx);
10540     XMEMCPY(buffer, seq, seqSz);
10541 
10542     return idx + seqSz;
10543 }
10544 
10545 
10546 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
10547 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
10548                        RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
10549                        const byte* ntruKey, word16 ntruSz,
10550                        ed25519_key* ed25519Key)
10551 {
10552     int ret;
10553 #ifdef WOLFSSL_SMALL_STACK
10554     DerCert* der;
10555 #else
10556     DerCert der[1];
10557 #endif
10558 
10559     cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY :
10560                                          (ed25519Key ? ED25519_KEY : NTRU_KEY));
10561 
10562 #ifdef WOLFSSL_SMALL_STACK
10563     der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
10564     if (der == NULL)
10565         return MEMORY_E;
10566 #endif
10567 
10568     ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz,
10569                      ed25519Key);
10570     if (ret == 0) {
10571         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
10572             ret = BUFFER_E;
10573         else
10574             ret = cert->bodySz = WriteCertBody(der, derBuffer);
10575     }
10576 
10577 #ifdef WOLFSSL_SMALL_STACK
10578     XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
10579 #endif
10580 
10581     return ret;
10582 }
10583 
10584 
10585 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
10586 int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
10587                    void* key, WC_RNG* rng)
10588 {
10589     RsaKey* rsaKey = NULL;
10590     ecc_key* eccKey = NULL;
10591     ed25519_key* ed25519Key = NULL;
10592 
10593     if (keyType == RSA_TYPE)
10594         rsaKey = (RsaKey*)key;
10595     else if (keyType == ECC_TYPE)
10596         eccKey = (ecc_key*)key;
10597     else if (keyType == ED25519_TYPE)
10598         ed25519Key = (ed25519_key*)key;
10599 
10600     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
10601                        ed25519Key);
10602 }
10603 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
10604 int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
10605              ecc_key* eccKey, WC_RNG* rng)
10606 {
10607     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
10608                        NULL);
10609 }
10610 
10611 
10612 #ifdef HAVE_NTRU
10613 
10614 int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
10615                   const byte* ntruKey, word16 keySz, WC_RNG* rng)
10616 {
10617     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);
10618 }
10619 
10620 #endif /* HAVE_NTRU */
10621 
10622 
10623 #ifdef WOLFSSL_CERT_REQ
10624 
10625 static int SetReqAttrib(byte* output, char* pw, int extSz)
10626 {
10627     static const byte cpOid[] =
10628         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
10629                          0x09, 0x07 };
10630     static const byte erOid[] =
10631         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
10632                          0x09, 0x0e };
10633 
10634     int sz      = 0; /* overall size */
10635     int cpSz    = 0; /* Challenge Password section size */
10636     int cpSeqSz = 0;
10637     int cpSetSz = 0;
10638     int cpStrSz = 0;
10639     int pwSz    = 0;
10640     int erSz    = 0; /* Extension Request section size */
10641     int erSeqSz = 0;
10642     int erSetSz = 0;
10643     byte cpSeq[MAX_SEQ_SZ];
10644     byte cpSet[MAX_SET_SZ];
10645     byte cpStr[MAX_PRSTR_SZ];
10646     byte erSeq[MAX_SEQ_SZ];
10647     byte erSet[MAX_SET_SZ];
10648 
10649     output[0] = 0xa0;
10650     sz++;
10651 
10652     if (pw && pw[0]) {
10653         pwSz = (int)XSTRLEN(pw);
10654         cpStrSz = SetUTF8String(pwSz, cpStr);
10655         cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
10656         cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
10657         cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
10658     }
10659 
10660     if (extSz) {
10661         erSetSz = SetSet(extSz, erSet);
10662         erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
10663         erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
10664     }
10665 
10666     /* Put the pieces together. */
10667     sz += SetLength(cpSz + erSz, &output[sz]);
10668 
10669     if (cpSz) {
10670         XMEMCPY(&output[sz], cpSeq, cpSeqSz);
10671         sz += cpSeqSz;
10672         XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
10673         sz += sizeof(cpOid);
10674         XMEMCPY(&output[sz], cpSet, cpSetSz);
10675         sz += cpSetSz;
10676         XMEMCPY(&output[sz], cpStr, cpStrSz);
10677         sz += cpStrSz;
10678         XMEMCPY(&output[sz], pw, pwSz);
10679         sz += pwSz;
10680     }
10681 
10682     if (erSz) {
10683         XMEMCPY(&output[sz], erSeq, erSeqSz);
10684         sz += erSeqSz;
10685         XMEMCPY(&output[sz], erOid, sizeof(erOid));
10686         sz += sizeof(erOid);
10687         XMEMCPY(&output[sz], erSet, erSetSz);
10688         sz += erSetSz;
10689         /* The actual extension data will be tacked onto the output later. */
10690     }
10691 
10692     return sz;
10693 }
10694 
10695 
10696 /* encode info from cert into DER encoded format */
10697 static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
10698                          ecc_key* eccKey, ed25519_key* ed25519Key)
10699 {
10700     (void)eccKey;
10701     (void)ed25519Key;
10702 
10703     if (cert == NULL || der == NULL)
10704         return BAD_FUNC_ARG;
10705 
10706     if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL)
10707             return PUBLIC_KEY_E;
10708 
10709     /* init */
10710     XMEMSET(der, 0, sizeof(DerCert));
10711 
10712     /* version */
10713     der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
10714 
10715     /* subject name */
10716     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
10717     if (der->subjectSz <= 0)
10718         return SUBJECT_E;
10719 
10720     /* public key */
10721 #ifndef NO_RSA
10722     if (cert->keyType == RSA_KEY) {
10723         if (rsaKey == NULL)
10724             return PUBLIC_KEY_E;
10725         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
10726                                            sizeof(der->publicKey), 1);
10727     }
10728 #endif
10729 
10730 #ifdef HAVE_ECC
10731     if (cert->keyType == ECC_KEY) {
10732         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
10733     }
10734 #endif
10735 
10736 #ifdef HAVE_ED25519
10737     if (cert->keyType == ED25519_KEY) {
10738         if (ed25519Key == NULL)
10739             return PUBLIC_KEY_E;
10740         der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
10741     }
10742 #endif
10743 
10744     if (der->publicKeySz <= 0)
10745         return PUBLIC_KEY_E;
10746 
10747     /* set the extensions */
10748     der->extensionsSz = 0;
10749 
10750     /* CA */
10751     if (cert->isCA) {
10752         der->caSz = SetCa(der->ca, sizeof(der->ca));
10753         if (der->caSz <= 0)
10754             return CA_TRUE_E;
10755 
10756         der->extensionsSz += der->caSz;
10757     }
10758     else
10759         der->caSz = 0;
10760 
10761 #ifdef WOLFSSL_CERT_EXT
10762     /* SKID */
10763     if (cert->skidSz) {
10764         /* check the provided SKID size */
10765         if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
10766             return SKID_E;
10767 
10768         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
10769                               cert->skid, cert->skidSz);
10770         if (der->skidSz <= 0)
10771             return SKID_E;
10772 
10773         der->extensionsSz += der->skidSz;
10774     }
10775     else
10776         der->skidSz = 0;
10777 
10778     /* Key Usage */
10779     if (cert->keyUsage != 0){
10780         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
10781                                       cert->keyUsage);
10782         if (der->keyUsageSz <= 0)
10783             return KEYUSAGE_E;
10784 
10785         der->extensionsSz += der->keyUsageSz;
10786     }
10787     else
10788         der->keyUsageSz = 0;
10789 
10790     /* Extended Key Usage */
10791     if (cert->extKeyUsage != 0){
10792         der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
10793                                 sizeof(der->extKeyUsage), cert->extKeyUsage);
10794         if (der->extKeyUsageSz <= 0)
10795             return EXTKEYUSAGE_E;
10796 
10797         der->extensionsSz += der->extKeyUsageSz;
10798     }
10799     else
10800         der->extKeyUsageSz = 0;
10801 
10802 #endif /* WOLFSSL_CERT_EXT */
10803 
10804     /* put extensions */
10805     if (der->extensionsSz > 0) {
10806         int ret;
10807 
10808         /* put the start of sequence (ID, Size) */
10809         der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
10810         if (der->extensionsSz <= 0)
10811             return EXTENSIONS_E;
10812 
10813         /* put CA */
10814         if (der->caSz) {
10815             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10816                                 &der->extensionsSz,
10817                                 der->ca, der->caSz);
10818             if (ret <= 0)
10819                 return EXTENSIONS_E;
10820         }
10821 
10822 #ifdef WOLFSSL_CERT_EXT
10823         /* put SKID */
10824         if (der->skidSz) {
10825             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10826                                 &der->extensionsSz,
10827                                 der->skid, der->skidSz);
10828             if (ret <= 0)
10829                 return EXTENSIONS_E;
10830         }
10831 
10832         /* put AKID */
10833         if (der->akidSz) {
10834             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10835                                 &der->extensionsSz,
10836                                 der->akid, der->akidSz);
10837             if (ret <= 0)
10838                 return EXTENSIONS_E;
10839         }
10840 
10841         /* put KeyUsage */
10842         if (der->keyUsageSz) {
10843             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10844                                 &der->extensionsSz,
10845                                 der->keyUsage, der->keyUsageSz);
10846             if (ret <= 0)
10847                 return EXTENSIONS_E;
10848         }
10849 
10850         /* put ExtendedKeyUsage */
10851         if (der->extKeyUsageSz) {
10852             ret = SetExtensions(der->extensions, sizeof(der->extensions),
10853                                 &der->extensionsSz,
10854                                 der->extKeyUsage, der->extKeyUsageSz);
10855             if (ret <= 0)
10856                 return EXTENSIONS_E;
10857         }
10858 
10859 #endif /* WOLFSSL_CERT_EXT */
10860     }
10861 
10862     der->attribSz = SetReqAttrib(der->attrib,
10863                                  cert->challengePw, der->extensionsSz);
10864     if (der->attribSz <= 0)
10865         return REQ_ATTRIBUTE_E;
10866 
10867     der->total = der->versionSz + der->subjectSz + der->publicKeySz +
10868         der->extensionsSz + der->attribSz;
10869 
10870     return 0;
10871 }
10872 
10873 
10874 /* write DER encoded cert req to buffer, size already checked */
10875 static int WriteCertReqBody(DerCert* der, byte* buffer)
10876 {
10877     int idx;
10878 
10879     /* signed part header */
10880     idx = SetSequence(der->total, buffer);
10881     /* version */
10882     XMEMCPY(buffer + idx, der->version, der->versionSz);
10883     idx += der->versionSz;
10884     /* subject */
10885     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
10886     idx += der->subjectSz;
10887     /* public key */
10888     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
10889     idx += der->publicKeySz;
10890     /* attributes */
10891     XMEMCPY(buffer + idx, der->attrib, der->attribSz);
10892     idx += der->attribSz;
10893     /* extensions */
10894     if (der->extensionsSz) {
10895         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
10896                                                (int)sizeof(der->extensions)));
10897         idx += der->extensionsSz;
10898     }
10899 
10900     return idx;
10901 }
10902 
10903 
10904 static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
10905                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key)
10906 {
10907     int ret;
10908 #ifdef WOLFSSL_SMALL_STACK
10909     DerCert* der;
10910 #else
10911     DerCert der[1];
10912 #endif
10913 
10914     cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : RSA_KEY);
10915 
10916 #ifdef WOLFSSL_SMALL_STACK
10917     der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
10918                                                     DYNAMIC_TYPE_TMP_BUFFER);
10919     if (der == NULL)
10920         return MEMORY_E;
10921 #endif
10922 
10923     ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key);
10924 
10925     if (ret == 0) {
10926         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
10927             ret = BUFFER_E;
10928         else
10929             ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
10930     }
10931 
10932 #ifdef WOLFSSL_SMALL_STACK
10933     XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
10934 #endif
10935 
10936     return ret;
10937 }
10938 
10939 int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
10940                       void* key)
10941 {
10942     RsaKey* rsaKey = NULL;
10943     ecc_key* eccKey = NULL;
10944     ed25519_key* ed25519Key = NULL;
10945 
10946     if (keyType == RSA_TYPE)
10947         rsaKey = (RsaKey*)key;
10948     else if (keyType == ECC_TYPE)
10949         eccKey = (ecc_key*)key;
10950     else if (keyType == ED25519_TYPE)
10951         ed25519Key = (ed25519_key*)key;
10952 
10953     return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key);
10954 }
10955 
10956 int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
10957                    RsaKey* rsaKey, ecc_key* eccKey)
10958 {
10959     return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL);
10960 }
10961 #endif /* WOLFSSL_CERT_REQ */
10962 
10963 
10964 static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
10965                     RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
10966                     WC_RNG* rng)
10967 {
10968     int sigSz = 0;
10969     void* heap = NULL;
10970     CertSignCtx* certSignCtx = NULL;
10971 #ifndef WOLFSSL_ASYNC_CRYPT
10972     CertSignCtx  certSignCtx_lcl;
10973     certSignCtx = &certSignCtx_lcl;
10974     XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
10975 #endif
10976 
10977     if (requestSz < 0)
10978         return requestSz;
10979 
10980     /* locate ctx */
10981     if (rsaKey) {
10982     #ifndef NO_RSA
10983     #ifdef WOLFSSL_ASYNC_CRYPT
10984         certSignCtx = &rsaKey->certSignCtx;
10985     #endif
10986         heap = rsaKey->heap;
10987     #else
10988         return NOT_COMPILED_IN;
10989     #endif /* NO_RSA */
10990     }
10991     else if (eccKey) {
10992     #ifdef HAVE_ECC
10993     #ifdef WOLFSSL_ASYNC_CRYPT
10994         certSignCtx = &eccKey->certSignCtx;
10995     #endif
10996         heap = eccKey->heap;
10997     #else
10998         return NOT_COMPILED_IN;
10999     #endif /* HAVE_ECC */
11000     }
11001 
11002 #ifdef WOLFSSL_ASYNC_CRYPT
11003     if (certSignCtx == NULL) {
11004         return BAD_FUNC_ARG;
11005     }
11006 #endif
11007 
11008     if (certSignCtx->sig == NULL) {
11009         certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
11010             DYNAMIC_TYPE_TMP_BUFFER);
11011         if (certSignCtx->sig == NULL)
11012             return MEMORY_E;
11013     }
11014 
11015     sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,
11016         MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap);
11017     if (sigSz == WC_PENDING_E) {
11018         /* Not free'ing certSignCtx->sig here because it could still be in use
11019          * with async operations. */
11020         return sigSz;
11021     }
11022 
11023     if (sigSz >= 0) {
11024         if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
11025             sigSz = BUFFER_E;
11026         else
11027             sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz,
11028                                  sType);
11029     }
11030 
11031     XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
11032     certSignCtx->sig = NULL;
11033 
11034     return sigSz;
11035 }
11036 
11037 int wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz,
11038                    int keyType, void* key, WC_RNG* rng)
11039 {
11040     RsaKey* rsaKey = NULL;
11041     ecc_key* eccKey = NULL;
11042     ed25519_key* ed25519Key = NULL;
11043 
11044     if (keyType == RSA_TYPE)
11045         rsaKey = (RsaKey*)key;
11046     else if (keyType == ECC_TYPE)
11047         eccKey = (ecc_key*)key;
11048     else if (keyType == ED25519_TYPE)
11049         ed25519Key = (ed25519_key*)key;
11050 
11051     return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey,
11052                     ed25519Key, rng);
11053 }
11054 
11055 int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
11056                 RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
11057 {
11058     return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey, NULL,
11059                     rng);
11060 }
11061 
11062 int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz,
11063                     RsaKey* key, WC_RNG* rng)
11064 {
11065     int ret;
11066 
11067     ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);
11068     if (ret < 0)
11069         return ret;
11070 
11071     return wc_SignCert(cert->bodySz, cert->sigType,
11072                        buffer, buffSz, key, NULL, rng);
11073 }
11074 
11075 
11076 #ifdef WOLFSSL_CERT_EXT
11077 
11078 /* Set KID from public key */
11079 static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
11080                                  byte *ntruKey, word16 ntruKeySz,
11081                                  ed25519_key* ed25519Key, int kid_type)
11082 {
11083     byte *buffer;
11084     int   bufferSz, ret;
11085 
11086     if (cert == NULL ||
11087         (rsakey == NULL && eckey == NULL && ntruKey == NULL &&
11088                                             ed25519Key == NULL) ||
11089         (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
11090         return BAD_FUNC_ARG;
11091 
11092     buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
11093                                                        DYNAMIC_TYPE_TMP_BUFFER);
11094     if (buffer == NULL)
11095         return MEMORY_E;
11096 
11097     /* Public Key */
11098     bufferSz = -1;
11099 #ifndef NO_RSA
11100     /* RSA public key */
11101     if (rsakey != NULL)
11102         bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0);
11103 #endif
11104 #ifdef HAVE_ECC
11105     /* ECC public key */
11106     if (eckey != NULL)
11107         bufferSz = SetEccPublicKey(buffer, eckey, 0);
11108 #endif
11109 #ifdef HAVE_NTRU
11110     /* NTRU public key */
11111     if (ntruKey != NULL) {
11112         bufferSz = MAX_PUBLIC_KEY_SZ;
11113         ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
11114                         ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer);
11115         if (ret != NTRU_OK)
11116             bufferSz = -1;
11117     }
11118 #else
11119     (void)ntruKeySz;
11120 #endif
11121 #ifdef HAVE_ED25519
11122     /* ED25519 public key */
11123     if (ed25519Key != NULL)
11124         bufferSz = SetEd25519PublicKey(buffer, ed25519Key, 0);
11125 #endif
11126 
11127     if (bufferSz <= 0) {
11128         XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11129         return PUBLIC_KEY_E;
11130     }
11131 
11132     /* Compute SKID by hashing public key */
11133 #ifdef NO_SHA
11134     if (kid_type == SKID_TYPE) {
11135         ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
11136         cert->skidSz = WC_SHA256_DIGEST_SIZE;
11137     }
11138     else if (kid_type == AKID_TYPE) {
11139         ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
11140         cert->akidSz = WC_SHA256_DIGEST_SIZE;
11141     }
11142     else
11143         ret = BAD_FUNC_ARG;
11144 #else /* NO_SHA */
11145     if (kid_type == SKID_TYPE) {
11146         ret = wc_ShaHash(buffer, bufferSz, cert->skid);
11147         cert->skidSz = WC_SHA_DIGEST_SIZE;
11148     }
11149     else if (kid_type == AKID_TYPE) {
11150         ret = wc_ShaHash(buffer, bufferSz, cert->akid);
11151         cert->akidSz = WC_SHA_DIGEST_SIZE;
11152     }
11153     else
11154         ret = BAD_FUNC_ARG;
11155 #endif /* NO_SHA */
11156 
11157     XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11158     return ret;
11159 }
11160 
11161 int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
11162 {
11163     RsaKey* rsaKey = NULL;
11164     ecc_key* eccKey = NULL;
11165     ed25519_key* ed25519Key = NULL;
11166 
11167     if (keyType == RSA_TYPE)
11168         rsaKey = (RsaKey*)key;
11169     else if (keyType == ECC_TYPE)
11170         eccKey = (ecc_key*)key;
11171     else if (keyType == ED25519_TYPE)
11172         ed25519Key = (ed25519_key*)key;
11173 
11174     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
11175                                  SKID_TYPE);
11176 }
11177 
11178 /* Set SKID from RSA or ECC public key */
11179 int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
11180 {
11181     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, SKID_TYPE);
11182 }
11183 
11184 #ifdef HAVE_NTRU
11185 /* Set SKID from NTRU public key */
11186 int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,
11187                                         byte *ntruKey, word16 ntruKeySz)
11188 {
11189     return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL,
11190                                  SKID_TYPE);
11191 }
11192 #endif
11193 
11194 int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
11195 {
11196     RsaKey* rsaKey = NULL;
11197     ecc_key* eccKey = NULL;
11198     ed25519_key* ed25519Key = NULL;
11199 
11200     if (keyType == RSA_TYPE)
11201         rsaKey = (RsaKey*)key;
11202     else if (keyType == ECC_TYPE)
11203         eccKey = (ecc_key*)key;
11204     else if (keyType == ED25519_TYPE)
11205         ed25519Key = (ed25519_key*)key;
11206 
11207     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
11208                                  AKID_TYPE);
11209 }
11210 
11211 /* Set SKID from RSA or ECC public key */
11212 int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
11213 {
11214     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, AKID_TYPE);
11215 }
11216 
11217 
11218 #ifndef NO_FILESYSTEM
11219 
11220 /* Set SKID from public key file in PEM */
11221 int wc_SetSubjectKeyId(Cert *cert, const char* file)
11222 {
11223     int     ret, derSz;
11224     byte*   der;
11225     word32  idx;
11226     RsaKey  *rsakey = NULL;
11227     ecc_key *eckey = NULL;
11228 
11229     if (cert == NULL || file == NULL)
11230         return BAD_FUNC_ARG;
11231 
11232     der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
11233     if (der == NULL) {
11234         WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
11235         return MEMORY_E;
11236     }
11237 
11238     derSz = wc_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
11239     if (derSz <= 0)
11240     {
11241         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11242         return derSz;
11243     }
11244 
11245     /* Load PubKey in internal structure */
11246 #ifndef NO_RSA
11247     rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
11248     if (rsakey == NULL) {
11249         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11250         return MEMORY_E;
11251     }
11252 
11253     if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
11254         WOLFSSL_MSG("wc_InitRsaKey failure");
11255         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
11256         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11257         return MEMORY_E;
11258     }
11259 
11260     idx = 0;
11261     ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
11262     if (ret != 0)
11263 #endif
11264     {
11265 #ifndef NO_RSA
11266         WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
11267         wc_FreeRsaKey(rsakey);
11268         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
11269         rsakey = NULL;
11270 #endif
11271 #ifdef HAVE_ECC
11272         /* Check to load ecc public key */
11273         eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
11274                                                               DYNAMIC_TYPE_ECC);
11275         if (eckey == NULL) {
11276             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11277             return MEMORY_E;
11278         }
11279 
11280         if (wc_ecc_init(eckey) != 0) {
11281             WOLFSSL_MSG("wc_ecc_init failure");
11282             wc_ecc_free(eckey);
11283             XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
11284             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11285             return MEMORY_E;
11286         }
11287 
11288         idx = 0;
11289         ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
11290         if (ret != 0) {
11291             WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
11292             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11293             wc_ecc_free(eckey);
11294             XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
11295             return PUBLIC_KEY_E;
11296         }
11297 #else
11298         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11299         return PUBLIC_KEY_E;
11300 #endif /* HAVE_ECC */
11301     }
11302 
11303     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11304 
11305     ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
11306 
11307 #ifndef NO_RSA
11308     wc_FreeRsaKey(rsakey);
11309     XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
11310 #endif
11311 #ifdef HAVE_ECC
11312     wc_ecc_free(eckey);
11313     XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
11314 #endif
11315     return ret;
11316 }
11317 
11318 #endif /* NO_FILESYSTEM */
11319 
11320 /* Set AKID from certificate contains in buffer (DER encoded) */
11321 int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
11322 {
11323     int ret;
11324 
11325 #ifdef WOLFSSL_SMALL_STACK
11326     DecodedCert* decoded;
11327 #else
11328     DecodedCert decoded[1];
11329 #endif
11330 
11331     if (cert == NULL || der == NULL || derSz <= 0)
11332         return BAD_FUNC_ARG;
11333 
11334 #ifdef WOLFSSL_SMALL_STACK
11335     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
11336                                     cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11337     if (decoded == NULL)
11338         return MEMORY_E;
11339 #endif
11340 
11341     /* decode certificate and get SKID that will be AKID of current cert */
11342     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
11343     ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
11344     if (ret != 0) {
11345         FreeDecodedCert(decoded);
11346         #ifdef WOLFSSL_SMALL_STACK
11347             XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11348         #endif
11349         return ret;
11350     }
11351 
11352     /* Subject Key Id not found !! */
11353     if (decoded->extSubjKeyIdSet == 0) {
11354         FreeDecodedCert(decoded);
11355         #ifdef WOLFSSL_SMALL_STACK
11356             XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11357         #endif
11358         return ASN_NO_SKID;
11359     }
11360 
11361     /* SKID invalid size */
11362     if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
11363         FreeDecodedCert(decoded);
11364         #ifdef WOLFSSL_SMALL_STACK
11365             XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11366         #endif
11367         return MEMORY_E;
11368     }
11369 
11370     /* Put the SKID of CA to AKID of certificate */
11371     XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
11372     cert->akidSz = KEYID_SIZE;
11373 
11374     FreeDecodedCert(decoded);
11375     #ifdef WOLFSSL_SMALL_STACK
11376         XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11377     #endif
11378 
11379     return 0;
11380 }
11381 
11382 
11383 #ifndef NO_FILESYSTEM
11384 
11385 /* Set AKID from certificate file in PEM */
11386 int wc_SetAuthKeyId(Cert *cert, const char* file)
11387 {
11388     int         ret;
11389     int         derSz;
11390     byte*       der;
11391 
11392     if (cert == NULL || file == NULL)
11393         return BAD_FUNC_ARG;
11394 
11395     der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
11396     if (der == NULL) {
11397         WOLFSSL_MSG("wc_SetAuthKeyId OOF Problem");
11398         return MEMORY_E;
11399     }
11400 
11401     derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
11402     if (derSz <= 0)
11403     {
11404         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11405         return derSz;
11406     }
11407 
11408     ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);
11409     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11410 
11411     return ret;
11412 }
11413 
11414 #endif /* NO_FILESYSTEM */
11415 
11416 /* Set KeyUsage from human readable string */
11417 int wc_SetKeyUsage(Cert *cert, const char *value)
11418 {
11419     int ret = 0;
11420     char *token, *str, *ptr;
11421     word32 len;
11422 
11423     if (cert == NULL || value == NULL)
11424         return BAD_FUNC_ARG;
11425 
11426     cert->keyUsage = 0;
11427 
11428     len = (word32)XSTRLEN(value);
11429     str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11430     if (str == NULL)
11431         return MEMORY_E;
11432 
11433     XSTRNCPY(str, value, len);
11434     str[len] = '\0';
11435 
11436     /* parse value, and set corresponding Key Usage value */
11437     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
11438         XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11439         return KEYUSAGE_E;
11440     }
11441     while (token != NULL)
11442     {
11443         len = (word32)XSTRLEN(token);
11444 
11445         if (!XSTRNCASECMP(token, "digitalSignature", len))
11446             cert->keyUsage |= KEYUSE_DIGITAL_SIG;
11447         else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
11448                  !XSTRNCASECMP(token, "contentCommitment", len))
11449             cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
11450         else if (!XSTRNCASECMP(token, "keyEncipherment", len))
11451             cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
11452         else if (!XSTRNCASECMP(token, "dataEncipherment", len))
11453             cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
11454         else if (!XSTRNCASECMP(token, "keyAgreement", len))
11455             cert->keyUsage |= KEYUSE_KEY_AGREE;
11456         else if (!XSTRNCASECMP(token, "keyCertSign", len))
11457             cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
11458         else if (!XSTRNCASECMP(token, "cRLSign", len))
11459             cert->keyUsage |= KEYUSE_CRL_SIGN;
11460         else if (!XSTRNCASECMP(token, "encipherOnly", len))
11461             cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
11462         else if (!XSTRNCASECMP(token, "decipherOnly", len))
11463             cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
11464         else {
11465             ret = KEYUSAGE_E;
11466             break;
11467         }
11468 
11469         token = XSTRTOK(NULL, ",", &ptr);
11470     }
11471 
11472     XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11473     return ret;
11474 }
11475 
11476 /* Set ExtendedKeyUsage from human readable string */
11477 int wc_SetExtKeyUsage(Cert *cert, const char *value)
11478 {
11479     int ret = 0;
11480     char *token, *str, *ptr;
11481     word32 len;
11482 
11483     if (cert == NULL || value == NULL)
11484         return BAD_FUNC_ARG;
11485 
11486     cert->extKeyUsage = 0;
11487 
11488     len = (word32)XSTRLEN(value);
11489     str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11490     if (str == NULL)
11491         return MEMORY_E;
11492 
11493     XSTRNCPY(str, value, len);
11494     str[len] = '\0';
11495 
11496     /* parse value, and set corresponding Key Usage value */
11497     if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
11498         XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11499         return EXTKEYUSAGE_E;
11500     }
11501 
11502     while (token != NULL)
11503     {
11504         len = (word32)XSTRLEN(token);
11505 
11506         if (!XSTRNCASECMP(token, "any", len))
11507             cert->extKeyUsage |= EXTKEYUSE_ANY;
11508         else if (!XSTRNCASECMP(token, "serverAuth", len))
11509             cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
11510         else if (!XSTRNCASECMP(token, "clientAuth", len))
11511             cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
11512         else if (!XSTRNCASECMP(token, "codeSigning", len))
11513             cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
11514         else if (!XSTRNCASECMP(token, "emailProtection", len))
11515             cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
11516         else if (!XSTRNCASECMP(token, "timeStamping", len))
11517             cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
11518         else if (!XSTRNCASECMP(token, "OCSPSigning", len))
11519             cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
11520         else {
11521             ret = EXTKEYUSAGE_E;
11522             break;
11523         }
11524 
11525         token = XSTRTOK(NULL, ",", &ptr);
11526     }
11527 
11528     XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11529     return ret;
11530 }
11531 
11532 #ifdef WOLFSSL_EKU_OID
11533 /*
11534  * cert structure to set EKU oid in
11535  * oid  the oid in byte representation
11536  * sz   size of oid buffer
11537  * idx  index of array to place oid
11538  *
11539  * returns 0 on success
11540  */
11541 int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
11542         void* heap)
11543 {
11544     byte oid[MAX_OID_SZ];
11545     word32 oidSz = MAX_OID_SZ;
11546 
11547     if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
11548         WOLFSSL_MSG("Either idx or sz was too large");
11549         return BAD_FUNC_ARG;
11550     }
11551 
11552     if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
11553         return BUFFER_E;
11554     }
11555 
11556     XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
11557     cert->extKeyUsageOIDSz[idx] = oidSz;
11558     cert->extKeyUsage |= EXTKEYUSE_USER;
11559 
11560     return 0;
11561 }
11562 #endif /* WOLFSSL_EKU_OID */
11563 #endif /* WOLFSSL_CERT_EXT */
11564 
11565 
11566 #ifdef WOLFSSL_ALT_NAMES
11567 
11568 /* Set Alt Names from der cert, return 0 on success */
11569 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
11570 {
11571     int ret;
11572 #ifdef WOLFSSL_SMALL_STACK
11573     DecodedCert* decoded;
11574 #else
11575     DecodedCert decoded[1];
11576 #endif
11577 
11578     if (derSz < 0)
11579         return derSz;
11580 
11581 #ifdef WOLFSSL_SMALL_STACK
11582     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
11583                                                        DYNAMIC_TYPE_TMP_BUFFER);
11584     if (decoded == NULL)
11585         return MEMORY_E;
11586 #endif
11587 
11588     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
11589     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
11590 
11591     if (ret < 0) {
11592         WOLFSSL_MSG("ParseCertRelative error");
11593     }
11594     else if (decoded->extensions) {
11595         byte   b;
11596         int    length;
11597         word32 maxExtensionsIdx;
11598 
11599         decoded->srcIdx = decoded->extensionsIdx;
11600         b = decoded->source[decoded->srcIdx++];
11601 
11602         if (b != ASN_EXTENSIONS) {
11603             ret = ASN_PARSE_E;
11604         }
11605         else if (GetLength(decoded->source, &decoded->srcIdx, &length,
11606                                                          decoded->maxIdx) < 0) {
11607             ret = ASN_PARSE_E;
11608         }
11609         else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
11610                                                          decoded->maxIdx) < 0) {
11611             ret = ASN_PARSE_E;
11612         }
11613         else {
11614             maxExtensionsIdx = decoded->srcIdx + length;
11615 
11616             while (decoded->srcIdx < maxExtensionsIdx) {
11617                 word32 oid;
11618                 word32 startIdx = decoded->srcIdx;
11619                 word32 tmpIdx;
11620 
11621                 if (GetSequence(decoded->source, &decoded->srcIdx, &length,
11622                             decoded->maxIdx) < 0) {
11623                     ret = ASN_PARSE_E;
11624                     break;
11625                 }
11626 
11627                 tmpIdx = decoded->srcIdx;
11628                 decoded->srcIdx = startIdx;
11629 
11630                 if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
11631                               oidCertExtType, decoded->maxIdx) < 0) {
11632                     ret = ASN_PARSE_E;
11633                     break;
11634                 }
11635 
11636                 if (oid == ALT_NAMES_OID) {
11637                     cert->altNamesSz = length + (tmpIdx - startIdx);
11638 
11639                     if (cert->altNamesSz < (int)sizeof(cert->altNames))
11640                         XMEMCPY(cert->altNames, &decoded->source[startIdx],
11641                                 cert->altNamesSz);
11642                     else {
11643                         cert->altNamesSz = 0;
11644                         WOLFSSL_MSG("AltNames extensions too big");
11645                         ret = ALT_NAME_E;
11646                         break;
11647                     }
11648                 }
11649                 decoded->srcIdx = tmpIdx + length;
11650             }
11651         }
11652     }
11653 
11654     FreeDecodedCert(decoded);
11655 #ifdef WOLFSSL_SMALL_STACK
11656     XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11657 #endif
11658 
11659     return ret < 0 ? ret : 0;
11660 }
11661 
11662 
11663 /* Set Dates from der cert, return 0 on success */
11664 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
11665 {
11666     int ret;
11667 #ifdef WOLFSSL_SMALL_STACK
11668     DecodedCert* decoded;
11669 #else
11670     DecodedCert decoded[1];
11671 #endif
11672 
11673     WOLFSSL_ENTER("SetDatesFromCert");
11674     if (derSz < 0)
11675         return derSz;
11676 
11677 #ifdef WOLFSSL_SMALL_STACK
11678     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
11679                                                        DYNAMIC_TYPE_TMP_BUFFER);
11680     if (decoded == NULL)
11681         return MEMORY_E;
11682 #endif
11683 
11684     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
11685     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
11686 
11687     if (ret < 0) {
11688         WOLFSSL_MSG("ParseCertRelative error");
11689     }
11690     else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
11691         WOLFSSL_MSG("Couldn't extract dates");
11692         ret = -1;
11693     }
11694     else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
11695                                         decoded->afterDateLen > MAX_DATE_SIZE) {
11696         WOLFSSL_MSG("Bad date size");
11697         ret = -1;
11698     }
11699     else {
11700         XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
11701         XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
11702 
11703         cert->beforeDateSz = decoded->beforeDateLen;
11704         cert->afterDateSz  = decoded->afterDateLen;
11705     }
11706 
11707     FreeDecodedCert(decoded);
11708 
11709 #ifdef WOLFSSL_SMALL_STACK
11710     XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
11711 #endif
11712 
11713     return ret < 0 ? ret : 0;
11714 }
11715 
11716 #endif /* WOLFSSL_ALT_NAMES */
11717 
11718 /* Set cn name from der buffer, return 0 on success */
11719 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
11720 {
11721     int ret, sz;
11722 #ifdef WOLFSSL_SMALL_STACK
11723     DecodedCert* decoded;
11724 #else
11725     DecodedCert decoded[1];
11726 #endif
11727 
11728     if (derSz < 0)
11729         return derSz;
11730 
11731 #ifdef WOLFSSL_SMALL_STACK
11732     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
11733                                                        DYNAMIC_TYPE_TMP_BUFFER);
11734     if (decoded == NULL)
11735         return MEMORY_E;
11736 #endif
11737 
11738     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
11739     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
11740 
11741     if (ret < 0) {
11742         WOLFSSL_MSG("ParseCertRelative error");
11743     }
11744     else {
11745         if (decoded->subjectCN) {
11746             sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
11747                                                          : CTC_NAME_SIZE - 1;
11748             XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
11749             cn->commonName[sz] = '\0';
11750             cn->commonNameEnc = decoded->subjectCNEnc;
11751         }
11752         if (decoded->subjectC) {
11753             sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
11754                                                         : CTC_NAME_SIZE - 1;
11755             XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
11756             cn->country[sz] = '\0';
11757             cn->countryEnc = decoded->subjectCEnc;
11758         }
11759         if (decoded->subjectST) {
11760             sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
11761                                                          : CTC_NAME_SIZE - 1;
11762             XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
11763             cn->state[sz] = '\0';
11764             cn->stateEnc = decoded->subjectSTEnc;
11765         }
11766         if (decoded->subjectL) {
11767             sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
11768                                                         : CTC_NAME_SIZE - 1;
11769             XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
11770             cn->locality[sz] = '\0';
11771             cn->localityEnc = decoded->subjectLEnc;
11772         }
11773         if (decoded->subjectO) {
11774             sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
11775                                                         : CTC_NAME_SIZE - 1;
11776             XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
11777             cn->org[sz] = '\0';
11778             cn->orgEnc = decoded->subjectOEnc;
11779         }
11780         if (decoded->subjectOU) {
11781             sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
11782                                                          : CTC_NAME_SIZE - 1;
11783             XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
11784             cn->unit[sz] = '\0';
11785             cn->unitEnc = decoded->subjectOUEnc;
11786         }
11787         if (decoded->subjectSN) {
11788             sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
11789                                                          : CTC_NAME_SIZE - 1;
11790             XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
11791             cn->sur[sz] = '\0';
11792             cn->surEnc = decoded->subjectSNEnc;
11793         }
11794         if (decoded->subjectEmail) {
11795             sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
11796                ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
11797             XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
11798             cn->email[sz] = '\0';
11799         }
11800     }
11801 
11802     FreeDecodedCert(decoded);
11803 
11804 #ifdef WOLFSSL_SMALL_STACK
11805     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11806 #endif
11807 
11808     return ret < 0 ? ret : 0;
11809 }
11810 
11811 
11812 #ifndef NO_FILESYSTEM
11813 
11814 /* Set cert issuer from issuerFile in PEM */
11815 int wc_SetIssuer(Cert* cert, const char* issuerFile)
11816 {
11817     int         ret;
11818     int         derSz;
11819     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
11820 
11821     if (der == NULL) {
11822         WOLFSSL_MSG("wc_SetIssuer OOF Problem");
11823         return MEMORY_E;
11824     }
11825     derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);
11826     cert->selfSigned = 0;
11827     ret = SetNameFromCert(&cert->issuer, der, derSz);
11828     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11829 
11830     return ret;
11831 }
11832 
11833 
11834 /* Set cert subject from subjectFile in PEM */
11835 int wc_SetSubject(Cert* cert, const char* subjectFile)
11836 {
11837     int         ret;
11838     int         derSz;
11839     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
11840 
11841     if (der == NULL) {
11842         WOLFSSL_MSG("wc_SetSubject OOF Problem");
11843         return MEMORY_E;
11844     }
11845     derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);
11846     ret = SetNameFromCert(&cert->subject, der, derSz);
11847     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11848 
11849     return ret;
11850 }
11851 
11852 
11853 #ifdef WOLFSSL_ALT_NAMES
11854 
11855 /* Set alt names from file in PEM */
11856 int wc_SetAltNames(Cert* cert, const char* file)
11857 {
11858     int         ret;
11859     int         derSz;
11860     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
11861 
11862     if (der == NULL) {
11863         WOLFSSL_MSG("wc_SetAltNames OOF Problem");
11864         return MEMORY_E;
11865     }
11866     derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
11867     ret = SetAltNamesFromCert(cert, der, derSz);
11868     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
11869 
11870     return ret;
11871 }
11872 
11873 #endif /* WOLFSSL_ALT_NAMES */
11874 
11875 #endif /* NO_FILESYSTEM */
11876 
11877 /* Set cert issuer from DER buffer */
11878 int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
11879 {
11880     cert->selfSigned = 0;
11881     return SetNameFromCert(&cert->issuer, der, derSz);
11882 }
11883 
11884 
11885 /* Set cert subject from DER buffer */
11886 int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
11887 {
11888     return SetNameFromCert(&cert->subject, der, derSz);
11889 }
11890 
11891 
11892 #ifdef WOLFSSL_ALT_NAMES
11893 
11894 /* Set cert alt names from DER buffer */
11895 int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
11896 {
11897     return SetAltNamesFromCert(cert, der, derSz);
11898 }
11899 
11900 /* Set cert dates from DER buffer */
11901 int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
11902 {
11903     return SetDatesFromCert(cert, der, derSz);
11904 }
11905 
11906 #endif /* WOLFSSL_ALT_NAMES */
11907 
11908 #endif /* WOLFSSL_CERT_GEN */
11909 
11910 
11911 #ifdef HAVE_ECC
11912 
11913 /* Der Encode r & s ints into out, outLen is (in/out) size */
11914 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
11915 {
11916     word32 idx = 0;
11917     int    rSz;                           /* encoding size */
11918     int    sSz;
11919     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
11920 
11921     /* If the leading bit on the INTEGER is a 1, add a leading zero */
11922     int rLeadingZero = mp_leading_bit(r);
11923     int sLeadingZero = mp_leading_bit(s);
11924     int rLen = mp_unsigned_bin_size(r);   /* big int size */
11925     int sLen = mp_unsigned_bin_size(s);
11926 
11927     if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
11928                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
11929         return BUFFER_E;
11930 
11931     idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
11932 
11933     /* store r */
11934     rSz = SetASNIntMP(r, -1, &out[idx]);
11935     if (rSz < 0)
11936         return rSz;
11937     idx += rSz;
11938 
11939     /* store s */
11940     sSz = SetASNIntMP(s, -1, &out[idx]);
11941     if (sSz < 0)
11942         return sSz;
11943     idx += sSz;
11944 
11945     *outLen = idx;
11946 
11947     return 0;
11948 }
11949 
11950 
11951 /* Der Decode ECC-DSA Signature, r & s stored as big ints */
11952 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
11953 {
11954     word32 idx = 0;
11955     int    len = 0;
11956 
11957     if (GetSequence(sig, &idx, &len, sigLen) < 0) {
11958         return ASN_ECC_KEY_E;
11959     }
11960 
11961     if ((word32)len > (sigLen - idx)) {
11962         return ASN_ECC_KEY_E;
11963     }
11964 
11965     if (GetInt(r, sig, &idx, sigLen) < 0) {
11966         return ASN_ECC_KEY_E;
11967     }
11968 
11969     if (GetInt(s, sig, &idx, sigLen) < 0) {
11970         return ASN_ECC_KEY_E;
11971     }
11972 
11973     return 0;
11974 }
11975 
11976 
11977 int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
11978                         word32 inSz)
11979 {
11980     word32 oidSum;
11981     int    version, length;
11982     int    privSz, pubSz = 0;
11983     byte   b;
11984     int    ret = 0;
11985     int    curve_id = ECC_CURVE_DEF;
11986 #ifdef WOLFSSL_SMALL_STACK
11987     byte* priv;
11988     byte* pub;
11989 #else
11990     byte priv[ECC_MAXSIZE+1];
11991     byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
11992 #endif
11993     byte* pubData = NULL;
11994 
11995     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
11996         return BAD_FUNC_ARG;
11997 
11998     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11999         return ASN_PARSE_E;
12000 
12001     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
12002         return ASN_PARSE_E;
12003 
12004     if (*inOutIdx >= inSz)
12005         return ASN_PARSE_E;
12006 
12007     b = input[*inOutIdx];
12008     *inOutIdx += 1;
12009 
12010     /* priv type */
12011     if (b != 4 && b != 6 && b != 7)
12012         return ASN_PARSE_E;
12013 
12014     if (GetLength(input, inOutIdx, &length, inSz) < 0)
12015         return ASN_PARSE_E;
12016 
12017     if (length > ECC_MAXSIZE)
12018         return BUFFER_E;
12019 
12020 #ifdef WOLFSSL_SMALL_STACK
12021     priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12022     if (priv == NULL)
12023         return MEMORY_E;
12024 
12025     pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12026     if (pub == NULL) {
12027         XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12028         return MEMORY_E;
12029     }
12030 #endif
12031 
12032     /* priv key */
12033     privSz = length;
12034     XMEMCPY(priv, &input[*inOutIdx], privSz);
12035     *inOutIdx += length;
12036 
12037     if (ret == 0 && (*inOutIdx + 1) < inSz) {
12038         /* prefix 0, may have */
12039         b = input[*inOutIdx];
12040         if (b == ECC_PREFIX_0) {
12041             *inOutIdx += 1;
12042 
12043             if (GetLength(input, inOutIdx, &length, inSz) <= 0)
12044                 ret = ASN_PARSE_E;
12045             else {
12046                 ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
12047                                   inSz);
12048                 if (ret == 0) {
12049                     if ((ret = CheckCurve(oidSum)) < 0)
12050                         ret = ECC_CURVE_OID_E;
12051                     else {
12052                         curve_id = ret;
12053                         ret = 0;
12054                     }
12055                 }
12056             }
12057         }
12058     }
12059 
12060     if (ret == 0 && (*inOutIdx + 1) < inSz) {
12061         /* prefix 1 */
12062         b = input[*inOutIdx];
12063         *inOutIdx += 1;
12064 
12065         if (b != ECC_PREFIX_1) {
12066             ret = ASN_ECC_KEY_E;
12067         }
12068         else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
12069             ret = ASN_PARSE_E;
12070         }
12071         else {
12072             /* key header */
12073             ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
12074             if (ret == 0) {
12075                 /* pub key */
12076                 pubSz = length;
12077                 if (pubSz < 2*(ECC_MAXSIZE+1)) {
12078                     XMEMCPY(pub, &input[*inOutIdx], pubSz);
12079                     *inOutIdx += length;
12080                     pubData = pub;
12081                 }
12082                 else
12083                     ret = BUFFER_E;
12084             }
12085         }
12086     }
12087 
12088     if (ret == 0) {
12089         ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,
12090                                                                       curve_id);
12091     }
12092 
12093 #ifdef WOLFSSL_SMALL_STACK
12094     XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12095     XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12096 #endif
12097 
12098     return ret;
12099 }
12100 
12101 
12102 #ifdef WOLFSSL_CUSTOM_CURVES
12103 static void ByteToHex(byte n, char* str)
12104 {
12105     static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
12106                                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
12107 
12108     str[0] = hexChar[n >> 4];
12109     str[1] = hexChar[n & 0xf];
12110 }
12111 
12112 /* returns 0 on success */
12113 static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
12114                           word32 inSz, void* heap, int heapType)
12115 {
12116     int len;
12117     int i;
12118     char* str;
12119 
12120     if (*inOutIdx >= inSz) {
12121         return BUFFER_E;
12122     }
12123 
12124     if (input[*inOutIdx] == ASN_INTEGER) {
12125         if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
12126             return ASN_PARSE_E;
12127     }
12128     else {
12129         if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
12130             return ASN_PARSE_E;
12131     }
12132 
12133     str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
12134     for (i=0; i<len; i++)
12135         ByteToHex(input[*inOutIdx + i], str + i*2);
12136     str[len*2] = '\0';
12137 
12138     *inOutIdx += len;
12139     *out = str;
12140 
12141     return 0;
12142 }
12143 #endif
12144 
12145 int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
12146                           ecc_key* key, word32 inSz)
12147 {
12148     int    length;
12149     int    ret;
12150     int    curve_id = ECC_CURVE_DEF;
12151     word32 oidSum;
12152 
12153     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
12154         return BAD_FUNC_ARG;
12155 
12156     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12157         return ASN_PARSE_E;
12158 
12159     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12160         return ASN_PARSE_E;
12161 
12162     ret = SkipObjectId(input, inOutIdx, inSz);
12163     if (ret != 0)
12164         return ret;
12165 
12166     if (*inOutIdx >= inSz) {
12167         return BUFFER_E;
12168     }
12169 
12170     if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
12171 #ifdef WOLFSSL_CUSTOM_CURVES
12172         ecc_set_type* curve;
12173         int len;
12174         char* point;
12175 
12176         ret = 0;
12177 
12178         curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
12179                                                        DYNAMIC_TYPE_ECC_BUFFER);
12180         if (curve == NULL)
12181             ret = MEMORY_E;
12182 
12183         if (ret == 0) {
12184             XMEMSET(curve, 0, sizeof(*curve));
12185             curve->name = "Custom";
12186             curve->id = ECC_CURVE_CUSTOM;
12187 
12188             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12189                 ret = ASN_PARSE_E;
12190         }
12191 
12192         if (ret == 0) {
12193             GetInteger7Bit(input, inOutIdx, inSz);
12194             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12195                 ret = ASN_PARSE_E;
12196         }
12197         if (ret == 0) {
12198             SkipObjectId(input, inOutIdx, inSz);
12199             ret = ASNToHexString(input, inOutIdx, (char**)&curve->prime, inSz,
12200                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12201         }
12202         if (ret == 0) {
12203             curve->size = (int)XSTRLEN(curve->prime) / 2;
12204 
12205             if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12206                 ret = ASN_PARSE_E;
12207         }
12208         if (ret == 0) {
12209             ret = ASNToHexString(input, inOutIdx, (char**)&curve->Af, inSz,
12210                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12211         }
12212         if (ret == 0) {
12213             ret = ASNToHexString(input, inOutIdx, (char**)&curve->Bf, inSz,
12214                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12215         }
12216         if (ret == 0) {
12217             if (*inOutIdx < inSz && input[*inOutIdx] == ASN_BIT_STRING) {
12218                 len = 0;
12219                 ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
12220                 *inOutIdx += len;
12221             }
12222         }
12223         if (ret == 0) {
12224             ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
12225                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12226 
12227             /* sanity check that point buffer is not smaller than the expected
12228              * size to hold ( 0 4 || Gx || Gy )
12229              * where Gx and Gy are each the size of curve->size * 2 */
12230             if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
12231                 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12232                 ret = BUFFER_E;
12233             }
12234         }
12235         if (ret == 0) {
12236             curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
12237                                                        DYNAMIC_TYPE_ECC_BUFFER);
12238             curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
12239                                                        DYNAMIC_TYPE_ECC_BUFFER);
12240             if (curve->Gx == NULL || curve->Gy == NULL) {
12241                 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12242                 ret = MEMORY_E;
12243             }
12244         }
12245         if (ret == 0) {
12246             XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
12247             XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
12248                                                                curve->size * 2);
12249             ((char*)curve->Gx)[curve->size * 2] = '\0';
12250             ((char*)curve->Gy)[curve->size * 2] = '\0';
12251             XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12252             ret = ASNToHexString(input, inOutIdx, (char**)&curve->order, inSz,
12253                                             key->heap, DYNAMIC_TYPE_ECC_BUFFER);
12254         }
12255         if (ret == 0) {
12256             curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
12257 
12258             curve->oid = NULL;
12259             curve->oidSz = 0;
12260             curve->oidSum = 0;
12261 
12262             if (wc_ecc_set_custom_curve(key, curve) < 0) {
12263                 ret = ASN_PARSE_E;
12264             }
12265             key->deallocSet = 1;
12266             curve = NULL;
12267         }
12268         if (curve != NULL)
12269             wc_ecc_free_curve(curve, key->heap);
12270 
12271         if (ret < 0)
12272             return ret;
12273 #else
12274         return ASN_PARSE_E;
12275 #endif
12276     }
12277     else {
12278         /* ecc params information */
12279         ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
12280         if (ret != 0)
12281             return ret;
12282 
12283         /* get curve id */
12284         curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
12285         if (curve_id < 0)
12286             return ECC_CURVE_OID_E;
12287     }
12288 
12289     /* key header */
12290     ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
12291     if (ret != 0)
12292         return ret;
12293 
12294     /* This is the raw point data compressed or uncompressed. */
12295     if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key,
12296                                                             curve_id) != 0) {
12297         return ASN_ECC_KEY_E;
12298     }
12299 
12300     return 0;
12301 }
12302 
12303 
12304 /* build DER formatted ECC key, include optional public key if requested,
12305  * return length on success, negative on error */
12306 static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
12307                              int pubIn)
12308 {
12309     byte   curve[MAX_ALGO_SZ+2];
12310     byte   ver[MAX_VERSION_SZ];
12311     byte   seq[MAX_SEQ_SZ];
12312     byte   *prv = NULL, *pub = NULL;
12313     int    ret, totalSz, curveSz, verSz;
12314     int    privHdrSz  = ASN_ECC_HEADER_SZ;
12315     int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
12316 
12317     word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
12318     word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
12319 
12320     if (key == NULL || output == NULL || inLen == 0)
12321         return BAD_FUNC_ARG;
12322 
12323     /* curve */
12324     curve[curveidx++] = ECC_PREFIX_0;
12325     curveidx++ /* to put the size after computation */;
12326     curveSz = SetCurve(key, curve+curveidx);
12327     if (curveSz < 0)
12328         return curveSz;
12329     /* set computed size */
12330     curve[1] = (byte)curveSz;
12331     curveidx += curveSz;
12332 
12333     /* private */
12334     privSz = key->dp->size;
12335     prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
12336                          key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12337     if (prv == NULL) {
12338         return MEMORY_E;
12339     }
12340     prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);
12341     ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
12342     if (ret < 0) {
12343         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12344         return ret;
12345     }
12346     prvidx += privSz;
12347 
12348     /* pubIn */
12349     if (pubIn) {
12350         ret = wc_ecc_export_x963(key, NULL, &pubSz);
12351         if (ret != LENGTH_ONLY_E) {
12352             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12353             return ret;
12354         }
12355 
12356         pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
12357                              key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12358         if (pub == NULL) {
12359             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12360             return MEMORY_E;
12361         }
12362 
12363         pub[pubidx++] = ECC_PREFIX_1;
12364         if (pubSz > 128) /* leading zero + extra size byte */
12365             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
12366         else /* leading zero */
12367             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
12368 
12369         /* SetBitString adds leading zero */
12370         pubidx += SetBitString(pubSz, 0, pub + pubidx);
12371         ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
12372         if (ret != 0) {
12373             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12374             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12375             return ret;
12376         }
12377         pubidx += pubSz;
12378     }
12379 
12380     /* make headers */
12381     verSz = SetMyVersion(1, ver, FALSE);
12382     seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
12383 
12384     totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
12385     if (totalSz > (int)inLen) {
12386         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12387         if (pubIn) {
12388             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12389         }
12390         return BAD_FUNC_ARG;
12391     }
12392 
12393     /* write out */
12394     /* seq */
12395     XMEMCPY(output + idx, seq, seqSz);
12396     idx = seqSz;
12397 
12398     /* ver */
12399     XMEMCPY(output + idx, ver, verSz);
12400     idx += verSz;
12401 
12402     /* private */
12403     XMEMCPY(output + idx, prv, prvidx);
12404     idx += prvidx;
12405     XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12406 
12407     /* curve */
12408     XMEMCPY(output + idx, curve, curveidx);
12409     idx += curveidx;
12410 
12411     /* pubIn */
12412     if (pubIn) {
12413         XMEMCPY(output + idx, pub, pubidx);
12414         /* idx += pubidx;  not used after write, if more data remove comment */
12415         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12416     }
12417 
12418     return totalSz;
12419 }
12420 
12421 
12422 /* Write a Private ecc key, including public to DER format,
12423  * length on success else < 0 */
12424 int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
12425 {
12426     return wc_BuildEccKeyDer(key, output, inLen, 1);
12427 }
12428 
12429 
12430 /* Write only private ecc key to DER format,
12431  * length on success else < 0 */
12432 int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
12433 {
12434     return wc_BuildEccKeyDer(key, output, inLen, 0);
12435 }
12436 
12437 /* Write only private ecc key to unencrypted PKCS#8 format.
12438  *
12439  * If output is NULL, places required PKCS#8 buffer size in outLen and
12440  * returns LENGTH_ONLY_E.
12441  *
12442  * return length on success else < 0 */
12443 int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
12444 {
12445     int ret, tmpDerSz;
12446     int algoID = 0;
12447     word32 oidSz = 0;
12448     word32 pkcs8Sz = 0;
12449     const byte* curveOID = NULL;
12450     byte* tmpDer = NULL;
12451 
12452     if (key == NULL || outLen == NULL)
12453         return BAD_FUNC_ARG;
12454 
12455     /* set algoID, get curve OID */
12456     algoID = ECDSAk;
12457     ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
12458     if (ret < 0)
12459         return ret;
12460 
12461     /* temp buffer for plain DER key */
12462     tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12463     if (tmpDer == NULL)
12464         return MEMORY_E;
12465 
12466     XMEMSET(tmpDer, 0, ECC_BUFSIZE);
12467 
12468     tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
12469     if (tmpDerSz < 0) {
12470         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12471         return tmpDerSz;
12472     }
12473 
12474     /* get pkcs8 expected output size */
12475     ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
12476                             curveOID, oidSz);
12477     if (ret != LENGTH_ONLY_E) {
12478         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12479         return ret;
12480     }
12481 
12482     if (output == NULL) {
12483         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12484         *outLen = pkcs8Sz;
12485         return LENGTH_ONLY_E;
12486 
12487     } else if (*outLen < pkcs8Sz) {
12488         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12489         WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
12490         return BUFFER_E;
12491     }
12492 
12493     ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
12494                             algoID, curveOID, oidSz);
12495     if (ret < 0) {
12496         XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12497         return ret;
12498     }
12499 
12500     XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12501 
12502     *outLen = ret;
12503     return ret;
12504 }
12505 
12506 #endif  /* HAVE_ECC */
12507 
12508 
12509 #ifdef HAVE_ED25519
12510 
12511 int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
12512                                ed25519_key* key, word32 inSz)
12513 {
12514     word32      oid;
12515     int         ret, version, length, endKeyIdx, privSz, pubSz;
12516     const byte* priv;
12517     const byte* pub;
12518 
12519     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
12520         return BAD_FUNC_ARG;
12521 
12522     if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
12523         endKeyIdx = *inOutIdx + length;
12524 
12525         if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
12526             return ASN_PARSE_E;
12527         if (version != 0) {
12528             WOLFSSL_MSG("Unrecognized version of ED25519 private key");
12529             return ASN_PARSE_E;
12530         }
12531 
12532         if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
12533             return ASN_PARSE_E;
12534         if (oid != ED25519k)
12535             return ASN_PARSE_E;
12536 
12537         if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
12538             return ASN_PARSE_E;
12539 
12540         if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
12541             return ASN_PARSE_E;
12542 
12543         priv = input + *inOutIdx;
12544         *inOutIdx += privSz;
12545     }
12546     else {
12547         if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
12548             return ASN_PARSE_E;
12549 
12550         priv = input + *inOutIdx;
12551         *inOutIdx += privSz;
12552         endKeyIdx = *inOutIdx;
12553     }
12554 
12555     if (endKeyIdx == (int)*inOutIdx) {
12556         ret = wc_ed25519_import_private_only(priv, privSz, key);
12557     }
12558     else {
12559         if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
12560                          inOutIdx, &length, inSz) < 0) {
12561             return ASN_PARSE_E;
12562         }
12563         if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0)
12564             return ASN_PARSE_E;
12565         pub = input + *inOutIdx;
12566         *inOutIdx += pubSz;
12567 
12568         ret = wc_ed25519_import_private_key(priv, privSz, pub, pubSz, key);
12569     }
12570     if (ret == 0 && endKeyIdx != (int)*inOutIdx)
12571         return ASN_PARSE_E;
12572 
12573     return ret;
12574 }
12575 
12576 
12577 int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
12578                               ed25519_key* key, word32 inSz)
12579 {
12580     int    length;
12581     int    ret;
12582 
12583     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
12584         return BAD_FUNC_ARG;
12585 
12586     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12587         return ASN_PARSE_E;
12588 
12589     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12590         return ASN_PARSE_E;
12591 
12592     ret = SkipObjectId(input, inOutIdx, inSz);
12593     if (ret != 0)
12594         return ret;
12595 
12596     /* key header */
12597     ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
12598     if (ret != 0)
12599         return ret;
12600 
12601     /* This is the raw point data compressed or uncompressed. */
12602     if (wc_ed25519_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
12603         return ASN_ECC_KEY_E;
12604 
12605     return 0;
12606 }
12607 
12608 
12609 #ifdef WOLFSSL_KEY_GEN
12610 
12611 /* build DER formatted ED25519 key,
12612  * return length on success, negative on error */
12613 static int wc_BuildEd25519KeyDer(ed25519_key* key, byte* output, word32 inLen,
12614                                  int pubOut)
12615 {
12616     byte   algoArray[MAX_ALGO_SZ];
12617     byte   ver[MAX_VERSION_SZ];
12618     byte   seq[MAX_SEQ_SZ];
12619     int    ret;
12620     word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0;
12621 
12622     if (key == NULL || output == NULL || inLen == 0)
12623         return BAD_FUNC_ARG;
12624 
12625     if (pubOut)
12626         pubSz = 2 + 2 + ED25519_PUB_KEY_SIZE;
12627     privSz = 2 + 2 + ED25519_KEY_SIZE;
12628     algoSz = SetAlgoID(ED25519k, algoArray, oidKeyType, 0);
12629     verSz  = SetMyVersion(0, ver, FALSE);
12630     seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, seq);
12631 
12632     if (seqSz + verSz + algoSz + privSz + pubSz > inLen)
12633         return BAD_FUNC_ARG;
12634 
12635     /* write out */
12636     /* seq */
12637     XMEMCPY(output + idx, seq, seqSz);
12638     idx = seqSz;
12639     /* ver */
12640     XMEMCPY(output + idx, ver, verSz);
12641     idx += verSz;
12642     /* algo */
12643     XMEMCPY(output + idx, algoArray, algoSz);
12644     idx += algoSz;
12645     /* privKey */
12646     idx += SetOctetString(2 + ED25519_KEY_SIZE, output + idx);
12647     idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
12648     ret = wc_ed25519_export_private_only(key, output + idx, &privSz);
12649     if (ret != 0)
12650         return ret;
12651     idx += privSz;
12652     /* pubKey */
12653     if (pubOut) {
12654         idx += SetExplicit(1, 2 + ED25519_PUB_KEY_SIZE, output + idx);
12655         idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
12656         ret = wc_ed25519_export_public(key, output + idx, &pubSz);
12657         if (ret != 0)
12658             return ret;
12659         idx += pubSz;
12660     }
12661 
12662     return idx;
12663 }
12664 
12665 /* Write a Private ecc key, including public to DER format,
12666  * length on success else < 0 */
12667 int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
12668 {
12669     return wc_BuildEd25519KeyDer(key, output, inLen, 1);
12670 }
12671 
12672 
12673 
12674 /* Write only private ecc key to DER format,
12675  * length on success else < 0 */
12676 int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
12677 {
12678     return wc_BuildEd25519KeyDer(key, output, inLen, 0);
12679 }
12680 
12681 #endif /* WOLFSSL_KEY_GEN */
12682 
12683 #endif  /* HAVE_ED25519 */
12684 
12685 
12686 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
12687 
12688 /* Get raw Date only, no processing, 0 on success */
12689 static int GetBasicDate(const byte* source, word32* idx, byte* date,
12690                         byte* format, int maxIdx)
12691 {
12692     int    ret, length;
12693     const byte *datePtr = NULL;
12694 
12695     WOLFSSL_ENTER("GetBasicDate");
12696 
12697     ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
12698     if (ret < 0)
12699         return ret;
12700 
12701     XMEMCPY(date, datePtr, length);
12702 
12703     return 0;
12704 }
12705 
12706 #endif
12707 
12708 
12709 #ifdef HAVE_OCSP
12710 
12711 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
12712 {
12713     word32 idx = *inOutIdx;
12714     word32 len;
12715 
12716     WOLFSSL_ENTER("GetEnumerated");
12717 
12718     *value = 0;
12719 
12720     if (input[idx++] != ASN_ENUMERATED)
12721         return ASN_PARSE_E;
12722 
12723     len = input[idx++];
12724     if (len > 4)
12725         return ASN_PARSE_E;
12726 
12727     while (len--) {
12728         *value  = *value << 8 | input[idx++];
12729     }
12730 
12731     *inOutIdx = idx;
12732 
12733     return *value;
12734 }
12735 
12736 
12737 static int DecodeSingleResponse(byte* source,
12738                             word32* ioIndex, OcspResponse* resp, word32 size)
12739 {
12740     word32 idx = *ioIndex, prevIndex, oid;
12741     int length, wrapperSz;
12742     CertStatus* cs = resp->status;
12743     int ret;
12744 
12745     WOLFSSL_ENTER("DecodeSingleResponse");
12746 
12747     /* Outer wrapper of the SEQUENCE OF Single Responses. */
12748     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
12749         return ASN_PARSE_E;
12750 
12751     prevIndex = idx;
12752 
12753     /* When making a request, we only request one status on one certificate
12754      * at a time. There should only be one SingleResponse */
12755 
12756     /* Wrapper around the Single Response */
12757     if (GetSequence(source, &idx, &length, size) < 0)
12758         return ASN_PARSE_E;
12759 
12760     /* Wrapper around the CertID */
12761     if (GetSequence(source, &idx, &length, size) < 0)
12762         return ASN_PARSE_E;
12763     /* Skip the hash algorithm */
12764     if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
12765         return ASN_PARSE_E;
12766     /* Save reference to the hash of CN */
12767     ret = GetOctetString(source, &idx, &length, size);
12768     if (ret < 0)
12769         return ret;
12770     resp->issuerHash = source + idx;
12771     idx += length;
12772     /* Save reference to the hash of the issuer public key */
12773     ret = GetOctetString(source, &idx, &length, size);
12774     if (ret < 0)
12775         return ret;
12776     resp->issuerKeyHash = source + idx;
12777     idx += length;
12778 
12779     /* Get serial number */
12780     if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
12781         return ASN_PARSE_E;
12782 
12783     /* CertStatus */
12784     switch (source[idx++])
12785     {
12786         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
12787             cs->status = CERT_GOOD;
12788             idx++;
12789             break;
12790         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
12791             cs->status = CERT_REVOKED;
12792             if (GetLength(source, &idx, &length, size) < 0)
12793                 return ASN_PARSE_E;
12794             idx += length;
12795             break;
12796         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
12797             cs->status = CERT_UNKNOWN;
12798             idx++;
12799             break;
12800         default:
12801             return ASN_PARSE_E;
12802     }
12803 
12804 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12805     cs->thisDateAsn = source + idx;
12806 #endif
12807     if (GetBasicDate(source, &idx, cs->thisDate,
12808                                                 &cs->thisDateFormat, size) < 0)
12809         return ASN_PARSE_E;
12810 
12811 #ifndef NO_ASN_TIME
12812     if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
12813         return ASN_BEFORE_DATE_E;
12814 #endif
12815 
12816     /* The following items are optional. Only check for them if there is more
12817      * unprocessed data in the singleResponse wrapper. */
12818 
12819     if (((int)(idx - prevIndex) < wrapperSz) &&
12820         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
12821     {
12822         idx++;
12823         if (GetLength(source, &idx, &length, size) < 0)
12824             return ASN_PARSE_E;
12825 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12826         cs->nextDateAsn = source + idx;
12827 #endif
12828         if (GetBasicDate(source, &idx, cs->nextDate,
12829                                                 &cs->nextDateFormat, size) < 0)
12830             return ASN_PARSE_E;
12831 
12832 #ifndef NO_ASN_TIME
12833         if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
12834             return ASN_AFTER_DATE_E;
12835 #endif
12836     }
12837     if (((int)(idx - prevIndex) < wrapperSz) &&
12838         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
12839     {
12840         idx++;
12841         if (GetLength(source, &idx, &length, size) < 0)
12842             return ASN_PARSE_E;
12843         idx += length;
12844     }
12845 
12846     *ioIndex = idx;
12847 
12848     return 0;
12849 }
12850 
12851 static int DecodeOcspRespExtensions(byte* source,
12852                             word32* ioIndex, OcspResponse* resp, word32 sz)
12853 {
12854     word32 idx = *ioIndex;
12855     int length;
12856     int ext_bound; /* boundary index for the sequence of extensions */
12857     word32 oid;
12858     int ret;
12859 
12860     WOLFSSL_ENTER("DecodeOcspRespExtensions");
12861 
12862     if ((idx + 1) > sz)
12863         return BUFFER_E;
12864 
12865     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
12866         return ASN_PARSE_E;
12867 
12868     if (GetLength(source, &idx, &length, sz) < 0)
12869         return ASN_PARSE_E;
12870 
12871     if (GetSequence(source, &idx, &length, sz) < 0)
12872         return ASN_PARSE_E;
12873 
12874     ext_bound = idx + length;
12875 
12876     while (idx < (word32)ext_bound) {
12877         if (GetSequence(source, &idx, &length, sz) < 0) {
12878             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
12879             return ASN_PARSE_E;
12880         }
12881 
12882         oid = 0;
12883         if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
12884             WOLFSSL_MSG("\tfail: OBJECT ID");
12885             return ASN_PARSE_E;
12886         }
12887 
12888         /* check for critical flag */
12889         if (source[idx] == ASN_BOOLEAN) {
12890             WOLFSSL_MSG("\tfound optional critical flag, moving past");
12891             ret = GetBoolean(source, &idx, sz);
12892             if (ret < 0)
12893                 return ret;
12894         }
12895 
12896         ret = GetOctetString(source, &idx, &length, sz);
12897         if (ret < 0)
12898             return ret;
12899 
12900         if (oid == OCSP_NONCE_OID) {
12901             /* get data inside extra OCTET_STRING */
12902             ret = GetOctetString(source, &idx, &length, sz);
12903             if (ret < 0)
12904                 return ret;
12905 
12906             resp->nonce = source + idx;
12907             resp->nonceSz = length;
12908         }
12909 
12910         idx += length;
12911     }
12912 
12913     *ioIndex = idx;
12914     return 0;
12915 }
12916 
12917 
12918 static int DecodeResponseData(byte* source,
12919                             word32* ioIndex, OcspResponse* resp, word32 size)
12920 {
12921     word32 idx = *ioIndex, prev_idx;
12922     int length;
12923     int version;
12924     word32 responderId = 0;
12925 
12926     WOLFSSL_ENTER("DecodeResponseData");
12927 
12928     resp->response = source + idx;
12929     prev_idx = idx;
12930     if (GetSequence(source, &idx, &length, size) < 0)
12931         return ASN_PARSE_E;
12932     resp->responseSz = length + idx - prev_idx;
12933 
12934     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
12935      * item isn't an EXPLICIT[0], then set version to zero and move
12936      * onto the next item.
12937      */
12938     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
12939     {
12940         idx += 2; /* Eat the value and length */
12941         if (GetMyVersion(source, &idx, &version, size) < 0)
12942             return ASN_PARSE_E;
12943     } else
12944         version = 0;
12945 
12946     responderId = source[idx++];
12947     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
12948         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
12949     {
12950         if (GetLength(source, &idx, &length, size) < 0)
12951             return ASN_PARSE_E;
12952         idx += length;
12953     }
12954     else
12955         return ASN_PARSE_E;
12956 
12957     /* save pointer to the producedAt time */
12958     if (GetBasicDate(source, &idx, resp->producedDate,
12959                                         &resp->producedDateFormat, size) < 0)
12960         return ASN_PARSE_E;
12961 
12962     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
12963         return ASN_PARSE_E;
12964 
12965     /*
12966      * Check the length of the ResponseData against the current index to
12967      * see if there are extensions, they are optional.
12968      */
12969     if (idx - prev_idx < resp->responseSz)
12970         if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
12971             return ASN_PARSE_E;
12972 
12973     *ioIndex = idx;
12974     return 0;
12975 }
12976 
12977 
12978 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
12979 
12980 static int DecodeCerts(byte* source,
12981                             word32* ioIndex, OcspResponse* resp, word32 size)
12982 {
12983     word32 idx = *ioIndex;
12984 
12985     WOLFSSL_ENTER("DecodeCerts");
12986 
12987     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
12988     {
12989         int length;
12990 
12991         if (GetLength(source, &idx, &length, size) < 0)
12992             return ASN_PARSE_E;
12993 
12994         if (GetSequence(source, &idx, &length, size) < 0)
12995             return ASN_PARSE_E;
12996 
12997         resp->cert = source + idx;
12998         resp->certSz = length;
12999 
13000         idx += length;
13001     }
13002     *ioIndex = idx;
13003     return 0;
13004 }
13005 
13006 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
13007 
13008 
13009 static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
13010             OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
13011 {
13012     int    length;
13013     word32 idx = *ioIndex;
13014     word32 end_index;
13015     int    ret;
13016     int    sigLength;
13017 
13018     WOLFSSL_ENTER("DecodeBasicOcspResponse");
13019     (void)heap;
13020 
13021     if (GetSequence(source, &idx, &length, size) < 0)
13022         return ASN_PARSE_E;
13023 
13024     if (idx + length > size)
13025         return ASN_INPUT_E;
13026     end_index = idx + length;
13027 
13028     if (DecodeResponseData(source, &idx, resp, size) < 0)
13029         return ASN_PARSE_E;
13030 
13031     /* Get the signature algorithm */
13032     if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
13033         return ASN_PARSE_E;
13034 
13035     ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
13036     if (ret != 0)
13037         return ret;
13038 
13039     resp->sigSz = sigLength;
13040     resp->sig = source + idx;
13041     idx += sigLength;
13042 
13043     /*
13044      * Check the length of the BasicOcspResponse against the current index to
13045      * see if there are certificates, they are optional.
13046      */
13047 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
13048     if (idx < end_index)
13049     {
13050         DecodedCert cert;
13051 
13052         if (DecodeCerts(source, &idx, resp, size) < 0)
13053             return ASN_PARSE_E;
13054 
13055         InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
13056 
13057         /* Don't verify if we don't have access to Cert Manager. */
13058         ret = ParseCertRelative(&cert, CERT_TYPE,
13059                                 noVerify ? NO_VERIFY : VERIFY_OCSP, cm);
13060         if (ret < 0) {
13061             WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
13062             FreeDecodedCert(&cert);
13063             return ret;
13064         }
13065 
13066 #ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
13067         if ((cert.extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
13068             if (XMEMCMP(cert.subjectHash,
13069                         resp->issuerHash, KEYID_SIZE) == 0) {
13070                 WOLFSSL_MSG("\tOCSP Response signed by issuer");
13071             }
13072             else {
13073                 WOLFSSL_MSG("\tOCSP Responder key usage check failed");
13074     #ifdef OPENSSL_EXTRA
13075                 resp->verifyError = OCSP_BAD_ISSUER;
13076     #else
13077                 FreeDecodedCert(&cert);
13078                 return BAD_OCSP_RESPONDER;
13079     #endif
13080             }
13081         }
13082 #endif
13083 
13084         /* ConfirmSignature is blocking here */
13085         ret = ConfirmSignature(&cert.sigCtx,
13086             resp->response, resp->responseSz,
13087             cert.publicKey, cert.pubKeySize, cert.keyOID,
13088             resp->sig, resp->sigSz, resp->sigOID);
13089         FreeDecodedCert(&cert);
13090 
13091         if (ret != 0) {
13092             WOLFSSL_MSG("\tOCSP Confirm signature failed");
13093             return ASN_OCSP_CONFIRM_E;
13094         }
13095     }
13096     else
13097 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
13098     {
13099         Signer* ca = NULL;
13100         int sigValid = -1;
13101 
13102         #ifndef NO_SKID
13103             ca = GetCA(cm, resp->issuerKeyHash);
13104         #else
13105             ca = GetCA(cm, resp->issuerHash);
13106         #endif
13107 
13108         if (ca) {
13109             SignatureCtx sigCtx;
13110             InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
13111 
13112             /* ConfirmSignature is blocking here */
13113             sigValid = ConfirmSignature(&sigCtx, resp->response,
13114                 resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
13115                                 resp->sig, resp->sigSz, resp->sigOID);
13116         }
13117         if (ca == NULL || sigValid != 0) {
13118             WOLFSSL_MSG("\tOCSP Confirm signature failed");
13119             return ASN_OCSP_CONFIRM_E;
13120         }
13121 
13122         (void)noVerify;
13123     }
13124 
13125     *ioIndex = idx;
13126     return 0;
13127 }
13128 
13129 
13130 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
13131                                                     byte* source, word32 inSz)
13132 {
13133     WOLFSSL_ENTER("InitOcspResponse");
13134 
13135     XMEMSET(status, 0, sizeof(CertStatus));
13136     XMEMSET(resp,   0, sizeof(OcspResponse));
13137 
13138     resp->responseStatus = -1;
13139     resp->status         = status;
13140     resp->source         = source;
13141     resp->maxIdx         = inSz;
13142 }
13143 
13144 
13145 int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
13146 {
13147     int ret;
13148     int length = 0;
13149     word32 idx = 0;
13150     byte* source = resp->source;
13151     word32 size = resp->maxIdx;
13152     word32 oid;
13153 
13154     WOLFSSL_ENTER("OcspResponseDecode");
13155 
13156     /* peel the outer SEQUENCE wrapper */
13157     if (GetSequence(source, &idx, &length, size) < 0)
13158         return ASN_PARSE_E;
13159 
13160     /* First get the responseStatus, an ENUMERATED */
13161     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
13162         return ASN_PARSE_E;
13163 
13164     if (resp->responseStatus != OCSP_SUCCESSFUL)
13165         return 0;
13166 
13167     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
13168     if (idx >= size)
13169         return ASN_INPUT_E;
13170     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
13171         return ASN_PARSE_E;
13172     if (GetLength(source, &idx, &length, size) < 0)
13173         return ASN_PARSE_E;
13174 
13175     /* Get the responseBytes SEQUENCE */
13176     if (GetSequence(source, &idx, &length, size) < 0)
13177         return ASN_PARSE_E;
13178 
13179     /* Check ObjectID for the resposeBytes */
13180     if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0)
13181         return ASN_PARSE_E;
13182     if (oid != OCSP_BASIC_OID)
13183         return ASN_PARSE_E;
13184     ret = GetOctetString(source, &idx, &length, size);
13185     if (ret < 0)
13186         return ret;
13187 
13188     ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
13189     if (ret < 0)
13190         return ret;
13191 
13192     return 0;
13193 }
13194 
13195 
13196 word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
13197 {
13198     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
13199                                        0x30, 0x01, 0x02 };
13200     byte seqArray[5][MAX_SEQ_SZ];
13201     word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
13202 
13203     WOLFSSL_ENTER("SetOcspReqExtensions");
13204 
13205     if (!req || !output || !req->nonceSz)
13206         return 0;
13207 
13208     totalSz += req->nonceSz;
13209     totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
13210     totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
13211     totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
13212     totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
13213     totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
13214 
13215     if (totalSz > size)
13216         return 0;
13217 
13218     totalSz = 0;
13219 
13220     XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
13221     totalSz += seqSz[4];
13222 
13223     XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
13224     totalSz += seqSz[3];
13225 
13226     XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
13227     totalSz += seqSz[2];
13228 
13229     XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
13230     totalSz += (word32)sizeof(NonceObjId);
13231 
13232     XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
13233     totalSz += seqSz[1];
13234 
13235     XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
13236     totalSz += seqSz[0];
13237 
13238     XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
13239     totalSz += req->nonceSz;
13240 
13241     return totalSz;
13242 }
13243 
13244 
13245 int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
13246 {
13247     byte seqArray[5][MAX_SEQ_SZ];
13248     /* The ASN.1 of the OCSP Request is an onion of sequences */
13249     byte algoArray[MAX_ALGO_SZ];
13250     byte issuerArray[MAX_ENCODED_DIG_SZ];
13251     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
13252     byte snArray[MAX_SN_SZ];
13253     byte extArray[MAX_OCSP_EXT_SZ];
13254     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
13255     int i, snSz;
13256 
13257     WOLFSSL_ENTER("EncodeOcspRequest");
13258 
13259 #ifdef NO_SHA
13260     algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
13261 #else
13262     algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
13263 #endif
13264 
13265     issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);
13266     issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);
13267     snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray, MAX_SN_SZ);
13268     extSz       = 0;
13269 
13270     if (snSz < 0)
13271         return snSz;
13272 
13273     if (req->nonceSz) {
13274         /* TLS Extensions use this function too - put extensions after
13275          * ASN.1: Context Specific [2].
13276          */
13277         extSz = EncodeOcspRequestExtensions(req, extArray + 2,
13278                                             OCSP_NONCE_EXT_SZ);
13279         extSz += SetExplicit(2, extSz, extArray);
13280     }
13281 
13282     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
13283     for (i = 4; i >= 0; i--) {
13284         seqSz[i] = SetSequence(totalSz, seqArray[i]);
13285         totalSz += seqSz[i];
13286         if (i == 2) totalSz += extSz;
13287     }
13288 
13289     if (output == NULL)
13290         return totalSz;
13291     if (totalSz > size)
13292         return BUFFER_E;
13293 
13294     totalSz = 0;
13295     for (i = 0; i < 5; i++) {
13296         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
13297         totalSz += seqSz[i];
13298     }
13299 
13300     XMEMCPY(output + totalSz, algoArray, algoSz);
13301     totalSz += algoSz;
13302 
13303     XMEMCPY(output + totalSz, issuerArray, issuerSz);
13304     totalSz += issuerSz;
13305 
13306     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
13307     totalSz += issuerKeySz;
13308 
13309     XMEMCPY(output + totalSz, snArray, snSz);
13310     totalSz += snSz;
13311 
13312     if (extSz != 0) {
13313         XMEMCPY(output + totalSz, extArray, extSz);
13314         totalSz += extSz;
13315     }
13316 
13317     return totalSz;
13318 }
13319 
13320 
13321 int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
13322                                                                      void* heap)
13323 {
13324     int ret;
13325 
13326     WOLFSSL_ENTER("InitOcspRequest");
13327 
13328     if (req == NULL)
13329         return BAD_FUNC_ARG;
13330 
13331     ForceZero(req, sizeof(OcspRequest));
13332     req->heap = heap;
13333 
13334     if (cert) {
13335         XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
13336         XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
13337 
13338         req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
13339                                                      DYNAMIC_TYPE_OCSP_REQUEST);
13340         if (req->serial == NULL)
13341             return MEMORY_E;
13342 
13343         XMEMCPY(req->serial, cert->serial, cert->serialSz);
13344         req->serialSz = cert->serialSz;
13345 
13346         if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
13347             req->url = (byte*)XMALLOC(cert->extAuthInfoSz, req->heap,
13348                                                      DYNAMIC_TYPE_OCSP_REQUEST);
13349             if (req->url == NULL) {
13350                 XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
13351                 return MEMORY_E;
13352             }
13353 
13354             XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
13355             req->urlSz = cert->extAuthInfoSz;
13356         }
13357     }
13358 
13359     if (useNonce) {
13360         WC_RNG rng;
13361 
13362     #ifndef HAVE_FIPS
13363         ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
13364     #else
13365         ret = wc_InitRng(&rng);
13366     #endif
13367         if (ret != 0) {
13368             WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
13369         } else {
13370             if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
13371                 WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
13372             else
13373                 req->nonceSz = MAX_OCSP_NONCE_SZ;
13374 
13375             wc_FreeRng(&rng);
13376         }
13377     }
13378 
13379     return 0;
13380 }
13381 
13382 void FreeOcspRequest(OcspRequest* req)
13383 {
13384     WOLFSSL_ENTER("FreeOcspRequest");
13385 
13386     if (req) {
13387         if (req->serial)
13388             XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
13389 
13390         if (req->url)
13391             XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
13392     }
13393 }
13394 
13395 
13396 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
13397 {
13398     int cmp;
13399 
13400     WOLFSSL_ENTER("CompareOcspReqResp");
13401 
13402     if (req == NULL)
13403     {
13404         WOLFSSL_MSG("\tReq missing");
13405         return -1;
13406     }
13407 
13408     if (resp == NULL)
13409     {
13410         WOLFSSL_MSG("\tResp missing");
13411         return 1;
13412     }
13413 
13414     /* Nonces are not critical. The responder may not necessarily add
13415      * the nonce to the response. */
13416     if (resp->nonceSz != 0) {
13417         cmp = req->nonceSz - resp->nonceSz;
13418         if (cmp != 0)
13419         {
13420             WOLFSSL_MSG("\tnonceSz mismatch");
13421             return cmp;
13422         }
13423 
13424         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
13425         if (cmp != 0)
13426         {
13427             WOLFSSL_MSG("\tnonce mismatch");
13428             return cmp;
13429         }
13430     }
13431 
13432     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
13433     if (cmp != 0)
13434     {
13435         WOLFSSL_MSG("\tissuerHash mismatch");
13436         return cmp;
13437     }
13438 
13439     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
13440     if (cmp != 0)
13441     {
13442         WOLFSSL_MSG("\tissuerKeyHash mismatch");
13443         return cmp;
13444     }
13445 
13446     cmp = req->serialSz - resp->status->serialSz;
13447     if (cmp != 0)
13448     {
13449         WOLFSSL_MSG("\tserialSz mismatch");
13450         return cmp;
13451     }
13452 
13453     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
13454     if (cmp != 0)
13455     {
13456         WOLFSSL_MSG("\tserial mismatch");
13457         return cmp;
13458     }
13459 
13460     return 0;
13461 }
13462 
13463 #endif
13464 
13465 
13466 /* store WC_SHA hash of NAME */
13467 WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
13468                              int maxIdx)
13469 {
13470     int    length;  /* length of all distinguished names */
13471     int    ret;
13472     word32 dummy;
13473 
13474     WOLFSSL_ENTER("GetNameHash");
13475 
13476     if (source[*idx] == ASN_OBJECT_ID) {
13477         WOLFSSL_MSG("Trying optional prefix...");
13478 
13479         if (GetLength(source, idx, &length, maxIdx) < 0)
13480             return ASN_PARSE_E;
13481 
13482         *idx += length;
13483         WOLFSSL_MSG("Got optional prefix");
13484     }
13485 
13486     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
13487      * calculated over the entire DER encoding of the Name field, including
13488      * the tag and length. */
13489     dummy = *idx;
13490     if (GetSequence(source, idx, &length, maxIdx) < 0)
13491         return ASN_PARSE_E;
13492 
13493 #ifdef NO_SHA
13494     ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
13495 #else
13496     ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
13497 #endif
13498 
13499     *idx += length;
13500 
13501     return ret;
13502 }
13503 
13504 
13505 #ifdef HAVE_CRL
13506 
13507 /* initialize decoded CRL */
13508 void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
13509 {
13510     WOLFSSL_MSG("InitDecodedCRL");
13511 
13512     dcrl->certBegin    = 0;
13513     dcrl->sigIndex     = 0;
13514     dcrl->sigLength    = 0;
13515     dcrl->signatureOID = 0;
13516     dcrl->certs        = NULL;
13517     dcrl->totalCerts   = 0;
13518     dcrl->heap         = heap;
13519     #ifdef WOLFSSL_HEAP_TEST
13520         dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
13521     #endif
13522 }
13523 
13524 
13525 /* free decoded CRL resources */
13526 void FreeDecodedCRL(DecodedCRL* dcrl)
13527 {
13528     RevokedCert* tmp = dcrl->certs;
13529 
13530     WOLFSSL_MSG("FreeDecodedCRL");
13531 
13532     while(tmp) {
13533         RevokedCert* next = tmp->next;
13534         XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
13535         tmp = next;
13536     }
13537 }
13538 
13539 
13540 /* Get Revoked Cert list, 0 on success */
13541 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
13542                       int maxIdx)
13543 {
13544     int    ret, len;
13545     word32 end;
13546     byte   b;
13547     RevokedCert* rc;
13548 
13549     WOLFSSL_ENTER("GetRevoked");
13550 
13551     if (GetSequence(buff, idx, &len, maxIdx) < 0)
13552         return ASN_PARSE_E;
13553 
13554     end = *idx + len;
13555 
13556     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
13557                                                           DYNAMIC_TYPE_REVOKED);
13558     if (rc == NULL) {
13559         WOLFSSL_MSG("Alloc Revoked Cert failed");
13560         return MEMORY_E;
13561     }
13562 
13563     if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
13564                                                                 maxIdx) < 0) {
13565         XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
13566         return ASN_PARSE_E;
13567     }
13568 
13569     /* add to list */
13570     rc->next = dcrl->certs;
13571     dcrl->certs = rc;
13572     dcrl->totalCerts++;
13573 
13574     /* get date */
13575     ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
13576     if (ret < 0) {
13577         WOLFSSL_MSG("Expecting Date");
13578         return ret;
13579     }
13580 
13581     if (*idx != end)  /* skip extensions */
13582         *idx = end;
13583 
13584     return 0;
13585 }
13586 
13587 
13588 /* Get CRL Signature, 0 on success */
13589 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
13590                             int maxIdx)
13591 {
13592     int    length;
13593     int    ret;
13594 
13595     WOLFSSL_ENTER("GetCRL_Signature");
13596 
13597     ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
13598     if (ret != 0)
13599         return ret;
13600     dcrl->sigLength = length;
13601 
13602     dcrl->signature = (byte*)&source[*idx];
13603     *idx += dcrl->sigLength;
13604 
13605     return 0;
13606 }
13607 
13608 int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
13609                         word32 tbsSz, const byte* signature, word32 sigSz,
13610                         word32 signatureOID, Signer *ca, void* heap)
13611 {
13612     /* try to confirm/verify signature */
13613 #ifndef IGNORE_KEY_EXTENSIONS
13614     if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
13615         WOLFSSL_MSG("CA cannot sign CRLs");
13616         return ASN_CRL_NO_SIGNER_E;
13617     }
13618 #endif /* IGNORE_KEY_EXTENSIONS */
13619 
13620     InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
13621     if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
13622                          ca->pubKeySize, ca->keyOID, signature, sigSz,
13623                          signatureOID) != 0) {
13624         WOLFSSL_MSG("CRL Confirm signature failed");
13625         return ASN_CRL_CONFIRM_E;
13626     }
13627 
13628     return 0;
13629 }
13630 
13631 /* prase crl buffer into decoded state, 0 on success */
13632 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
13633 {
13634     int          version, len, doNextDate = 1;
13635     word32       oid, idx = 0, dateIdx;
13636     Signer*      ca = NULL;
13637     SignatureCtx sigCtx;
13638 
13639     WOLFSSL_MSG("ParseCRL");
13640 
13641     /* raw crl hash */
13642     /* hash here if needed for optimized comparisons
13643      * wc_Sha sha;
13644      * wc_InitSha(&sha);
13645      * wc_ShaUpdate(&sha, buff, sz);
13646      * wc_ShaFinal(&sha, dcrl->crlHash); */
13647 
13648     if (GetSequence(buff, &idx, &len, sz) < 0)
13649         return ASN_PARSE_E;
13650 
13651     dcrl->certBegin = idx;
13652 
13653     if (GetSequence(buff, &idx, &len, sz) < 0)
13654         return ASN_PARSE_E;
13655     dcrl->sigIndex = len + idx;
13656 
13657     /* may have version */
13658     if (buff[idx] == ASN_INTEGER) {
13659         if (GetMyVersion(buff, &idx, &version, sz) < 0)
13660             return ASN_PARSE_E;
13661     }
13662 
13663     if (GetAlgoId(buff, &idx, &oid, oidIgnoreType, sz) < 0)
13664         return ASN_PARSE_E;
13665 
13666     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
13667         return ASN_PARSE_E;
13668 
13669     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
13670         return ASN_PARSE_E;
13671 
13672     dateIdx = idx;
13673 
13674     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
13675     {
13676 #ifndef WOLFSSL_NO_CRL_NEXT_DATE
13677         (void)dateIdx;
13678         return ASN_PARSE_E;
13679 #else
13680         dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
13681         doNextDate = 0;
13682         idx = dateIdx;
13683 #endif
13684     }
13685 
13686     if (doNextDate) {
13687 #ifndef NO_ASN_TIME
13688         if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
13689             WOLFSSL_MSG("CRL after date is no longer valid");
13690             return ASN_AFTER_DATE_E;
13691         }
13692 #endif
13693     }
13694 
13695     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
13696         if (GetSequence(buff, &idx, &len, sz) < 0)
13697             return ASN_PARSE_E;
13698 
13699         len += idx;
13700 
13701         while (idx < (word32)len) {
13702             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
13703                 return ASN_PARSE_E;
13704         }
13705     }
13706 
13707     if (idx != dcrl->sigIndex)
13708         idx = dcrl->sigIndex;   /* skip extensions */
13709 
13710     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
13711         return ASN_PARSE_E;
13712 
13713     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
13714         return ASN_PARSE_E;
13715 
13716     /* openssl doesn't add skid by default for CRLs cause firefox chokes
13717        we're not assuming it's available yet */
13718 #if !defined(NO_SKID) && defined(CRL_SKID_READY)
13719     if (dcrl->extAuthKeyIdSet)
13720         ca = GetCA(cm, dcrl->extAuthKeyId);
13721     if (ca == NULL)
13722         ca = GetCAByName(cm, dcrl->issuerHash);
13723 #else
13724     ca = GetCA(cm, dcrl->issuerHash);
13725 #endif /* !NO_SKID && CRL_SKID_READY */
13726     WOLFSSL_MSG("About to verify CRL signature");
13727 
13728     if (ca == NULL) {
13729         WOLFSSL_MSG("Did NOT find CRL issuer CA");
13730         return ASN_CRL_NO_SIGNER_E;
13731     }
13732 
13733     WOLFSSL_MSG("Found CRL issuer CA");
13734     return VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
13735            dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
13736            dcrl->signatureOID, ca, dcrl->heap);
13737 }
13738 
13739 #endif /* HAVE_CRL */
13740 
13741 #undef ERROR_OUT
13742 
13743 #endif /* !NO_ASN */
13744 
13745 #ifdef WOLFSSL_SEP
13746 
13747 
13748 #endif /* WOLFSSL_SEP */
13749