wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

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-2016 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 <wolfssl/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 */
00038 
00039 #ifndef NO_ASN
00040 
00041 #ifdef HAVE_RTP_SYS
00042     #include "os.h"           /* dc_rtc_api needs    */
00043     #include "dc_rtc_api.h"   /* to get current time */
00044 #endif
00045 
00046 #include <wolfssl/wolfcrypt/asn.h>
00047 #include <wolfssl/wolfcrypt/coding.h>
00048 #include <wolfssl/wolfcrypt/md2.h>
00049 #include <wolfssl/wolfcrypt/hmac.h>
00050 #include <wolfssl/wolfcrypt/error-crypt.h>
00051 #include <wolfssl/wolfcrypt/pwdbased.h>
00052 #include <wolfssl/wolfcrypt/des3.h>
00053 #include <wolfssl/wolfcrypt/logging.h>
00054 
00055 #include <wolfssl/wolfcrypt/random.h>
00056 #include <wolfssl/wolfcrypt/hash.h>
00057 #ifdef NO_INLINE
00058     #include <wolfssl/wolfcrypt/misc.h>
00059 #else
00060     #define WOLFSSL_MISC_INCLUDED
00061     #include <wolfcrypt/src/misc.c>
00062 #endif
00063 
00064 #ifndef NO_RC4
00065     #include <wolfssl/wolfcrypt/arc4.h>
00066 #endif
00067 
00068 #ifdef HAVE_NTRU
00069     #include "libntruencrypt/ntru_crypto.h"
00070 #endif
00071 
00072 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
00073     #include <wolfssl/wolfcrypt/sha512.h>
00074 #endif
00075 
00076 #ifndef NO_SHA256
00077     #include <wolfssl/wolfcrypt/sha256.h>
00078 #endif
00079 
00080 #ifdef HAVE_ECC
00081     #include <wolfssl/wolfcrypt/ecc.h>
00082 #endif
00083 
00084 #ifndef NO_RSA
00085     #include <wolfssl/wolfcrypt/rsa.h>
00086 #endif
00087 
00088 #ifdef WOLFSSL_DEBUG_ENCODING
00089     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00090         #if MQX_USE_IO_OLD
00091             #include <fio.h>
00092         #else
00093             #include <nio.h>
00094         #endif
00095     #else
00096         #include <stdio.h>
00097     #endif
00098 #endif
00099 
00100 #ifdef _MSC_VER
00101     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
00102     #pragma warning(disable: 4996)
00103 #endif
00104 
00105 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
00106 
00107 #ifndef NO_ASN_TIME
00108 #if defined(USER_TIME)
00109     /* Use our gmtime and time_t/struct tm types.
00110        Only needs seconds since EPOCH using XTIME function.
00111        time_t XTIME(time_t * timer) {}
00112     */
00113     #define WOLFSSL_GMTIME
00114     #define USE_WOLF_TM
00115     #define USE_WOLF_TIME_T
00116 
00117 #elif defined(TIME_OVERRIDES)
00118     /* Override XTIME() and XGMTIME() functionality.
00119        Requires user to provide these functions:
00120         time_t XTIME(time_t * timer) {}
00121         struct tm* XGMTIME(const time_t* timer, struct tm* tmp) {}
00122     */
00123     #ifndef HAVE_TIME_T_TYPE
00124         #define USE_WOLF_TIME_T
00125     #endif
00126     #ifndef HAVE_TM_TYPE
00127         #define USE_WOLF_TM
00128     #endif
00129     #define NEED_TMP_TIME
00130 
00131 #elif defined(HAVE_RTP_SYS)
00132     /* uses parital <time.h> structures */
00133     #define XTIME(tl)       (0)
00134     #define XGMTIME(c, t)   rtpsys_gmtime((c))
00135 
00136 #elif defined(MICRIUM)
00137     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
00138         #define XVALIDATE_DATE(d, f, t) NetSecure_ValidateDateHandler((d), (f), (t))
00139     #else
00140         #define XVALIDATE_DATE(d, f, t) (0)
00141     #endif
00142     #define NO_TIME_H
00143     /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
00144 
00145 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
00146     #include <time.h>
00147     #define XTIME(t1)       pic32_time((t1))
00148     #define XGMTIME(c, t)   gmtime((c))
00149 
00150 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00151     #define XTIME(t1)       mqx_time((t1))
00152     #define HAVE_GMTIME_R
00153 
00154 #elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
00155     #include <time.h>
00156     #ifndef XTIME
00157         #define XTIME(t1)   ksdk_time((t1))
00158     #endif
00159     #define XGMTIME(c, t)   gmtime((c))
00160 
00161 #elif defined(WOLFSSL_ATMEL)
00162     #define XTIME(t1)       atmel_get_curr_time_and_date((t1))
00163     #define WOLFSSL_GMTIME
00164     #define USE_WOLF_TM
00165     #define USE_WOLF_TIME_T
00166 
00167 #elif defined(IDIRECT_DEV_TIME)
00168     /*Gets the timestamp from cloak software owned by VT iDirect
00169     in place of time() from <time.h> */
00170     #include <time.h>
00171     #define XTIME(t1)       idirect_time((t1))
00172     #define XGMTIME(c, t)   gmtime((c))
00173 
00174 #elif defined(_WIN32_WCE)
00175     #include <windows.h>
00176     #define XTIME(t1)       windows_time((t1))
00177     #define WOLFSSL_GMTIME
00178 
00179 #else
00180     /* default */
00181     /* uses complete <time.h> facility */
00182     #include <time.h>
00183 #endif
00184 
00185 
00186 /* Map default time functions */
00187 #if !defined(XTIME) && !defined(TIME_OVERRIDES) && !defined(USER_TIME)
00188     #define XTIME(tl)       time((tl))
00189 #endif
00190 #if !defined(XGMTIME) && !defined(TIME_OVERRIDES)
00191     #if defined(WOLFSSL_GMTIME) || !defined(HAVE_GMTIME_R)
00192         #define XGMTIME(c, t)   gmtime((c))
00193     #else
00194         #define XGMTIME(c, t)   gmtime_r((c), (t))
00195         #define NEED_TMP_TIME
00196     #endif
00197 #endif
00198 #if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE)
00199     #define USE_WOLF_VALIDDATE
00200     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00201 #endif
00202 
00203 /* wolf struct tm and time_t */
00204 #if defined(USE_WOLF_TM)
00205     struct tm {
00206         int  tm_sec;     /* seconds after the minute [0-60] */
00207         int  tm_min;     /* minutes after the hour [0-59] */
00208         int  tm_hour;    /* hours since midnight [0-23] */
00209         int  tm_mday;    /* day of the month [1-31] */
00210         int  tm_mon;     /* months since January [0-11] */
00211         int  tm_year;    /* years since 1900 */
00212         int  tm_wday;    /* days since Sunday [0-6] */
00213         int  tm_yday;    /* days since January 1 [0-365] */
00214         int  tm_isdst;   /* Daylight Savings Time flag */
00215         long tm_gmtoff;  /* offset from CUT in seconds */
00216         char *tm_zone;   /* timezone abbreviation */
00217     };
00218 #endif /* USE_WOLF_TM */
00219 #if defined(USE_WOLF_TIME_T)
00220     typedef long time_t;
00221 #endif
00222 
00223 /* forward declarations */
00224 #if defined(USER_TIME)
00225     struct tm* gmtime(const time_t* timer);
00226     extern time_t XTIME(time_t * timer);
00227 
00228     #ifdef STACK_TRAP
00229         /* for stack trap tracking, don't call os gmtime on OS X/linux,
00230            uses a lot of stack spce */
00231         extern time_t time(time_t * timer);
00232         #define XTIME(tl)  time((tl))
00233     #endif /* STACK_TRAP */
00234 
00235 #elif defined(TIME_OVERRIDES)
00236     extern time_t XTIME(time_t * timer);
00237     extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
00238 #elif defined(WOLFSSL_GMTIME)
00239     struct tm* gmtime(const time_t* timer);
00240 #endif
00241 
00242 #if defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
00243     /* extern time_t ksdk_time(time_t* timer); */
00244 #endif /* FREESCALE_KSDK_BM || FREESCALE_FREE_RTOS */
00245 
00246 
00247 #if defined(_WIN32_WCE)
00248 time_t windows_time(time_t* timer)
00249 {
00250     SYSTEMTIME     sysTime;
00251     FILETIME       fTime;
00252     ULARGE_INTEGER intTime;
00253     time_t         localTime;
00254 
00255     if (timer == NULL)
00256         timer = &localTime;
00257 
00258     GetSystemTime(&sysTime);
00259     SystemTimeToFileTime(&sysTime, &fTime);
00260 
00261     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
00262     /* subtract EPOCH */
00263     intTime.QuadPart -= 0x19db1ded53e8000;
00264     /* to secs */
00265     intTime.QuadPart /= 10000000;
00266     *timer = (time_t)intTime.QuadPart;
00267 
00268     return *timer;
00269 }
00270 #endif /*  _WIN32_WCE */
00271 
00272 #if defined(WOLFSSL_GMTIME)
00273 struct tm* gmtime(const time_t* timer)
00274 {
00275     #define YEAR0          1900
00276     #define EPOCH_YEAR     1970
00277     #define SECS_DAY       (24L * 60L * 60L)
00278     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
00279     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
00280 
00281     static const int _ytab[2][12] =
00282     {
00283         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
00284         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
00285     };
00286 
00287     static struct tm st_time;
00288     struct tm* ret = &st_time;
00289     time_t secs = *timer;
00290     unsigned long dayclock, dayno;
00291     int year = EPOCH_YEAR;
00292 
00293     dayclock = (unsigned long)secs % SECS_DAY;
00294     dayno    = (unsigned long)secs / SECS_DAY;
00295 
00296     ret->tm_sec  = (int) dayclock % 60;
00297     ret->tm_min  = (int)(dayclock % 3600) / 60;
00298     ret->tm_hour = (int) dayclock / 3600;
00299     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
00300 
00301     while(dayno >= (unsigned long)YEARSIZE(year)) {
00302         dayno -= YEARSIZE(year);
00303         year++;
00304     }
00305 
00306     ret->tm_year = year - YEAR0;
00307     ret->tm_yday = (int)dayno;
00308     ret->tm_mon  = 0;
00309 
00310     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
00311         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
00312         ret->tm_mon++;
00313     }
00314 
00315     ret->tm_mday  = (int)++dayno;
00316     ret->tm_isdst = 0;
00317 
00318     return ret;
00319 }
00320 #endif /* WOLFSSL_GMTIME */
00321 
00322 
00323 #if defined(HAVE_RTP_SYS)
00324 #define YEAR0          1900
00325 
00326 struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
00327 {
00328     static struct tm st_time;
00329     struct tm* ret = &st_time;
00330 
00331     DC_RTC_CALENDAR cal;
00332     dc_rtc_time_get(&cal, TRUE);
00333 
00334     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
00335     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
00336     ret->tm_mday  = cal.day;
00337     ret->tm_hour  = cal.hour;
00338     ret->tm_min   = cal.minute;
00339     ret->tm_sec   = cal.second;
00340 
00341     return ret;
00342 }
00343 
00344 #endif /* HAVE_RTP_SYS */
00345 
00346 
00347 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
00348 
00349 /*
00350  * time() is just a stub in Microchip libraries. We need our own
00351  * implementation. Use SNTP client to get seconds since epoch.
00352  */
00353 time_t pic32_time(time_t* timer)
00354 {
00355 #ifdef MICROCHIP_TCPIP_V5
00356     DWORD sec = 0;
00357 #else
00358     uint32_t sec = 0;
00359 #endif
00360     time_t localTime;
00361 
00362     if (timer == NULL)
00363         timer = &localTime;
00364 
00365 #ifdef MICROCHIP_MPLAB_HARMONY
00366     sec = TCPIP_SNTP_UTCSecondsGet();
00367 #else
00368     sec = SNTPGetUTCSeconds();
00369 #endif
00370     *timer = (time_t) sec;
00371 
00372     return *timer;
00373 }
00374 
00375 #endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
00376 
00377 
00378 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00379 
00380 time_t mqx_time(time_t* timer)
00381 {
00382     time_t localTime;
00383     TIME_STRUCT time_s;
00384 
00385     if (timer == NULL)
00386         timer = &localTime;
00387 
00388     _time_get(&time_s);
00389     *timer = (time_t) time_s.SECONDS;
00390 
00391     return *timer;
00392 }
00393 
00394 #endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
00395 
00396 
00397 #if defined(WOLFSSL_TIRTOS)
00398 
00399 time_t XTIME(time_t * timer)
00400 {
00401     time_t sec = 0;
00402 
00403     sec = (time_t) Seconds_get();
00404 
00405     if (timer != NULL)
00406         *timer = sec;
00407 
00408     return sec;
00409 }
00410 
00411 #endif /* WOLFSSL_TIRTOS */
00412 
00413 
00414 static INLINE word32 btoi(byte b)
00415 {
00416     return (word32)(b - 0x30);
00417 }
00418 
00419 
00420 /* two byte date/time, add to value */
00421 static INLINE void GetTime(int* value, const byte* date, int* idx)
00422 {
00423     int i = *idx;
00424 
00425     *value += btoi(date[i++]) * 10;
00426     *value += btoi(date[i++]);
00427 
00428     *idx = i;
00429 }
00430 
00431 
00432 #if defined(MICRIUM)
00433 
00434 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
00435                                          CPU_INT08U dateType)
00436 {
00437     CPU_BOOLEAN  rtn_code;
00438     CPU_INT32S   i;
00439     CPU_INT32S   val;
00440     CPU_INT16U   year;
00441     CPU_INT08U   month;
00442     CPU_INT16U   day;
00443     CPU_INT08U   hour;
00444     CPU_INT08U   min;
00445     CPU_INT08U   sec;
00446 
00447     i    = 0;
00448     year = 0u;
00449 
00450     if (format == ASN_UTC_TIME) {
00451         if (btoi(date[0]) >= 5)
00452             year = 1900;
00453         else
00454             year = 2000;
00455     }
00456     else  { /* format == GENERALIZED_TIME */
00457         year += btoi(date[i++]) * 1000;
00458         year += btoi(date[i++]) * 100;
00459     }
00460 
00461     val = year;
00462     GetTime(&val, date, &i);
00463     year = (CPU_INT16U)val;
00464 
00465     val = 0;
00466     GetTime(&val, date, &i);
00467     month = (CPU_INT08U)val;
00468 
00469     val = 0;
00470     GetTime(&val, date, &i);
00471     day = (CPU_INT16U)val;
00472 
00473     val = 0;
00474     GetTime(&val, date, &i);
00475     hour = (CPU_INT08U)val;
00476 
00477     val = 0;
00478     GetTime(&val, date, &i);
00479     min = (CPU_INT08U)val;
00480 
00481     val = 0;
00482     GetTime(&val, date, &i);
00483     sec = (CPU_INT08U)val;
00484 
00485     return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType);
00486 }
00487 
00488 #endif /* MICRIUM */
00489 
00490 
00491 #if defined(IDIRECT_DEV_TIME)
00492 
00493 extern time_t getTimestamp();
00494 
00495 time_t idirect_time(time_t * timer)
00496 {
00497     time_t sec = getTimestamp();
00498 
00499     if (timer != NULL)
00500         *timer = sec;
00501 
00502     return sec;
00503 }
00504 
00505 #endif /* IDIRECT_DEV_TIME */
00506 
00507 #endif /* !NO_ASN_TIME */
00508 
00509 
00510 WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
00511                            word32 maxIdx)
00512 {
00513     int     length = 0;
00514     word32  idx = *inOutIdx;
00515     byte    b;
00516 
00517     *len = 0;    /* default length */
00518 
00519     if ((idx + 1) > maxIdx) {   /* for first read */
00520         WOLFSSL_MSG("GetLength bad index on input");
00521         return BUFFER_E;
00522     }
00523 
00524     b = input[idx++];
00525     if (b >= ASN_LONG_LENGTH) {
00526         word32 bytes = b & 0x7F;
00527 
00528         if ((idx + bytes) > maxIdx) {   /* for reading bytes */
00529             WOLFSSL_MSG("GetLength bad long length");
00530             return BUFFER_E;
00531         }
00532 
00533         while (bytes--) {
00534             b = input[idx++];
00535             length = (length << 8) | b;
00536         }
00537     }
00538     else
00539         length = b;
00540 
00541     if ((idx + length) > maxIdx) {   /* for user of length */
00542         WOLFSSL_MSG("GetLength value exceeds buffer length");
00543         return BUFFER_E;
00544     }
00545 
00546     *inOutIdx = idx;
00547     if (length > 0)
00548         *len = length;
00549 
00550     return length;
00551 }
00552 
00553 
00554 /* Get the DER/BER encoding of an ASN.1 header.
00555  *
00556  * input     Buffer holding DER/BER encoded data.
00557  * tag       ASN.1 tag value expected in header.
00558  * inOutIdx  Current index into buffer to parse.
00559  * len       The number of bytes in the ASN.1 data.
00560  * maxIdx    Length of data in buffer.
00561  * returns BUFFER_E when there is not enough data to parse.
00562  *         ASN_PARSE_E when the expected tag is not found or length is invalid.
00563  *         Otherwise, the number of bytes in the ASN.1 data.
00564  */
00565 static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
00566                         word32 maxIdx)
00567 {
00568     word32 idx = *inOutIdx;
00569     byte   b;
00570     int    length;
00571 
00572     if ((idx + 1) > maxIdx)
00573         return BUFFER_E;
00574 
00575     b = input[idx++];
00576     if (b != tag)
00577         return ASN_PARSE_E;
00578 
00579     if (GetLength(input, &idx, &length, maxIdx) < 0)
00580         return ASN_PARSE_E;
00581 
00582     *len      = length;
00583     *inOutIdx = idx;
00584     return length;
00585 }
00586 
00587 WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
00588                            word32 maxIdx)
00589 {
00590     return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
00591                         maxIdx);
00592 }
00593 
00594 
00595 WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
00596                         word32 maxIdx)
00597 {
00598     return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
00599                         maxIdx);
00600 }
00601 
00602 /* Get the DER/BER encoded ASN.1 NULL element.
00603  * Ensure that the all fields are as expected and move index past the element.
00604  *
00605  * input     Buffer holding DER/BER encoded data.
00606  * inOutIdx  Current index into buffer to parse.
00607  * maxIdx    Length of data in buffer.
00608  * returns BUFFER_E when there is not enough data to parse.
00609  *         ASN_TAG_NULL_E when the NULL tag is not found.
00610  *         ASN_EXPECT_0_E when the length is not zero.
00611  *         Otherwise, 0 to indicate success.
00612  */
00613 static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
00614 {
00615     word32 idx = *inOutIdx;
00616     byte   b;
00617 
00618     if ((idx + 2) > maxIdx)
00619         return BUFFER_E;
00620 
00621     b = input[idx++];
00622     if (b != ASN_TAG_NULL)
00623         return ASN_TAG_NULL_E;
00624 
00625     if (input[idx++] != 0)
00626         return ASN_EXPECT_0_E;
00627 
00628     *inOutIdx = idx;
00629     return 0;
00630 }
00631 
00632 /* Set the DER/BER encoding of the ASN.1 NULL element.
00633  *
00634  * output  Buffer to write into.
00635  * returns the number of bytes added to the buffer.
00636  */
00637 static int SetASNNull(byte* output)
00638 {
00639     output[0] = ASN_TAG_NULL;
00640     output[1] = 0;
00641 
00642     return 2;
00643 }
00644 
00645 /* Get the DER/BER encoding of an ASN.1 BOOLEAN.
00646  *
00647  * input     Buffer holding DER/BER encoded data.
00648  * inOutIdx  Current index into buffer to parse.
00649  * maxIdx    Length of data in buffer.
00650  * returns BUFFER_E when there is not enough data to parse.
00651  *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
00652  *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
00653  */
00654 static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
00655 {
00656     word32 idx = *inOutIdx;
00657     byte   b;
00658 
00659     if ((idx + 3) > maxIdx)
00660         return BUFFER_E;
00661 
00662     b = input[idx++];
00663     if (b != ASN_BOOLEAN)
00664         return ASN_PARSE_E;
00665 
00666     if (input[idx++] != 1)
00667         return ASN_PARSE_E;
00668 
00669     b = input[idx++] != 0;
00670 
00671     *inOutIdx = idx;
00672     return b;
00673 }
00674 
00675 #ifdef ASN1_SET_BOOLEAN
00676 /* Set the DER/BER encoding of the ASN.1 NULL element.
00677  * Note: Function not required as yet.
00678  *
00679  * val     Boolean value to encode.
00680  * output  Buffer to write into.
00681  * returns the number of bytes added to the buffer.
00682  */
00683 static int SetBoolean(int val, byte* output)
00684 {
00685     output[0] = ASN_BOOLEAN;
00686     output[1] = 1;
00687     output[2] = val ? -1 : 0;
00688 
00689     return 3;
00690 }
00691 #endif
00692 
00693 /* Get the DER/BER encoding of an ASN.1 OCTET_STRING header.
00694  *
00695  * input     Buffer holding DER/BER encoded data.
00696  * inOutIdx  Current index into buffer to parse.
00697  * len       The number of bytes in the ASN.1 data.
00698  * maxIdx    Length of data in buffer.
00699  * returns BUFFER_E when there is not enough data to parse.
00700  *         ASN_PARSE_E when the OCTET_STRING tag is not found or length is
00701  *         invalid.
00702  *         Otherwise, the number of bytes in the ASN.1 data.
00703  */
00704 static int GetOctetString(const byte* input, word32* inOutIdx, int* len,
00705                           word32 maxIdx)
00706 {
00707     return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
00708 }
00709 
00710 /* Get the DER/BER encoding of an ASN.1 INTEGER header.
00711  * Removes the leading zero byte when found.
00712  *
00713  * input     Buffer holding DER/BER encoded data.
00714  * inOutIdx  Current index into buffer to parse.
00715  * len       The number of bytes in the ASN.1 data (excluding any leading zero).
00716  * maxIdx    Length of data in buffer.
00717  * returns BUFFER_E when there is not enough data to parse.
00718  *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
00719  *         or invalid use of or missing leading zero.
00720  *         Otherwise, 0 to indicate success.
00721  */
00722 static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
00723                      word32 maxIdx)
00724 {
00725     int    ret;
00726 
00727     ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
00728     if (ret < 0)
00729         return ret;
00730 
00731     if (*len > 0) {
00732         /* remove leading zero, unless there is only one 0x00 byte */
00733         if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
00734             (*inOutIdx)++;
00735             (*len)--;
00736 
00737             if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
00738                 return ASN_PARSE_E;
00739         }
00740         else if ((input[*inOutIdx] & 0x80) == 0x80)
00741             return ASN_PARSE_E;
00742     }
00743 
00744     return 0;
00745 }
00746 
00747 /* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
00748  * 7 bits.
00749  *
00750  * input     Buffer holding DER/BER encoded data.
00751  * inOutIdx  Current index into buffer to parse.
00752  * maxIdx    Length of data in buffer.
00753  * returns BUFFER_E when there is not enough data to parse.
00754  *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
00755  *         Otherwise, the 7-bit value.
00756  */
00757 static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
00758 {
00759     word32 idx = *inOutIdx;
00760     byte   b;
00761 
00762     if ((idx + 3) > maxIdx)
00763         return BUFFER_E;
00764 
00765     if (input[idx++] != ASN_INTEGER)
00766         return ASN_PARSE_E;
00767     if (input[idx++] != 1)
00768         return ASN_PARSE_E;
00769     b = input[idx++];
00770 
00771     *inOutIdx = idx;
00772     return b;
00773 }
00774 
00775 #if !defined(NO_DSA) || defined(HAVE_ECC) || (!defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA))))
00776 /* Set the DER/BER encoding of the ASN.1 INTEGER header.
00777  *
00778  * len        Length of data to encode.
00779  * firstByte  First byte of data, most significant byte of integer, to encode.
00780  * output     Buffer to write into.
00781  * returns the number of bytes added to the buffer.
00782  */
00783 static int SetASNInt(int len, byte firstByte, byte* output)
00784 {
00785     word32 idx = 0;
00786 
00787     output[idx++] = ASN_INTEGER;
00788     if (firstByte & 0x80)
00789         len++;
00790     idx += SetLength(len, output + idx);
00791     if (firstByte & 0x80)
00792         output[idx++] = 0x00;
00793 
00794     return idx;
00795 }
00796 #endif
00797 
00798 #if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
00799 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
00800  * The number is assumed to be positive.
00801  *
00802  * n       Multi-precision integer to encode.
00803  * maxSz   Maximum size of the encoded integer.
00804  *         A negative value indicates no check of length requested.
00805  * output  Buffer to write into.
00806  * returns BUFFER_E when the data is too long for the buffer.
00807  *         MP_TO_E when encoding the integer fails.
00808  *         Otherwise, the number of bytes added to the buffer.
00809  */
00810 static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
00811 {
00812     int idx = 0;
00813     int leadingBit;
00814     int length;
00815     int err;
00816 
00817     leadingBit = mp_leading_bit(n);
00818     length = mp_unsigned_bin_size(n);
00819     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
00820     if (maxSz >= 0 && (idx + length) > maxSz)
00821         return BUFFER_E;
00822 
00823     err = mp_to_unsigned_bin(n, output + idx);
00824     if (err != MP_OKAY)
00825         return MP_TO_E;
00826     idx += length;
00827 
00828     return idx;
00829 }
00830 #endif
00831 
00832 #if !defined(NO_RSA) && defined(HAVE_USER_RSA) && defined(WOLFSSL_CERT_GEN)
00833 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
00834  * an RSA key.
00835  * The number is assumed to be positive.
00836  *
00837  * n       Multi-precision integer to encode.
00838  * output  Buffer to write into.
00839  * returns BUFFER_E when the data is too long for the buffer.
00840  *         MP_TO_E when encoding the integer fails.
00841  *         Otherwise, the number of bytes added to the buffer.
00842  */
00843 static int SetASNIntRSA(mp_int* n, byte* output)
00844 {
00845     int idx = 0;
00846     int leadingBit;
00847     int length;
00848     int err;
00849 
00850     leadingBit = wc_Rsa_leading_bit(n);
00851     length = wc_Rsa_unsigned_bin_size(n);
00852     idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
00853     if ((idx + length) > MAX_RSA_INT_SZ)
00854         return BUFFER_E;
00855 
00856     err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
00857     if (err != MP_OKAY)
00858         return MP_TO_E;
00859     idx += length;
00860 
00861     return idx;
00862 }
00863 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
00864                                            !HAVE_USER_RSA))) */
00865 
00866 /* Windows header clash for WinCE using GetVersion */
00867 WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
00868                                int* version, word32 maxIdx)
00869 {
00870     word32 idx = *inOutIdx;
00871 
00872     if ((idx + MIN_VERSION_SZ) > maxIdx)
00873         return ASN_PARSE_E;
00874 
00875     if (input[idx++] != ASN_INTEGER)
00876         return ASN_PARSE_E;
00877 
00878     if (input[idx++] != 0x01)
00879         return ASN_VERSION_E;
00880 
00881     *version  = input[idx++];
00882     *inOutIdx = idx;
00883 
00884     return *version;
00885 }
00886 
00887 
00888 #ifndef NO_PWDBASED
00889 /* Get small count integer, 32 bits or less */
00890 int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
00891 {
00892     word32 idx = *inOutIdx;
00893     word32 len;
00894 
00895     *number = 0;
00896 
00897     /* check for type and length bytes */
00898     if ((idx + 2) > maxIdx)
00899         return BUFFER_E;
00900 
00901     if (input[idx++] != ASN_INTEGER)
00902         return ASN_PARSE_E;
00903 
00904     len = input[idx++];
00905     if (len > 4)
00906         return ASN_PARSE_E;
00907 
00908     if (len + idx > maxIdx)
00909         return ASN_PARSE_E;
00910 
00911     while (len--) {
00912         *number  = *number << 8 | input[idx++];
00913     }
00914 
00915     *inOutIdx = idx;
00916 
00917     return *number;
00918 }
00919 #endif /* !NO_PWDBASED */
00920 
00921 /* May not have one, not an error */
00922 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
00923                               word32 maxIdx)
00924 {
00925     word32 idx = *inOutIdx;
00926 
00927     WOLFSSL_ENTER("GetExplicitVersion");
00928 
00929     if ((idx + 1) > maxIdx)
00930         return BUFFER_E;
00931 
00932     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
00933         *inOutIdx = ++idx;  /* skip header */
00934         return GetMyVersion(input, inOutIdx, version, maxIdx);
00935     }
00936 
00937     /* go back as is */
00938     *version = 0;
00939 
00940     return 0;
00941 }
00942 
00943 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
00944 {
00945     word32 idx = *inOutIdx;
00946     int    ret;
00947     int    length;
00948 
00949     ret = GetASNInt(input, &idx, &length, maxIdx);
00950     if (ret != 0)
00951         return ret;
00952 
00953     if (mp_init(mpi) != MP_OKAY)
00954         return MP_INIT_E;
00955 
00956     if (mp_read_unsigned_bin(mpi, (byte*)input + idx, length) != 0) {
00957         mp_clear(mpi);
00958         return ASN_GETINT_E;
00959     }
00960 
00961 #ifdef HAVE_WOLF_BIGINT
00962     if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
00963         mp_clear(mpi);
00964         return ASN_GETINT_E;
00965     }
00966 #endif /* HAVE_WOLF_BIGINT */
00967 
00968     *inOutIdx = idx + length;
00969 
00970     return 0;
00971 }
00972 
00973 static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
00974                           word32 maxIdx, int zeroBits, byte* unusedBits)
00975 {
00976     word32 idx = *inOutIdx;
00977     int    length;
00978     byte   b;
00979 
00980     if ((idx + 1) > maxIdx)
00981         return BUFFER_E;
00982 
00983     if (input[idx++] != ASN_BIT_STRING)
00984         return ASN_BITSTR_E;
00985 
00986     if (GetLength(input, &idx, &length, maxIdx) < 0)
00987         return ASN_PARSE_E;
00988 
00989     /* extra sanity check that length is greater than 0 */
00990     if (length <= 0) {
00991         WOLFSSL_MSG("Error length was 0 in CheckBitString");
00992         return BUFFER_E;
00993     }
00994 
00995     if (idx + 1 > maxIdx) {
00996         WOLFSSL_MSG("Attempted buffer read larger than input buffer");
00997         return BUFFER_E;
00998     }
00999 
01000     b = input[idx];
01001     if (zeroBits && b != 0x00)
01002         return ASN_EXPECT_0_E;
01003     if (b >= 0x08)
01004         return ASN_PARSE_E;
01005     if (b != 0) {
01006         if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
01007             return ASN_PARSE_E;
01008     }
01009     idx++;
01010     length--; /* length has been checked for greater than 0 */
01011 
01012     *inOutIdx = idx;
01013     if (len != NULL)
01014         *len = length;
01015     if (unusedBits != NULL)
01016         *unusedBits = b;
01017 
01018     return 0;
01019 }
01020 
01021 #if (!defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
01022                           (defined(WOLFSSL_KEY_GEN) && \
01023                            !defined(HAVE_USER_RSA)))) || \
01024     (defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || \
01025                            defined(WOLFSSL_KEY_GEN)))
01026 /* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
01027  *
01028  * len         Length of data to encode.
01029  * unusedBits  The number of unused bits in the last byte of data.
01030  *             That is, the number of least significant zero bits before a one.
01031  *             The last byte is the most-significant non-zero byte of a number.
01032  * output      Buffer to write into.
01033  * returns the number of bytes added to the buffer.
01034  */
01035 static word32 SetBitString(word32 len, byte unusedBits, byte* output)
01036 {
01037     word32 idx = 0;
01038 
01039     output[idx++] = ASN_BIT_STRING;
01040     idx += SetLength(len + 1, output + idx);
01041     output[idx++] = unusedBits;
01042 
01043     return idx;
01044 }
01045 
01046 #ifdef WOLFSSL_CERT_EXT
01047 /* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
01048  *
01049  * val         16-bit value to encode.
01050  * output      Buffer to write into.
01051  * returns the number of bytes added to the buffer.
01052  */
01053 static word32 SetBitString16Bit(word16 val, byte* output)
01054 {
01055     word32 idx;
01056     int    len;
01057     byte   lastByte;
01058     byte   unusedBits = 0;
01059 
01060     if ((val >> 8) != 0) {
01061         len = 2;
01062         lastByte = (byte)(val >> 8);
01063     }
01064     else {
01065         len = 1;
01066         lastByte = (byte)val;
01067     }
01068 
01069     while (((lastByte >> unusedBits) & 0x01) == 0x00)
01070         unusedBits++;
01071 
01072     idx = SetBitString(len, unusedBits, output);
01073     output[idx++] = (byte)val;
01074     output[idx++] = (byte)(val >> 8);
01075 
01076     return idx;
01077 }
01078 #endif /* WOLFSSL_CERT_EXT */
01079 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
01080                                            !HAVE_USER_RSA)) */
01081 
01082 
01083 
01084 /* hashType */
01085 static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
01086 static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
01087 static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
01088 static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
01089 static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
01090 static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
01091 static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
01092 
01093 /* sigType */
01094 #ifndef NO_DSA
01095     static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
01096 #endif /* NO_DSA */
01097 #ifndef NO_RSA
01098     static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
01099     static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
01100     static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
01101     static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
01102     static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
01103     static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
01104     static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
01105 #endif /* NO_RSA */
01106 #ifdef HAVE_ECC
01107     static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
01108     static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
01109     static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
01110     static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
01111     static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
01112 #endif /* HAVE_ECC */
01113 
01114 /* keyType */
01115 #ifndef NO_DSA
01116     static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
01117 #endif /* NO_DSA */
01118 #ifndef NO_RSA
01119     static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
01120 #endif /* NO_RSA */
01121 #ifdef HAVE_NTRU
01122     static const byte keyNtruOid[] = {43, 6, 1, 4, 1, 193, 22, 1, 1, 1, 1};
01123 #endif /* HAVE_NTRU */
01124 #ifdef HAVE_ECC
01125     static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
01126 #endif /* HAVE_ECC */
01127 
01128 /* curveType */
01129 #ifdef HAVE_ECC
01130     /* See "ecc_sets" table in ecc.c */
01131 #endif /* HAVE_ECC */
01132 
01133 /* blkType */
01134 static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
01135 static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
01136 static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
01137 static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
01138 static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
01139 
01140 /* keyWrapType */
01141 static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
01142 static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
01143 static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
01144 
01145 /* cmsKeyAgreeType */
01146 static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
01147                                           {43, 129, 5, 16, 134, 72, 63, 0, 2};
01148 static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
01149 static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
01150 static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
01151 static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
01152 
01153 /* ocspType */
01154 #ifdef HAVE_OCSP
01155     static const byte ocspBasicOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 1};
01156     static const byte ocspNonceOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 2};
01157 #endif /* HAVE_OCSP */
01158 
01159 /* certExtType */
01160 static const byte extBasicCaOid[] = {85, 29, 19};
01161 static const byte extAltNamesOid[] = {85, 29, 17};
01162 static const byte extCrlDistOid[] = {85, 29, 31};
01163 static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
01164 static const byte extAuthKeyOid[] = {85, 29, 35};
01165 static const byte extSubjKeyOid[] = {85, 29, 14};
01166 static const byte extCertPolicyOid[] = {85, 29, 32};
01167 static const byte extKeyUsageOid[] = {85, 29, 15};
01168 static const byte extInhibitAnyOid[] = {85, 29, 54};
01169 static const byte extExtKeyUsageOid[] = {85, 29, 37};
01170 static const byte extNameConsOid[] = {85, 29, 30};
01171 
01172 /* certAuthInfoType */
01173 static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
01174 static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
01175 
01176 /* certPolicyType */
01177 static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
01178 
01179 /* certKeyUseType */
01180 static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
01181 
01182 /* certKeyUseType */
01183 static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
01184 static const byte extExtKeyUsageServerAuthOid[] = {43, 6, 1, 5, 5, 7, 3, 1};
01185 static const byte extExtKeyUsageClientAuthOid[] = {43, 6, 1, 5, 5, 7, 3, 2};
01186 static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9};
01187 
01188 /* kdfType */
01189 static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
01190 
01191 static const byte* OidFromId(word32 id, word32 type, word32* oidSz)
01192 {
01193     const byte* oid = NULL;
01194 
01195     *oidSz = 0;
01196 
01197     switch (type) {
01198 
01199         case oidHashType:
01200             switch (id) {
01201                 case MD2h:
01202                     oid = hashMd2hOid;
01203                     *oidSz = sizeof(hashMd2hOid);
01204                     break;
01205                 case MD5h:
01206                     oid = hashMd5hOid;
01207                     *oidSz = sizeof(hashMd5hOid);
01208                     break;
01209                 case SHAh:
01210                     oid = hashSha1hOid;
01211                     *oidSz = sizeof(hashSha1hOid);
01212                     break;
01213                 case SHA224h:
01214                     oid = hashSha224hOid;
01215                     *oidSz = sizeof(hashSha224hOid);
01216                     break;
01217                 case SHA256h:
01218                     oid = hashSha256hOid;
01219                     *oidSz = sizeof(hashSha256hOid);
01220                     break;
01221                 case SHA384h:
01222                     oid = hashSha384hOid;
01223                     *oidSz = sizeof(hashSha384hOid);
01224                     break;
01225                 case SHA512h:
01226                     oid = hashSha512hOid;
01227                     *oidSz = sizeof(hashSha512hOid);
01228                     break;
01229             }
01230             break;
01231 
01232         case oidSigType:
01233             switch (id) {
01234                 #ifndef NO_DSA
01235                 case CTC_SHAwDSA:
01236                     oid = sigSha1wDsaOid;
01237                     *oidSz = sizeof(sigSha1wDsaOid);
01238                     break;
01239                 #endif /* NO_DSA */
01240                 #ifndef NO_RSA
01241                 case CTC_MD2wRSA:
01242                     oid = sigMd2wRsaOid;
01243                     *oidSz = sizeof(sigMd2wRsaOid);
01244                     break;
01245                 case CTC_MD5wRSA:
01246                     oid = sigMd5wRsaOid;
01247                     *oidSz = sizeof(sigMd5wRsaOid);
01248                     break;
01249                 case CTC_SHAwRSA:
01250                     oid = sigSha1wRsaOid;
01251                     *oidSz = sizeof(sigSha1wRsaOid);
01252                     break;
01253                 case CTC_SHA224wRSA:
01254                     oid = sigSha224wRsaOid;
01255                     *oidSz = sizeof(sigSha224wRsaOid);
01256                     break;
01257                 case CTC_SHA256wRSA:
01258                     oid = sigSha256wRsaOid;
01259                     *oidSz = sizeof(sigSha256wRsaOid);
01260                     break;
01261                 case CTC_SHA384wRSA:
01262                     oid = sigSha384wRsaOid;
01263                     *oidSz = sizeof(sigSha384wRsaOid);
01264                     break;
01265                 case CTC_SHA512wRSA:
01266                     oid = sigSha512wRsaOid;
01267                     *oidSz = sizeof(sigSha512wRsaOid);
01268                     break;
01269                 #endif /* NO_RSA */
01270                 #ifdef HAVE_ECC
01271                 case CTC_SHAwECDSA:
01272                     oid = sigSha1wEcdsaOid;
01273                     *oidSz = sizeof(sigSha1wEcdsaOid);
01274                     break;
01275                 case CTC_SHA224wECDSA:
01276                     oid = sigSha224wEcdsaOid;
01277                     *oidSz = sizeof(sigSha224wEcdsaOid);
01278                     break;
01279                 case CTC_SHA256wECDSA:
01280                     oid = sigSha256wEcdsaOid;
01281                     *oidSz = sizeof(sigSha256wEcdsaOid);
01282                     break;
01283                 case CTC_SHA384wECDSA:
01284                     oid = sigSha384wEcdsaOid;
01285                     *oidSz = sizeof(sigSha384wEcdsaOid);
01286                     break;
01287                 case CTC_SHA512wECDSA:
01288                     oid = sigSha512wEcdsaOid;
01289                     *oidSz = sizeof(sigSha512wEcdsaOid);
01290                     break;
01291                 #endif /* HAVE_ECC */
01292                 default:
01293                     break;
01294             }
01295             break;
01296 
01297         case oidKeyType:
01298             switch (id) {
01299                 #ifndef NO_DSA
01300                 case DSAk:
01301                     oid = keyDsaOid;
01302                     *oidSz = sizeof(keyDsaOid);
01303                     break;
01304                 #endif /* NO_DSA */
01305                 #ifndef NO_RSA
01306                 case RSAk:
01307                     oid = keyRsaOid;
01308                     *oidSz = sizeof(keyRsaOid);
01309                     break;
01310                 #endif /* NO_RSA */
01311                 #ifdef HAVE_NTRU
01312                 case NTRUk:
01313                     oid = keyNtruOid;
01314                     *oidSz = sizeof(keyNtruOid);
01315                     break;
01316                 #endif /* HAVE_NTRU */
01317                 #ifdef HAVE_ECC
01318                 case ECDSAk:
01319                     oid = keyEcdsaOid;
01320                     *oidSz = sizeof(keyEcdsaOid);
01321                     break;
01322                 #endif /* HAVE_ECC */
01323                 default:
01324                     break;
01325             }
01326             break;
01327 
01328         #ifdef HAVE_ECC
01329         case oidCurveType:
01330             if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
01331                 WOLFSSL_MSG("ECC OID not found");
01332             }
01333             break;
01334         #endif /* HAVE_ECC */
01335 
01336         case oidBlkType:
01337             switch (id) {
01338                 case AES128CBCb:
01339                     oid = blkAes128CbcOid;
01340                     *oidSz = sizeof(blkAes128CbcOid);
01341                     break;
01342                 case AES192CBCb:
01343                     oid = blkAes192CbcOid;
01344                     *oidSz = sizeof(blkAes192CbcOid);
01345                     break;
01346                 case AES256CBCb:
01347                     oid = blkAes256CbcOid;
01348                     *oidSz = sizeof(blkAes256CbcOid);
01349                     break;
01350                 case DESb:
01351                     oid = blkDesCbcOid;
01352                     *oidSz = sizeof(blkDesCbcOid);
01353                     break;
01354                 case DES3b:
01355                     oid = blkDes3CbcOid;
01356                     *oidSz = sizeof(blkDes3CbcOid);
01357                     break;
01358             }
01359             break;
01360 
01361         #ifdef HAVE_OCSP
01362         case oidOcspType:
01363             switch (id) {
01364                 case OCSP_BASIC_OID:
01365                     oid = ocspBasicOid;
01366                     *oidSz = sizeof(ocspBasicOid);
01367                     break;
01368                 case OCSP_NONCE_OID:
01369                     oid = ocspNonceOid;
01370                     *oidSz = sizeof(ocspNonceOid);
01371                     break;
01372             }
01373             break;
01374         #endif /* HAVE_OCSP */
01375 
01376         case oidCertExtType:
01377             switch (id) {
01378                 case BASIC_CA_OID:
01379                     oid = extBasicCaOid;
01380                     *oidSz = sizeof(extBasicCaOid);
01381                     break;
01382                 case ALT_NAMES_OID:
01383                     oid = extAltNamesOid;
01384                     *oidSz = sizeof(extAltNamesOid);
01385                     break;
01386                 case CRL_DIST_OID:
01387                     oid = extCrlDistOid;
01388                     *oidSz = sizeof(extCrlDistOid);
01389                     break;
01390                 case AUTH_INFO_OID:
01391                     oid = extAuthInfoOid;
01392                     *oidSz = sizeof(extAuthInfoOid);
01393                     break;
01394                 case AUTH_KEY_OID:
01395                     oid = extAuthKeyOid;
01396                     *oidSz = sizeof(extAuthKeyOid);
01397                     break;
01398                 case SUBJ_KEY_OID:
01399                     oid = extSubjKeyOid;
01400                     *oidSz = sizeof(extSubjKeyOid);
01401                     break;
01402                 case CERT_POLICY_OID:
01403                     oid = extCertPolicyOid;
01404                     *oidSz = sizeof(extCertPolicyOid);
01405                     break;
01406                 case KEY_USAGE_OID:
01407                     oid = extKeyUsageOid;
01408                     *oidSz = sizeof(extKeyUsageOid);
01409                     break;
01410                 case INHIBIT_ANY_OID:
01411                     oid = extInhibitAnyOid;
01412                     *oidSz = sizeof(extInhibitAnyOid);
01413                     break;
01414                 case EXT_KEY_USAGE_OID:
01415                     oid = extExtKeyUsageOid;
01416                     *oidSz = sizeof(extExtKeyUsageOid);
01417                     break;
01418                 case NAME_CONS_OID:
01419                     oid = extNameConsOid;
01420                     *oidSz = sizeof(extNameConsOid);
01421                     break;
01422             }
01423             break;
01424 
01425         case oidCertAuthInfoType:
01426             switch (id) {
01427                 case AIA_OCSP_OID:
01428                     oid = extAuthInfoOcspOid;
01429                     *oidSz = sizeof(extAuthInfoOcspOid);
01430                     break;
01431                 case AIA_CA_ISSUER_OID:
01432                     oid = extAuthInfoCaIssuerOid;
01433                     *oidSz = sizeof(extAuthInfoCaIssuerOid);
01434                     break;
01435             }
01436             break;
01437 
01438         case oidCertPolicyType:
01439             switch (id) {
01440                 case CP_ANY_OID:
01441                     oid = extCertPolicyAnyOid;
01442                     *oidSz = sizeof(extCertPolicyAnyOid);
01443                     break;
01444             }
01445             break;
01446 
01447         case oidCertAltNameType:
01448             switch (id) {
01449                 case HW_NAME_OID:
01450                     oid = extAltNamesHwNameOid;
01451                     *oidSz = sizeof(extAltNamesHwNameOid);
01452                     break;
01453             }
01454             break;
01455 
01456         case oidCertKeyUseType:
01457             switch (id) {
01458                 case EKU_ANY_OID:
01459                     oid = extExtKeyUsageAnyOid;
01460                     *oidSz = sizeof(extExtKeyUsageAnyOid);
01461                     break;
01462                 case EKU_SERVER_AUTH_OID:
01463                     oid = extExtKeyUsageServerAuthOid;
01464                     *oidSz = sizeof(extExtKeyUsageServerAuthOid);
01465                     break;
01466                 case EKU_CLIENT_AUTH_OID:
01467                     oid = extExtKeyUsageClientAuthOid;
01468                     *oidSz = sizeof(extExtKeyUsageClientAuthOid);
01469                     break;
01470                 case EKU_OCSP_SIGN_OID:
01471                     oid = extExtKeyUsageOcspSignOid;
01472                     *oidSz = sizeof(extExtKeyUsageOcspSignOid);
01473                     break;
01474             }
01475             break;
01476 
01477         case oidKdfType:
01478             switch (id) {
01479                 case PBKDF2_OID:
01480                     oid = pbkdf2Oid;
01481                     *oidSz = sizeof(pbkdf2Oid);
01482                     break;
01483             }
01484             break;
01485 
01486         case oidKeyWrapType:
01487             switch (id) {
01488                 case AES128_WRAP:
01489                     oid = wrapAes128Oid;
01490                     *oidSz = sizeof(wrapAes128Oid);
01491                     break;
01492                 case AES192_WRAP:
01493                     oid = wrapAes192Oid;
01494                     *oidSz = sizeof(wrapAes192Oid);
01495                     break;
01496                 case AES256_WRAP:
01497                     oid = wrapAes256Oid;
01498                     *oidSz = sizeof(wrapAes256Oid);
01499                     break;
01500             }
01501             break;
01502 
01503         case oidCmsKeyAgreeType:
01504             switch (id) {
01505                 case dhSinglePass_stdDH_sha1kdf_scheme:
01506                     oid = dhSinglePass_stdDH_sha1kdf_Oid;
01507                     *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
01508                     break;
01509                 case dhSinglePass_stdDH_sha224kdf_scheme:
01510                     oid = dhSinglePass_stdDH_sha224kdf_Oid;
01511                     *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
01512                     break;
01513                 case dhSinglePass_stdDH_sha256kdf_scheme:
01514                     oid = dhSinglePass_stdDH_sha256kdf_Oid;
01515                     *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
01516                     break;
01517                 case dhSinglePass_stdDH_sha384kdf_scheme:
01518                     oid = dhSinglePass_stdDH_sha384kdf_Oid;
01519                     *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
01520                     break;
01521                 case dhSinglePass_stdDH_sha512kdf_scheme:
01522                     oid = dhSinglePass_stdDH_sha512kdf_Oid;
01523                     *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
01524                     break;
01525             }
01526             break;
01527 
01528         case oidIgnoreType:
01529         default:
01530             break;
01531     }
01532 
01533     return oid;
01534 }
01535 
01536 #ifdef HAVE_OID_ENCODING
01537 int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
01538 {
01539     int i, x, len;
01540     word32 d, t;
01541 
01542     /* check args */
01543     if (in == NULL || outSz == NULL) {
01544         return BAD_FUNC_ARG;
01545     }
01546 
01547     /* compute length of encoded OID */
01548     d = (in[0] * 40) + in[1];
01549     len = 0;
01550     for (i = 1; i < (int)inSz; i++) {
01551         x = 0;
01552         t = d;
01553         while (t) {
01554             x++;
01555             t >>= 1;
01556         }
01557         len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
01558 
01559         if (i < (int)inSz - 1) {
01560             d = in[i + 1];
01561         }
01562     }
01563 
01564     if (out) {
01565         /* verify length */
01566         if ((int)*outSz < len) {
01567             return BUFFER_E; /* buffer provided is not large enough */
01568         }
01569 
01570         /* calc first byte */
01571         d = (in[0] * 40) + in[1];
01572 
01573         /* encode bytes */
01574         x = 0;
01575         for (i = 1; i < (int)inSz; i++) {
01576             if (d) {
01577                 int y = x, z;
01578                 byte mask = 0;
01579                 while (d) {
01580                     out[x++] = (byte)((d & 0x7F) | mask);
01581                     d     >>= 7;
01582                     mask  |= 0x80;  /* upper bit is set on all but the last byte */
01583                 }
01584                 /* now swap bytes y...x-1 */
01585                 z = x - 1;
01586                 while (y < z) {
01587                     mask = out[y];
01588                     out[y] = out[z];
01589                     out[z] = mask;
01590                     ++y;
01591                     --z;
01592                 }
01593             }
01594             else {
01595               out[x++] = 0x00; /* zero value */
01596             }
01597 
01598             /* next word */
01599             if (i < (int)inSz - 1) {
01600                 d = in[i + 1];
01601             }
01602         }
01603     }
01604 
01605     /* return length */
01606     *outSz = len;
01607 
01608     return 0;
01609 }
01610 #endif /* HAVE_OID_ENCODING */
01611 
01612 #ifdef HAVE_OID_DECODING
01613 int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
01614 {
01615     int x = 0, y = 0;
01616     word32 t = 0;
01617 
01618     /* check args */
01619     if (in == NULL || outSz == NULL) {
01620         return BAD_FUNC_ARG;
01621     }
01622 
01623     /* decode bytes */
01624     while (inSz--) {
01625         t = (t << 7) | (in[x] & 0x7F);
01626         if (!(in[x] & 0x80)) {
01627             if (y >= (int)*outSz) {
01628                 return BUFFER_E;
01629             }
01630             if (y == 0) {
01631                 out[0] = (t / 40);
01632                 out[1] = (t % 40);
01633                 y = 2;
01634             }
01635             else {
01636                 out[y++] = t;
01637             }
01638             t = 0; /* reset tmp */
01639         }
01640         x++;
01641     }
01642 
01643     /* return length */
01644     *outSz = y;
01645 
01646     return 0;
01647 }
01648 #endif /* HAVE_OID_DECODING */
01649 
01650 /* Get the DER/BER encoding of an ASN.1 OBJECT_ID header.
01651  *
01652  * input     Buffer holding DER/BER encoded data.
01653  * inOutIdx  Current index into buffer to parse.
01654  * len       The number of bytes in the ASN.1 data.
01655  * maxIdx    Length of data in buffer.
01656  * returns BUFFER_E when there is not enough data to parse.
01657  *         ASN_OBJECt_ID_E when the OBJECT_ID tag is not found.
01658  *         ASN_PARSE_E when length is invalid.
01659  *         Otherwise, 0 to indicate success.
01660  */
01661 static int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
01662                           word32 maxIdx)
01663 {
01664     word32 idx = *inOutIdx;
01665     byte   b;
01666     int    length;
01667 
01668     if ((idx + 1) > maxIdx)
01669         return BUFFER_E;
01670 
01671     b = input[idx++];
01672     if (b != ASN_OBJECT_ID)
01673         return ASN_OBJECT_ID_E;
01674 
01675     if (GetLength(input, &idx, &length, maxIdx) < 0)
01676         return ASN_PARSE_E;
01677 
01678     *len = length;
01679     *inOutIdx = idx;
01680     return 0;
01681 }
01682 
01683 /* Set the DER/BER encoding of the ASN.1 OBJECT_ID header.
01684  *
01685  * len         Length of the OBJECT_ID data.
01686  * output      Buffer to write into.
01687  * returns the number of bytes added to the buffer.
01688  */
01689 static int SetObjectId(int len, byte* output)
01690 {
01691     int idx = 0;
01692 
01693     output[idx++] = ASN_OBJECT_ID;
01694     idx += SetLength(len, output + idx);
01695 
01696     return idx;
01697 }
01698 
01699 int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
01700                                   word32 oidType, word32 maxIdx)
01701 {
01702     int    ret = 0, length;
01703     word32 idx = *inOutIdx;
01704 #ifndef NO_VERIFY_OID
01705     word32 actualOidSz = 0;
01706     const byte* actualOid;
01707 #endif /* NO_VERIFY_OID */
01708 
01709     (void)oidType;
01710     WOLFSSL_ENTER("GetObjectId()");
01711     *oid = 0;
01712 
01713     ret = GetASNObjectId(input, &idx, &length, maxIdx);
01714     if (ret != 0)
01715         return ret;
01716 
01717 #ifndef NO_VERIFY_OID
01718     actualOid = &input[idx];
01719     if (length > 0)
01720         actualOidSz = (word32)length;
01721 #endif /* NO_VERIFY_OID */
01722 
01723     while (length--) {
01724         /* odd HC08 compiler behavior here when input[idx++] */
01725         *oid += (word32)input[idx];
01726         idx++;
01727     }
01728     /* just sum it up for now */
01729 
01730     *inOutIdx = idx;
01731 
01732 #ifndef NO_VERIFY_OID
01733     {
01734         const byte* checkOid = NULL;
01735         word32 checkOidSz;
01736     #ifdef ASN_DUMP_OID
01737         int i;
01738     #endif
01739 
01740         if (oidType != oidIgnoreType) {
01741             checkOid = OidFromId(*oid, oidType, &checkOidSz);
01742 
01743         #ifdef ASN_DUMP_OID
01744             /* support for dumping OID information */
01745             printf("OID (Type %d, Sz %d, Sum %d): ", oidType, actualOidSz, *oid);
01746             for (i=0; i<actualOidSz; i++) {
01747                 printf("%d, ", actualOid[i]);
01748             }
01749             printf("\n");
01750             #ifdef HAVE_OID_DECODING
01751             {
01752                 word16 decOid[16];
01753                 word32 decOidSz = sizeof(decOid);
01754                 ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);
01755                 if (ret == 0) {
01756                     printf("  Decoded (Sz %d): ", decOidSz);
01757                     for (i=0; i<decOidSz; i++) {
01758                         printf("%d.", decOid[i]);
01759                     }
01760                     printf("\n");
01761                 }
01762                 else {
01763                     printf("DecodeObjectId failed: %d\n", ret);
01764                 }
01765             }
01766             #endif /* HAVE_OID_DECODING */
01767         #endif /* ASN_DUMP_OID */
01768 
01769             if (checkOid != NULL &&
01770                 (checkOidSz != actualOidSz ||
01771                     XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) {
01772                 WOLFSSL_MSG("OID Check Failed");
01773                 return ASN_UNKNOWN_OID_E;
01774             }
01775         }
01776     }
01777 #endif /* NO_VERIFY_OID */
01778 
01779     return ret;
01780 }
01781 
01782 
01783 #if defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && (defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)))
01784 static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
01785 {
01786     word32 idx = *inOutIdx;
01787     int    length;
01788     int ret;
01789 
01790     ret = GetASNObjectId(input, &idx, &length, maxIdx);
01791     if (ret != 0)
01792         return ret;
01793 
01794     idx += length;
01795     *inOutIdx = idx;
01796 
01797     return 0;
01798 }
01799 #endif
01800 
01801 WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
01802                      word32 oidType, word32 maxIdx)
01803 {
01804     int    length;
01805     word32 idx = *inOutIdx;
01806     int    ret;
01807     *oid = 0;
01808 
01809     WOLFSSL_ENTER("GetAlgoId");
01810 
01811     if (GetSequence(input, &idx, &length, maxIdx) < 0)
01812         return ASN_PARSE_E;
01813 
01814     if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
01815         return ASN_OBJECT_ID_E;
01816 
01817     /* could have NULL tag and 0 terminator, but may not */
01818     if (input[idx] == ASN_TAG_NULL) {
01819         ret = GetASNNull(input, &idx, maxIdx);
01820         if (ret != 0)
01821             return ret;
01822     }
01823 
01824     *inOutIdx = idx;
01825 
01826     return 0;
01827 }
01828 
01829 #ifndef NO_RSA
01830 
01831 #ifndef HAVE_USER_RSA
01832 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
01833                         word32 inSz)
01834 {
01835     int version, length;
01836 
01837     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01838         return ASN_PARSE_E;
01839 
01840     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
01841         return ASN_PARSE_E;
01842 
01843     key->type = RSA_PRIVATE;
01844 
01845     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
01846         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
01847         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
01848         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
01849         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
01850         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
01851         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
01852         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
01853 
01854     return 0;
01855 }
01856 #endif /* HAVE_USER_RSA */
01857 #endif /* NO_RSA */
01858 
01859 /* Remove PKCS8 header, place inOutIdx at beginning of traditional,
01860  * return traditional length on success, negative on error */
01861 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
01862 {
01863     word32 idx, oid;
01864     int    version, length;
01865     int    ret;
01866 
01867     if (input == NULL || inOutIdx == NULL)
01868         return BAD_FUNC_ARG;
01869 
01870     idx = *inOutIdx;
01871 
01872     if (GetSequence(input, &idx, &length, sz) < 0)
01873         return ASN_PARSE_E;
01874 
01875     if (GetMyVersion(input, &idx, &version, sz) < 0)
01876         return ASN_PARSE_E;
01877 
01878     if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
01879         return ASN_PARSE_E;
01880 
01881     if (input[idx] == ASN_OBJECT_ID) {
01882         if (SkipObjectId(input, &idx, sz) < 0)
01883             return ASN_PARSE_E;
01884     }
01885 
01886     ret = GetOctetString(input, &idx, &length, sz);
01887     if (ret < 0)
01888         return ret;
01889 
01890     *inOutIdx = idx;
01891 
01892     return length;
01893 }
01894 
01895 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
01896 int ToTraditional(byte* input, word32 sz)
01897 {
01898     word32 inOutIdx = 0;
01899     int    length;
01900 
01901     if (input == NULL)
01902         return BAD_FUNC_ARG;
01903 
01904     length = ToTraditionalInline(input, &inOutIdx, sz);
01905     if (length < 0)
01906         return length;
01907 
01908     XMEMMOVE(input, input + inOutIdx, length);
01909 
01910     return length;
01911 }
01912 
01913 
01914 /* find beginning of traditional key inside PKCS#8 unencrypted buffer
01915  * return traditional length on success, with inOutIdx at beginning of
01916  * traditional
01917  * return negative on failure/error */
01918 int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
01919 {
01920     int length;
01921 
01922     if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
01923         return BAD_FUNC_ARG;
01924 
01925     length = ToTraditionalInline(input, inOutIdx, sz);
01926 
01927     return length;
01928 }
01929 
01930 
01931 /* PKCS#8 from RFC 5208
01932  * This function takes in a DER key and converts it to PKCS#8 format. Used
01933  * in creating PKCS#12 shrouded key bags.
01934  * Reverse of ToTraditional
01935  *
01936  * PrivateKeyInfo ::= SEQUENCE {
01937  *  version Version,
01938  *  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
01939  *  privateKey          PrivateKey,
01940  *  attributes          optional
01941  *  }
01942  *  Version ::= INTEGER
01943  *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
01944  *  PrivateKey ::= OCTET STRING
01945  *
01946  * out      buffer to place result in
01947  * outSz    size of out buffer
01948  * key      buffer with DER key
01949  * keySz    size of key buffer
01950  * algoID   algorithm ID i.e. RSAk
01951  * curveOID ECC curve oid if used. Should be NULL for RSA keys.
01952  * oidSz    size of curve oid. Is set to 0 if curveOID is NULL.
01953  *
01954  * Returns the size of PKCS#8 placed into out. In error cases returns negative
01955  * values.
01956  */
01957 int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
01958         int algoID, const byte* curveOID, word32 oidSz)
01959 {
01960         word32 keyIdx = 0;
01961         word32 tmpSz  = 0;
01962         word32 sz;
01963 
01964 
01965         /* If out is NULL then return the max size needed
01966          * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
01967         if (out == NULL && outSz != NULL) {
01968             *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
01969                      + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
01970 
01971             if (curveOID != NULL)
01972                 *outSz += oidSz + MAX_LENGTH_SZ + 1;
01973 
01974             WOLFSSL_MSG("Checking size of PKCS8");
01975 
01976             return LENGTH_ONLY_E;
01977         }
01978 
01979         WOLFSSL_ENTER("wc_CreatePKCS8Key()");
01980 
01981         if (key == NULL || out == NULL || outSz == NULL) {
01982             return BAD_FUNC_ARG;
01983         }
01984 
01985         /* check the buffer has enough room for largest possible size */
01986         if (curveOID != NULL) {
01987             if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
01988                    + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
01989                 return BUFFER_E;
01990         }
01991         else {
01992             oidSz = 0; /* with no curveOID oid size must be 0 */
01993             if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
01994                       + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
01995                 return BUFFER_E;
01996         }
01997 
01998         /* PrivateKeyInfo ::= SEQUENCE */
01999         keyIdx += MAX_SEQ_SZ; /* save room for sequence */
02000 
02001         /*  version Version
02002          *  no header information just INTEGER */
02003         sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
02004         tmpSz += sz; keyIdx += sz;
02005 
02006         /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
02007         sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
02008         if (curveOID != NULL && oidSz > 0) {
02009             byte buf[MAX_LENGTH_SZ];
02010             sz = SetLength(oidSz, buf);
02011             sz += 1; /* plus one for ASN object id */
02012         }
02013         sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
02014         tmpSz += sz; keyIdx += sz;
02015 
02016         /*  privateKey          PrivateKey *
02017          * pkcs8 ecc uses slightly different format. Places curve oid in
02018          * buffer */
02019         if (curveOID != NULL && oidSz > 0) {
02020             sz = SetObjectId(oidSz, out + keyIdx);
02021             keyIdx += sz; tmpSz += sz;
02022             XMEMCPY(out + keyIdx, curveOID, oidSz);
02023             keyIdx += oidSz; tmpSz += oidSz;
02024         }
02025 
02026         sz = SetOctetString(keySz, out + keyIdx);
02027         keyIdx += sz; tmpSz += sz;
02028         XMEMCPY(out + keyIdx, key, keySz);
02029         tmpSz += keySz;
02030 
02031         /*  attributes          optional
02032          * No attributes currently added */
02033 
02034         /* rewind and add sequence */
02035         sz = SetSequence(tmpSz, out);
02036         XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
02037 
02038         return tmpSz + sz;
02039 }
02040 
02041 
02042 /* check that the private key is a pair for the public key in certificate
02043  * return 1 (true) on match
02044  * return 0 or negative value on failure/error
02045  *
02046  * key   : buffer holding DER fromat key
02047  * keySz : size of key buffer
02048  * der   : a initialized and parsed DecodedCert holding a certificate */
02049 int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
02050 {
02051     if (key == NULL || der == NULL) {
02052         return BAD_FUNC_ARG;
02053     }
02054 
02055     #if !defined(NO_RSA)
02056     {
02057         RsaKey a, b;
02058         word32 keyIdx = 0;
02059         int    ret    = 0;
02060 
02061         /* test if RSA key */
02062         if (der->keyOID == RSAk) {
02063             if (wc_InitRsaKey(&a, NULL) == 0 &&
02064                 wc_RsaPrivateKeyDecode(key, &keyIdx, &a, keySz) == 0) {
02065                 WOLFSSL_MSG("Checking RSA key pair");
02066                 keyIdx = 0; /* reset to 0 for parsing public key */
02067 
02068                 if (wc_InitRsaKey(&b, NULL) == 0) {
02069                     if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx,
02070                                                    &b, der->pubKeySize)) == 0) {
02071                         /* limit for user RSA crypto because of RsaKey
02072                          * dereference. */
02073                         #if defined(HAVE_USER_RSA)
02074                             WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
02075                             wc_FreeRsaKey(&b);
02076                             wc_FreeRsaKey(&a);
02077                             return 1; /* return first RSA cert as match */
02078                         #else
02079                         /* both keys extracted successfully now check n and e
02080                          * values are the same. This is dereferencing RsaKey */
02081                         if (mp_cmp(&(a.n), &(b.n)) != MP_EQ ||
02082                             mp_cmp(&(a.e), &(b.e)) != MP_EQ) {
02083                             ret = MP_CMP_E;
02084                         }
02085                         else {
02086                             /* match found, free keys and return success */
02087                             wc_FreeRsaKey(&b);
02088                             wc_FreeRsaKey(&a);
02089                             return 1;
02090                         }
02091                         #endif
02092                     }
02093                     wc_FreeRsaKey(&b);
02094                 }
02095             }
02096             wc_FreeRsaKey(&a);
02097         }
02098 
02099         /* if ret is not 0 then there was a failed comparision attempt */
02100         if (ret != 0) {
02101             return ret;
02102         }
02103     }
02104     #endif /* NO_RSA */
02105 
02106     #ifdef HAVE_ECC
02107     {
02108         int ret = 0;
02109         word32  keyIdx = 0;
02110         ecc_key key_pair;
02111 
02112         if (der->keyOID == ECDSAk) {
02113             if ((ret = wc_ecc_init(&key_pair)) == 0 &&
02114                 wc_EccPrivateKeyDecode(key, &keyIdx, &key_pair, keySz) == 0) {
02115                 WOLFSSL_MSG("Checking ECC key pair");
02116                 keyIdx = 0;
02117                 if ((ret = wc_ecc_import_x963(der->publicKey, der->pubKeySize,
02118                                                              &key_pair)) == 0) {
02119                     /* public and private extracted successfuly no check if is
02120                      * a pair and also do sanity checks on key. wc_ecc_check_key
02121                      * checks that private * base generator equals pubkey */
02122                     if ((ret = wc_ecc_check_key(&key_pair)) == 0) {
02123                         /* found a match */
02124                         wc_ecc_free(&key_pair);
02125                         return 1;
02126                     }
02127 
02128                 }
02129             }
02130             wc_ecc_free(&key_pair);
02131         }
02132 
02133         /* error on attempt to match */
02134         if (ret != 0) {
02135             return ret;
02136         }
02137     }
02138     #endif /* HAVE_ECC */
02139 
02140     /* no match found */
02141     return 0;
02142 }
02143 
02144 #ifndef NO_PWDBASED
02145 
02146 /* Check To see if PKCS version algo is supported, set id if it is return 0
02147    < 0 on error */
02148 static int CheckAlgo(int first, int second, int* id, int* version)
02149 {
02150     *id      = ALGO_ID_E;
02151     *version = PKCS5;   /* default */
02152 
02153     if (first == 1) {
02154         switch (second) {
02155         case 1:
02156             *id = PBE_SHA1_RC4_128;
02157             *version = PKCS12v1;
02158             return 0;
02159         case 3:
02160             *id = PBE_SHA1_DES3;
02161             *version = PKCS12v1;
02162             return 0;
02163         default:
02164             return ALGO_ID_E;
02165         }
02166     }
02167 
02168     if (first != PKCS5)
02169         return ASN_INPUT_E;  /* VERSION ERROR */
02170 
02171     if (second == PBES2) {
02172         *version = PKCS5v2;
02173         return 0;
02174     }
02175 
02176     switch (second) {
02177     case 3:                   /* see RFC 2898 for ids */
02178         *id = PBE_MD5_DES;
02179         return 0;
02180     case 10:
02181         *id = PBE_SHA1_DES;
02182         return 0;
02183     default:
02184         return ALGO_ID_E;
02185 
02186     }
02187 }
02188 
02189 
02190 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
02191    < 0 on error */
02192 static int CheckAlgoV2(int oid, int* id)
02193 {
02194     switch (oid) {
02195     case 69:
02196         *id = PBE_SHA1_DES;
02197         return 0;
02198     case 652:
02199         *id = PBE_SHA1_DES3;
02200         return 0;
02201     default:
02202         return ALGO_ID_E;
02203 
02204     }
02205 }
02206 
02207 
02208 /* Decrypt input in place from parameters based on id */
02209 static int DecryptKey(const char* password, int passwordSz, byte* salt,
02210                       int saltSz, int iterations, int id, byte* input,
02211                       int length, int version, byte* cbcIv)
02212 {
02213     int typeH;
02214     int derivedLen;
02215     int decryptionType;
02216     int ret = 0;
02217 #ifdef WOLFSSL_SMALL_STACK
02218     byte* key;
02219 #else
02220     byte key[MAX_KEY_SIZE];
02221 #endif
02222 
02223     (void)input;
02224     (void)length;
02225 
02226     switch (id) {
02227         case PBE_MD5_DES:
02228             typeH = MD5;
02229             derivedLen = 16;           /* may need iv for v1.5 */
02230             decryptionType = DES_TYPE;
02231             break;
02232 
02233         case PBE_SHA1_DES:
02234             typeH = SHA;
02235             derivedLen = 16;           /* may need iv for v1.5 */
02236             decryptionType = DES_TYPE;
02237             break;
02238 
02239         case PBE_SHA1_DES3:
02240             typeH = SHA;
02241             derivedLen = 32;           /* may need iv for v1.5 */
02242             decryptionType = DES3_TYPE;
02243             break;
02244 
02245         case PBE_SHA1_RC4_128:
02246             typeH = SHA;
02247             derivedLen = 16;
02248             decryptionType = RC4_TYPE;
02249             break;
02250 
02251         default:
02252             return ALGO_ID_E;
02253     }
02254 
02255 #ifdef WOLFSSL_SMALL_STACK
02256     key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02257     if (key == NULL)
02258         return MEMORY_E;
02259 #endif
02260 
02261     if (version == PKCS5v2)
02262         ret = wc_PBKDF2(key, (byte*)password, passwordSz,
02263                         salt, saltSz, iterations, derivedLen, typeH);
02264 #ifndef NO_SHA
02265     else if (version == PKCS5)
02266         ret = wc_PBKDF1(key, (byte*)password, passwordSz,
02267                         salt, saltSz, iterations, derivedLen, typeH);
02268 #endif
02269     else if (version == PKCS12v1) {
02270         int  i, idx = 0;
02271         byte unicodePasswd[MAX_UNICODE_SZ];
02272 
02273         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
02274 #ifdef WOLFSSL_SMALL_STACK
02275             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02276 #endif
02277             return UNICODE_SIZE_E;
02278         }
02279 
02280         for (i = 0; i < passwordSz; i++) {
02281             unicodePasswd[idx++] = 0x00;
02282             unicodePasswd[idx++] = (byte)password[i];
02283         }
02284         /* add trailing NULL */
02285         unicodePasswd[idx++] = 0x00;
02286         unicodePasswd[idx++] = 0x00;
02287 
02288         ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
02289                             iterations, derivedLen, typeH, 1);
02290         if (decryptionType != RC4_TYPE)
02291             ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
02292                                 iterations, 8, typeH, 2);
02293     }
02294     else {
02295 #ifdef WOLFSSL_SMALL_STACK
02296         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02297 #endif
02298         return ALGO_ID_E;
02299     }
02300 
02301     if (ret != 0) {
02302 #ifdef WOLFSSL_SMALL_STACK
02303         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02304 #endif
02305         return ret;
02306     }
02307 
02308     switch (decryptionType) {
02309 #ifndef NO_DES3
02310         case DES_TYPE:
02311         {
02312             Des    dec;
02313             byte*  desIv = key + 8;
02314 
02315             if (version == PKCS5v2 || version == PKCS12v1)
02316                 desIv = cbcIv;
02317 
02318             ret = wc_Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
02319             if (ret != 0) {
02320 #ifdef WOLFSSL_SMALL_STACK
02321                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02322 #endif
02323                 return ret;
02324             }
02325 
02326             wc_Des_CbcDecrypt(&dec, input, input, length);
02327             break;
02328         }
02329 
02330         case DES3_TYPE:
02331         {
02332             Des3   dec;
02333             byte*  desIv = key + 24;
02334 
02335             if (version == PKCS5v2 || version == PKCS12v1)
02336                 desIv = cbcIv;
02337             ret = wc_Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
02338             if (ret != 0) {
02339 #ifdef WOLFSSL_SMALL_STACK
02340                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02341 #endif
02342                 return ret;
02343             }
02344             ret = wc_Des3_CbcDecrypt(&dec, input, input, length);
02345             if (ret != 0) {
02346 #ifdef WOLFSSL_SMALL_STACK
02347                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02348 #endif
02349                 return ret;
02350             }
02351             break;
02352         }
02353 #endif
02354 #ifndef NO_RC4
02355         case RC4_TYPE:
02356         {
02357             Arc4    dec;
02358 
02359             wc_Arc4SetKey(&dec, key, derivedLen);
02360             wc_Arc4Process(&dec, input, input, length);
02361             break;
02362         }
02363 #endif
02364 
02365         default:
02366 #ifdef WOLFSSL_SMALL_STACK
02367             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02368 #endif
02369             return ALGO_ID_E;
02370     }
02371 
02372 #ifdef WOLFSSL_SMALL_STACK
02373     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02374 #endif
02375 
02376     return 0;
02377 }
02378 
02379 
02380 int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
02381         int* algoID, void* heap)
02382 {
02383     word32 tmpIdx = 0;
02384 #ifdef HAVE_ECC
02385     ecc_key ecc;
02386 #endif
02387 #ifndef NO_RSA
02388     RsaKey rsa;
02389 #endif
02390 
02391     if (algoID == NULL) {
02392         return BAD_FUNC_ARG;
02393     }
02394     *algoID = 0;
02395 
02396 #ifndef NO_RSA
02397     if (wc_InitRsaKey(&rsa, heap) == 0) {
02398         if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
02399             *algoID = RSAk;
02400         }
02401         else {
02402             WOLFSSL_MSG("Not RSA DER key");
02403         }
02404         wc_FreeRsaKey(&rsa);
02405     }
02406     else {
02407         WOLFSSL_MSG("GetKeyOID wc_InitRsaKey failed");
02408     }
02409 #endif /* NO_RSA */
02410 #ifdef HAVE_ECC
02411     if (*algoID != RSAk) {
02412         tmpIdx = 0;
02413         if (wc_ecc_init_ex(&ecc, heap, INVALID_DEVID) == 0) {
02414             if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
02415                 *algoID = ECDSAk;
02416 
02417                 /* sanity check on arguments */
02418                 if (curveOID == NULL || oidSz == NULL) {
02419                     WOLFSSL_MSG("Error getting ECC curve OID");
02420                     wc_ecc_free(&ecc);
02421                     return BAD_FUNC_ARG;
02422                 }
02423 
02424                 /* now find oid */
02425                 if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
02426                     WOLFSSL_MSG("Error getting ECC curve OID");
02427                     wc_ecc_free(&ecc);
02428                     return BAD_FUNC_ARG;
02429                 }
02430             }
02431             else {
02432                 WOLFSSL_MSG("Not ECC DER key either");
02433             }
02434             wc_ecc_free(&ecc);
02435         }
02436         else {
02437             WOLFSSL_MSG("GetKeyOID wc_ecc_init_ex failed");
02438         }
02439     }
02440 #endif /* HAVE_ECC */
02441 
02442     /* if flag is not set then is neither RSA or ECC key that could be
02443      * found */
02444     if (*algoID == 0) {
02445         WOLFSSL_MSG("Bad key DER or compile options");
02446         return BAD_FUNC_ARG;
02447     }
02448 
02449     (void)curveOID;
02450     (void)oidSz;
02451 
02452     return 1;
02453 }
02454 
02455 
02456 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
02457    of input */
02458 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
02459 {
02460     word32 inOutIdx = 0, oid;
02461     int    ret = 0, first, second, length = 0, version, saltSz, id;
02462     int    iterations = 0;
02463 #ifdef WOLFSSL_SMALL_STACK
02464     byte*  salt = NULL;
02465     byte*  cbcIv = NULL;
02466 #else
02467     byte   salt[MAX_SALT_SIZE];
02468     byte   cbcIv[MAX_IV_SIZE];
02469 #endif
02470 
02471     if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
02472         ERROR_OUT(ASN_PARSE_E, exit_tte);
02473     }
02474 
02475     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
02476         ERROR_OUT(ASN_PARSE_E, exit_tte);
02477     }
02478 
02479     first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
02480     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
02481 
02482     if (CheckAlgo(first, second, &id, &version) < 0) {
02483         ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */
02484     }
02485 
02486     if (version == PKCS5v2) {
02487         if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
02488             ERROR_OUT(ASN_PARSE_E, exit_tte);
02489         }
02490 
02491         if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
02492             ERROR_OUT(ASN_PARSE_E, exit_tte);
02493         }
02494 
02495         if (oid != PBKDF2_OID) {
02496             ERROR_OUT(ASN_PARSE_E, exit_tte);
02497         }
02498     }
02499 
02500     if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
02501         ERROR_OUT(ASN_PARSE_E, exit_tte);
02502     }
02503 
02504     ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
02505     if (ret < 0)
02506         goto exit_tte;
02507 
02508     if (saltSz > MAX_SALT_SIZE) {
02509         ERROR_OUT(ASN_PARSE_E, exit_tte);
02510     }
02511 
02512 #ifdef WOLFSSL_SMALL_STACK
02513     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02514     if (salt == NULL) {
02515         ERROR_OUT(MEMORY_E, exit_tte);
02516     }
02517 #endif
02518 
02519     XMEMCPY(salt, &input[inOutIdx], saltSz);
02520     inOutIdx += saltSz;
02521 
02522     if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
02523         ERROR_OUT(ASN_PARSE_E, exit_tte);
02524     }
02525 
02526 #ifdef WOLFSSL_SMALL_STACK
02527     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02528     if (cbcIv == NULL) {
02529         ERROR_OUT(MEMORY_E, exit_tte);
02530     }
02531 #endif
02532 
02533     if (version == PKCS5v2) {
02534         /* get encryption algo */
02535         /* JOHN: New type. Need a little more research. */
02536         if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
02537             ERROR_OUT(ASN_PARSE_E, exit_tte);
02538         }
02539 
02540         if (CheckAlgoV2(oid, &id) < 0) {
02541             ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */
02542         }
02543 
02544         ret = GetOctetString(input, &inOutIdx, &length, sz);
02545         if (ret < 0)
02546             goto exit_tte;
02547 
02548         if (length > MAX_IV_SIZE) {
02549             ERROR_OUT(ASN_PARSE_E, exit_tte);
02550         }
02551 
02552         XMEMCPY(cbcIv, &input[inOutIdx], length);
02553         inOutIdx += length;
02554     }
02555 
02556     ret = GetOctetString(input, &inOutIdx, &length, sz);
02557     if (ret < 0)
02558         goto exit_tte;
02559 
02560     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
02561                                    input + inOutIdx, length, version, cbcIv);
02562 
02563 exit_tte:
02564 #ifdef WOLFSSL_SMALL_STACK
02565     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
02566     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02567 #endif
02568 
02569     if (ret == 0) {
02570         XMEMMOVE(input, input + inOutIdx, length);
02571         ret = ToTraditional(input, length);
02572     }
02573 
02574     return ret;
02575 }
02576 
02577 /* decrypt PKCS */
02578 int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
02579 {
02580     word32 inOutIdx = 0, oid;
02581     int    ret = 0;
02582     int    first, second, length = 0, version, saltSz, id;
02583     int    iterations = 0;
02584 #ifdef WOLFSSL_SMALL_STACK
02585     byte*  salt = NULL;
02586     byte*  cbcIv = NULL;
02587 #else
02588     byte   salt[MAX_SALT_SIZE];
02589     byte   cbcIv[MAX_IV_SIZE];
02590 #endif
02591 
02592     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
02593         ERROR_OUT(ASN_PARSE_E, exit_dc);
02594     }
02595 
02596     first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
02597     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
02598 
02599     if (CheckAlgo(first, second, &id, &version) < 0) {
02600         ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
02601     }
02602 
02603     if (version == PKCS5v2) {
02604         if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
02605             ERROR_OUT(ASN_PARSE_E, exit_dc);
02606         }
02607 
02608         if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
02609             ERROR_OUT(ASN_PARSE_E, exit_dc);
02610         }
02611 
02612         if (oid != PBKDF2_OID) {
02613             ERROR_OUT(ASN_PARSE_E, exit_dc);
02614         }
02615     }
02616 
02617     if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
02618         ERROR_OUT(ASN_PARSE_E, exit_dc);
02619     }
02620 
02621     ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
02622     if (ret < 0)
02623         goto exit_dc;
02624 
02625     if (saltSz > MAX_SALT_SIZE) {
02626         ERROR_OUT(ASN_PARSE_E, exit_dc);
02627     }
02628 
02629 #ifdef WOLFSSL_SMALL_STACK
02630     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02631     if (salt == NULL) {
02632         ERROR_OUT(MEMORY_E, exit_dc);
02633     }
02634 #endif
02635 
02636     XMEMCPY(salt, &input[inOutIdx], saltSz);
02637     inOutIdx += saltSz;
02638 
02639     if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
02640         ERROR_OUT(ASN_PARSE_E, exit_dc);
02641     }
02642 
02643 #ifdef WOLFSSL_SMALL_STACK
02644     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02645     if (cbcIv == NULL) {
02646         ERROR_OUT(MEMORY_E, exit_dc);
02647     }
02648 #endif
02649 
02650     if (version == PKCS5v2) {
02651         /* get encryption algo */
02652         /* JOHN: New type. Need a little more research. */
02653         if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
02654             ERROR_OUT(ASN_PARSE_E, exit_dc);
02655         }
02656 
02657         if (CheckAlgoV2(oid, &id) < 0) {
02658             ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
02659         }
02660 
02661         ret = GetOctetString(input, &inOutIdx, &length, sz);
02662         if (ret < 0)
02663             goto exit_dc;
02664 
02665         XMEMCPY(cbcIv, &input[inOutIdx], length);
02666         inOutIdx += length;
02667     }
02668 
02669     if (input[inOutIdx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
02670         ERROR_OUT(ASN_PARSE_E, exit_dc);
02671     }
02672 
02673     if (GetLength(input, &inOutIdx, &length, sz) < 0) {
02674         ERROR_OUT(ASN_PARSE_E, exit_dc);
02675     }
02676 
02677     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
02678                                    input + inOutIdx, length, version, cbcIv);
02679 
02680 exit_dc:
02681 
02682 #ifdef WOLFSSL_SMALL_STACK
02683     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
02684     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02685 #endif
02686 
02687     if (ret == 0) {
02688         XMEMMOVE(input, input + inOutIdx, length);
02689         ret = length;
02690     }
02691 
02692     return ret;
02693 }
02694 #endif /* NO_PWDBASED */
02695 
02696 #ifndef NO_RSA
02697 
02698 #ifndef HAVE_USER_RSA
02699 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
02700                        word32 inSz)
02701 {
02702     int  length;
02703 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
02704     byte b;
02705 #endif
02706     int ret;
02707 
02708     if (input == NULL || inOutIdx == NULL || key == NULL)
02709         return BAD_FUNC_ARG;
02710 
02711     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02712         return ASN_PARSE_E;
02713 
02714     key->type = RSA_PUBLIC;
02715 
02716 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
02717     if ((*inOutIdx + 1) > inSz)
02718         return BUFFER_E;
02719 
02720     b = input[*inOutIdx];
02721     if (b != ASN_INTEGER) {
02722         /* not from decoded cert, will have algo id, skip past */
02723         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02724             return ASN_PARSE_E;
02725 
02726         if (SkipObjectId(input, inOutIdx, inSz) < 0)
02727             return ASN_PARSE_E;
02728 
02729         /* Option NULL ASN.1 tag */
02730         if (input[*inOutIdx] == ASN_TAG_NULL) {
02731             ret = GetASNNull(input, inOutIdx, inSz);
02732             if (ret != 0)
02733                 return ret;
02734         }
02735 
02736         /* should have bit tag length and seq next */
02737         ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
02738         if (ret != 0)
02739             return ret;
02740 
02741         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02742             return ASN_PARSE_E;
02743     }
02744 #endif /* OPENSSL_EXTRA */
02745 
02746     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0)
02747         return ASN_RSA_KEY_E;
02748     if (GetInt(&key->e,  input, inOutIdx, inSz) < 0) {
02749         mp_clear(&key->n);
02750         return ASN_RSA_KEY_E;
02751     }
02752 
02753     return 0;
02754 }
02755 
02756 /* import RSA public key elements (n, e) into RsaKey structure (key) */
02757 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
02758                              word32 eSz, RsaKey* key)
02759 {
02760     if (n == NULL || e == NULL || key == NULL)
02761         return BAD_FUNC_ARG;
02762 
02763     key->type = RSA_PUBLIC;
02764 
02765     if (mp_init(&key->n) != MP_OKAY)
02766         return MP_INIT_E;
02767 
02768     if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
02769         mp_clear(&key->n);
02770         return ASN_GETINT_E;
02771     }
02772 
02773     if (mp_init(&key->e) != MP_OKAY) {
02774         mp_clear(&key->n);
02775         return MP_INIT_E;
02776     }
02777 
02778     if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
02779         mp_clear(&key->n);
02780         mp_clear(&key->e);
02781         return ASN_GETINT_E;
02782     }
02783 
02784     return 0;
02785 }
02786 #endif /* HAVE_USER_RSA */
02787 #endif
02788 
02789 #ifndef NO_DH
02790 
02791 int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
02792 {
02793     int    length;
02794 
02795     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02796         return ASN_PARSE_E;
02797 
02798     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
02799         GetInt(&key->g,  input, inOutIdx, inSz) < 0) {
02800         return ASN_DH_KEY_E;
02801     }
02802 
02803     return 0;
02804 }
02805 
02806 
02807 int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
02808                  byte* g, word32* gInOutSz)
02809 {
02810     word32 idx = 0;
02811     int    ret;
02812     int    length;
02813 
02814     if (GetSequence(input, &idx, &length, inSz) <= 0)
02815         return ASN_PARSE_E;
02816 
02817     ret = GetASNInt(input, &idx, &length, inSz);
02818     if (ret != 0)
02819         return ret;
02820 
02821     if (length <= (int)*pInOutSz) {
02822         XMEMCPY(p, &input[idx], length);
02823         *pInOutSz = length;
02824     }
02825     else {
02826         return BUFFER_E;
02827     }
02828     idx += length;
02829 
02830     ret = GetASNInt(input, &idx, &length, inSz);
02831     if (ret != 0)
02832         return ret;
02833 
02834     if (length <= (int)*gInOutSz) {
02835         XMEMCPY(g, &input[idx], length);
02836         *gInOutSz = length;
02837     }
02838     else {
02839         return BUFFER_E;
02840     }
02841 
02842     return 0;
02843 }
02844 
02845 #endif /* NO_DH */
02846 
02847 
02848 #ifndef NO_DSA
02849 
02850 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
02851                         word32 inSz)
02852 {
02853     int    length;
02854 
02855     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02856         return ASN_PARSE_E;
02857 
02858     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
02859         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
02860         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
02861         GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
02862         return ASN_DH_KEY_E;
02863 
02864     key->type = DSA_PUBLIC;
02865     return 0;
02866 }
02867 
02868 
02869 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
02870                         word32 inSz)
02871 {
02872     int    length, version;
02873 
02874     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
02875         return ASN_PARSE_E;
02876 
02877     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
02878         return ASN_PARSE_E;
02879 
02880     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
02881         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
02882         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
02883         GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
02884         GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
02885         return ASN_DH_KEY_E;
02886 
02887     key->type = DSA_PRIVATE;
02888     return 0;
02889 }
02890 
02891 static mp_int* GetDsaInt(DsaKey* key, int idx)
02892 {
02893     if (idx == 0)
02894         return &key->p;
02895     if (idx == 1)
02896         return &key->q;
02897     if (idx == 2)
02898         return &key->g;
02899     if (idx == 3)
02900         return &key->y;
02901     if (idx == 4)
02902         return &key->x;
02903 
02904     return NULL;
02905 }
02906 
02907 /* Release Tmp DSA resources */
02908 static INLINE void FreeTmpDsas(byte** tmps, void* heap)
02909 {
02910     int i;
02911 
02912     for (i = 0; i < DSA_INTS; i++)
02913         XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
02914 
02915     (void)heap;
02916 }
02917 
02918 /* Convert DsaKey key to DER format, write to output (inLen), return bytes
02919  written */
02920 int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
02921 {
02922     word32 seqSz, verSz, rawLen, intTotalLen = 0;
02923     word32 sizes[DSA_INTS];
02924     int    i, j, outLen, ret = 0, mpSz;
02925 
02926     byte  seq[MAX_SEQ_SZ];
02927     byte  ver[MAX_VERSION_SZ];
02928     byte* tmps[DSA_INTS];
02929 
02930     if (!key || !output)
02931         return BAD_FUNC_ARG;
02932 
02933     if (key->type != DSA_PRIVATE)
02934         return BAD_FUNC_ARG;
02935 
02936     for (i = 0; i < DSA_INTS; i++)
02937         tmps[i] = NULL;
02938 
02939     /* write all big ints from key to DER tmps */
02940     for (i = 0; i < DSA_INTS; i++) {
02941         mp_int* keyInt = GetDsaInt(key, i);
02942 
02943         rawLen = mp_unsigned_bin_size(keyInt) + 1;
02944         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
02945                                                               DYNAMIC_TYPE_DSA);
02946         if (tmps[i] == NULL) {
02947             ret = MEMORY_E;
02948             break;
02949         }
02950 
02951         mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
02952         if (mpSz < 0) {
02953             ret = mpSz;
02954             break;
02955         }
02956         intTotalLen += (sizes[i] = mpSz);
02957     }
02958 
02959     if (ret != 0) {
02960         FreeTmpDsas(tmps, key->heap);
02961         return ret;
02962     }
02963 
02964     /* make headers */
02965     verSz = SetMyVersion(0, ver, FALSE);
02966     seqSz = SetSequence(verSz + intTotalLen, seq);
02967 
02968     outLen = seqSz + verSz + intTotalLen;
02969     if (outLen > (int)inLen)
02970         return BAD_FUNC_ARG;
02971 
02972     /* write to output */
02973     XMEMCPY(output, seq, seqSz);
02974     j = seqSz;
02975     XMEMCPY(output + j, ver, verSz);
02976     j += verSz;
02977 
02978     for (i = 0; i < DSA_INTS; i++) {
02979         XMEMCPY(output + j, tmps[i], sizes[i]);
02980         j += sizes[i];
02981     }
02982     FreeTmpDsas(tmps, key->heap);
02983 
02984     return outLen;
02985 }
02986 
02987 #endif /* NO_DSA */
02988 
02989 
02990 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
02991 {
02992     cert->publicKey       = 0;
02993     cert->pubKeySize      = 0;
02994     cert->pubKeyStored    = 0;
02995     cert->keyOID          = 0;
02996     cert->version         = 0;
02997     cert->signature       = 0;
02998     cert->subjectCN       = 0;
02999     cert->subjectCNLen    = 0;
03000     cert->subjectCNEnc    = CTC_UTF8;
03001     cert->subjectCNStored = 0;
03002     cert->weOwnAltNames   = 0;
03003     cert->altNames        = NULL;
03004 #ifndef IGNORE_NAME_CONSTRAINTS
03005     cert->altEmailNames   = NULL;
03006     cert->permittedNames  = NULL;
03007     cert->excludedNames   = NULL;
03008 #endif /* IGNORE_NAME_CONSTRAINTS */
03009     cert->issuer[0]       = '\0';
03010     cert->subject[0]      = '\0';
03011     cert->source          = source;  /* don't own */
03012     cert->srcIdx          = 0;
03013     cert->maxIdx          = inSz;    /* can't go over this index */
03014     cert->heap            = heap;
03015     XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
03016     cert->serialSz        = 0;
03017     cert->extensions      = 0;
03018     cert->extensionsSz    = 0;
03019     cert->extensionsIdx   = 0;
03020     cert->extAuthInfo     = NULL;
03021     cert->extAuthInfoSz   = 0;
03022     cert->extCrlInfo      = NULL;
03023     cert->extCrlInfoSz    = 0;
03024     XMEMSET(cert->extSubjKeyId, 0, KEYID_SIZE);
03025     cert->extSubjKeyIdSet = 0;
03026     XMEMSET(cert->extAuthKeyId, 0, KEYID_SIZE);
03027     cert->extAuthKeyIdSet = 0;
03028     cert->extKeyUsageSet  = 0;
03029     cert->extKeyUsage     = 0;
03030     cert->extExtKeyUsageSet = 0;
03031     cert->extExtKeyUsage    = 0;
03032     cert->isCA            = 0;
03033     cert->pathLengthSet   = 0;
03034     cert->pathLength      = 0;
03035 #ifdef HAVE_PKCS7
03036     cert->issuerRaw       = NULL;
03037     cert->issuerRawLen    = 0;
03038 #endif
03039 #ifdef WOLFSSL_CERT_GEN
03040     cert->subjectSN       = 0;
03041     cert->subjectSNLen    = 0;
03042     cert->subjectSNEnc    = CTC_UTF8;
03043     cert->subjectC        = 0;
03044     cert->subjectCLen     = 0;
03045     cert->subjectCEnc     = CTC_PRINTABLE;
03046     cert->subjectL        = 0;
03047     cert->subjectLLen     = 0;
03048     cert->subjectLEnc     = CTC_UTF8;
03049     cert->subjectST       = 0;
03050     cert->subjectSTLen    = 0;
03051     cert->subjectSTEnc    = CTC_UTF8;
03052     cert->subjectO        = 0;
03053     cert->subjectOLen     = 0;
03054     cert->subjectOEnc     = CTC_UTF8;
03055     cert->subjectOU       = 0;
03056     cert->subjectOULen    = 0;
03057     cert->subjectOUEnc    = CTC_UTF8;
03058     cert->subjectEmail    = 0;
03059     cert->subjectEmailLen = 0;
03060 #endif /* WOLFSSL_CERT_GEN */
03061     cert->beforeDate      = NULL;
03062     cert->beforeDateLen   = 0;
03063     cert->afterDate       = NULL;
03064     cert->afterDateLen    = 0;
03065 #ifdef OPENSSL_EXTRA
03066     XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
03067     XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
03068     cert->extCRLdistSet = 0;
03069     cert->extCRLdistCrit = 0;
03070     cert->extAuthInfoSet = 0;
03071     cert->extAuthInfoCrit = 0;
03072     cert->extBasicConstSet = 0;
03073     cert->extBasicConstCrit = 0;
03074     cert->extSubjAltNameSet = 0;
03075     cert->extSubjAltNameCrit = 0;
03076     cert->extAuthKeyIdCrit = 0;
03077     cert->extSubjKeyIdCrit = 0;
03078     cert->extKeyUsageCrit = 0;
03079     cert->extExtKeyUsageCrit = 0;
03080     cert->extExtKeyUsageSrc = NULL;
03081     cert->extExtKeyUsageSz = 0;
03082     cert->extExtKeyUsageCount = 0;
03083     cert->extAuthKeyIdSrc = NULL;
03084     cert->extAuthKeyIdSz = 0;
03085     cert->extSubjKeyIdSrc = NULL;
03086     cert->extSubjKeyIdSz = 0;
03087 #endif /* OPENSSL_EXTRA */
03088 #if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS)
03089     cert->extNameConstraintSet = 0;
03090 #endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */
03091 #ifdef HAVE_ECC
03092     cert->pkCurveOID = 0;
03093 #endif /* HAVE_ECC */
03094 #ifdef WOLFSSL_SEP
03095     cert->deviceTypeSz = 0;
03096     cert->deviceType = NULL;
03097     cert->hwTypeSz = 0;
03098     cert->hwType = NULL;
03099     cert->hwSerialNumSz = 0;
03100     cert->hwSerialNum = NULL;
03101     #ifdef OPENSSL_EXTRA
03102         cert->extCertPolicySet = 0;
03103         cert->extCertPolicyCrit = 0;
03104     #endif /* OPENSSL_EXTRA */
03105 #endif /* WOLFSSL_SEP */
03106 #ifdef WOLFSSL_CERT_EXT
03107     XMEMSET(cert->extCertPolicies, 0, MAX_CERTPOL_NB*MAX_CERTPOL_SZ);
03108     cert->extCertPoliciesNb = 0;
03109 #endif
03110 
03111     cert->ca = NULL;
03112     InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
03113 }
03114 
03115 
03116 void FreeAltNames(DNS_entry* altNames, void* heap)
03117 {
03118     (void)heap;
03119 
03120     while (altNames) {
03121         DNS_entry* tmp = altNames->next;
03122 
03123         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
03124         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
03125         altNames = tmp;
03126     }
03127 }
03128 
03129 #ifndef IGNORE_NAME_CONSTRAINTS
03130 
03131 void FreeNameSubtrees(Base_entry* names, void* heap)
03132 {
03133     (void)heap;
03134 
03135     while (names) {
03136         Base_entry* tmp = names->next;
03137 
03138         XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
03139         XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
03140         names = tmp;
03141     }
03142 }
03143 
03144 #endif /* IGNORE_NAME_CONSTRAINTS */
03145 
03146 void FreeDecodedCert(DecodedCert* cert)
03147 {
03148     if (cert->subjectCNStored == 1)
03149         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
03150     if (cert->pubKeyStored == 1)
03151         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
03152     if (cert->weOwnAltNames && cert->altNames)
03153         FreeAltNames(cert->altNames, cert->heap);
03154 #ifndef IGNORE_NAME_CONSTRAINTS
03155     if (cert->altEmailNames)
03156         FreeAltNames(cert->altEmailNames, cert->heap);
03157     if (cert->permittedNames)
03158         FreeNameSubtrees(cert->permittedNames, cert->heap);
03159     if (cert->excludedNames)
03160         FreeNameSubtrees(cert->excludedNames, cert->heap);
03161 #endif /* IGNORE_NAME_CONSTRAINTS */
03162 #ifdef WOLFSSL_SEP
03163     XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
03164     XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
03165     XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
03166 #endif /* WOLFSSL_SEP */
03167 #ifdef OPENSSL_EXTRA
03168     if (cert->issuerName.fullName != NULL)
03169         XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
03170     if (cert->subjectName.fullName != NULL)
03171         XFREE(cert->subjectName.fullName, cert->heap, DYNAMIC_TYPE_X509);
03172 #endif /* OPENSSL_EXTRA */
03173     FreeSignatureCtx(&cert->sigCtx);
03174 }
03175 
03176 static int GetCertHeader(DecodedCert* cert)
03177 {
03178     int ret = 0, len;
03179 
03180     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
03181         return ASN_PARSE_E;
03182 
03183     cert->certBegin = cert->srcIdx;
03184 
03185     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
03186         return ASN_PARSE_E;
03187     cert->sigIndex = len + cert->srcIdx;
03188 
03189     if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
03190                                                               cert->maxIdx) < 0)
03191         return ASN_PARSE_E;
03192 
03193     if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
03194                                         &cert->serialSz, cert->maxIdx) < 0)
03195         return ASN_PARSE_E;
03196 
03197     return ret;
03198 }
03199 
03200 #if !defined(NO_RSA)
03201 /* Store Rsa Key, may save later, Dsa could use in future */
03202 static int StoreRsaKey(DecodedCert* cert)
03203 {
03204     int    length;
03205     word32 recvd = cert->srcIdx;
03206 
03207     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
03208         return ASN_PARSE_E;
03209 
03210     recvd = cert->srcIdx - recvd;
03211     length += recvd;
03212 
03213     while (recvd--)
03214        cert->srcIdx--;
03215 
03216     cert->pubKeySize = length;
03217     cert->publicKey = cert->source + cert->srcIdx;
03218     cert->srcIdx += length;
03219 
03220     return 0;
03221 }
03222 #endif /* !NO_RSA */
03223 
03224 #ifdef HAVE_ECC
03225 
03226     /* return 0 on success if the ECC curve oid sum is supported */
03227     static int CheckCurve(word32 oid)
03228     {
03229         int ret = 0;
03230         word32 oidSz = 0;
03231 
03232         ret = wc_ecc_get_oid(oid, NULL, &oidSz);
03233         if (ret < 0 || oidSz <= 0) {
03234             WOLFSSL_MSG("CheckCurve not found");
03235             ret = ALGO_ID_E;
03236         }
03237 
03238         return ret;
03239     }
03240 
03241 #endif /* HAVE_ECC */
03242 
03243 static int GetKey(DecodedCert* cert)
03244 {
03245     int length;
03246 #ifdef HAVE_NTRU
03247     int tmpIdx = cert->srcIdx;
03248 #endif
03249 
03250     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
03251         return ASN_PARSE_E;
03252 
03253     if (GetAlgoId(cert->source, &cert->srcIdx,
03254                   &cert->keyOID, oidKeyType, cert->maxIdx) < 0)
03255         return ASN_PARSE_E;
03256 
03257     switch (cert->keyOID) {
03258    #ifndef NO_RSA
03259         case RSAk:
03260         {
03261             int ret;
03262             ret = CheckBitString(cert->source, &cert->srcIdx, NULL,
03263                                  cert->maxIdx, 1, NULL);
03264             if (ret != 0)
03265                 return ret;
03266 
03267             return StoreRsaKey(cert);
03268         }
03269 
03270     #endif /* NO_RSA */
03271     #ifdef HAVE_NTRU
03272         case NTRUk:
03273         {
03274             const byte* key = &cert->source[tmpIdx];
03275             byte*       next = (byte*)key;
03276             word16      keyLen;
03277             word32      rc;
03278             word32      remaining = cert->maxIdx - cert->srcIdx;
03279 #ifdef WOLFSSL_SMALL_STACK
03280             byte*       keyBlob = NULL;
03281 #else
03282             byte        keyBlob[MAX_NTRU_KEY_SZ];
03283 #endif
03284             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
03285                                 &keyLen, NULL, &next, &remaining);
03286             if (rc != NTRU_OK)
03287                 return ASN_NTRU_KEY_E;
03288             if (keyLen > MAX_NTRU_KEY_SZ)
03289                 return ASN_NTRU_KEY_E;
03290 
03291 #ifdef WOLFSSL_SMALL_STACK
03292             keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
03293                                      DYNAMIC_TYPE_TMP_BUFFER);
03294             if (keyBlob == NULL)
03295                 return MEMORY_E;
03296 #endif
03297 
03298             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
03299                                 &keyLen, keyBlob, &next, &remaining);
03300             if (rc != NTRU_OK) {
03301 #ifdef WOLFSSL_SMALL_STACK
03302                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03303 #endif
03304                 return ASN_NTRU_KEY_E;
03305             }
03306 
03307             if ( (next - key) < 0) {
03308 #ifdef WOLFSSL_SMALL_STACK
03309                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03310 #endif
03311                 return ASN_NTRU_KEY_E;
03312             }
03313 
03314             cert->srcIdx = tmpIdx + (int)(next - key);
03315 
03316             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
03317                                               DYNAMIC_TYPE_PUBLIC_KEY);
03318             if (cert->publicKey == NULL) {
03319 #ifdef WOLFSSL_SMALL_STACK
03320                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03321 #endif
03322                 return MEMORY_E;
03323             }
03324             XMEMCPY(cert->publicKey, keyBlob, keyLen);
03325             cert->pubKeyStored = 1;
03326             cert->pubKeySize   = keyLen;
03327 
03328 #ifdef WOLFSSL_SMALL_STACK
03329             XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03330 #endif
03331 
03332             return 0;
03333         }
03334     #endif /* HAVE_NTRU */
03335     #ifdef HAVE_ECC
03336         case ECDSAk:
03337         {
03338             int ret;
03339 
03340             if (GetObjectId(cert->source, &cert->srcIdx,
03341                             &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
03342                 return ASN_PARSE_E;
03343 
03344             if (CheckCurve(cert->pkCurveOID) < 0)
03345                 return ECC_CURVE_OID_E;
03346 
03347             /* key header */
03348             ret = CheckBitString(cert->source, &cert->srcIdx, &length,
03349                                  cert->maxIdx, 1, NULL);
03350             if (ret != 0)
03351                 return ret;
03352 
03353             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
03354                                               DYNAMIC_TYPE_PUBLIC_KEY);
03355             if (cert->publicKey == NULL)
03356                 return MEMORY_E;
03357             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
03358             cert->pubKeyStored = 1;
03359             cert->pubKeySize   = length;
03360 
03361             cert->srcIdx += length;
03362 
03363             return 0;
03364         }
03365     #endif /* HAVE_ECC */
03366         default:
03367             return ASN_UNKNOWN_OID_E;
03368     }
03369 }
03370 
03371 /* process NAME, either issuer or subject */
03372 static int GetName(DecodedCert* cert, int nameType)
03373 {
03374     int    length;  /* length of all distinguished names */
03375     int    dummy;
03376     int    ret;
03377     char*  full;
03378     byte*  hash;
03379     word32 idx;
03380     #ifdef OPENSSL_EXTRA
03381         DecodedName* dName =
03382                   (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
03383     #endif /* OPENSSL_EXTRA */
03384 
03385     WOLFSSL_MSG("Getting Cert Name");
03386 
03387     if (nameType == ISSUER) {
03388         full = cert->issuer;
03389         hash = cert->issuerHash;
03390     }
03391     else {
03392         full = cert->subject;
03393         hash = cert->subjectHash;
03394     }
03395 
03396     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
03397         WOLFSSL_MSG("Trying optional prefix...");
03398 
03399         if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0)
03400             return ASN_PARSE_E;
03401         WOLFSSL_MSG("Got optional prefix");
03402     }
03403 
03404     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
03405      * calculated over the entire DER encoding of the Name field, including
03406      * the tag and length. */
03407     idx = cert->srcIdx;
03408     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
03409         return ASN_PARSE_E;
03410 
03411 #ifdef NO_SHA
03412     ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
03413 #else
03414     ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
03415 #endif
03416     if (ret != 0)
03417         return ret;
03418 
03419     length += cert->srcIdx;
03420     idx = 0;
03421 
03422 #ifdef HAVE_PKCS7
03423     /* store pointer to raw issuer */
03424     if (nameType == ISSUER) {
03425         cert->issuerRaw = &cert->source[cert->srcIdx];
03426         cert->issuerRawLen = length - cert->srcIdx;
03427     }
03428 #endif
03429 #ifndef IGNORE_NAME_CONSTRAINTS
03430     if (nameType == SUBJECT) {
03431         cert->subjectRaw = &cert->source[cert->srcIdx];
03432         cert->subjectRawLen = length - cert->srcIdx;
03433     }
03434 #endif
03435 
03436     while (cert->srcIdx < (word32)length) {
03437         byte   b;
03438         byte   joint[2];
03439         byte   tooBig = FALSE;
03440         int    oidSz;
03441 
03442         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
03443             WOLFSSL_MSG("Cert name lacks set header, trying sequence");
03444         }
03445 
03446         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) <= 0)
03447             return ASN_PARSE_E;
03448 
03449         ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx);
03450         if (ret != 0)
03451             return ret;
03452 
03453         /* make sure there is room for joint */
03454         if ((cert->srcIdx + sizeof(joint)) > cert->maxIdx)
03455             return ASN_PARSE_E;
03456 
03457         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
03458 
03459         /* v1 name types */
03460         if (joint[0] == 0x55 && joint[1] == 0x04) {
03461             byte   id;
03462             byte   copy = FALSE;
03463             int    strLen;
03464 
03465             cert->srcIdx += 2;
03466             id = cert->source[cert->srcIdx++];
03467             b  = cert->source[cert->srcIdx++]; /* encoding */
03468 
03469             if (GetLength(cert->source, &cert->srcIdx, &strLen,
03470                           cert->maxIdx) < 0)
03471                 return ASN_PARSE_E;
03472 
03473             if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
03474                 /* include biggest pre fix header too 4 = "/serialNumber=" */
03475                 WOLFSSL_MSG("ASN Name too big, skipping");
03476                 tooBig = TRUE;
03477             }
03478 
03479             if (id == ASN_COMMON_NAME) {
03480                 if (nameType == SUBJECT) {
03481                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
03482                     cert->subjectCNLen = strLen;
03483                     cert->subjectCNEnc = b;
03484                 }
03485 
03486                 if (!tooBig) {
03487                     XMEMCPY(&full[idx], "/CN=", 4);
03488                     idx += 4;
03489                     copy = TRUE;
03490                 }
03491                 #ifdef OPENSSL_EXTRA
03492                     dName->cnIdx = cert->srcIdx;
03493                     dName->cnLen = strLen;
03494                 #endif /* OPENSSL_EXTRA */
03495             }
03496             else if (id == ASN_SUR_NAME) {
03497                 if (!tooBig) {
03498                     XMEMCPY(&full[idx], "/SN=", 4);
03499                     idx += 4;
03500                     copy = TRUE;
03501                 }
03502                 #ifdef WOLFSSL_CERT_GEN
03503                     if (nameType == SUBJECT) {
03504                         cert->subjectSN = (char*)&cert->source[cert->srcIdx];
03505                         cert->subjectSNLen = strLen;
03506                         cert->subjectSNEnc = b;
03507                     }
03508                 #endif /* WOLFSSL_CERT_GEN */
03509                 #ifdef OPENSSL_EXTRA
03510                     dName->snIdx = cert->srcIdx;
03511                     dName->snLen = strLen;
03512                 #endif /* OPENSSL_EXTRA */
03513             }
03514             else if (id == ASN_COUNTRY_NAME) {
03515                 if (!tooBig) {
03516                     XMEMCPY(&full[idx], "/C=", 3);
03517                     idx += 3;
03518                     copy = TRUE;
03519                 }
03520                 #ifdef WOLFSSL_CERT_GEN
03521                     if (nameType == SUBJECT) {
03522                         cert->subjectC = (char*)&cert->source[cert->srcIdx];
03523                         cert->subjectCLen = strLen;
03524                         cert->subjectCEnc = b;
03525                     }
03526                 #endif /* WOLFSSL_CERT_GEN */
03527                 #ifdef OPENSSL_EXTRA
03528                     dName->cIdx = cert->srcIdx;
03529                     dName->cLen = strLen;
03530                 #endif /* OPENSSL_EXTRA */
03531             }
03532             else if (id == ASN_LOCALITY_NAME) {
03533                 if (!tooBig) {
03534                     XMEMCPY(&full[idx], "/L=", 3);
03535                     idx += 3;
03536                     copy = TRUE;
03537                 }
03538                 #ifdef WOLFSSL_CERT_GEN
03539                     if (nameType == SUBJECT) {
03540                         cert->subjectL = (char*)&cert->source[cert->srcIdx];
03541                         cert->subjectLLen = strLen;
03542                         cert->subjectLEnc = b;
03543                     }
03544                 #endif /* WOLFSSL_CERT_GEN */
03545                 #ifdef OPENSSL_EXTRA
03546                     dName->lIdx = cert->srcIdx;
03547                     dName->lLen = strLen;
03548                 #endif /* OPENSSL_EXTRA */
03549             }
03550             else if (id == ASN_STATE_NAME) {
03551                 if (!tooBig) {
03552                     XMEMCPY(&full[idx], "/ST=", 4);
03553                     idx += 4;
03554                     copy = TRUE;
03555                 }
03556                 #ifdef WOLFSSL_CERT_GEN
03557                     if (nameType == SUBJECT) {
03558                         cert->subjectST = (char*)&cert->source[cert->srcIdx];
03559                         cert->subjectSTLen = strLen;
03560                         cert->subjectSTEnc = b;
03561                     }
03562                 #endif /* WOLFSSL_CERT_GEN */
03563                 #ifdef OPENSSL_EXTRA
03564                     dName->stIdx = cert->srcIdx;
03565                     dName->stLen = strLen;
03566                 #endif /* OPENSSL_EXTRA */
03567             }
03568             else if (id == ASN_ORG_NAME) {
03569                 if (!tooBig) {
03570                     XMEMCPY(&full[idx], "/O=", 3);
03571                     idx += 3;
03572                     copy = TRUE;
03573                 }
03574                 #ifdef WOLFSSL_CERT_GEN
03575                     if (nameType == SUBJECT) {
03576                         cert->subjectO = (char*)&cert->source[cert->srcIdx];
03577                         cert->subjectOLen = strLen;
03578                         cert->subjectOEnc = b;
03579                     }
03580                 #endif /* WOLFSSL_CERT_GEN */
03581                 #ifdef OPENSSL_EXTRA
03582                     dName->oIdx = cert->srcIdx;
03583                     dName->oLen = strLen;
03584                 #endif /* OPENSSL_EXTRA */
03585             }
03586             else if (id == ASN_ORGUNIT_NAME) {
03587                 if (!tooBig) {
03588                     XMEMCPY(&full[idx], "/OU=", 4);
03589                     idx += 4;
03590                     copy = TRUE;
03591                 }
03592                 #ifdef WOLFSSL_CERT_GEN
03593                     if (nameType == SUBJECT) {
03594                         cert->subjectOU = (char*)&cert->source[cert->srcIdx];
03595                         cert->subjectOULen = strLen;
03596                         cert->subjectOUEnc = b;
03597                     }
03598                 #endif /* WOLFSSL_CERT_GEN */
03599                 #ifdef OPENSSL_EXTRA
03600                     dName->ouIdx = cert->srcIdx;
03601                     dName->ouLen = strLen;
03602                 #endif /* OPENSSL_EXTRA */
03603             }
03604             else if (id == ASN_SERIAL_NUMBER) {
03605                 if (!tooBig) {
03606                    XMEMCPY(&full[idx], "/serialNumber=", 14);
03607                    idx += 14;
03608                    copy = TRUE;
03609                 }
03610                 #ifdef OPENSSL_EXTRA
03611                     dName->snIdx = cert->srcIdx;
03612                     dName->snLen = strLen;
03613                 #endif /* OPENSSL_EXTRA */
03614             }
03615 
03616             if (copy && !tooBig) {
03617                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
03618                 idx += strLen;
03619             }
03620 
03621             cert->srcIdx += strLen;
03622         }
03623         else {
03624             /* skip */
03625             byte email = FALSE;
03626             byte uid   = FALSE;
03627             int  adv;
03628 
03629             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
03630                 email = TRUE;
03631 
03632             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
03633                 uid = TRUE;
03634 
03635             cert->srcIdx += oidSz + 1;
03636 
03637             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
03638                 return ASN_PARSE_E;
03639 
03640             if (adv > (int)(ASN_NAME_MAX - idx)) {
03641                 WOLFSSL_MSG("ASN name too big, skipping");
03642                 tooBig = TRUE;
03643             }
03644 
03645             if (email) {
03646                 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
03647                     WOLFSSL_MSG("ASN name too big, skipping");
03648                     tooBig = TRUE;
03649                 }
03650                 if (!tooBig) {
03651                     XMEMCPY(&full[idx], "/emailAddress=", 14);
03652                     idx += 14;
03653                 }
03654 
03655                 #ifdef WOLFSSL_CERT_GEN
03656                     if (nameType == SUBJECT) {
03657                         cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
03658                         cert->subjectEmailLen = adv;
03659                     }
03660                 #endif /* WOLFSSL_CERT_GEN */
03661                 #ifdef OPENSSL_EXTRA
03662                     dName->emailIdx = cert->srcIdx;
03663                     dName->emailLen = adv;
03664                 #endif /* OPENSSL_EXTRA */
03665                 #ifndef IGNORE_NAME_CONSTRAINTS
03666                     {
03667                         DNS_entry* emailName = NULL;
03668 
03669                         emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
03670                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
03671                         if (emailName == NULL) {
03672                             WOLFSSL_MSG("\tOut of Memory");
03673                             return MEMORY_E;
03674                         }
03675                         emailName->name = (char*)XMALLOC(adv + 1,
03676                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
03677                         if (emailName->name == NULL) {
03678                             WOLFSSL_MSG("\tOut of Memory");
03679                             XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
03680                             return MEMORY_E;
03681                         }
03682                         XMEMCPY(emailName->name,
03683                                               &cert->source[cert->srcIdx], adv);
03684                         emailName->name[adv] = 0;
03685 
03686                         emailName->next = cert->altEmailNames;
03687                         cert->altEmailNames = emailName;
03688                     }
03689                 #endif /* IGNORE_NAME_CONSTRAINTS */
03690                 if (!tooBig) {
03691                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
03692                     idx += adv;
03693                 }
03694             }
03695 
03696             if (uid) {
03697                 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
03698                     WOLFSSL_MSG("ASN name too big, skipping");
03699                     tooBig = TRUE;
03700                 }
03701                 if (!tooBig) {
03702                     XMEMCPY(&full[idx], "/UID=", 5);
03703                     idx += 5;
03704 
03705                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
03706                     idx += adv;
03707                 }
03708                 #ifdef OPENSSL_EXTRA
03709                     dName->uidIdx = cert->srcIdx;
03710                     dName->uidLen = adv;
03711                 #endif /* OPENSSL_EXTRA */
03712             }
03713 
03714             cert->srcIdx += adv;
03715         }
03716     }
03717     full[idx++] = 0;
03718 
03719     #ifdef OPENSSL_EXTRA
03720     {
03721         int totalLen = 0;
03722 
03723         if (dName->cnLen != 0)
03724             totalLen += dName->cnLen + 4;
03725         if (dName->snLen != 0)
03726             totalLen += dName->snLen + 4;
03727         if (dName->cLen != 0)
03728             totalLen += dName->cLen + 3;
03729         if (dName->lLen != 0)
03730             totalLen += dName->lLen + 3;
03731         if (dName->stLen != 0)
03732             totalLen += dName->stLen + 4;
03733         if (dName->oLen != 0)
03734             totalLen += dName->oLen + 3;
03735         if (dName->ouLen != 0)
03736             totalLen += dName->ouLen + 4;
03737         if (dName->emailLen != 0)
03738             totalLen += dName->emailLen + 14;
03739         if (dName->uidLen != 0)
03740             totalLen += dName->uidLen + 5;
03741         if (dName->serialLen != 0)
03742             totalLen += dName->serialLen + 14;
03743 
03744         dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
03745                                                              DYNAMIC_TYPE_X509);
03746         if (dName->fullName != NULL) {
03747             idx = 0;
03748 
03749             if (dName->cnLen != 0) {
03750                 dName->entryCount++;
03751                 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
03752                 idx += 4;
03753                 XMEMCPY(&dName->fullName[idx],
03754                                      &cert->source[dName->cnIdx], dName->cnLen);
03755                 dName->cnIdx = idx;
03756                 idx += dName->cnLen;
03757             }
03758             if (dName->snLen != 0) {
03759                 dName->entryCount++;
03760                 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
03761                 idx += 4;
03762                 XMEMCPY(&dName->fullName[idx],
03763                                      &cert->source[dName->snIdx], dName->snLen);
03764                 dName->snIdx = idx;
03765                 idx += dName->snLen;
03766             }
03767             if (dName->cLen != 0) {
03768                 dName->entryCount++;
03769                 XMEMCPY(&dName->fullName[idx], "/C=", 3);
03770                 idx += 3;
03771                 XMEMCPY(&dName->fullName[idx],
03772                                        &cert->source[dName->cIdx], dName->cLen);
03773                 dName->cIdx = idx;
03774                 idx += dName->cLen;
03775             }
03776             if (dName->lLen != 0) {
03777                 dName->entryCount++;
03778                 XMEMCPY(&dName->fullName[idx], "/L=", 3);
03779                 idx += 3;
03780                 XMEMCPY(&dName->fullName[idx],
03781                                        &cert->source[dName->lIdx], dName->lLen);
03782                 dName->lIdx = idx;
03783                 idx += dName->lLen;
03784             }
03785             if (dName->stLen != 0) {
03786                 dName->entryCount++;
03787                 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
03788                 idx += 4;
03789                 XMEMCPY(&dName->fullName[idx],
03790                                      &cert->source[dName->stIdx], dName->stLen);
03791                 dName->stIdx = idx;
03792                 idx += dName->stLen;
03793             }
03794             if (dName->oLen != 0) {
03795                 dName->entryCount++;
03796                 XMEMCPY(&dName->fullName[idx], "/O=", 3);
03797                 idx += 3;
03798                 XMEMCPY(&dName->fullName[idx],
03799                                        &cert->source[dName->oIdx], dName->oLen);
03800                 dName->oIdx = idx;
03801                 idx += dName->oLen;
03802             }
03803             if (dName->ouLen != 0) {
03804                 dName->entryCount++;
03805                 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
03806                 idx += 4;
03807                 XMEMCPY(&dName->fullName[idx],
03808                                      &cert->source[dName->ouIdx], dName->ouLen);
03809                 dName->ouIdx = idx;
03810                 idx += dName->ouLen;
03811             }
03812             if (dName->emailLen != 0) {
03813                 dName->entryCount++;
03814                 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
03815                 idx += 14;
03816                 XMEMCPY(&dName->fullName[idx],
03817                                &cert->source[dName->emailIdx], dName->emailLen);
03818                 dName->emailIdx = idx;
03819                 idx += dName->emailLen;
03820             }
03821             if (dName->uidLen != 0) {
03822                 dName->entryCount++;
03823                 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
03824                 idx += 5;
03825                 XMEMCPY(&dName->fullName[idx],
03826                                    &cert->source[dName->uidIdx], dName->uidLen);
03827                 dName->uidIdx = idx;
03828                 idx += dName->uidLen;
03829             }
03830             if (dName->serialLen != 0) {
03831                 dName->entryCount++;
03832                 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
03833                 idx += 14;
03834                 XMEMCPY(&dName->fullName[idx],
03835                              &cert->source[dName->serialIdx], dName->serialLen);
03836                 dName->serialIdx = idx;
03837                 idx += dName->serialLen;
03838             }
03839             dName->fullName[idx] = '\0';
03840             dName->fullNameLen = totalLen;
03841         }
03842     }
03843     #endif /* OPENSSL_EXTRA */
03844 
03845     return 0;
03846 }
03847 
03848 
03849 #ifndef NO_ASN_TIME
03850 #if !defined(NO_TIME_H) && defined(USE_WOLF_VALIDDATE)
03851 
03852 /* to the second */
03853 static int DateGreaterThan(const struct tm* a, const struct tm* b)
03854 {
03855     if (a->tm_year > b->tm_year)
03856         return 1;
03857 
03858     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
03859         return 1;
03860 
03861     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
03862            a->tm_mday > b->tm_mday)
03863         return 1;
03864 
03865     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
03866         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
03867         return 1;
03868 
03869     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
03870         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
03871         a->tm_min > b->tm_min)
03872         return 1;
03873 
03874     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
03875         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
03876         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
03877         return 1;
03878 
03879     return 0; /* false */
03880 }
03881 
03882 
03883 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
03884 {
03885     return DateGreaterThan(b,a);
03886 }
03887 
03888 
03889 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
03890 int GetTimeString(byte* date, int format, char* buf, int len)
03891 {
03892     struct tm t;
03893     int idx = 0;
03894 
03895     if (!ExtractDate(date, format, &t, &idx)) {
03896         return 0;
03897     }
03898 
03899     if (date[idx] != 'Z') {
03900         WOLFSSL_MSG("UTCtime, not Zulu") ;
03901         return 0;
03902     }
03903 
03904     /* place month in buffer */
03905     buf[0] = '\0';
03906     switch(t.tm_mon) {
03907         case 0:  XSTRNCAT(buf, "Jan ", 4); break;
03908         case 1:  XSTRNCAT(buf, "Feb ", 4); break;
03909         case 2:  XSTRNCAT(buf, "Mar ", 4); break;
03910         case 3:  XSTRNCAT(buf, "Apr ", 4); break;
03911         case 4:  XSTRNCAT(buf, "May ", 4); break;
03912         case 5:  XSTRNCAT(buf, "Jun ", 4); break;
03913         case 6:  XSTRNCAT(buf, "Jul ", 4); break;
03914         case 7:  XSTRNCAT(buf, "Aug ", 4); break;
03915         case 8:  XSTRNCAT(buf, "Sep ", 4); break;
03916         case 9:  XSTRNCAT(buf, "Oct ", 4); break;
03917         case 10: XSTRNCAT(buf, "Nov ", 4); break;
03918         case 11: XSTRNCAT(buf, "Dec ", 4); break;
03919         default:
03920             return 0;
03921 
03922     }
03923     idx = 4; /* use idx now for char buffer */
03924     buf[idx] = ' ';
03925 
03926     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
03927               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
03928 
03929     return 1;
03930 }
03931 #endif /* WOLFSSL_MYSQL_COMPATIBLE */
03932 
03933 int ExtractDate(const unsigned char* date, unsigned char format,
03934                                                   struct tm* certTime, int* idx)
03935 {
03936     XMEMSET(certTime, 0, sizeof(struct tm));
03937 
03938     if (format == ASN_UTC_TIME) {
03939         if (btoi(date[0]) >= 5)
03940             certTime->tm_year = 1900;
03941         else
03942             certTime->tm_year = 2000;
03943     }
03944     else  { /* format == GENERALIZED_TIME */
03945         certTime->tm_year += btoi(date[*idx]) * 1000; *idx = *idx + 1;
03946         certTime->tm_year += btoi(date[*idx]) * 100;  *idx = *idx + 1;
03947     }
03948 
03949     /* adjust tm_year, tm_mon */
03950     GetTime((int*)&certTime->tm_year, date, idx); certTime->tm_year -= 1900;
03951     GetTime((int*)&certTime->tm_mon,  date, idx); certTime->tm_mon  -= 1;
03952     GetTime((int*)&certTime->tm_mday, date, idx);
03953     GetTime((int*)&certTime->tm_hour, date, idx);
03954     GetTime((int*)&certTime->tm_min,  date, idx);
03955     GetTime((int*)&certTime->tm_sec,  date, idx);
03956 
03957     return 1;
03958 }
03959 
03960 
03961 /* like atoi but only use first byte */
03962 /* Make sure before and after dates are valid */
03963 int ValidateDate(const byte* date, byte format, int dateType)
03964 {
03965     time_t ltime;
03966     struct tm  certTime;
03967     struct tm* localTime;
03968     struct tm* tmpTime = NULL;
03969     int    i = 0;
03970     int    timeDiff = 0 ;
03971     int    diffHH = 0 ; int diffMM = 0 ;
03972     int    diffSign = 0 ;
03973 
03974 #if defined(NEED_TMP_TIME)
03975     struct tm tmpTimeStorage;
03976     tmpTime = &tmpTimeStorage;
03977 #else
03978     (void)tmpTime;
03979 #endif
03980 
03981     ltime = XTIME(0);
03982 
03983 #ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
03984     if (dateType == BEFORE) {
03985         WOLFSSL_MSG("Skewing local time for before date check");
03986         ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
03987     }
03988 #endif
03989 
03990 #ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
03991     if (dateType == AFTER) {
03992         WOLFSSL_MSG("Skewing local time for after date check");
03993         ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
03994     }
03995 #endif
03996 
03997     if (!ExtractDate(date, format, &certTime, &i)) {
03998         WOLFSSL_MSG("Error extracting the date");
03999         return 0;
04000     }
04001 
04002     if ((date[i] == '+') || (date[i] == '-')) {
04003         WOLFSSL_MSG("Using time differential, not Zulu") ;
04004         diffSign = date[i++] == '+' ? 1 : -1 ;
04005         GetTime(&diffHH, date, &i);
04006         GetTime(&diffMM, date, &i);
04007         timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
04008     } else if (date[i] != 'Z') {
04009         WOLFSSL_MSG("UTCtime, niether Zulu or time differential") ;
04010         return 0;
04011     }
04012 
04013     ltime -= (time_t)timeDiff ;
04014     localTime = XGMTIME(&ltime, tmpTime);
04015 
04016     if (localTime == NULL) {
04017         WOLFSSL_MSG("XGMTIME failed");
04018         return 0;
04019     }
04020 
04021     if (dateType == BEFORE) {
04022         if (DateLessThan(localTime, &certTime)) {
04023             WOLFSSL_MSG("Date BEFORE check failed");
04024             return 0;
04025         }
04026     }
04027     else {  /* dateType == AFTER */
04028         if (DateGreaterThan(localTime, &certTime)) {
04029             WOLFSSL_MSG("Date AFTER check failed");
04030             return 0;
04031         }
04032     }
04033 
04034     return 1;
04035 }
04036 #endif /* !NO_TIME_H && USE_WOLF_VALIDDATE */
04037 
04038 int wc_GetTime(void* timePtr, word32 timeSize)
04039 {
04040     time_t* ltime = (time_t*)timePtr;
04041 
04042     if (timePtr == NULL) {
04043         return BAD_FUNC_ARG;
04044     }
04045 
04046     if ((word32)sizeof(time_t) > timeSize) {
04047         return BUFFER_E;
04048     }
04049 
04050     *ltime = XTIME(0);
04051 
04052     return 0;
04053 }
04054 
04055 #endif /* !NO_ASN_TIME */
04056 
04057 static int GetDate(DecodedCert* cert, int dateType)
04058 {
04059     int    length;
04060     byte   date[MAX_DATE_SIZE];
04061     byte   b;
04062     word32 startIdx = 0;
04063 
04064     XMEMSET(date, 0, MAX_DATE_SIZE);
04065 
04066     if (dateType == BEFORE)
04067         cert->beforeDate = &cert->source[cert->srcIdx];
04068     else
04069         cert->afterDate = &cert->source[cert->srcIdx];
04070     startIdx = cert->srcIdx;
04071 
04072     b = cert->source[cert->srcIdx++];
04073     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
04074         return ASN_TIME_E;
04075 
04076     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
04077         return ASN_PARSE_E;
04078 
04079     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
04080         return ASN_DATE_SZ_E;
04081 
04082     XMEMCPY(date, &cert->source[cert->srcIdx], length);
04083     cert->srcIdx += length;
04084 
04085     if (dateType == BEFORE)
04086         cert->beforeDateLen = cert->srcIdx - startIdx;
04087     else
04088         cert->afterDateLen  = cert->srcIdx - startIdx;
04089 
04090 #ifndef NO_ASN_TIME
04091     if (!XVALIDATE_DATE(date, b, dateType)) {
04092         if (dateType == BEFORE)
04093             return ASN_BEFORE_DATE_E;
04094         else
04095             return ASN_AFTER_DATE_E;
04096     }
04097 #endif
04098 
04099     return 0;
04100 }
04101 
04102 static int GetValidity(DecodedCert* cert, int verify)
04103 {
04104     int length;
04105     int badDate = 0;
04106 
04107     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
04108         return ASN_PARSE_E;
04109 
04110     if (GetDate(cert, BEFORE) < 0 && verify)
04111         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
04112 
04113     if (GetDate(cert, AFTER) < 0 && verify)
04114         return ASN_AFTER_DATE_E;
04115 
04116     if (badDate != 0)
04117         return badDate;
04118 
04119     return 0;
04120 }
04121 
04122 
04123 int DecodeToKey(DecodedCert* cert, int verify)
04124 {
04125     int badDate = 0;
04126     int ret;
04127 
04128     if ( (ret = GetCertHeader(cert)) < 0)
04129         return ret;
04130 
04131     WOLFSSL_MSG("Got Cert Header");
04132 
04133     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
04134                           oidSigType, cert->maxIdx)) < 0)
04135         return ret;
04136 
04137     WOLFSSL_MSG("Got Algo ID");
04138 
04139     if ( (ret = GetName(cert, ISSUER)) < 0)
04140         return ret;
04141 
04142     if ( (ret = GetValidity(cert, verify)) < 0)
04143         badDate = ret;
04144 
04145     if ( (ret = GetName(cert, SUBJECT)) < 0)
04146         return ret;
04147 
04148     WOLFSSL_MSG("Got Subject Name");
04149 
04150     if ( (ret = GetKey(cert)) < 0)
04151         return ret;
04152 
04153     WOLFSSL_MSG("Got Key");
04154 
04155     if (badDate != 0)
04156         return badDate;
04157 
04158     return ret;
04159 }
04160 
04161 static int GetSignature(DecodedCert* cert)
04162 {
04163     int length;
04164     int ret;
04165     ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
04166                          NULL);
04167     if (ret != 0)
04168         return ret;
04169 
04170     cert->sigLength = length;
04171     cert->signature = &cert->source[cert->srcIdx];
04172     cert->srcIdx += cert->sigLength;
04173 
04174     return 0;
04175 }
04176 
04177 static word32 SetOctetString8Bit(word32 len, byte* output)
04178 {
04179     output[0] = ASN_OCTET_STRING;
04180     output[1] = (byte)len;
04181     return 2;
04182 }
04183 
04184 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
04185 {
04186     word32 idx = SetOctetString8Bit(digSz, output);
04187     XMEMCPY(&output[idx], digest, digSz);
04188 
04189     return idx + digSz;
04190 }
04191 
04192 
04193 static word32 BytePrecision(word32 value)
04194 {
04195     word32 i;
04196     for (i = sizeof(value); i; --i)
04197         if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
04198             break;
04199 
04200     return i;
04201 }
04202 
04203 
04204 WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)
04205 {
04206     word32 i = 0, j;
04207 
04208     if (length < ASN_LONG_LENGTH)
04209         output[i++] = (byte)length;
04210     else {
04211         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
04212 
04213         for (j = BytePrecision(length); j; --j) {
04214             output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
04215             i++;
04216         }
04217     }
04218 
04219     return i;
04220 }
04221 
04222 
04223 WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)
04224 {
04225     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
04226     return SetLength(len, output + 1) + 1;
04227 }
04228 
04229 WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)
04230 {
04231     output[0] = ASN_OCTET_STRING;
04232     return SetLength(len, output + 1) + 1;
04233 }
04234 
04235 /* Write a set header to output */
04236 WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)
04237 {
04238     output[0] = ASN_SET | ASN_CONSTRUCTED;
04239     return SetLength(len, output + 1) + 1;
04240 }
04241 
04242 WOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
04243 {
04244 
04245     output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
04246                     | ASN_CONTEXT_SPECIFIC | number;
04247     return SetLength(len, output + 1) + 1;
04248 }
04249 
04250 WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
04251 {
04252     output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
04253     return SetLength(len, output + 1) + 1;
04254 }
04255 
04256 
04257 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
04258 
04259 static int SetCurve(ecc_key* key, byte* output)
04260 {
04261 #ifdef HAVE_OID_ENCODING
04262     int ret;
04263 #endif
04264     int idx = 0;
04265     word32 oidSz = 0;
04266 
04267     /* validate key */
04268     if (key == NULL || key->dp == NULL) {
04269         return BAD_FUNC_ARG;
04270     }
04271 
04272 #ifdef HAVE_OID_ENCODING
04273     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
04274     if (ret != 0) {
04275         return ret;
04276     }
04277 #else
04278     oidSz = key->dp->oidSz;
04279 #endif
04280 
04281     idx += SetObjectId(oidSz, output);
04282 
04283 #ifdef HAVE_OID_ENCODING
04284     ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
04285     if (ret != 0) {
04286         return ret;
04287     }
04288 #else
04289     XMEMCPY(output+idx, key->dp->oid, oidSz);
04290 #endif
04291     idx += oidSz;
04292 
04293     return idx;
04294 }
04295 
04296 #endif /* HAVE_ECC && WOLFSSL_CERT_GEN */
04297 
04298 
04299 static INLINE int IsSigAlgoECDSA(int algoOID)
04300 {
04301     /* ECDSA sigAlgo must not have ASN1 NULL parameters */
04302     if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
04303         algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
04304         return 1;
04305     }
04306 
04307     return 0;
04308 }
04309 
04310 WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
04311 {
04312     word32 tagSz, idSz, seqSz, algoSz = 0;
04313     const  byte* algoName = 0;
04314     byte   ID_Length[1 + MAX_LENGTH_SZ];
04315     byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
04316 
04317     tagSz = (type == oidHashType ||
04318              (type == oidSigType && !IsSigAlgoECDSA(algoOID)) ||
04319              (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
04320 
04321     algoName = OidFromId(algoOID, type, &algoSz);
04322 
04323     if (algoName == NULL) {
04324         WOLFSSL_MSG("Unknown Algorithm");
04325         return 0;
04326     }
04327 
04328     idSz  = SetObjectId(algoSz, ID_Length);
04329     seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
04330 
04331     XMEMCPY(output, seqArray, seqSz);
04332     XMEMCPY(output + seqSz, ID_Length, idSz);
04333     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
04334     if (tagSz == 2)
04335         SetASNNull(&output[seqSz + idSz + algoSz]);
04336 
04337     return seqSz + idSz + algoSz + tagSz;
04338 
04339 }
04340 
04341 
04342 word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
04343                           int hashOID)
04344 {
04345     byte digArray[MAX_ENCODED_DIG_SZ];
04346     byte algoArray[MAX_ALGO_SZ];
04347     byte seqArray[MAX_SEQ_SZ];
04348     word32 encDigSz, algoSz, seqSz;
04349 
04350     encDigSz = SetDigest(digest, digSz, digArray);
04351     algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
04352     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
04353 
04354     XMEMCPY(out, seqArray, seqSz);
04355     XMEMCPY(out + seqSz, algoArray, algoSz);
04356     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
04357 
04358     return encDigSz + algoSz + seqSz;
04359 }
04360 
04361 
04362 int wc_GetCTC_HashOID(int type)
04363 {
04364     switch (type) {
04365 #ifdef WOLFSSL_MD2
04366         case MD2:
04367             return MD2h;
04368 #endif
04369 #ifndef NO_MD5
04370         case MD5:
04371             return MD5h;
04372 #endif
04373 #ifndef NO_SHA
04374         case SHA:
04375             return SHAh;
04376 #endif
04377 #ifdef WOLFSSL_SHA224
04378         case SHA224:
04379             return SHA224h;
04380 #endif
04381 #ifndef NO_SHA256
04382         case SHA256:
04383             return SHA256h;
04384 #endif
04385 #ifdef WOLFSSL_SHA384
04386         case SHA384:
04387             return SHA384h;
04388 #endif
04389 #ifdef WOLFSSL_SHA512
04390         case SHA512:
04391             return SHA512h;
04392 #endif
04393         default:
04394             return 0;
04395     };
04396 }
04397 
04398 void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
04399 {
04400     if (sigCtx) {
04401         XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
04402         sigCtx->devId = devId;
04403         sigCtx->heap = heap;
04404     }
04405 }
04406 
04407 void FreeSignatureCtx(SignatureCtx* sigCtx)
04408 {
04409     if (sigCtx == NULL)
04410         return;
04411 
04412     if (sigCtx->digest) {
04413         XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
04414         sigCtx->digest = NULL;
04415     }
04416 #ifndef NO_RSA
04417     if (sigCtx->plain) {
04418         XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
04419         sigCtx->plain = NULL;
04420     }
04421 #endif
04422     if (sigCtx->key.ptr) {
04423         switch (sigCtx->keyOID) {
04424         #ifndef NO_RSA
04425             case RSAk:
04426                 wc_FreeRsaKey(sigCtx->key.rsa);
04427                 XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);
04428                 break;
04429         #endif /* !NO_RSA */
04430         #ifdef HAVE_ECC
04431             case ECDSAk:
04432                 wc_ecc_free(sigCtx->key.ecc);
04433                 XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
04434                 break;
04435         #endif /* HAVE_ECC */
04436             default:
04437                 break;
04438         } /* switch (keyOID) */
04439         sigCtx->key.ptr = NULL;
04440     }
04441 
04442     /* reset state, we are done */
04443     sigCtx->state = SIG_STATE_BEGIN;
04444 }
04445 
04446 /* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
04447 static int ConfirmSignature(SignatureCtx* sigCtx,
04448     const byte* buf, word32 bufSz,
04449     const byte* key, word32 keySz, word32 keyOID,
04450     const byte* sig, word32 sigSz, word32 sigOID)
04451 {
04452     int ret = 0;
04453 
04454     if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
04455         keySz == 0 || sig == NULL || sigSz == 0) {
04456         return BAD_FUNC_ARG;
04457     }
04458 
04459     (void)key;
04460     (void)keySz;
04461     (void)sig;
04462     (void)sigSz;
04463 
04464     WOLFSSL_ENTER("ConfirmSignature");
04465 
04466     switch (sigCtx->state) {
04467         case SIG_STATE_BEGIN:
04468         {
04469             sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
04470                                                     DYNAMIC_TYPE_TMP_BUFFER);
04471             if (sigCtx->digest == NULL) {
04472                 ERROR_OUT(MEMORY_E, exit_cs);
04473             }
04474 
04475             /* fall through */
04476             sigCtx->state = SIG_STATE_HASH;
04477         } /* SIG_STATE_BEGIN */
04478 
04479         case SIG_STATE_HASH:
04480         {
04481             switch (sigOID) {
04482             #ifndef NO_MD5
04483                 case CTC_MD5wRSA:
04484                 if ((ret = wc_Md5Hash(buf, bufSz, sigCtx->digest)) == 0) {
04485                     sigCtx->typeH    = MD5h;
04486                     sigCtx->digestSz = MD5_DIGEST_SIZE;
04487                 }
04488                 break;
04489             #endif
04490             #if defined(WOLFSSL_MD2)
04491                 case CTC_MD2wRSA:
04492                 if ((ret = wc_Md2Hash(buf, bufSz, sigCtx->digest)) == 0) {
04493                     sigCtx->typeH    = MD2h;
04494                     sigCtx->digestSz = MD2_DIGEST_SIZE;
04495                 }
04496                 break;
04497             #endif
04498             #ifndef NO_SHA
04499                 case CTC_SHAwRSA:
04500                 case CTC_SHAwDSA:
04501                 case CTC_SHAwECDSA:
04502                 if ((ret = wc_ShaHash(buf, bufSz, sigCtx->digest)) == 0) {
04503                     sigCtx->typeH    = SHAh;
04504                     sigCtx->digestSz = SHA_DIGEST_SIZE;
04505                 }
04506                 break;
04507             #endif
04508             #ifdef WOLFSSL_SHA224
04509                 case CTC_SHA224wRSA:
04510                 case CTC_SHA224wECDSA:
04511                 if ((ret = wc_Sha224Hash(buf, bufSz, sigCtx->digest)) == 0) {
04512                     sigCtx->typeH    = SHA224h;
04513                     sigCtx->digestSz = SHA224_DIGEST_SIZE;
04514                 }
04515                 break;
04516             #endif
04517             #ifndef NO_SHA256
04518                 case CTC_SHA256wRSA:
04519                 case CTC_SHA256wECDSA:
04520                 if ((ret = wc_Sha256Hash(buf, bufSz, sigCtx->digest)) == 0) {
04521                     sigCtx->typeH    = SHA256h;
04522                     sigCtx->digestSz = SHA256_DIGEST_SIZE;
04523                 }
04524                 break;
04525             #endif
04526             #ifdef WOLFSSL_SHA512
04527                 case CTC_SHA512wRSA:
04528                 case CTC_SHA512wECDSA:
04529                 if ((ret = wc_Sha512Hash(buf, bufSz, sigCtx->digest)) == 0) {
04530                     sigCtx->typeH    = SHA512h;
04531                     sigCtx->digestSz = SHA512_DIGEST_SIZE;
04532                 }
04533                 break;
04534             #endif
04535             #ifdef WOLFSSL_SHA384
04536                 case CTC_SHA384wRSA:
04537                 case CTC_SHA384wECDSA:
04538                 if ((ret = wc_Sha384Hash(buf, bufSz, sigCtx->digest)) == 0) {
04539                     sigCtx->typeH    = SHA384h;
04540                     sigCtx->digestSz = SHA384_DIGEST_SIZE;
04541                 }
04542                 break;
04543             #endif
04544                 default:
04545                     ret = HASH_TYPE_E;
04546                     WOLFSSL_MSG("Verify Signature has unsupported type");
04547             }
04548 
04549             if (ret != 0) {
04550                 goto exit_cs;
04551             }
04552 
04553             /* fall through */
04554             sigCtx->state = SIG_STATE_KEY;
04555         } /* SIG_STATE_HASH */
04556 
04557         case SIG_STATE_KEY:
04558         {
04559             sigCtx->keyOID = keyOID;
04560 
04561             switch (keyOID) {
04562             #ifndef NO_RSA
04563                 case RSAk:
04564                 {
04565                     word32 idx = 0;
04566 
04567                     sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
04568                                                 sigCtx->heap, DYNAMIC_TYPE_RSA);
04569                     sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
04570                                          sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
04571                     if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) {
04572                         ERROR_OUT(MEMORY_E, exit_cs);
04573                     }
04574 
04575                     if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
04576                                                         sigCtx->devId)) != 0) {
04577                         goto exit_cs;
04578                     }
04579 
04580                     if (sigSz > MAX_ENCODED_SIG_SZ) {
04581                         WOLFSSL_MSG("Verify Signature is too big");
04582                         ERROR_OUT(BUFFER_E, exit_cs);
04583                     }
04584 
04585                     if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
04586                                                                  keySz)) != 0) {
04587                         WOLFSSL_MSG("ASN Key decode error RSA");
04588                         goto exit_cs;
04589                     }
04590 
04591                     XMEMCPY(sigCtx->plain, sig, sigSz);
04592                     sigCtx->out = NULL;
04593                     break;
04594                 }
04595             #endif /* !NO_RSA */
04596             #ifdef HAVE_ECC
04597                 case ECDSAk:
04598                 {
04599                     sigCtx->verify = 0;
04600                     sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
04601                                                 sigCtx->heap, DYNAMIC_TYPE_ECC);
04602                     if (sigCtx->key.ecc == NULL) {
04603                         ERROR_OUT(MEMORY_E, exit_cs);
04604                     }
04605 
04606                     if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
04607                                                           sigCtx->devId)) < 0) {
04608                         goto exit_cs;
04609                     }
04610                     if ((ret = wc_ecc_import_x963(key, keySz,
04611                                                         sigCtx->key.ecc)) < 0) {
04612                         WOLFSSL_MSG("ASN Key import error ECC");
04613                         goto exit_cs;
04614                     }
04615                     break;
04616                 }
04617             #endif /* HAVE_ECC */
04618                 default:
04619                     WOLFSSL_MSG("Verify Key type unknown");
04620                     ret = ASN_UNKNOWN_OID_E;
04621                     break;
04622             } /* switch (keyOID) */
04623 
04624             if (ret != 0) {
04625                 goto exit_cs;
04626             }
04627 
04628             /* fall through */
04629             sigCtx->state = SIG_STATE_DO;
04630         } /* SIG_STATE_KEY */
04631 
04632         case SIG_STATE_DO:
04633         {
04634             switch (keyOID) {
04635             #ifndef NO_RSA
04636                 case RSAk:
04637                 {
04638                     ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
04639                                                 &sigCtx->out, sigCtx->key.rsa);
04640                 #ifdef WOLFSSL_ASYNC_CRYPT
04641                     if (ret == WC_PENDING_E)
04642                         sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
04643                 #endif
04644                     break;
04645                 }
04646             #endif /* !NO_RSA */
04647             #ifdef HAVE_ECC
04648                 case ECDSAk:
04649                 {
04650                     ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
04651                         sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
04652                 #ifdef WOLFSSL_ASYNC_CRYPT
04653                     if (ret == WC_PENDING_E)
04654                         sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
04655                 #endif
04656                     break;
04657                 }
04658             #endif /* HAVE_ECC */
04659                 default:
04660                     break;
04661             }  /* switch (keyOID) */
04662 
04663             if (ret < 0) {
04664                 /* treat all non async RSA errors as ASN_SIG_CONFIRM_E */
04665                 if (ret != WC_PENDING_E)
04666                     ret = ASN_SIG_CONFIRM_E;
04667                 goto exit_cs;
04668             }
04669 
04670             /* fall through */
04671             sigCtx->state = SIG_STATE_CHECK;
04672         } /* SIG_STATE_DO */
04673 
04674         case SIG_STATE_CHECK:
04675         {
04676             switch (keyOID) {
04677             #ifndef NO_RSA
04678                 case RSAk:
04679                 {
04680                     int encodedSigSz, verifySz;
04681                 #ifdef WOLFSSL_SMALL_STACK
04682                     byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
04683                                         sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
04684                     if (encodedSig == NULL) {
04685                         ERROR_OUT(MEMORY_E, exit_cs);
04686                     }
04687                 #else
04688                     byte encodedSig[MAX_ENCODED_SIG_SZ];
04689                 #endif
04690 
04691                     verifySz = ret;
04692 
04693                     /* make sure we're right justified */
04694                     encodedSigSz = wc_EncodeSignature(encodedSig,
04695                             sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
04696                     if (encodedSigSz == verifySz &&
04697                         XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
04698                         ret = 0;
04699                     }
04700                     else {
04701                         WOLFSSL_MSG("RSA SSL verify match encode error");
04702                         ret = ASN_SIG_CONFIRM_E;
04703                     }
04704 
04705                 #ifdef WOLFSSL_SMALL_STACK
04706                     XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
04707                 #endif
04708                     break;
04709                 }
04710             #endif /* NO_RSA */
04711             #ifdef HAVE_ECC
04712                 case ECDSAk:
04713                 {
04714                     if (sigCtx->verify == 1) {
04715                         ret = 0;
04716                     }
04717                     else {
04718                         WOLFSSL_MSG("ECC Verify didn't match");
04719                         ret = ASN_SIG_CONFIRM_E;
04720                     }
04721                     break;
04722                 }
04723             #endif /* HAVE_ECC */
04724                 default:
04725                     break;
04726             }  /* switch (keyOID) */
04727 
04728             break;
04729         } /* SIG_STATE_CHECK */
04730     } /* switch (sigCtx->state) */
04731 
04732 exit_cs:
04733 
04734     WOLFSSL_LEAVE("ConfirmSignature", ret);
04735 
04736     if (ret != WC_PENDING_E) {
04737         FreeSignatureCtx(sigCtx);
04738     }
04739 
04740     return ret;
04741 }
04742 
04743 
04744 #ifndef IGNORE_NAME_CONSTRAINTS
04745 
04746 static int MatchBaseName(int type, const char* name, int nameSz,
04747                          const char* base, int baseSz)
04748 {
04749     if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
04750             name[0] == '.' || nameSz < baseSz ||
04751             (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
04752         return 0;
04753 
04754     /* If an email type, handle special cases where the base is only
04755      * a domain, or is an email address itself. */
04756     if (type == ASN_RFC822_TYPE) {
04757         const char* p = NULL;
04758         int count = 0;
04759 
04760         if (base[0] != '.') {
04761             p = base;
04762             count = 0;
04763 
04764             /* find the '@' in the base */
04765             while (*p != '@' && count < baseSz) {
04766                 count++;
04767                 p++;
04768             }
04769 
04770             /* No '@' in base, reset p to NULL */
04771             if (count >= baseSz)
04772                 p = NULL;
04773         }
04774 
04775         if (p == NULL) {
04776             /* Base isn't an email address, it is a domain name,
04777              * wind the name forward one character past its '@'. */
04778             p = name;
04779             count = 0;
04780             while (*p != '@' && count < baseSz) {
04781                 count++;
04782                 p++;
04783             }
04784 
04785             if (count < baseSz && *p == '@') {
04786                 name = p + 1;
04787                 nameSz -= count + 1;
04788             }
04789         }
04790     }
04791 
04792     if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
04793         int szAdjust = nameSz - baseSz;
04794         name += szAdjust;
04795         nameSz -= szAdjust;
04796     }
04797 
04798     while (nameSz > 0) {
04799         if (XTOLOWER((unsigned char)*name++) !=
04800                                                XTOLOWER((unsigned char)*base++))
04801             return 0;
04802         nameSz--;
04803     }
04804 
04805     return 1;
04806 }
04807 
04808 
04809 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
04810 {
04811     if (signer == NULL || cert == NULL)
04812         return 0;
04813 
04814     /* Check against the excluded list */
04815     if (signer->excludedNames) {
04816         Base_entry* base = signer->excludedNames;
04817 
04818         while (base != NULL) {
04819             if (base->type == ASN_DNS_TYPE) {
04820                 DNS_entry* name = cert->altNames;
04821                 while (name != NULL) {
04822                     if (MatchBaseName(ASN_DNS_TYPE,
04823                                           name->name, (int)XSTRLEN(name->name),
04824                                           base->name, base->nameSz))
04825                         return 0;
04826                     name = name->next;
04827                 }
04828             }
04829             else if (base->type == ASN_RFC822_TYPE) {
04830                 DNS_entry* name = cert->altEmailNames;
04831                 while (name != NULL) {
04832                     if (MatchBaseName(ASN_RFC822_TYPE,
04833                                           name->name, (int)XSTRLEN(name->name),
04834                                           base->name, base->nameSz))
04835                         return 0;
04836 
04837                     name = name->next;
04838                 }
04839             }
04840             else if (base->type == ASN_DIR_TYPE) {
04841                 if (cert->subjectRawLen == base->nameSz &&
04842                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
04843 
04844                     return 0;
04845                 }
04846             }
04847             base = base->next;
04848         }
04849     }
04850 
04851     /* Check against the permitted list */
04852     if (signer->permittedNames != NULL) {
04853         int needDns = 0;
04854         int matchDns = 0;
04855         int needEmail = 0;
04856         int matchEmail = 0;
04857         int needDir = 0;
04858         int matchDir = 0;
04859         Base_entry* base = signer->permittedNames;
04860 
04861         while (base != NULL) {
04862             if (base->type == ASN_DNS_TYPE) {
04863                 DNS_entry* name = cert->altNames;
04864 
04865                 if (name != NULL)
04866                     needDns = 1;
04867 
04868                 while (name != NULL) {
04869                     matchDns = MatchBaseName(ASN_DNS_TYPE,
04870                                           name->name, (int)XSTRLEN(name->name),
04871                                           base->name, base->nameSz);
04872                     name = name->next;
04873                 }
04874             }
04875             else if (base->type == ASN_RFC822_TYPE) {
04876                 DNS_entry* name = cert->altEmailNames;
04877 
04878                 if (name != NULL)
04879                     needEmail = 1;
04880 
04881                 while (name != NULL) {
04882                     matchEmail = MatchBaseName(ASN_DNS_TYPE,
04883                                           name->name, (int)XSTRLEN(name->name),
04884                                           base->name, base->nameSz);
04885                     name = name->next;
04886                 }
04887             }
04888             else if (base->type == ASN_DIR_TYPE) {
04889                 needDir = 1;
04890                 if (cert->subjectRaw != NULL &&
04891                     cert->subjectRawLen == base->nameSz &&
04892                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
04893 
04894                     matchDir = 1;
04895                 }
04896             }
04897             base = base->next;
04898         }
04899 
04900         if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
04901             (needDir && !matchDir)) {
04902 
04903             return 0;
04904         }
04905     }
04906 
04907     return 1;
04908 }
04909 
04910 #endif /* IGNORE_NAME_CONSTRAINTS */
04911 
04912 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
04913 {
04914     word32 idx = 0;
04915     int length = 0;
04916 
04917     WOLFSSL_ENTER("DecodeAltNames");
04918 
04919     if (GetSequence(input, &idx, &length, sz) < 0) {
04920         WOLFSSL_MSG("\tBad Sequence");
04921         return ASN_PARSE_E;
04922     }
04923 
04924     cert->weOwnAltNames = 1;
04925 
04926     while (length > 0) {
04927         byte b = input[idx++];
04928 
04929         length--;
04930 
04931         /* Save DNS Type names in the altNames list. */
04932         /* Save Other Type names in the cert's OidMap */
04933         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
04934             DNS_entry* dnsEntry;
04935             int strLen;
04936             word32 lenStartIdx = idx;
04937 
04938             if (GetLength(input, &idx, &strLen, sz) < 0) {
04939                 WOLFSSL_MSG("\tfail: str length");
04940                 return ASN_PARSE_E;
04941             }
04942             length -= (idx - lenStartIdx);
04943 
04944             dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
04945                                         DYNAMIC_TYPE_ALTNAME);
04946             if (dnsEntry == NULL) {
04947                 WOLFSSL_MSG("\tOut of Memory");
04948                 return MEMORY_E;
04949             }
04950 
04951             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
04952                                          DYNAMIC_TYPE_ALTNAME);
04953             if (dnsEntry->name == NULL) {
04954                 WOLFSSL_MSG("\tOut of Memory");
04955                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
04956                 return MEMORY_E;
04957             }
04958 
04959             XMEMCPY(dnsEntry->name, &input[idx], strLen);
04960             dnsEntry->name[strLen] = '\0';
04961 
04962             dnsEntry->next = cert->altNames;
04963             cert->altNames = dnsEntry;
04964 
04965             length -= strLen;
04966             idx    += strLen;
04967         }
04968     #ifndef IGNORE_NAME_CONSTRAINTS
04969         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
04970             DNS_entry* emailEntry;
04971             int strLen;
04972             word32 lenStartIdx = idx;
04973 
04974             if (GetLength(input, &idx, &strLen, sz) < 0) {
04975                 WOLFSSL_MSG("\tfail: str length");
04976                 return ASN_PARSE_E;
04977             }
04978             length -= (idx - lenStartIdx);
04979 
04980             emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
04981                                         DYNAMIC_TYPE_ALTNAME);
04982             if (emailEntry == NULL) {
04983                 WOLFSSL_MSG("\tOut of Memory");
04984                 return MEMORY_E;
04985             }
04986 
04987             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
04988                                          DYNAMIC_TYPE_ALTNAME);
04989             if (emailEntry->name == NULL) {
04990                 WOLFSSL_MSG("\tOut of Memory");
04991                 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
04992                 return MEMORY_E;
04993             }
04994 
04995             XMEMCPY(emailEntry->name, &input[idx], strLen);
04996             emailEntry->name[strLen] = '\0';
04997 
04998             emailEntry->next = cert->altEmailNames;
04999             cert->altEmailNames = emailEntry;
05000 
05001             length -= strLen;
05002             idx    += strLen;
05003         }
05004     #endif /* IGNORE_NAME_CONSTRAINTS */
05005     #ifdef WOLFSSL_SEP
05006         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
05007         {
05008             int strLen;
05009             word32 lenStartIdx = idx;
05010             word32 oid = 0;
05011             int    ret;
05012 
05013             if (GetLength(input, &idx, &strLen, sz) < 0) {
05014                 WOLFSSL_MSG("\tfail: other name length");
05015                 return ASN_PARSE_E;
05016             }
05017             /* Consume the rest of this sequence. */
05018             length -= (strLen + idx - lenStartIdx);
05019 
05020             if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
05021                 WOLFSSL_MSG("\tbad OID");
05022                 return ASN_PARSE_E;
05023             }
05024 
05025             if (oid != HW_NAME_OID) {
05026                 WOLFSSL_MSG("\tincorrect OID");
05027                 return ASN_PARSE_E;
05028             }
05029 
05030             if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
05031                 WOLFSSL_MSG("\twrong type");
05032                 return ASN_PARSE_E;
05033             }
05034 
05035             if (GetLength(input, &idx, &strLen, sz) < 0) {
05036                 WOLFSSL_MSG("\tfail: str len");
05037                 return ASN_PARSE_E;
05038             }
05039 
05040             if (GetSequence(input, &idx, &strLen, sz) < 0) {
05041                 WOLFSSL_MSG("\tBad Sequence");
05042                 return ASN_PARSE_E;
05043             }
05044 
05045             ret = GetASNObjectId(input, &idx, &strLen, sz);
05046             if (ret != 0) {
05047                 WOLFSSL_MSG("\tbad OID");
05048                 return ret;
05049             }
05050 
05051             cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
05052                                           DYNAMIC_TYPE_X509_EXT);
05053             if (cert->hwType == NULL) {
05054                 WOLFSSL_MSG("\tOut of Memory");
05055                 return MEMORY_E;
05056             }
05057 
05058             XMEMCPY(cert->hwType, &input[idx], strLen);
05059             cert->hwTypeSz = strLen;
05060             idx += strLen;
05061 
05062             ret = GetOctetString(input, &idx, &strLen, sz);
05063             if (ret < 0)
05064                 return ret;
05065 
05066             cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
05067                                                DYNAMIC_TYPE_X509_EXT);
05068             if (cert->hwSerialNum == NULL) {
05069                 WOLFSSL_MSG("\tOut of Memory");
05070                 return MEMORY_E;
05071             }
05072 
05073             XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
05074             cert->hwSerialNum[strLen] = '\0';
05075             cert->hwSerialNumSz = strLen;
05076             idx += strLen;
05077         }
05078     #endif /* WOLFSSL_SEP */
05079         else {
05080             int strLen;
05081             word32 lenStartIdx = idx;
05082 
05083             WOLFSSL_MSG("\tUnsupported name type, skipping");
05084 
05085             if (GetLength(input, &idx, &strLen, sz) < 0) {
05086                 WOLFSSL_MSG("\tfail: unsupported name length");
05087                 return ASN_PARSE_E;
05088             }
05089             length -= (strLen + idx - lenStartIdx);
05090             idx += strLen;
05091         }
05092     }
05093     return 0;
05094 }
05095 
05096 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
05097 {
05098     word32 idx = 0;
05099     int length = 0;
05100     int ret;
05101 
05102     WOLFSSL_ENTER("DecodeBasicCaConstraint");
05103 
05104     if (GetSequence(input, &idx, &length, sz) < 0) {
05105         WOLFSSL_MSG("\tfail: bad SEQUENCE");
05106         return ASN_PARSE_E;
05107     }
05108 
05109     if (length == 0)
05110         return 0;
05111 
05112     /* If the basic ca constraint is false, this extension may be named, but
05113      * left empty. So, if the length is 0, just return. */
05114 
05115     ret = GetBoolean(input, &idx, sz);
05116     if (ret < 0) {
05117         WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN");
05118         return ret;
05119     }
05120 
05121     cert->isCA = (byte)ret;
05122 
05123     /* If there isn't any more data, return. */
05124     if (idx >= (word32)sz)
05125         return 0;
05126 
05127     ret = GetInteger7Bit(input, &idx, sz);
05128     if (ret < 0)
05129         return ret;
05130 
05131     cert->pathLength = (byte)ret;
05132     cert->pathLengthSet = 1;
05133 
05134     return 0;
05135 }
05136 
05137 
05138 #define CRLDP_FULL_NAME 0
05139     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
05140 #define GENERALNAME_URI 6
05141     /* From RFC3280 SS4.2.1.7, GeneralName */
05142 
05143 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
05144 {
05145     word32 idx = 0;
05146     int length = 0;
05147 
05148     WOLFSSL_ENTER("DecodeCrlDist");
05149 
05150     /* Unwrap the list of Distribution Points*/
05151     if (GetSequence(input, &idx, &length, sz) < 0)
05152         return ASN_PARSE_E;
05153 
05154     /* Unwrap a single Distribution Point */
05155     if (GetSequence(input, &idx, &length, sz) < 0)
05156         return ASN_PARSE_E;
05157 
05158     /* The Distribution Point has three explicit optional members
05159      *  First check for a DistributionPointName
05160      */
05161     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
05162     {
05163         idx++;
05164         if (GetLength(input, &idx, &length, sz) < 0)
05165             return ASN_PARSE_E;
05166 
05167         if (input[idx] ==
05168                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
05169         {
05170             idx++;
05171             if (GetLength(input, &idx, &length, sz) < 0)
05172                 return ASN_PARSE_E;
05173 
05174             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
05175             {
05176                 idx++;
05177                 if (GetLength(input, &idx, &length, sz) < 0)
05178                     return ASN_PARSE_E;
05179 
05180                 cert->extCrlInfoSz = length;
05181                 cert->extCrlInfo = input + idx;
05182                 idx += length;
05183             }
05184             else
05185                 /* This isn't a URI, skip it. */
05186                 idx += length;
05187         }
05188         else {
05189             /* This isn't a FULLNAME, skip it. */
05190             idx += length;
05191         }
05192     }
05193 
05194     /* Check for reasonFlags */
05195     if (idx < (word32)sz &&
05196         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
05197     {
05198         idx++;
05199         if (GetLength(input, &idx, &length, sz) < 0)
05200             return ASN_PARSE_E;
05201         idx += length;
05202     }
05203 
05204     /* Check for cRLIssuer */
05205     if (idx < (word32)sz &&
05206         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
05207     {
05208         idx++;
05209         if (GetLength(input, &idx, &length, sz) < 0)
05210             return ASN_PARSE_E;
05211         idx += length;
05212     }
05213 
05214     if (idx < (word32)sz)
05215     {
05216         WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
05217                    "but we only use the first one.");
05218     }
05219 
05220     return 0;
05221 }
05222 
05223 
05224 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
05225 /*
05226  *  Read the first of the Authority Information Access records. If there are
05227  *  any issues, return without saving the record.
05228  */
05229 {
05230     word32 idx = 0;
05231     int length = 0;
05232     byte b;
05233     word32 oid;
05234 
05235     WOLFSSL_ENTER("DecodeAuthInfo");
05236 
05237     /* Unwrap the list of AIAs */
05238     if (GetSequence(input, &idx, &length, sz) < 0)
05239         return ASN_PARSE_E;
05240 
05241     while (idx < (word32)sz) {
05242         /* Unwrap a single AIA */
05243         if (GetSequence(input, &idx, &length, sz) < 0)
05244             return ASN_PARSE_E;
05245 
05246         oid = 0;
05247         if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
05248             return ASN_PARSE_E;
05249 
05250 
05251         /* Only supporting URIs right now. */
05252         b = input[idx++];
05253         if (GetLength(input, &idx, &length, sz) < 0)
05254             return ASN_PARSE_E;
05255 
05256         if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
05257             oid == AIA_OCSP_OID)
05258         {
05259             cert->extAuthInfoSz = length;
05260             cert->extAuthInfo = input + idx;
05261             break;
05262         }
05263         idx += length;
05264     }
05265 
05266     return 0;
05267 }
05268 
05269 
05270 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
05271 {
05272     word32 idx = 0;
05273     int length = 0, ret = 0;
05274 
05275     WOLFSSL_ENTER("DecodeAuthKeyId");
05276 
05277     if (GetSequence(input, &idx, &length, sz) < 0) {
05278         WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
05279         return ASN_PARSE_E;
05280     }
05281 
05282     if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
05283         WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
05284         return 0;
05285     }
05286 
05287     if (GetLength(input, &idx, &length, sz) <= 0) {
05288         WOLFSSL_MSG("\tfail: extension data length");
05289         return ASN_PARSE_E;
05290     }
05291 
05292 #ifdef OPENSSL_EXTRA
05293     cert->extAuthKeyIdSrc = &input[idx];
05294     cert->extAuthKeyIdSz = length;
05295 #endif /* OPENSSL_EXTRA */
05296 
05297     if (length == KEYID_SIZE) {
05298         XMEMCPY(cert->extAuthKeyId, input + idx, length);
05299     }
05300     else {
05301     #ifdef NO_SHA
05302         ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
05303     #else
05304         ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
05305     #endif
05306     }
05307 
05308     return ret;
05309 }
05310 
05311 
05312 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
05313 {
05314     word32 idx = 0;
05315     int length = 0, ret = 0;
05316 
05317     WOLFSSL_ENTER("DecodeSubjKeyId");
05318 
05319     if (sz <= 0)
05320         return ASN_PARSE_E;
05321 
05322     ret = GetOctetString(input, &idx, &length, sz);
05323     if (ret < 0)
05324         return ret;
05325 
05326     #ifdef OPENSSL_EXTRA
05327         cert->extSubjKeyIdSrc = &input[idx];
05328         cert->extSubjKeyIdSz = length;
05329     #endif /* OPENSSL_EXTRA */
05330 
05331     if (length == SIGNER_DIGEST_SIZE) {
05332         XMEMCPY(cert->extSubjKeyId, input + idx, length);
05333     }
05334     else {
05335     #ifdef NO_SHA
05336         ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
05337     #else
05338         ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
05339     #endif
05340     }
05341 
05342     return ret;
05343 }
05344 
05345 
05346 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
05347 {
05348     word32 idx = 0;
05349     int length;
05350     int ret;
05351     WOLFSSL_ENTER("DecodeKeyUsage");
05352 
05353     ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
05354     if (ret != 0)
05355         return ret;
05356 
05357     cert->extKeyUsage = (word16)(input[idx]);
05358     if (length == 2)
05359         cert->extKeyUsage |= (word16)(input[idx+1] << 8);
05360 
05361     return 0;
05362 }
05363 
05364 
05365 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
05366 {
05367     word32 idx = 0, oid;
05368     int length;
05369 
05370     WOLFSSL_ENTER("DecodeExtKeyUsage");
05371 
05372     if (GetSequence(input, &idx, &length, sz) < 0) {
05373         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
05374         return ASN_PARSE_E;
05375     }
05376 
05377 #ifdef OPENSSL_EXTRA
05378     cert->extExtKeyUsageSrc = input + idx;
05379     cert->extExtKeyUsageSz = length;
05380 #endif
05381 
05382     while (idx < (word32)sz) {
05383         if (GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz) < 0)
05384             return ASN_PARSE_E;
05385 
05386         switch (oid) {
05387             case EKU_ANY_OID:
05388                 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
05389                 break;
05390             case EKU_SERVER_AUTH_OID:
05391                 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
05392                 break;
05393             case EKU_CLIENT_AUTH_OID:
05394                 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
05395                 break;
05396             case EKU_OCSP_SIGN_OID:
05397                 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
05398                 break;
05399         }
05400 
05401     #ifdef OPENSSL_EXTRA
05402         cert->extExtKeyUsageCount++;
05403     #endif
05404     }
05405 
05406     return 0;
05407 }
05408 
05409 
05410 #ifndef IGNORE_NAME_CONSTRAINTS
05411 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
05412 {
05413     word32 idx = 0;
05414 
05415     (void)heap;
05416 
05417     while (idx < (word32)sz) {
05418         int seqLength, strLength;
05419         word32 nameIdx;
05420         byte b;
05421 
05422         if (GetSequence(input, &idx, &seqLength, sz) < 0) {
05423             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
05424             return ASN_PARSE_E;
05425         }
05426 
05427         nameIdx = idx;
05428         b = input[nameIdx++];
05429         if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
05430             WOLFSSL_MSG("\tinvalid length");
05431             return ASN_PARSE_E;
05432         }
05433 
05434         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
05435             b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
05436             b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
05437 
05438             Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
05439                                                     heap, DYNAMIC_TYPE_ALTNAME);
05440 
05441             if (entry == NULL) {
05442                 WOLFSSL_MSG("allocate error");
05443                 return MEMORY_E;
05444             }
05445 
05446             entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
05447             if (entry->name == NULL) {
05448                 WOLFSSL_MSG("allocate error");
05449                 XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
05450                 return MEMORY_E;
05451             }
05452 
05453             XMEMCPY(entry->name, &input[nameIdx], strLength);
05454             entry->nameSz = strLength;
05455             entry->type = b & 0x0F;
05456 
05457             entry->next = *head;
05458             *head = entry;
05459         }
05460 
05461         idx += seqLength;
05462     }
05463 
05464     return 0;
05465 }
05466 
05467 
05468 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
05469 {
05470     word32 idx = 0;
05471     int length = 0;
05472 
05473     WOLFSSL_ENTER("DecodeNameConstraints");
05474 
05475     if (GetSequence(input, &idx, &length, sz) < 0) {
05476         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
05477         return ASN_PARSE_E;
05478     }
05479 
05480     while (idx < (word32)sz) {
05481         byte b = input[idx++];
05482         Base_entry** subtree = NULL;
05483 
05484         if (GetLength(input, &idx, &length, sz) <= 0) {
05485             WOLFSSL_MSG("\tinvalid length");
05486             return ASN_PARSE_E;
05487         }
05488 
05489         if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
05490             subtree = &cert->permittedNames;
05491         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
05492             subtree = &cert->excludedNames;
05493         else {
05494             WOLFSSL_MSG("\tinvalid subtree");
05495             return ASN_PARSE_E;
05496         }
05497 
05498         DecodeSubtree(input + idx, length, subtree, cert->heap);
05499 
05500         idx += length;
05501     }
05502 
05503     return 0;
05504 }
05505 #endif /* IGNORE_NAME_CONSTRAINTS */
05506 
05507 
05508 #if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)
05509 
05510 static int Word32ToString(char* d, word32 number)
05511 {
05512     int i = 0;
05513 
05514     if (d != NULL) {
05515         word32 order = 1000000000;
05516         word32 digit;
05517 
05518         if (number == 0) {
05519             d[i++] = '0';
05520         }
05521         else {
05522             while (order) {
05523                 digit = number / order;
05524                 if (i > 0 || digit != 0) {
05525                     d[i++] = (char)digit + '0';
05526                 }
05527                 if (digit != 0)
05528                     number %= digit * order;
05529                 if (order > 1)
05530                     order /= 10;
05531                 else
05532                     order = 0;
05533             }
05534         }
05535         d[i] = 0;
05536     }
05537 
05538     return i;
05539 }
05540 
05541 
05542 /* Decode ITU-T X.690 OID format to a string representation
05543  * return string length */
05544 static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
05545 {
05546     word32 val, idx = 0, nb_bytes;
05547     size_t w_bytes = 0;
05548 
05549     if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
05550         return BAD_FUNC_ARG;
05551 
05552     /* first two byte must be interpreted as : 40 * int1 + int2 */
05553     val = (word16)in[idx++];
05554 
05555     w_bytes = Word32ToString(out, val / 40);
05556     out[w_bytes++] = '.';
05557     w_bytes += Word32ToString(out+w_bytes, val % 40);
05558 
05559     while (idx < inSz) {
05560         /* init value */
05561         val = 0;
05562         nb_bytes = 0;
05563 
05564         /* check that output size is ok */
05565         if (w_bytes > (outSz - 3))
05566             return BUFFER_E;
05567 
05568         /* first bit is used to set if value is coded on 1 or multiple bytes */
05569         while ((in[idx+nb_bytes] & 0x80))
05570             nb_bytes++;
05571 
05572         if (!nb_bytes)
05573             val = (word32)(in[idx++] & 0x7f);
05574         else {
05575             word32 base = 1, tmp = nb_bytes;
05576 
05577             while (tmp != 0) {
05578                 val += (word32)(in[idx+tmp] & 0x7f) * base;
05579                 base *= 128;
05580                 tmp--;
05581             }
05582             val += (word32)(in[idx++] & 0x7f) * base;
05583 
05584             idx += nb_bytes;
05585         }
05586 
05587         out[w_bytes++] = '.';
05588         w_bytes += Word32ToString(out+w_bytes, val);
05589     }
05590 
05591     return 0;
05592 }
05593 #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
05594 
05595 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
05596     /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
05597     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
05598     {
05599         word32 idx = 0;
05600         word32 oldIdx;
05601         int ret;
05602         int total_length = 0, policy_length = 0, length = 0;
05603     #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
05604         !defined(WOLFSSL_DUP_CERTPOL)
05605         int i;
05606     #endif
05607 
05608         WOLFSSL_ENTER("DecodeCertPolicy");
05609 
05610         if (GetSequence(input, &idx, &total_length, sz) < 0) {
05611             WOLFSSL_MSG("\tGet CertPolicy total seq failed");
05612             return ASN_PARSE_E;
05613         }
05614 
05615         /* Validate total length (2 is the CERT_POLICY_OID+SEQ) */
05616         if ((total_length + 2) != sz) {
05617             WOLFSSL_MSG("\tCertPolicy length mismatch");
05618             return ASN_PARSE_E;
05619         }
05620 
05621         /* Unwrap certificatePolicies */
05622         do {
05623             if (GetSequence(input, &idx, &policy_length, sz) < 0) {
05624                 WOLFSSL_MSG("\tGet CertPolicy seq failed");
05625                 return ASN_PARSE_E;
05626             }
05627 
05628             oldIdx = idx;
05629             ret = GetASNObjectId(input, &idx, &length, sz);
05630             if (ret != 0)
05631                 return ret;
05632             policy_length -= idx - oldIdx;
05633 
05634             if (length > 0) {
05635                 /* Verify length won't overrun buffer */
05636                 if (length > (sz - (int)idx)) {
05637                     WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
05638                     return ASN_PARSE_E;
05639                 }
05640 
05641     #if defined(WOLFSSL_SEP)
05642                 cert->deviceType = (byte*)XMALLOC(length, cert->heap,
05643                                                   DYNAMIC_TYPE_X509_EXT);
05644                 if (cert->deviceType == NULL) {
05645                     WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
05646                     return MEMORY_E;
05647                 }
05648                 cert->deviceTypeSz = length;
05649                 XMEMCPY(cert->deviceType, input + idx, length);
05650                 break;
05651     #elif defined(WOLFSSL_CERT_EXT)
05652                 /* decode cert policy */
05653                 if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
05654                                     input + idx, length) != 0) {
05655                     WOLFSSL_MSG("\tCouldn't decode CertPolicy");
05656                     return ASN_PARSE_E;
05657                 }
05658                 #ifndef WOLFSSL_DUP_CERTPOL
05659                 /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
05660                  * NOT appear more than once in a certificate policies
05661                  * extension". This is a sanity check for duplicates.
05662                  * extCertPolicies should only have OID values, additional
05663                  * qualifiers need to be stored in a seperate array. */
05664                 for (i = 0; i < cert->extCertPoliciesNb; i++) {
05665                     if (XMEMCMP(cert->extCertPolicies[i],
05666                             cert->extCertPolicies[cert->extCertPoliciesNb],
05667                             MAX_CERTPOL_SZ) == 0) {
05668                             WOLFSSL_MSG("Duplicate policy OIDs not allowed");
05669                             WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
05670                             return CERTPOLICIES_E;
05671                     }
05672                 }
05673                 #endif /* !defined(WOLFSSL_DUP_CERTPOL) */
05674                 cert->extCertPoliciesNb++;
05675     #else
05676                 WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
05677                 return 0;
05678     #endif
05679             }
05680             idx += policy_length;
05681         } while((int)idx < total_length
05682     #if defined(WOLFSSL_CERT_EXT)
05683             && cert->extCertPoliciesNb < MAX_CERTPOL_NB
05684     #endif
05685         );
05686 
05687         WOLFSSL_LEAVE("DecodeCertPolicy", 0);
05688         return 0;
05689     }
05690 #endif /* WOLFSSL_SEP */
05691 
05692 static int DecodeCertExtensions(DecodedCert* cert)
05693 /*
05694  *  Processing the Certificate Extensions. This does not modify the current
05695  *  index. It is works starting with the recorded extensions pointer.
05696  */
05697 {
05698     int ret;
05699     word32 idx = 0;
05700     int sz = cert->extensionsSz;
05701     byte* input = cert->extensions;
05702     int length;
05703     word32 oid;
05704     byte critical = 0;
05705     byte criticalFail = 0;
05706 
05707     WOLFSSL_ENTER("DecodeCertExtensions");
05708 
05709     if (input == NULL || sz == 0)
05710         return BAD_FUNC_ARG;
05711 
05712     if (input[idx++] != ASN_EXTENSIONS) {
05713         WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
05714         return ASN_PARSE_E;
05715     }
05716 
05717     if (GetLength(input, &idx, &length, sz) < 0) {
05718         WOLFSSL_MSG("\tfail: invalid length");
05719         return ASN_PARSE_E;
05720     }
05721 
05722     if (GetSequence(input, &idx, &length, sz) < 0) {
05723         WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
05724         return ASN_PARSE_E;
05725     }
05726 
05727     while (idx < (word32)sz) {
05728         if (GetSequence(input, &idx, &length, sz) < 0) {
05729             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
05730             return ASN_PARSE_E;
05731         }
05732 
05733         oid = 0;
05734         if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
05735             WOLFSSL_MSG("\tfail: OBJECT ID");
05736             return ret;
05737         }
05738 
05739         /* check for critical flag */
05740         critical = 0;
05741         if (input[idx] == ASN_BOOLEAN) {
05742             ret = GetBoolean(input, &idx, sz);
05743             if (ret < 0) {
05744                 WOLFSSL_MSG("\tfail: critical boolean");
05745                 return ret;
05746             }
05747 
05748             critical = (byte)ret;
05749         }
05750 
05751         /* process the extension based on the OID */
05752         ret = GetOctetString(input, &idx, &length, sz);
05753         if (ret < 0) {
05754             WOLFSSL_MSG("\tfail: bad OCTET STRING");
05755             return ret;
05756         }
05757 
05758         switch (oid) {
05759             case BASIC_CA_OID:
05760                 #ifdef OPENSSL_EXTRA
05761                     cert->extBasicConstSet = 1;
05762                     cert->extBasicConstCrit = critical;
05763                 #endif
05764                 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
05765                     return ASN_PARSE_E;
05766                 break;
05767 
05768             case CRL_DIST_OID:
05769                 #ifdef OPENSSL_EXTRA
05770                     cert->extCRLdistSet  = 1;
05771                     cert->extCRLdistCrit = critical;
05772                 #endif
05773                 if (DecodeCrlDist(&input[idx], length, cert) < 0)
05774                     return ASN_PARSE_E;
05775                 break;
05776 
05777             case AUTH_INFO_OID:
05778                 #ifdef OPENSSL_EXTRA
05779                     cert->extAuthInfoSet  = 1;
05780                     cert->extAuthInfoCrit = critical;
05781                 #endif
05782                 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
05783                     return ASN_PARSE_E;
05784                 break;
05785 
05786             case ALT_NAMES_OID:
05787                 #ifdef OPENSSL_EXTRA
05788                     cert->extSubjAltNameSet = 1;
05789                     cert->extSubjAltNameCrit = critical;
05790                 #endif
05791                 if (DecodeAltNames(&input[idx], length, cert) < 0)
05792                     return ASN_PARSE_E;
05793                 break;
05794 
05795             case AUTH_KEY_OID:
05796                 cert->extAuthKeyIdSet = 1;
05797                 #ifdef OPENSSL_EXTRA
05798                     cert->extAuthKeyIdCrit = critical;
05799                 #endif
05800                 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
05801                     return ASN_PARSE_E;
05802                 break;
05803 
05804             case SUBJ_KEY_OID:
05805                 cert->extSubjKeyIdSet = 1;
05806                 #ifdef OPENSSL_EXTRA
05807                     cert->extSubjKeyIdCrit = critical;
05808                 #endif
05809                 #ifndef WOLFSSL_ALLOW_CRIT_SKID
05810                     /* This check is added due to RFC 5280 section 4.2.1.2
05811                      * stating that conforming CA's must mark this extension
05812                      * as non-critical. When parsing extensions check that
05813                      * certificate was made in compliance with this. */
05814                     if (critical) {
05815                         WOLFSSL_MSG("Critical Subject Key ID is not allowed");
05816                         WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
05817                         return ASN_CRIT_EXT_E;
05818                     }
05819                 #endif
05820 
05821                 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
05822                     return ASN_PARSE_E;
05823                 break;
05824 
05825             case CERT_POLICY_OID:
05826                 #ifdef WOLFSSL_SEP
05827                     #ifdef OPENSSL_EXTRA
05828                         cert->extCertPolicySet = 1;
05829                         cert->extCertPolicyCrit = critical;
05830                     #endif
05831                 #endif
05832                 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
05833                     if (DecodeCertPolicy(&input[idx], length, cert) < 0) {
05834                         return ASN_PARSE_E;
05835                     }
05836                 #else
05837                     WOLFSSL_MSG("Certificate Policy extension not supported yet.");
05838                 #endif
05839                 break;
05840 
05841             case KEY_USAGE_OID:
05842                 cert->extKeyUsageSet = 1;
05843                 #ifdef OPENSSL_EXTRA
05844                     cert->extKeyUsageCrit = critical;
05845                 #endif
05846                 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
05847                     return ASN_PARSE_E;
05848                 break;
05849 
05850             case EXT_KEY_USAGE_OID:
05851                 cert->extExtKeyUsageSet = 1;
05852                 #ifdef OPENSSL_EXTRA
05853                     cert->extExtKeyUsageCrit = critical;
05854                 #endif
05855                 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
05856                     return ASN_PARSE_E;
05857                 break;
05858 
05859             #ifndef IGNORE_NAME_CONSTRAINTS
05860             case NAME_CONS_OID:
05861                 cert->extNameConstraintSet = 1;
05862                 #ifdef OPENSSL_EXTRA
05863                     cert->extNameConstraintCrit = critical;
05864                 #endif
05865                 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
05866                     return ASN_PARSE_E;
05867                 break;
05868             #endif /* IGNORE_NAME_CONSTRAINTS */
05869 
05870             case INHIBIT_ANY_OID:
05871                 WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
05872                 break;
05873 
05874             default:
05875                 /* While it is a failure to not support critical extensions,
05876                  * still parse the certificate ignoring the unsupported
05877                  * extension to allow caller to accept it with the verify
05878                  * callback. */
05879                 if (critical)
05880                     criticalFail = 1;
05881                 break;
05882         }
05883         idx += length;
05884     }
05885 
05886     return criticalFail ? ASN_CRIT_EXT_E : 0;
05887 }
05888 
05889 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
05890 {
05891     int   ret;
05892     char* ptr;
05893 
05894     ret = ParseCertRelative(cert, type, verify, cm);
05895     if (ret < 0)
05896         return ret;
05897 
05898     if (cert->subjectCNLen > 0) {
05899         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
05900                               DYNAMIC_TYPE_SUBJECT_CN);
05901         if (ptr == NULL)
05902             return MEMORY_E;
05903         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
05904         ptr[cert->subjectCNLen] = '\0';
05905         cert->subjectCN = ptr;
05906         cert->subjectCNStored = 1;
05907     }
05908 
05909     if (cert->keyOID == RSAk &&
05910                           cert->publicKey != NULL  && cert->pubKeySize > 0) {
05911         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
05912                               DYNAMIC_TYPE_PUBLIC_KEY);
05913         if (ptr == NULL)
05914             return MEMORY_E;
05915         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
05916         cert->publicKey = (byte *)ptr;
05917         cert->pubKeyStored = 1;
05918     }
05919 
05920     return ret;
05921 }
05922 
05923 /* from SSL proper, for locking can't do find here anymore */
05924 #ifdef __cplusplus
05925     extern "C" {
05926 #endif
05927     WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);
05928     #ifndef NO_SKID
05929         WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
05930     #endif
05931 #ifdef __cplusplus
05932     }
05933 #endif
05934 
05935 
05936 #if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS)
05937 
05938 /* dummy functions, not using wolfSSL so don't need actual ones */
05939 Signer* GetCA(void* signers, byte* hash)
05940 {
05941     (void)hash;
05942 
05943     return (Signer*)signers;
05944 }
05945 
05946 #ifndef NO_SKID
05947 Signer* GetCAByName(void* signers, byte* hash)
05948 {
05949     (void)hash;
05950 
05951     return (Signer*)signers;
05952 }
05953 #endif /* NO_SKID */
05954 
05955 #endif /* WOLFCRYPT_ONLY || NO_CERTS */
05956 
05957 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
05958 {
05959     int    ret = 0;
05960     int    badDate = 0;
05961     int    criticalExt = 0;
05962     word32 confirmOID;
05963 
05964     if (cert == NULL) {
05965         return BAD_FUNC_ARG;
05966     }
05967 
05968     if (cert->sigCtx.state == SIG_STATE_BEGIN) {
05969         if ((ret = DecodeToKey(cert, verify)) < 0) {
05970             if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
05971                 badDate = ret;
05972             else
05973                 return ret;
05974         }
05975 
05976         WOLFSSL_MSG("Parsed Past Key");
05977 
05978         if (cert->srcIdx < cert->sigIndex) {
05979         #ifndef ALLOW_V1_EXTENSIONS
05980             if (cert->version < 2) {
05981                 WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
05982                 return ASN_VERSION_E;
05983             }
05984         #endif
05985 
05986             /* save extensions */
05987             cert->extensions    = &cert->source[cert->srcIdx];
05988             cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
05989             cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
05990 
05991             if ((ret = DecodeCertExtensions(cert)) < 0) {
05992                 if (ret == ASN_CRIT_EXT_E)
05993                     criticalExt = ret;
05994                 else
05995                     return ret;
05996             }
05997 
05998             /* advance past extensions */
05999             cert->srcIdx = cert->sigIndex;
06000         }
06001 
06002         if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
06003                              oidSigType, cert->maxIdx)) < 0)
06004             return ret;
06005 
06006         if ((ret = GetSignature(cert)) < 0)
06007             return ret;
06008 
06009         if (confirmOID != cert->signatureOID)
06010             return ASN_SIG_OID_E;
06011 
06012     #ifndef NO_SKID
06013         if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
06014                                                         cert->pubKeySize > 0) {
06015         #ifdef NO_SHA
06016             ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
06017                                                             cert->extSubjKeyId);
06018         #else
06019             ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
06020                                                             cert->extSubjKeyId);
06021         #endif /* NO_SHA */
06022             if (ret != 0)
06023                 return ret;
06024         }
06025     #endif /* !NO_SKID */
06026 
06027         if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
06028             cert->ca = NULL;
06029         #ifndef NO_SKID
06030             if (cert->extAuthKeyIdSet)
06031                 cert->ca = GetCA(cm, cert->extAuthKeyId);
06032             if (cert->ca == NULL)
06033                 cert->ca = GetCAByName(cm, cert->issuerHash);
06034         #else
06035             cert->ca = GetCA(cm, cert->issuerHash);
06036         #endif /* !NO_SKID */
06037 
06038             WOLFSSL_MSG("About to verify certificate signature");
06039             if (cert->ca) {
06040                 if (cert->isCA) {
06041                     if (cert->ca->pathLengthSet) {
06042                         if (cert->ca->pathLength == 0) {
06043                             WOLFSSL_MSG("CA with path length 0 signing a CA");
06044                             return ASN_PATHLEN_INV_E;
06045                         }
06046                         if (cert->pathLengthSet &&
06047                             cert->pathLength >= cert->ca->pathLength) {
06048 
06049                             WOLFSSL_MSG("CA signing CA with longer path length");
06050                             return ASN_PATHLEN_INV_E;
06051                         }
06052                     }
06053                 }
06054 
06055         #ifdef HAVE_OCSP
06056                 /* Need the CA's public key hash for OCSP */
06057             #ifdef NO_SHA
06058                 ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
06059                                                             cert->issuerKeyHash);
06060             #else
06061                 ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
06062                                                             cert->issuerKeyHash);
06063             #endif /* NO_SHA */
06064                 if (ret != 0)
06065                     return ret;
06066         #endif /* HAVE_OCSP */
06067             }
06068         }
06069     }
06070 
06071     if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
06072         if (cert->ca) {
06073             if (verify == VERIFY) {
06074                 /* try to confirm/verify signature */
06075                 if ((ret = ConfirmSignature(&cert->sigCtx,
06076                         cert->source + cert->certBegin,
06077                         cert->sigIndex - cert->certBegin,
06078                         cert->ca->publicKey, cert->ca->pubKeySize,
06079                         cert->ca->keyOID, cert->signature,
06080                         cert->sigLength, cert->signatureOID)) != 0) {
06081                     if (ret != WC_PENDING_E) {
06082                         WOLFSSL_MSG("Confirm signature failed");
06083                     }
06084                     return ret;
06085                 }
06086             #ifndef IGNORE_NAME_CONSTRAINTS
06087                 /* check that this cert's name is permitted by the signer's
06088                  * name constraints */
06089                 if (!ConfirmNameConstraints(cert->ca, cert)) {
06090                     WOLFSSL_MSG("Confirm name constraint failed");
06091                     return ASN_NAME_INVALID_E;
06092                 }
06093             #endif /* IGNORE_NAME_CONSTRAINTS */
06094             }
06095         }
06096         else {
06097             /* no signer */
06098             WOLFSSL_MSG("No CA signer to verify with");
06099             return ASN_NO_SIGNER_E;
06100         }
06101     }
06102 
06103     if (badDate != 0)
06104         return badDate;
06105 
06106     if (criticalExt != 0)
06107         return criticalExt;
06108 
06109     return ret;
06110 }
06111 
06112 /* Create and init an new signer */
06113 Signer* MakeSigner(void* heap)
06114 {
06115     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
06116                                        DYNAMIC_TYPE_SIGNER);
06117     if (signer) {
06118         signer->pubKeySize = 0;
06119         signer->keyOID     = 0;
06120         signer->publicKey  = NULL;
06121         signer->nameLen    = 0;
06122         signer->name       = NULL;
06123         #ifndef IGNORE_NAME_CONSTRAINTS
06124             signer->permittedNames = NULL;
06125             signer->excludedNames = NULL;
06126         #endif /* IGNORE_NAME_CONSTRAINTS */
06127         signer->pathLengthSet = 0;
06128         signer->pathLength = 0;
06129         signer->next       = NULL;
06130     }
06131     (void)heap;
06132 
06133     return signer;
06134 }
06135 
06136 
06137 /* Free an individual signer */
06138 void FreeSigner(Signer* signer, void* heap)
06139 {
06140     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
06141     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
06142     #ifndef IGNORE_NAME_CONSTRAINTS
06143         if (signer->permittedNames)
06144             FreeNameSubtrees(signer->permittedNames, heap);
06145         if (signer->excludedNames)
06146             FreeNameSubtrees(signer->excludedNames, heap);
06147     #endif
06148     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
06149 
06150     (void)heap;
06151 }
06152 
06153 
06154 /* Free the whole singer table with number of rows */
06155 void FreeSignerTable(Signer** table, int rows, void* heap)
06156 {
06157     int i;
06158 
06159     for (i = 0; i < rows; i++) {
06160         Signer* signer = table[i];
06161         while (signer) {
06162             Signer* next = signer->next;
06163             FreeSigner(signer, heap);
06164             signer = next;
06165         }
06166         table[i] = NULL;
06167     }
06168 }
06169 
06170 #ifdef WOLFSSL_TRUST_PEER_CERT
06171 /* Free an individual trusted peer cert */
06172 void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
06173 {
06174     if (tp == NULL) {
06175         return;
06176     }
06177 
06178     if (tp->name) {
06179         XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
06180     }
06181 
06182     if (tp->sig) {
06183         XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
06184     }
06185     #ifndef IGNORE_NAME_CONSTRAINTS
06186         if (tp->permittedNames)
06187             FreeNameSubtrees(tp->permittedNames, heap);
06188         if (tp->excludedNames)
06189             FreeNameSubtrees(tp->excludedNames, heap);
06190     #endif
06191     XFREE(tp, heap, DYNAMIC_TYPE_CERT);
06192 
06193     (void)heap;
06194 }
06195 
06196 /* Free the whole Trusted Peer linked list */
06197 void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
06198 {
06199     int i;
06200 
06201     for (i = 0; i < rows; i++) {
06202         TrustedPeerCert* tp = table[i];
06203         while (tp) {
06204             TrustedPeerCert* next = tp->next;
06205             FreeTrustedPeer(tp, heap);
06206             tp = next;
06207         }
06208         table[i] = NULL;
06209     }
06210 }
06211 #endif /* WOLFSSL_TRUST_PEER_CERT */
06212 
06213 WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
06214 {
06215     int i = 0;
06216 
06217     if (output == NULL)
06218         return BAD_FUNC_ARG;
06219 
06220     if (header) {
06221         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
06222         output[i++] = 3;
06223     }
06224     output[i++] = ASN_INTEGER;
06225     output[i++] = 0x01;
06226     output[i++] = (byte)version;
06227 
06228     return i;
06229 }
06230 
06231 
06232 WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
06233 {
06234     int result = 0;
06235 
06236     WOLFSSL_ENTER("SetSerialNumber");
06237 
06238     if (sn == NULL || output == NULL)
06239         return BAD_FUNC_ARG;
06240 
06241     if (snSz <= EXTERNAL_SERIAL_SIZE) {
06242         output[0] = ASN_INTEGER;
06243         /* The serial number is always positive. When encoding the
06244          * INTEGER, if the MSB is 1, add a padding zero to keep the
06245          * number positive. */
06246         if (sn[0] & 0x80) {
06247             output[1] = (byte)snSz + 1;
06248             output[2] = 0;
06249             XMEMCPY(&output[3], sn, snSz);
06250             result = snSz + 3;
06251         }
06252         else {
06253             output[1] = (byte)snSz;
06254             XMEMCPY(&output[2], sn, snSz);
06255             result = snSz + 2;
06256         }
06257     }
06258     return result;
06259 }
06260 
06261 WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
06262     byte* serial, int* serialSz, word32 maxIdx)
06263 {
06264     int result = 0;
06265     int ret;
06266 
06267     WOLFSSL_ENTER("GetSerialNumber");
06268 
06269     if (serial == NULL || input == NULL || serialSz == NULL) {
06270         return BAD_FUNC_ARG;
06271     }
06272 
06273     /* First byte is ASN type */
06274     if ((*inOutIdx+1) > maxIdx) {
06275         WOLFSSL_MSG("Bad idx first");
06276         return BUFFER_E;
06277     }
06278 
06279     ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
06280     if (ret != 0)
06281         return ret;
06282 
06283     if (*serialSz > EXTERNAL_SERIAL_SIZE) {
06284         WOLFSSL_MSG("Serial size bad");
06285         return ASN_PARSE_E;
06286     }
06287 
06288     /* return serial */
06289     XMEMCPY(serial, &input[*inOutIdx], *serialSz);
06290     *inOutIdx += *serialSz;
06291 
06292     return result;
06293 }
06294 
06295 
06296 
06297 const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
06298 const char* END_CERT           = "-----END CERTIFICATE-----";
06299 const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
06300 const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
06301 const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
06302 const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
06303 const char* BEGIN_DSA_PARAM    = "-----BEGIN DSA PARAMETERS-----";
06304 const char* END_DSA_PARAM      = "-----END DSA PARAMETERS-----";
06305 const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
06306 const char* END_X509_CRL       = "-----END X509 CRL-----";
06307 const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
06308 const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
06309 const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
06310 const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
06311 const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
06312 const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
06313 const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
06314 const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
06315 const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
06316 const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
06317 const char* BEGIN_PUB_KEY      = "-----BEGIN PUBLIC KEY-----";
06318 const char* END_PUB_KEY        = "-----END PUBLIC KEY-----";
06319 
06320 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA)
06321 
06322 /* Used for compatibility API */
06323 int wc_DerToPem(const byte* der, word32 derSz,
06324                 byte* output, word32 outSz, int type)
06325 {
06326     return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
06327 }
06328 
06329 /* convert der buffer to pem into output, can't do inplace, der and output
06330    need to be different */
06331 int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
06332              byte *cipher_info, int type)
06333 {
06334 #ifdef WOLFSSL_SMALL_STACK
06335     char* header = NULL;
06336     char* footer = NULL;
06337 #else
06338     char header[40 + HEADER_ENCRYPTED_KEY_SIZE];
06339     char footer[40];
06340 #endif
06341 
06342     int headerLen = 40 + HEADER_ENCRYPTED_KEY_SIZE;
06343     int footerLen = 40;
06344     int i;
06345     int err;
06346     int outLen;   /* return length or error */
06347 
06348     if (der == output)      /* no in place conversion */
06349         return BAD_FUNC_ARG;
06350 
06351 #ifdef WOLFSSL_SMALL_STACK
06352     header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06353     if (header == NULL)
06354         return MEMORY_E;
06355 
06356     footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06357     if (footer == NULL) {
06358         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06359         return MEMORY_E;
06360     }
06361 #endif
06362     if (type == CERT_TYPE) {
06363         XSTRNCPY(header, BEGIN_CERT, headerLen);
06364         XSTRNCAT(header, "\n", 1);
06365 
06366         XSTRNCPY(footer, END_CERT, footerLen);
06367         XSTRNCAT(footer, "\n", 1);
06368     }
06369     else if (type == PRIVATEKEY_TYPE) {
06370         XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen);
06371         XSTRNCAT(header, "\n", 1);
06372 
06373         XSTRNCPY(footer, END_RSA_PRIV, footerLen);
06374         XSTRNCAT(footer, "\n", 1);
06375     }
06376 #ifndef NO_DSA
06377     else if (type == DSA_PRIVATEKEY_TYPE) {
06378         XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen);
06379         XSTRNCAT(header, "\n", 1);
06380 
06381         XSTRNCPY(footer, END_DSA_PRIV, footerLen);
06382         XSTRNCAT(footer, "\n", 1);
06383     }
06384 #endif
06385 #ifdef HAVE_ECC
06386     else if (type == ECC_PRIVATEKEY_TYPE) {
06387         XSTRNCPY(header, BEGIN_EC_PRIV, headerLen);
06388         XSTRNCAT(header, "\n", 1);
06389 
06390         XSTRNCPY(footer, END_EC_PRIV, footerLen);
06391         XSTRNCAT(footer, "\n", 1);
06392     }
06393 #endif
06394 #ifdef WOLFSSL_CERT_REQ
06395     else if (type == CERTREQ_TYPE)
06396     {
06397         XSTRNCPY(header, BEGIN_CERT_REQ, headerLen);
06398         XSTRNCAT(header, "\n", 1);
06399 
06400         XSTRNCPY(footer, END_CERT_REQ, footerLen);
06401         XSTRNCAT(footer, "\n", 1);
06402     }
06403 #endif
06404 #ifdef HAVE_CRL
06405     else if (type == CRL_TYPE)
06406     {
06407         XSTRNCPY(header, BEGIN_X509_CRL, headerLen);
06408         XSTRNCAT(header, "\n", 1);
06409 
06410         XSTRNCPY(footer, END_X509_CRL, footerLen);
06411         XSTRNCAT(footer, "\n", 1);
06412     }
06413 #endif
06414     else {
06415 #ifdef WOLFSSL_SMALL_STACK
06416         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06417         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06418 #endif
06419         return BAD_FUNC_ARG;
06420     }
06421 
06422     /* extra header information for encrypted key */
06423     if (cipher_info != NULL) {
06424         size_t cipherInfoStrLen = XSTRLEN((char*)cipher_info);
06425         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (23+10+2))
06426             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (23+10+2);
06427 
06428         XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23);
06429         XSTRNCAT(header, "DEK-Info: ", 10);
06430         XSTRNCAT(header, (char*)cipher_info, cipherInfoStrLen);
06431         XSTRNCAT(header, "\n\n", 2);
06432     }
06433 
06434     headerLen = (int)XSTRLEN(header);
06435     footerLen = (int)XSTRLEN(footer);
06436 
06437     /* if null output and 0 size passed in then return size needed */
06438     if (!output && outSz == 0) {
06439 #ifdef WOLFSSL_SMALL_STACK
06440         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06441         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06442 #endif
06443         outLen = 0;
06444         if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
06445                 != LENGTH_ONLY_E) {
06446             return err;
06447         }
06448         return headerLen + footerLen + outLen;
06449     }
06450 
06451     if (!der || !output) {
06452 #ifdef WOLFSSL_SMALL_STACK
06453         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06454         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06455 #endif
06456         return BAD_FUNC_ARG;
06457     }
06458 
06459     /* don't even try if outSz too short */
06460     if (outSz < headerLen + footerLen + derSz) {
06461 #ifdef WOLFSSL_SMALL_STACK
06462         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06463         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06464 #endif
06465         return BAD_FUNC_ARG;
06466     }
06467 
06468     /* header */
06469     XMEMCPY(output, header, headerLen);
06470     i = headerLen;
06471 
06472 #ifdef WOLFSSL_SMALL_STACK
06473     XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06474 #endif
06475 
06476     /* body */
06477     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
06478     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
06479 #ifdef WOLFSSL_SMALL_STACK
06480         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06481 #endif
06482         return err;
06483     }
06484     i += outLen;
06485 
06486     /* footer */
06487     if ( (i + footerLen) > (int)outSz) {
06488 #ifdef WOLFSSL_SMALL_STACK
06489         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06490 #endif
06491         return BAD_FUNC_ARG;
06492     }
06493     XMEMCPY(output + i, footer, footerLen);
06494 
06495 #ifdef WOLFSSL_SMALL_STACK
06496     XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06497 #endif
06498 
06499     return outLen + headerLen + footerLen;
06500 }
06501 
06502 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */
06503 
06504 #if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)))
06505 /* USER RSA ifdef portions used instead of refactor in consideration for
06506    possible fips build */
06507 /* Write a public RSA key to output */
06508 static int SetRsaPublicKey(byte* output, RsaKey* key,
06509                            int outLen, int with_header)
06510 {
06511 #ifdef WOLFSSL_SMALL_STACK
06512     byte* n = NULL;
06513     byte* e = NULL;
06514 #else
06515     byte n[MAX_RSA_INT_SZ];
06516     byte e[MAX_RSA_E_SZ];
06517 #endif
06518     byte seq[MAX_SEQ_SZ];
06519     byte bitString[1 + MAX_LENGTH_SZ + 1];
06520     int  nSz;
06521     int  eSz;
06522     int  seqSz;
06523     int  bitStringSz;
06524     int  idx;
06525 
06526     if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
06527         return BAD_FUNC_ARG;
06528 
06529     /* n */
06530 #ifdef WOLFSSL_SMALL_STACK
06531     n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06532     if (n == NULL)
06533         return MEMORY_E;
06534 #endif
06535 
06536 #ifdef HAVE_USER_RSA
06537     nSz = SetASNIntRSA(key->n, n);
06538 #else
06539     nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);
06540 #endif
06541     if (nSz < 0) {
06542 #ifdef WOLFSSL_SMALL_STACK
06543         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06544 #endif
06545         return nSz;
06546     }
06547 
06548     /* e */
06549 #ifdef WOLFSSL_SMALL_STACK
06550     e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06551     if (e == NULL) {
06552 #ifdef WOLFSSL_SMALL_STACK
06553         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06554 #endif
06555         return MEMORY_E;
06556     }
06557 #endif
06558 
06559 #ifdef HAVE_USER_RSA
06560     eSz = SetASNIntRSA(key->e, e);
06561 #else
06562     eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);
06563 #endif
06564     if (eSz < 0) {
06565 #ifdef WOLFSSL_SMALL_STACK
06566         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06567         XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06568 #endif
06569         return eSz;
06570     }
06571 
06572     seqSz  = SetSequence(nSz + eSz, seq);
06573 
06574     /* check output size */
06575     if ( (seqSz + nSz + eSz) > outLen) {
06576 #ifdef WOLFSSL_SMALL_STACK
06577         XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06578         XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06579 #endif
06580         return BUFFER_E;
06581     }
06582 
06583     /* headers */
06584     if (with_header) {
06585         int  algoSz;
06586 #ifdef WOLFSSL_SMALL_STACK
06587         byte* algo = NULL;
06588 
06589         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06590         if (algo == NULL) {
06591             XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06592             XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06593             return MEMORY_E;
06594         }
06595 #else
06596         byte algo[MAX_ALGO_SZ];
06597 #endif
06598         algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
06599         bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
06600 
06601         idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);
06602 
06603         /* check output size */
06604         if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
06605             #ifdef WOLFSSL_SMALL_STACK
06606                 XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06607                 XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06608                 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06609             #endif
06610 
06611             return BUFFER_E;
06612         }
06613 
06614         /* algo */
06615         XMEMCPY(output + idx, algo, algoSz);
06616         idx += algoSz;
06617         /* bit string */
06618         XMEMCPY(output + idx, bitString, bitStringSz);
06619         idx += bitStringSz;
06620 #ifdef WOLFSSL_SMALL_STACK
06621         XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06622 #endif
06623     }
06624     else
06625         idx = 0;
06626 
06627     /* seq */
06628     XMEMCPY(output + idx, seq, seqSz);
06629     idx += seqSz;
06630     /* n */
06631     XMEMCPY(output + idx, n, nSz);
06632     idx += nSz;
06633     /* e */
06634     XMEMCPY(output + idx, e, eSz);
06635     idx += eSz;
06636 
06637 #ifdef WOLFSSL_SMALL_STACK
06638     XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06639     XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
06640 #endif
06641 
06642     return idx;
06643 }
06644 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
06645                                            !HAVE_USER_RSA))) */
06646 
06647 
06648 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
06649 
06650 
06651 static mp_int* GetRsaInt(RsaKey* key, int idx)
06652 {
06653     if (idx == 0)
06654         return &key->n;
06655     if (idx == 1)
06656         return &key->e;
06657     if (idx == 2)
06658         return &key->d;
06659     if (idx == 3)
06660         return &key->p;
06661     if (idx == 4)
06662         return &key->q;
06663     if (idx == 5)
06664         return &key->dP;
06665     if (idx == 6)
06666         return &key->dQ;
06667     if (idx == 7)
06668         return &key->u;
06669 
06670     return NULL;
06671 }
06672 
06673 
06674 /* Release Tmp RSA resources */
06675 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
06676 {
06677     int i;
06678 
06679     (void)heap;
06680 
06681     for (i = 0; i < RSA_INTS; i++)
06682         XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
06683 }
06684 
06685 
06686 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
06687    written */
06688 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
06689 {
06690     word32 seqSz, verSz, rawLen, intTotalLen = 0;
06691     word32 sizes[RSA_INTS];
06692     int    i, j, outLen, ret = 0, mpSz;
06693 
06694     byte  seq[MAX_SEQ_SZ];
06695     byte  ver[MAX_VERSION_SZ];
06696     byte* tmps[RSA_INTS];
06697 
06698     if (!key || !output)
06699         return BAD_FUNC_ARG;
06700 
06701     if (key->type != RSA_PRIVATE)
06702         return BAD_FUNC_ARG;
06703 
06704     for (i = 0; i < RSA_INTS; i++)
06705         tmps[i] = NULL;
06706 
06707     /* write all big ints from key to DER tmps */
06708     for (i = 0; i < RSA_INTS; i++) {
06709         mp_int* keyInt = GetRsaInt(key, i);
06710 
06711         rawLen = mp_unsigned_bin_size(keyInt) + 1;
06712         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
06713                                  DYNAMIC_TYPE_RSA);
06714         if (tmps[i] == NULL) {
06715             ret = MEMORY_E;
06716             break;
06717         }
06718 
06719         mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
06720         if (mpSz < 0) {
06721             ret = mpSz;
06722             break;
06723         }
06724         intTotalLen += (sizes[i] = mpSz);
06725     }
06726 
06727     if (ret != 0) {
06728         FreeTmpRsas(tmps, key->heap);
06729         return ret;
06730     }
06731 
06732     /* make headers */
06733     verSz = SetMyVersion(0, ver, FALSE);
06734     seqSz = SetSequence(verSz + intTotalLen, seq);
06735 
06736     outLen = seqSz + verSz + intTotalLen;
06737     if (outLen > (int)inLen)
06738         return BAD_FUNC_ARG;
06739 
06740     /* write to output */
06741     XMEMCPY(output, seq, seqSz);
06742     j = seqSz;
06743     XMEMCPY(output + j, ver, verSz);
06744     j += verSz;
06745 
06746     for (i = 0; i < RSA_INTS; i++) {
06747         XMEMCPY(output + j, tmps[i], sizes[i]);
06748         j += sizes[i];
06749     }
06750     FreeTmpRsas(tmps, key->heap);
06751 
06752     return outLen;
06753 }
06754 
06755 
06756 /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
06757    written */
06758 int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
06759 {
06760     return SetRsaPublicKey(output, key, inLen, 1);
06761 }
06762 
06763 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
06764 
06765 
06766 #if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
06767 
06768 /* Initialize and Set Certificate defaults:
06769    version    = 3 (0x2)
06770    serial     = 0
06771    sigType    = SHA_WITH_RSA
06772    issuer     = blank
06773    daysValid  = 500
06774    selfSigned = 1 (true) use subject as issuer
06775    subject    = blank
06776 */
06777 void wc_InitCert(Cert* cert)
06778 {
06779     cert->version    = 2;   /* version 3 is hex 2 */
06780     cert->sigType    = CTC_SHAwRSA;
06781     cert->daysValid  = 500;
06782     cert->selfSigned = 1;
06783     cert->isCA       = 0;
06784     cert->bodySz     = 0;
06785 #ifdef WOLFSSL_ALT_NAMES
06786     cert->altNamesSz   = 0;
06787     cert->beforeDateSz = 0;
06788     cert->afterDateSz  = 0;
06789 #endif
06790 #ifdef WOLFSSL_CERT_EXT
06791     cert->skidSz = 0;
06792     cert->akidSz = 0;
06793     cert->keyUsage = 0;
06794     cert->certPoliciesNb = 0;
06795     XMEMSET(cert->akid, 0, CTC_MAX_AKID_SIZE);
06796     XMEMSET(cert->skid, 0, CTC_MAX_SKID_SIZE);
06797     XMEMSET(cert->certPolicies, 0, CTC_MAX_CERTPOL_NB*CTC_MAX_CERTPOL_SZ);
06798 #endif
06799     cert->keyType    = RSA_KEY;
06800     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
06801 
06802     cert->issuer.country[0] = '\0';
06803     cert->issuer.countryEnc = CTC_PRINTABLE;
06804     cert->issuer.state[0] = '\0';
06805     cert->issuer.stateEnc = CTC_UTF8;
06806     cert->issuer.locality[0] = '\0';
06807     cert->issuer.localityEnc = CTC_UTF8;
06808     cert->issuer.sur[0] = '\0';
06809     cert->issuer.surEnc = CTC_UTF8;
06810     cert->issuer.org[0] = '\0';
06811     cert->issuer.orgEnc = CTC_UTF8;
06812     cert->issuer.unit[0] = '\0';
06813     cert->issuer.unitEnc = CTC_UTF8;
06814     cert->issuer.commonName[0] = '\0';
06815     cert->issuer.commonNameEnc = CTC_UTF8;
06816     cert->issuer.email[0] = '\0';
06817 
06818     cert->subject.country[0] = '\0';
06819     cert->subject.countryEnc = CTC_PRINTABLE;
06820     cert->subject.state[0] = '\0';
06821     cert->subject.stateEnc = CTC_UTF8;
06822     cert->subject.locality[0] = '\0';
06823     cert->subject.localityEnc = CTC_UTF8;
06824     cert->subject.sur[0] = '\0';
06825     cert->subject.surEnc = CTC_UTF8;
06826     cert->subject.org[0] = '\0';
06827     cert->subject.orgEnc = CTC_UTF8;
06828     cert->subject.unit[0] = '\0';
06829     cert->subject.unitEnc = CTC_UTF8;
06830     cert->subject.commonName[0] = '\0';
06831     cert->subject.commonNameEnc = CTC_UTF8;
06832     cert->subject.email[0] = '\0';
06833 
06834 #ifdef WOLFSSL_CERT_REQ
06835     cert->challengePw[0] ='\0';
06836 #endif
06837 #ifdef WOLFSSL_HEAP_TEST
06838     cert->heap = (void*)WOLFSSL_HEAP_TEST;
06839 #else
06840     cert->heap = NULL;
06841 #endif
06842 }
06843 
06844 
06845 /* DER encoded x509 Certificate */
06846 typedef struct DerCert {
06847     byte size[MAX_LENGTH_SZ];          /* length encoded */
06848     byte version[MAX_VERSION_SZ];      /* version encoded */
06849     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
06850     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
06851     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
06852     byte subject[ASN_NAME_MAX];        /* subject encoded */
06853     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
06854     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
06855     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
06856     byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
06857 #ifdef WOLFSSL_CERT_EXT
06858     byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
06859     byte akid[MAX_KID_SZ];             /* Authority Key Identifier extension */
06860     byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
06861     byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
06862 #endif
06863 #ifdef WOLFSSL_CERT_REQ
06864     byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
06865 #endif
06866 #ifdef WOLFSSL_ALT_NAMES
06867     byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
06868 #endif
06869     int  sizeSz;                       /* encoded size length */
06870     int  versionSz;                    /* encoded version length */
06871     int  serialSz;                     /* encoded serial length */
06872     int  sigAlgoSz;                    /* encoded sig alog length */
06873     int  issuerSz;                     /* encoded issuer length */
06874     int  subjectSz;                    /* encoded subject length */
06875     int  validitySz;                   /* encoded validity length */
06876     int  publicKeySz;                  /* encoded public key length */
06877     int  caSz;                         /* encoded CA extension length */
06878 #ifdef WOLFSSL_CERT_EXT
06879     int  skidSz;                       /* encoded SKID extension length */
06880     int  akidSz;                       /* encoded SKID extension length */
06881     int  keyUsageSz;                   /* encoded KeyUsage extension length */
06882     int  certPoliciesSz;               /* encoded CertPolicies extension length*/
06883 #endif
06884 #ifdef WOLFSSL_ALT_NAMES
06885     int  altNamesSz;                   /* encoded AltNames extension length */
06886 #endif
06887     int  extensionsSz;                 /* encoded extensions total length */
06888     int  total;                        /* total encoded lengths */
06889 #ifdef WOLFSSL_CERT_REQ
06890     int  attribSz;
06891 #endif
06892 } DerCert;
06893 
06894 
06895 #ifdef WOLFSSL_CERT_REQ
06896 
06897 /* Write a set header to output */
06898 static word32 SetUTF8String(word32 len, byte* output)
06899 {
06900     output[0] = ASN_UTF8STRING;
06901     return SetLength(len, output + 1) + 1;
06902 }
06903 
06904 #endif /* WOLFSSL_CERT_REQ */
06905 
06906 
06907 /* Write a serial number to output */
06908 static int SetSerial(const byte* serial, byte* output)
06909 {
06910     int length = 0;
06911 
06912     output[length++] = ASN_INTEGER;
06913     length += SetLength(CTC_SERIAL_SIZE, &output[length]);
06914     XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
06915 
06916     return length + CTC_SERIAL_SIZE;
06917 }
06918 
06919 #endif /* defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) */
06920 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
06921 
06922 /* Write a public ECC key to output */
06923 static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
06924 {
06925     byte bitString[1 + MAX_LENGTH_SZ + 1];
06926     int  algoSz;
06927     int  curveSz;
06928     int  bitStringSz;
06929     int  idx;
06930     word32 pubSz = ECC_BUFSIZE;
06931 #ifdef WOLFSSL_SMALL_STACK
06932     byte* algo = NULL;
06933     byte* curve = NULL;
06934     byte* pub = NULL;
06935 #else
06936     byte algo[MAX_ALGO_SZ];
06937     byte curve[MAX_ALGO_SZ];
06938     byte pub[ECC_BUFSIZE];
06939 #endif
06940 
06941 #ifdef WOLFSSL_SMALL_STACK
06942     pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06943     if (pub == NULL)
06944         return MEMORY_E;
06945 #endif
06946 
06947     int ret = wc_ecc_export_x963(key, pub, &pubSz);
06948     if (ret != 0) {
06949 #ifdef WOLFSSL_SMALL_STACK
06950         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06951 #endif
06952         return ret;
06953     }
06954 
06955     /* headers */
06956     if (with_header) {
06957 #ifdef WOLFSSL_SMALL_STACK
06958         curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06959         if (curve == NULL) {
06960             XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06961             return MEMORY_E;
06962         }
06963 #endif
06964         curveSz = SetCurve(key, curve);
06965         if (curveSz <= 0) {
06966 #ifdef WOLFSSL_SMALL_STACK
06967             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06968             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
06969 #endif
06970             return curveSz;
06971         }
06972 
06973 #ifdef WOLFSSL_SMALL_STACK
06974         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06975         if (algo == NULL) {
06976             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
06977             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
06978             return MEMORY_E;
06979         }
06980 #endif
06981         algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
06982 
06983         bitStringSz = SetBitString(pubSz, 0, bitString);
06984 
06985         idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
06986         /* algo */
06987         XMEMCPY(output + idx, algo, algoSz);
06988         idx += algoSz;
06989        /* curve */
06990         XMEMCPY(output + idx, curve, curveSz);
06991         idx += curveSz;
06992         /* bit string */
06993         XMEMCPY(output + idx, bitString, bitStringSz);
06994         idx += bitStringSz;
06995     }
06996     else
06997         idx = 0;
06998 
06999     /* pub */
07000     XMEMCPY(output + idx, pub, pubSz);
07001     idx += pubSz;
07002 
07003 #ifdef WOLFSSL_SMALL_STACK
07004     if (with_header) {
07005         XFREE(algo,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
07006         XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07007     }
07008     XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
07009 #endif
07010 
07011     return idx;
07012 }
07013 
07014 
07015 /* returns the size of buffer used, the public ECC key in DER format is stored
07016    in output buffer
07017    with_AlgCurve is a flag for when to include a header that has the Algorithm
07018    and Curve infromation */
07019 int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
07020                                                               int with_AlgCurve)
07021 {
07022     word32 infoSz = 0;
07023     word32 keySz  = 0;
07024     int ret;
07025 
07026     if (output == NULL || key == NULL) {
07027         return BAD_FUNC_ARG;
07028     }
07029 
07030     if (with_AlgCurve) {
07031         /* buffer space for algorithm/curve */
07032         infoSz += MAX_SEQ_SZ;
07033         infoSz += 2 * MAX_ALGO_SZ;
07034 
07035         /* buffer space for public key sequence */
07036         infoSz += MAX_SEQ_SZ;
07037         infoSz += TRAILING_ZERO;
07038     }
07039 
07040     if ((ret = wc_ecc_export_x963(key, NULL, &keySz)) != LENGTH_ONLY_E) {
07041         WOLFSSL_MSG("Error in getting ECC public key size");
07042         return ret;
07043     }
07044 
07045     if (inLen < keySz + infoSz) {
07046         return BUFFER_E;
07047     }
07048 
07049     return SetEccPublicKey(output, key, with_AlgCurve);
07050 }
07051 #endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
07052 #if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
07053 
07054 static INLINE byte itob(int number)
07055 {
07056     return (byte)number + 0x30;
07057 }
07058 
07059 
07060 /* write time to output, format */
07061 static void SetTime(struct tm* date, byte* output)
07062 {
07063     int i = 0;
07064 
07065     output[i++] = itob((date->tm_year % 10000) / 1000);
07066     output[i++] = itob((date->tm_year % 1000)  /  100);
07067     output[i++] = itob((date->tm_year % 100)   /   10);
07068     output[i++] = itob( date->tm_year % 10);
07069 
07070     output[i++] = itob(date->tm_mon / 10);
07071     output[i++] = itob(date->tm_mon % 10);
07072 
07073     output[i++] = itob(date->tm_mday / 10);
07074     output[i++] = itob(date->tm_mday % 10);
07075 
07076     output[i++] = itob(date->tm_hour / 10);
07077     output[i++] = itob(date->tm_hour % 10);
07078 
07079     output[i++] = itob(date->tm_min / 10);
07080     output[i++] = itob(date->tm_min % 10);
07081 
07082     output[i++] = itob(date->tm_sec / 10);
07083     output[i++] = itob(date->tm_sec % 10);
07084 
07085     output[i] = 'Z';  /* Zulu profile */
07086 }
07087 
07088 
07089 #ifdef WOLFSSL_ALT_NAMES
07090 
07091 /* Copy Dates from cert, return bytes written */
07092 static int CopyValidity(byte* output, Cert* cert)
07093 {
07094     int seqSz;
07095 
07096     WOLFSSL_ENTER("CopyValidity");
07097 
07098     /* headers and output */
07099     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
07100     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
07101     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
07102                                                  cert->afterDateSz);
07103     return seqSz + cert->beforeDateSz + cert->afterDateSz;
07104 }
07105 
07106 #endif
07107 
07108 
07109 /* for systems where mktime() doesn't normalize fully */
07110 static void RebuildTime(time_t* in, struct tm* out)
07111 {
07112     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
07113         out = localtime_r(in, out);
07114     #else
07115         (void)in;
07116         (void)out;
07117     #endif
07118 }
07119 
07120 
07121 /* Set Date validity from now until now + daysValid
07122  * return size in bytes written to output, 0 on error */
07123 static int SetValidity(byte* output, int daysValid)
07124 {
07125     byte before[MAX_DATE_SIZE];
07126     byte  after[MAX_DATE_SIZE];
07127 
07128     int beforeSz;
07129     int afterSz;
07130     int seqSz;
07131 
07132     time_t     ticks;
07133     time_t     normalTime;
07134     struct tm* now;
07135     struct tm* tmpTime = NULL;
07136     struct tm  local;
07137 
07138 #if defined(NEED_TMP_TIME)
07139     /* for use with gmtime_r */
07140     struct tm tmpTimeStorage;
07141     tmpTime = &tmpTimeStorage;
07142 #else
07143     (void)tmpTime;
07144 #endif
07145 
07146     ticks = XTIME(0);
07147     now   = XGMTIME(&ticks, tmpTime);
07148 
07149     if (now == NULL) {
07150         WOLFSSL_MSG("XGMTIME failed");
07151         return 0;   /* error */
07152     }
07153 
07154     /* before now */
07155     local = *now;
07156     before[0] = ASN_GENERALIZED_TIME;
07157     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
07158 
07159     /* subtract 1 day for more compliance */
07160     local.tm_mday -= 1;
07161     normalTime = mktime(&local);
07162     RebuildTime(&normalTime, &local);
07163 
07164     /* adjust */
07165     local.tm_year += 1900;
07166     local.tm_mon  +=    1;
07167 
07168     SetTime(&local, before + beforeSz);
07169     beforeSz += ASN_GEN_TIME_SZ;
07170 
07171     /* after now + daysValid */
07172     local = *now;
07173     after[0] = ASN_GENERALIZED_TIME;
07174     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
07175 
07176     /* add daysValid */
07177     local.tm_mday += daysValid;
07178     normalTime = mktime(&local);
07179     RebuildTime(&normalTime, &local);
07180 
07181     /* adjust */
07182     local.tm_year += 1900;
07183     local.tm_mon  +=    1;
07184 
07185     SetTime(&local, after + afterSz);
07186     afterSz += ASN_GEN_TIME_SZ;
07187 
07188     /* headers and output */
07189     seqSz = SetSequence(beforeSz + afterSz, output);
07190     XMEMCPY(output + seqSz, before, beforeSz);
07191     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
07192 
07193     return seqSz + beforeSz + afterSz;
07194 }
07195 
07196 
07197 /* ASN Encoded Name field */
07198 typedef struct EncodedName {
07199     int  nameLen;                /* actual string value length */
07200     int  totalLen;               /* total encoded length */
07201     int  type;                   /* type of name */
07202     int  used;                   /* are we actually using this one */
07203     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
07204 } EncodedName;
07205 
07206 
07207 /* Get Which Name from index */
07208 static const char* GetOneName(CertName* name, int idx)
07209 {
07210     switch (idx) {
07211     case 0:
07212        return name->country;
07213 
07214     case 1:
07215        return name->state;
07216 
07217     case 2:
07218        return name->locality;
07219 
07220     case 3:
07221        return name->sur;
07222 
07223     case 4:
07224        return name->org;
07225 
07226     case 5:
07227        return name->unit;
07228 
07229     case 6:
07230        return name->commonName;
07231 
07232     case 7:
07233        return name->email;
07234 
07235     default:
07236        return 0;
07237     }
07238 }
07239 
07240 
07241 /* Get Which Name Encoding from index */
07242 static char GetNameType(CertName* name, int idx)
07243 {
07244     switch (idx) {
07245     case 0:
07246        return name->countryEnc;
07247 
07248     case 1:
07249        return name->stateEnc;
07250 
07251     case 2:
07252        return name->localityEnc;
07253 
07254     case 3:
07255        return name->surEnc;
07256 
07257     case 4:
07258        return name->orgEnc;
07259 
07260     case 5:
07261        return name->unitEnc;
07262 
07263     case 6:
07264        return name->commonNameEnc;
07265 
07266     default:
07267        return 0;
07268     }
07269 }
07270 
07271 
07272 /* Get ASN Name from index */
07273 static byte GetNameId(int idx)
07274 {
07275     switch (idx) {
07276     case 0:
07277        return ASN_COUNTRY_NAME;
07278 
07279     case 1:
07280        return ASN_STATE_NAME;
07281 
07282     case 2:
07283        return ASN_LOCALITY_NAME;
07284 
07285     case 3:
07286        return ASN_SUR_NAME;
07287 
07288     case 4:
07289        return ASN_ORG_NAME;
07290 
07291     case 5:
07292        return ASN_ORGUNIT_NAME;
07293 
07294     case 6:
07295        return ASN_COMMON_NAME;
07296 
07297     case 7:
07298        /* email uses different id type */
07299        return 0;
07300 
07301     default:
07302        return 0;
07303     }
07304 }
07305 
07306 /*
07307  Extensions ::= SEQUENCE OF Extension
07308 
07309  Extension ::= SEQUENCE {
07310  extnId     OBJECT IDENTIFIER,
07311  critical   BOOLEAN DEFAULT FALSE,
07312  extnValue  OCTET STRING }
07313  */
07314 
07315 /* encode all extensions, return total bytes written */
07316 static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
07317                          const byte* ext, int extSz)
07318 {
07319     if (out == NULL || IdxInOut == NULL || ext == NULL)
07320         return BAD_FUNC_ARG;
07321 
07322     if (outSz < (word32)(*IdxInOut+extSz))
07323         return BUFFER_E;
07324 
07325     XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
07326     *IdxInOut += extSz;
07327 
07328     return *IdxInOut;
07329 }
07330 
07331 /* encode extensions header, return total bytes written */
07332 static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
07333 {
07334     byte sequence[MAX_SEQ_SZ];
07335     byte len[MAX_LENGTH_SZ];
07336     int seqSz, lenSz, idx = 0;
07337 
07338     if (out == NULL)
07339         return BAD_FUNC_ARG;
07340 
07341     if (outSz < 3)
07342         return BUFFER_E;
07343 
07344     seqSz = SetSequence(extSz, sequence);
07345 
07346     /* encode extensions length provided */
07347     lenSz = SetLength(extSz+seqSz, len);
07348 
07349     if (outSz < (word32)(lenSz+seqSz+1))
07350         return BUFFER_E;
07351 
07352     out[idx++] = ASN_EXTENSIONS; /* extensions id */
07353     XMEMCPY(&out[idx], len, lenSz);  /* length */
07354     idx += lenSz;
07355 
07356     XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
07357     idx += seqSz;
07358 
07359     return idx;
07360 }
07361 
07362 
07363 /* encode CA basic constraint true, return total bytes written */
07364 static int SetCa(byte* out, word32 outSz)
07365 {
07366     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
07367                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
07368 
07369     if (out == NULL)
07370         return BAD_FUNC_ARG;
07371 
07372     if (outSz < sizeof(ca))
07373         return BUFFER_E;
07374 
07375     XMEMCPY(out, ca, sizeof(ca));
07376 
07377     return (int)sizeof(ca);
07378 }
07379 
07380 
07381 #ifdef WOLFSSL_CERT_EXT
07382 /* encode OID and associated value, return total bytes written */
07383 static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
07384                        byte *in, word32 inSz)
07385 {
07386     int idx = 0;
07387 
07388     if (out == NULL || oid == NULL || in == NULL)
07389         return BAD_FUNC_ARG;
07390 
07391     if (outSz < 3)
07392         return BUFFER_E;
07393 
07394     /* sequence,  + 1 => byte to put value size */
07395     idx = SetSequence(inSz + oidSz + 1, out);
07396 
07397     if ((idx + inSz + oidSz + 1) > outSz)
07398         return BUFFER_E;
07399 
07400     XMEMCPY(out+idx, oid, oidSz);
07401     idx += oidSz;
07402     out[idx++] = (byte)inSz;
07403     XMEMCPY(out+idx, in, inSz);
07404 
07405     return (idx+inSz);
07406 }
07407 
07408 /* encode Subject Key Identifier, return total bytes written
07409  * RFC5280 : non-critical */
07410 static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
07411 {
07412     byte skid_len[1 + MAX_LENGTH_SZ];
07413     byte skid_enc_len[MAX_LENGTH_SZ];
07414     int idx = 0, skid_lenSz, skid_enc_lenSz;
07415     static const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
07416 
07417     if (output == NULL || input == NULL)
07418         return BAD_FUNC_ARG;
07419 
07420     /* Octet String header */
07421     skid_lenSz = SetOctetString(length, skid_len);
07422 
07423     /* length of encoded value */
07424     skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
07425 
07426     if (outSz < 3)
07427         return BUFFER_E;
07428 
07429     idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
07430                       output);
07431 
07432     if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
07433         return BUFFER_E;
07434 
07435     /* put oid */
07436     XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
07437     idx += sizeof(skid_oid);
07438 
07439     /* put encoded len */
07440     XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
07441     idx += skid_enc_lenSz;
07442 
07443     /* put octet header */
07444     XMEMCPY(output+idx, skid_len, skid_lenSz);
07445     idx += skid_lenSz;
07446 
07447     /* put value */
07448     XMEMCPY(output+idx, input, length);
07449     idx += length;
07450 
07451     return idx;
07452 }
07453 
07454 /* encode Authority Key Identifier, return total bytes written
07455  * RFC5280 : non-critical */
07456 static int SetAKID(byte* output, word32 outSz,
07457                                          byte *input, word32 length, void* heap)
07458 {
07459     byte    *enc_val;
07460     int     ret, enc_valSz;
07461     static const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04 };
07462     static const byte akid_cs[] = { 0x80 };
07463 
07464     if (output == NULL || input == NULL)
07465         return BAD_FUNC_ARG;
07466 
07467     enc_valSz = length + 3 + sizeof(akid_cs);
07468     enc_val = (byte *)XMALLOC(enc_valSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
07469     if (enc_val == NULL)
07470         return MEMORY_E;
07471 
07472     /* sequence for ContentSpec & value */
07473     ret = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
07474                       input, length);
07475     if (ret > 0) {
07476         enc_valSz = ret;
07477 
07478         ret = SetOidValue(output, outSz, akid_oid, sizeof(akid_oid),
07479                           enc_val, enc_valSz);
07480     }
07481 
07482     XFREE(enc_val, heap, DYNAMIC_TYPE_TMP_BUFFER);
07483     return ret;
07484 }
07485 
07486 /* encode Key Usage, return total bytes written
07487  * RFC5280 : critical */
07488 static int SetKeyUsage(byte* output, word32 outSz, word16 input)
07489 {
07490     byte ku[5];
07491     int  idx;
07492     static const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
07493                                          0x01, 0x01, 0xff, 0x04};
07494 
07495     if (output == NULL)
07496         return BAD_FUNC_ARG;
07497 
07498     idx = SetBitString16Bit(input, ku);
07499     return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
07500                        ku, idx);
07501 }
07502 
07503 /* Encode OID string representation to ITU-T X.690 format */
07504 static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
07505 {
07506     word32 val, idx = 0, nb_val;
07507     char *token, *str, *ptr;
07508     word32 len;
07509 
07510     if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
07511         return BAD_FUNC_ARG;
07512 
07513     len = (word32)XSTRLEN(in);
07514 
07515     str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
07516     if (str == NULL)
07517         return MEMORY_E;
07518 
07519     XSTRNCPY(str, in, len);
07520     str[len] = 0x00;
07521 
07522     nb_val = 0;
07523 
07524     /* parse value, and set corresponding Policy OID value */
07525     token = XSTRTOK(str, ".", &ptr);
07526     while (token != NULL)
07527     {
07528         val = (word32)atoi(token);
07529 
07530         if (nb_val == 0) {
07531             if (val > 2) {
07532                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
07533                 return ASN_OBJECT_ID_E;
07534             }
07535 
07536             out[idx] = (byte)(40 * val);
07537         }
07538         else if (nb_val == 1) {
07539             if (val > 127) {
07540                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
07541                 return ASN_OBJECT_ID_E;
07542             }
07543 
07544             if (idx > *outSz) {
07545                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
07546                 return BUFFER_E;
07547             }
07548 
07549             out[idx++] += (byte)val;
07550         }
07551         else {
07552             word32  tb = 0, x;
07553             int     i = 0;
07554             byte    oid[MAX_OID_SZ];
07555 
07556             while (val >= 128) {
07557                 x = val % 128;
07558                 val /= 128;
07559                 oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
07560             }
07561 
07562             if ((idx+(word32)i) > *outSz) {
07563                 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
07564                 return BUFFER_E;
07565             }
07566 
07567             oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
07568 
07569             /* push value in the right order */
07570             while (i >= 0)
07571                 out[idx++] = oid[i--];
07572         }
07573 
07574         token = XSTRTOK(NULL, ".", &ptr);
07575         nb_val++;
07576     }
07577 
07578     *outSz = idx;
07579 
07580     XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
07581     return 0;
07582 }
07583 
07584 /* encode Certificate Policies, return total bytes written
07585  * each input value must be ITU-T X.690 formatted : a.b.c...
07586  * input must be an array of values with a NULL terminated for the latest
07587  * RFC5280 : non-critical */
07588 static int SetCertificatePolicies(byte *output,
07589                                   word32 outputSz,
07590                                   char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
07591                                   word16 nb_certpol,
07592                                   void* heap)
07593 {
07594     byte    oid[MAX_OID_SZ],
07595             der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],
07596             out[MAX_CERTPOL_SZ];
07597     word32  oidSz;
07598     word32  outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];
07599     int     ret;
07600 
07601     static const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
07602     static const byte oid_oid[] = { 0x06 };
07603 
07604     if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
07605         return BAD_FUNC_ARG;
07606 
07607     for (i = 0; i < nb_certpol; i++) {
07608         oidSz = sizeof(oid);
07609         XMEMSET(oid, 0, oidSz);
07610 
07611         ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
07612         if (ret != 0)
07613             return ret;
07614 
07615         /* compute sequence value for the oid */
07616         ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
07617                           sizeof(oid_oid), oid, oidSz);
07618         if (ret <= 0)
07619             return ret;
07620         else
07621             der_oidSz[i] = (word32)ret;
07622     }
07623 
07624     /* concatenate oid, keep two byte for sequence/size of the created value */
07625     for (i = 0, outSz = 2; i < nb_certpol; i++) {
07626         XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
07627         outSz += der_oidSz[i];
07628     }
07629 
07630     /* add sequence */
07631     ret = SetSequence(outSz-2, out);
07632     if (ret <= 0)
07633         return ret;
07634 
07635     /* add Policy OID to compute final value */
07636     return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
07637                       out, outSz);
07638 }
07639 #endif /* WOLFSSL_CERT_EXT */
07640 
07641 #ifdef WOLFSSL_ALT_NAMES
07642 /* encode Alternative Names, return total bytes written */
07643 static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
07644 {
07645     if (out == NULL || input == NULL)
07646         return BAD_FUNC_ARG;
07647 
07648     if (outSz < length)
07649         return BUFFER_E;
07650 
07651     /* Alternative Names come from certificate or computed by
07652      * external function, so already encoded. Just copy value */
07653     XMEMCPY(out, input, length);
07654     return length;
07655 }
07656 #endif /* WOLFSL_ALT_NAMES */
07657 
07658 
07659 /* encode CertName into output, return total bytes written */
07660 int SetName(byte* output, word32 outputSz, CertName* name)
07661 {
07662     int          totalBytes = 0, i, idx;
07663 #ifdef WOLFSSL_SMALL_STACK
07664     EncodedName* names = NULL;
07665 #else
07666     EncodedName  names[NAME_ENTRIES];
07667 #endif
07668 
07669     if (output == NULL || name == NULL)
07670         return BAD_FUNC_ARG;
07671 
07672     if (outputSz < 3)
07673         return BUFFER_E;
07674 
07675 #ifdef WOLFSSL_SMALL_STACK
07676     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
07677                                                        DYNAMIC_TYPE_TMP_BUFFER);
07678     if (names == NULL)
07679         return MEMORY_E;
07680 #endif
07681 
07682     for (i = 0; i < NAME_ENTRIES; i++) {
07683         const char* nameStr = GetOneName(name, i);
07684         if (nameStr) {
07685             /* bottom up */
07686             byte firstLen[1 + MAX_LENGTH_SZ];
07687             byte secondLen[MAX_LENGTH_SZ];
07688             byte sequence[MAX_SEQ_SZ];
07689             byte set[MAX_SET_SZ];
07690 
07691             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
07692             int strLen  = (int)XSTRLEN(nameStr);
07693             int thisLen = strLen;
07694             int firstSz, secondSz, seqSz, setSz;
07695 
07696             if (strLen == 0) { /* no user data for this item */
07697                 names[i].used = 0;
07698                 continue;
07699             }
07700 
07701             /* Restrict country code size */
07702             if (i == 0 && strLen != CTC_COUNTRY_SIZE) {
07703 #ifdef WOLFSSL_SMALL_STACK
07704                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07705 #endif
07706                 return ASN_COUNTRY_SIZE_E;
07707             }
07708 
07709             secondSz = SetLength(strLen, secondLen);
07710             thisLen += secondSz;
07711             if (email) {
07712                 thisLen += EMAIL_JOINT_LEN;
07713                 thisLen ++;                               /* id type */
07714                 firstSz  = SetObjectId(EMAIL_JOINT_LEN, firstLen);
07715             }
07716             else {
07717                 thisLen++;                                 /* str type */
07718                 thisLen++;                                 /* id  type */
07719                 thisLen += JOINT_LEN;
07720                 firstSz  = SetObjectId(JOINT_LEN + 1, firstLen);
07721             }
07722             thisLen += firstSz;
07723 
07724             seqSz = SetSequence(thisLen, sequence);
07725             thisLen += seqSz;
07726             setSz = SetSet(thisLen, set);
07727             thisLen += setSz;
07728 
07729             if (thisLen > (int)sizeof(names[i].encoded)) {
07730 #ifdef WOLFSSL_SMALL_STACK
07731                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07732 #endif
07733                 return BUFFER_E;
07734             }
07735 
07736             /* store it */
07737             idx = 0;
07738             /* set */
07739             XMEMCPY(names[i].encoded, set, setSz);
07740             idx += setSz;
07741             /* seq */
07742             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
07743             idx += seqSz;
07744             /* asn object id */
07745             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
07746             idx += firstSz;
07747             if (email) {
07748                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
07749                                            0x01, 0x09, 0x01, 0x16 };
07750                 /* email joint id */
07751                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
07752                 idx += (int)sizeof(EMAIL_OID);
07753             }
07754             else {
07755                 /* joint id */
07756                 byte bType = GetNameId(i);
07757                 names[i].encoded[idx++] = 0x55;
07758                 names[i].encoded[idx++] = 0x04;
07759                 /* id type */
07760                 names[i].encoded[idx++] = bType;
07761                 /* str type */
07762                 names[i].encoded[idx++] = GetNameType(name, i);
07763             }
07764             /* second length */
07765             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
07766             idx += secondSz;
07767             /* str value */
07768             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
07769             idx += strLen;
07770 
07771             totalBytes += idx;
07772             names[i].totalLen = idx;
07773             names[i].used = 1;
07774         }
07775         else
07776             names[i].used = 0;
07777     }
07778 
07779     /* header */
07780     idx = SetSequence(totalBytes, output);
07781     totalBytes += idx;
07782     if (totalBytes > ASN_NAME_MAX) {
07783 #ifdef WOLFSSL_SMALL_STACK
07784         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07785 #endif
07786         return BUFFER_E;
07787     }
07788 
07789     for (i = 0; i < NAME_ENTRIES; i++) {
07790         if (names[i].used) {
07791             if (outputSz < (word32)(idx+names[i].totalLen)) {
07792 #ifdef WOLFSSL_SMALL_STACK
07793                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07794 #endif
07795                 return BUFFER_E;
07796             }
07797 
07798             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
07799             idx += names[i].totalLen;
07800         }
07801     }
07802 
07803 #ifdef WOLFSSL_SMALL_STACK
07804     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07805 #endif
07806 
07807     return totalBytes;
07808 }
07809 
07810 /* encode info from cert into DER encoded format */
07811 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
07812                       WC_RNG* rng, const byte* ntruKey, word16 ntruSz)
07813 {
07814     int ret;
07815 
07816     (void)eccKey;
07817     (void)ntruKey;
07818     (void)ntruSz;
07819 
07820     if (cert == NULL || der == NULL || rng == NULL)
07821         return BAD_FUNC_ARG;
07822 
07823     /* init */
07824     XMEMSET(der, 0, sizeof(DerCert));
07825 
07826     /* version */
07827     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
07828 
07829     /* serial number */
07830     ret = wc_RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
07831     if (ret != 0)
07832         return ret;
07833 
07834     cert->serial[0] = 0x01;   /* ensure positive */
07835     der->serialSz  = SetSerial(cert->serial, der->serial);
07836 
07837     /* signature algo */
07838     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
07839     if (der->sigAlgoSz <= 0)
07840         return ALGO_ID_E;
07841 
07842     /* public key */
07843     if (cert->keyType == RSA_KEY) {
07844         if (rsaKey == NULL)
07845             return PUBLIC_KEY_E;
07846         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
07847                                            sizeof(der->publicKey), 1);
07848         if (der->publicKeySz <= 0)
07849             return PUBLIC_KEY_E;
07850     }
07851 
07852 #ifdef HAVE_ECC
07853     if (cert->keyType == ECC_KEY) {
07854         if (eccKey == NULL)
07855             return PUBLIC_KEY_E;
07856         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
07857         if (der->publicKeySz <= 0)
07858             return PUBLIC_KEY_E;
07859     }
07860 #endif /* HAVE_ECC */
07861 
07862 #ifdef HAVE_NTRU
07863     if (cert->keyType == NTRU_KEY) {
07864         word32 rc;
07865         word16 encodedSz;
07866 
07867         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
07868                                                    ntruKey, &encodedSz, NULL);
07869         if (rc != NTRU_OK)
07870             return PUBLIC_KEY_E;
07871         if (encodedSz > MAX_PUBLIC_KEY_SZ)
07872             return PUBLIC_KEY_E;
07873 
07874         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
07875                                          ntruKey, &encodedSz, der->publicKey);
07876         if (rc != NTRU_OK)
07877             return PUBLIC_KEY_E;
07878 
07879         der->publicKeySz = encodedSz;
07880     }
07881 #endif /* HAVE_NTRU */
07882 
07883     der->validitySz = 0;
07884 #ifdef WOLFSSL_ALT_NAMES
07885     /* date validity copy ? */
07886     if (cert->beforeDateSz && cert->afterDateSz) {
07887         der->validitySz = CopyValidity(der->validity, cert);
07888         if (der->validitySz <= 0)
07889             return DATE_E;
07890     }
07891 #endif
07892 
07893     /* date validity */
07894     if (der->validitySz == 0) {
07895         der->validitySz = SetValidity(der->validity, cert->daysValid);
07896         if (der->validitySz <= 0)
07897             return DATE_E;
07898     }
07899 
07900     /* subject name */
07901     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
07902     if (der->subjectSz <= 0)
07903         return SUBJECT_E;
07904 
07905     /* issuer name */
07906     der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
07907              &cert->subject : &cert->issuer);
07908     if (der->issuerSz <= 0)
07909         return ISSUER_E;
07910 
07911     /* set the extensions */
07912     der->extensionsSz = 0;
07913 
07914     /* CA */
07915     if (cert->isCA) {
07916         der->caSz = SetCa(der->ca, sizeof(der->ca));
07917         if (der->caSz <= 0)
07918             return CA_TRUE_E;
07919 
07920         der->extensionsSz += der->caSz;
07921     }
07922     else
07923         der->caSz = 0;
07924 
07925 #ifdef WOLFSSL_ALT_NAMES
07926     /* Alternative Name */
07927     if (cert->altNamesSz) {
07928         der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
07929                                       cert->altNames, cert->altNamesSz);
07930         if (der->altNamesSz <= 0)
07931             return ALT_NAME_E;
07932 
07933         der->extensionsSz += der->altNamesSz;
07934     }
07935     else
07936         der->altNamesSz = 0;
07937 #endif
07938 
07939 #ifdef WOLFSSL_CERT_EXT
07940     /* SKID */
07941     if (cert->skidSz) {
07942         /* check the provided SKID size */
07943         if (cert->skidSz > (int)sizeof(der->skid))
07944             return SKID_E;
07945 
07946         /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
07947             cert (CTC_MAX_SKID_SIZE). */
07948         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
07949                               cert->skid, cert->skidSz);
07950         if (der->skidSz <= 0)
07951             return SKID_E;
07952 
07953         der->extensionsSz += der->skidSz;
07954     }
07955     else
07956         der->skidSz = 0;
07957 
07958     /* AKID */
07959     if (cert->akidSz) {
07960         /* check the provided AKID size */
07961         if (cert->akidSz > (int)sizeof(der->akid))
07962             return AKID_E;
07963 
07964         der->akidSz = SetAKID(der->akid, sizeof(der->akid),
07965                               cert->akid, cert->akidSz, cert->heap);
07966         if (der->akidSz <= 0)
07967             return AKID_E;
07968 
07969         der->extensionsSz += der->akidSz;
07970     }
07971     else
07972         der->akidSz = 0;
07973 
07974     /* Key Usage */
07975     if (cert->keyUsage != 0){
07976         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
07977                                       cert->keyUsage);
07978         if (der->keyUsageSz <= 0)
07979             return KEYUSAGE_E;
07980 
07981         der->extensionsSz += der->keyUsageSz;
07982     }
07983     else
07984         der->keyUsageSz = 0;
07985 
07986     /* Certificate Policies */
07987     if (cert->certPoliciesNb != 0) {
07988         der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
07989                                                      sizeof(der->certPolicies),
07990                                                      cert->certPolicies,
07991                                                      cert->certPoliciesNb,
07992                                                      cert->heap);
07993         if (der->certPoliciesSz <= 0)
07994             return CERTPOLICIES_E;
07995 
07996         der->extensionsSz += der->certPoliciesSz;
07997     }
07998     else
07999         der->certPoliciesSz = 0;
08000 #endif /* WOLFSSL_CERT_EXT */
08001 
08002     /* put extensions */
08003     if (der->extensionsSz > 0) {
08004 
08005         /* put the start of extensions sequence (ID, Size) */
08006         der->extensionsSz = SetExtensionsHeader(der->extensions,
08007                                                 sizeof(der->extensions),
08008                                                 der->extensionsSz);
08009         if (der->extensionsSz <= 0)
08010             return EXTENSIONS_E;
08011 
08012         /* put CA */
08013         if (der->caSz) {
08014             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08015                                 &der->extensionsSz,
08016                                 der->ca, der->caSz);
08017             if (ret == 0)
08018                 return EXTENSIONS_E;
08019         }
08020 
08021 #ifdef WOLFSSL_ALT_NAMES
08022         /* put Alternative Names */
08023         if (der->altNamesSz) {
08024             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08025                                 &der->extensionsSz,
08026                                 der->altNames, der->altNamesSz);
08027             if (ret <= 0)
08028                 return EXTENSIONS_E;
08029         }
08030 #endif
08031 
08032 #ifdef WOLFSSL_CERT_EXT
08033         /* put SKID */
08034         if (der->skidSz) {
08035             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08036                                 &der->extensionsSz,
08037                                 der->skid, der->skidSz);
08038             if (ret <= 0)
08039                 return EXTENSIONS_E;
08040         }
08041 
08042         /* put AKID */
08043         if (der->akidSz) {
08044             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08045                                 &der->extensionsSz,
08046                                 der->akid, der->akidSz);
08047             if (ret <= 0)
08048                 return EXTENSIONS_E;
08049         }
08050 
08051         /* put KeyUsage */
08052         if (der->keyUsageSz) {
08053             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08054                                 &der->extensionsSz,
08055                                 der->keyUsage, der->keyUsageSz);
08056             if (ret <= 0)
08057                 return EXTENSIONS_E;
08058         }
08059 
08060         /* put Certificate Policies */
08061         if (der->certPoliciesSz) {
08062             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08063                                 &der->extensionsSz,
08064                                 der->certPolicies, der->certPoliciesSz);
08065             if (ret <= 0)
08066                 return EXTENSIONS_E;
08067         }
08068 #endif /* WOLFSSL_CERT_EXT */
08069     }
08070 
08071     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
08072         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
08073         der->extensionsSz;
08074 
08075     return 0;
08076 }
08077 
08078 
08079 /* write DER encoded cert to buffer, size already checked */
08080 static int WriteCertBody(DerCert* der, byte* buffer)
08081 {
08082     int idx;
08083 
08084     /* signed part header */
08085     idx = SetSequence(der->total, buffer);
08086     /* version */
08087     XMEMCPY(buffer + idx, der->version, der->versionSz);
08088     idx += der->versionSz;
08089     /* serial */
08090     XMEMCPY(buffer + idx, der->serial, der->serialSz);
08091     idx += der->serialSz;
08092     /* sig algo */
08093     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
08094     idx += der->sigAlgoSz;
08095     /* issuer */
08096     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
08097     idx += der->issuerSz;
08098     /* validity */
08099     XMEMCPY(buffer + idx, der->validity, der->validitySz);
08100     idx += der->validitySz;
08101     /* subject */
08102     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
08103     idx += der->subjectSz;
08104     /* public key */
08105     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
08106     idx += der->publicKeySz;
08107     if (der->extensionsSz) {
08108         /* extensions */
08109         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
08110                                                    (int)sizeof(der->extensions)));
08111         idx += der->extensionsSz;
08112     }
08113 
08114     return idx;
08115 }
08116 
08117 
08118 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
08119 static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz,
08120     byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
08121     int sigAlgoType, void* heap)
08122 {
08123     int digestSz = 0, typeH = 0, ret = 0;
08124 
08125     (void)digestSz;
08126     (void)typeH;
08127     (void)buffer;
08128     (void)sz;
08129     (void)sig;
08130     (void)sigSz;
08131     (void)rsaKey;
08132     (void)eccKey;
08133     (void)rng;
08134 
08135     switch (certSignCtx->state) {
08136     case CERTSIGN_STATE_BEGIN:
08137     case CERTSIGN_STATE_DIGEST:
08138 
08139         certSignCtx->state = CERTSIGN_STATE_DIGEST;
08140         certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
08141             DYNAMIC_TYPE_TMP_BUFFER);
08142         if (certSignCtx->digest == NULL) {
08143             ret = MEMORY_E; goto exit_ms;
08144         }
08145 
08146         switch (sigAlgoType) {
08147         #ifndef NO_MD5
08148             case CTC_MD5wRSA:
08149             if ((ret = wc_Md5Hash(buffer, sz, certSignCtx->digest)) == 0) {
08150                 typeH    = MD5h;
08151                 digestSz = MD5_DIGEST_SIZE;
08152             }
08153             break;
08154         #endif
08155         #ifndef NO_SHA
08156             case CTC_SHAwRSA:
08157             case CTC_SHAwECDSA:
08158             if ((ret = wc_ShaHash(buffer, sz, certSignCtx->digest)) == 0) {
08159                 typeH    = SHAh;
08160                 digestSz = SHA_DIGEST_SIZE;
08161             }
08162             break;
08163         #endif
08164         #ifdef WOLFSSL_SHA224
08165             case CTC_SHA224wRSA:
08166             case CTC_SHA224wECDSA:
08167             if ((ret = wc_Sha224Hash(buffer, sz, certSignCtx->digest)) == 0) {
08168                 typeH    = SHA224h;
08169                 digestSz = SHA224_DIGEST_SIZE;
08170             }
08171             break;
08172         #endif
08173         #ifndef NO_SHA256
08174             case CTC_SHA256wRSA:
08175             case CTC_SHA256wECDSA:
08176             if ((ret = wc_Sha256Hash(buffer, sz, certSignCtx->digest)) == 0) {
08177                 typeH    = SHA256h;
08178                 digestSz = SHA256_DIGEST_SIZE;
08179             }
08180             break;
08181         #endif
08182         #ifdef WOLFSSL_SHA384
08183             case CTC_SHA384wRSA:
08184             case CTC_SHA384wECDSA:
08185             if ((ret = wc_Sha384Hash(buffer, sz, certSignCtx->digest)) == 0) {
08186                 typeH    = SHA384h;
08187                 digestSz = SHA384_DIGEST_SIZE;
08188             }
08189             break;
08190         #endif
08191         #ifdef WOLFSSL_SHA512
08192             case CTC_SHA512wRSA:
08193             case CTC_SHA512wECDSA:
08194             if ((ret = wc_Sha512Hash(buffer, sz, certSignCtx->digest)) == 0) {
08195                 typeH    = SHA512h;
08196                 digestSz = SHA512_DIGEST_SIZE;
08197             }
08198             break;
08199         #endif
08200             default:
08201                 WOLFSSL_MSG("MakeSignautre called with unsupported type");
08202                 ret = ALGO_ID_E;
08203         }
08204 
08205         /* set next state, since WC_PENDING rentry for these are not "call again" */
08206         certSignCtx->state = CERTSIGN_STATE_ENCODE;
08207         if (ret != 0) {
08208             goto exit_ms;
08209         }
08210 
08211         /* fall-through */
08212     case CERTSIGN_STATE_ENCODE:
08213     #ifndef NO_RSA
08214         if (rsaKey) {
08215             certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
08216                 DYNAMIC_TYPE_TMP_BUFFER);
08217             if (certSignCtx->encSig == NULL) {
08218                 ret = MEMORY_E; goto exit_ms;
08219             }
08220 
08221             /* signature */
08222             certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
08223                                           certSignCtx->digest, digestSz, typeH);
08224         }
08225     #endif /* !NO_RSA */
08226 
08227         /* fall-through */
08228     case CERTSIGN_STATE_DO:
08229         certSignCtx->state = CERTSIGN_STATE_DO;
08230         ret = ALGO_ID_E; /* default to error */
08231 
08232     #ifndef NO_RSA
08233         if (rsaKey) {
08234             /* signature */
08235             ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
08236                                  sig, sigSz, rsaKey, rng);
08237         }
08238     #endif /* !NO_RSA */
08239 
08240     #ifdef HAVE_ECC
08241         if (!rsaKey && eccKey) {
08242             word32 outSz = sigSz;
08243 
08244             ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
08245                                    sig, &outSz, rng, eccKey);
08246             if (ret == 0)
08247                 ret = outSz;
08248         }
08249     #endif /* HAVE_ECC */
08250         break;
08251     }
08252 
08253 exit_ms:
08254 
08255     if (ret == WC_PENDING_E) {
08256         return ret;
08257     }
08258 
08259 #ifndef NO_RSA
08260     if (rsaKey) {
08261         XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
08262     }
08263 #endif /* !NO_RSA */
08264 
08265     XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
08266     certSignCtx->digest = NULL;
08267 
08268     /* reset state */
08269     certSignCtx->state = CERTSIGN_STATE_BEGIN;
08270 
08271     return ret;
08272 }
08273 
08274 
08275 /* add signature to end of buffer, size of buffer assumed checked, return
08276    new length */
08277 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
08278                         int sigAlgoType)
08279 {
08280     byte seq[MAX_SEQ_SZ];
08281     int  idx = bodySz, seqSz;
08282 
08283     /* algo */
08284     idx += SetAlgoID(sigAlgoType, buffer + idx, oidSigType, 0);
08285     /* bit string */
08286     idx += SetBitString(sigSz, 0, buffer + idx);
08287     /* signature */
08288     XMEMCPY(buffer + idx, sig, sigSz);
08289     idx += sigSz;
08290 
08291     /* make room for overall header */
08292     seqSz = SetSequence(idx, seq);
08293     XMEMMOVE(buffer + seqSz, buffer, idx);
08294     XMEMCPY(buffer, seq, seqSz);
08295 
08296     return idx + seqSz;
08297 }
08298 
08299 
08300 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
08301 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
08302                        RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
08303                        const byte* ntruKey, word16 ntruSz)
08304 {
08305     int ret;
08306 #ifdef WOLFSSL_SMALL_STACK
08307     DerCert* der;
08308 #else
08309     DerCert der[1];
08310 #endif
08311 
08312     cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY);
08313 
08314 #ifdef WOLFSSL_SMALL_STACK
08315     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
08316     if (der == NULL)
08317         return MEMORY_E;
08318 #endif
08319 
08320     ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz);
08321     if (ret == 0) {
08322         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
08323             ret = BUFFER_E;
08324         else
08325             ret = cert->bodySz = WriteCertBody(der, derBuffer);
08326     }
08327 
08328 #ifdef WOLFSSL_SMALL_STACK
08329     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08330 #endif
08331 
08332     return ret;
08333 }
08334 
08335 
08336 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
08337 int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
08338              ecc_key* eccKey, WC_RNG* rng)
08339 {
08340     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0);
08341 }
08342 
08343 
08344 #ifdef HAVE_NTRU
08345 
08346 int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
08347                   const byte* ntruKey, word16 keySz, WC_RNG* rng)
08348 {
08349     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
08350 }
08351 
08352 #endif /* HAVE_NTRU */
08353 
08354 
08355 #ifdef WOLFSSL_CERT_REQ
08356 
08357 static int SetReqAttrib(byte* output, char* pw, int extSz)
08358 {
08359     static const byte cpOid[] =
08360         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
08361                          0x09, 0x07 };
08362     static const byte erOid[] =
08363         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
08364                          0x09, 0x0e };
08365 
08366     int sz      = 0; /* overall size */
08367     int cpSz    = 0; /* Challenge Password section size */
08368     int cpSeqSz = 0;
08369     int cpSetSz = 0;
08370     int cpStrSz = 0;
08371     int pwSz    = 0;
08372     int erSz    = 0; /* Extension Request section size */
08373     int erSeqSz = 0;
08374     int erSetSz = 0;
08375     byte cpSeq[MAX_SEQ_SZ];
08376     byte cpSet[MAX_SET_SZ];
08377     byte cpStr[MAX_PRSTR_SZ];
08378     byte erSeq[MAX_SEQ_SZ];
08379     byte erSet[MAX_SET_SZ];
08380 
08381     output[0] = 0xa0;
08382     sz++;
08383 
08384     if (pw && pw[0]) {
08385         pwSz = (int)XSTRLEN(pw);
08386         cpStrSz = SetUTF8String(pwSz, cpStr);
08387         cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
08388         cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
08389         cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
08390     }
08391 
08392     if (extSz) {
08393         erSetSz = SetSet(extSz, erSet);
08394         erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
08395         erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
08396     }
08397 
08398     /* Put the pieces together. */
08399     sz += SetLength(cpSz + erSz, &output[sz]);
08400 
08401     if (cpSz) {
08402         XMEMCPY(&output[sz], cpSeq, cpSeqSz);
08403         sz += cpSeqSz;
08404         XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
08405         sz += sizeof(cpOid);
08406         XMEMCPY(&output[sz], cpSet, cpSetSz);
08407         sz += cpSetSz;
08408         XMEMCPY(&output[sz], cpStr, cpStrSz);
08409         sz += cpStrSz;
08410         XMEMCPY(&output[sz], pw, pwSz);
08411         sz += pwSz;
08412     }
08413 
08414     if (erSz) {
08415         XMEMCPY(&output[sz], erSeq, erSeqSz);
08416         sz += erSeqSz;
08417         XMEMCPY(&output[sz], erOid, sizeof(erOid));
08418         sz += sizeof(erOid);
08419         XMEMCPY(&output[sz], erSet, erSetSz);
08420         sz += erSetSz;
08421         /* The actual extension data will be tacked onto the output later. */
08422     }
08423 
08424     return sz;
08425 }
08426 
08427 
08428 /* encode info from cert into DER encoded format */
08429 static int EncodeCertReq(Cert* cert, DerCert* der,
08430                          RsaKey* rsaKey, ecc_key* eccKey)
08431 {
08432     (void)eccKey;
08433 
08434     if (cert == NULL || der == NULL)
08435         return BAD_FUNC_ARG;
08436 
08437     /* init */
08438     XMEMSET(der, 0, sizeof(DerCert));
08439 
08440     /* version */
08441     der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
08442 
08443     /* subject name */
08444     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
08445     if (der->subjectSz <= 0)
08446         return SUBJECT_E;
08447 
08448     /* public key */
08449     if (cert->keyType == RSA_KEY) {
08450         if (rsaKey == NULL)
08451             return PUBLIC_KEY_E;
08452         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
08453                                            sizeof(der->publicKey), 1);
08454         if (der->publicKeySz <= 0)
08455             return PUBLIC_KEY_E;
08456     }
08457 
08458 #ifdef HAVE_ECC
08459     if (cert->keyType == ECC_KEY) {
08460         if (eccKey == NULL)
08461             return PUBLIC_KEY_E;
08462         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
08463         if (der->publicKeySz <= 0)
08464             return PUBLIC_KEY_E;
08465     }
08466 #endif /* HAVE_ECC */
08467 
08468     /* set the extensions */
08469     der->extensionsSz = 0;
08470 
08471     /* CA */
08472     if (cert->isCA) {
08473         der->caSz = SetCa(der->ca, sizeof(der->ca));
08474         if (der->caSz <= 0)
08475             return CA_TRUE_E;
08476 
08477         der->extensionsSz += der->caSz;
08478     }
08479     else
08480         der->caSz = 0;
08481 
08482 #ifdef WOLFSSL_CERT_EXT
08483     /* SKID */
08484     if (cert->skidSz) {
08485         /* check the provided SKID size */
08486         if (cert->skidSz > (int)sizeof(der->skid))
08487             return SKID_E;
08488 
08489         der->skidSz = SetSKID(der->skid, sizeof(der->skid),
08490                               cert->skid, cert->skidSz);
08491         if (der->skidSz <= 0)
08492             return SKID_E;
08493 
08494         der->extensionsSz += der->skidSz;
08495     }
08496     else
08497         der->skidSz = 0;
08498 
08499     /* Key Usage */
08500     if (cert->keyUsage != 0){
08501         der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
08502                                       cert->keyUsage);
08503         if (der->keyUsageSz <= 0)
08504             return KEYUSAGE_E;
08505 
08506         der->extensionsSz += der->keyUsageSz;
08507     }
08508     else
08509         der->keyUsageSz = 0;
08510 #endif /* WOLFSSL_CERT_EXT */
08511 
08512     /* put extensions */
08513     if (der->extensionsSz > 0) {
08514         int ret;
08515 
08516         /* put the start of sequence (ID, Size) */
08517         der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
08518         if (der->extensionsSz <= 0)
08519             return EXTENSIONS_E;
08520 
08521         /* put CA */
08522         if (der->caSz) {
08523             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08524                                 &der->extensionsSz,
08525                                 der->ca, der->caSz);
08526             if (ret <= 0)
08527                 return EXTENSIONS_E;
08528         }
08529 
08530 #ifdef WOLFSSL_CERT_EXT
08531         /* put SKID */
08532         if (der->skidSz) {
08533             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08534                                 &der->extensionsSz,
08535                                 der->skid, der->skidSz);
08536             if (ret <= 0)
08537                 return EXTENSIONS_E;
08538         }
08539 
08540         /* put AKID */
08541         if (der->akidSz) {
08542             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08543                                 &der->extensionsSz,
08544                                 der->akid, der->akidSz);
08545             if (ret <= 0)
08546                 return EXTENSIONS_E;
08547         }
08548 
08549         /* put KeyUsage */
08550         if (der->keyUsageSz) {
08551             ret = SetExtensions(der->extensions, sizeof(der->extensions),
08552                                 &der->extensionsSz,
08553                                 der->keyUsage, der->keyUsageSz);
08554             if (ret <= 0)
08555                 return EXTENSIONS_E;
08556         }
08557 
08558 #endif /* WOLFSSL_CERT_EXT */
08559     }
08560 
08561     der->attribSz = SetReqAttrib(der->attrib,
08562                                  cert->challengePw, der->extensionsSz);
08563     if (der->attribSz <= 0)
08564         return REQ_ATTRIBUTE_E;
08565 
08566     der->total = der->versionSz + der->subjectSz + der->publicKeySz +
08567         der->extensionsSz + der->attribSz;
08568 
08569     return 0;
08570 }
08571 
08572 
08573 /* write DER encoded cert req to buffer, size already checked */
08574 static int WriteCertReqBody(DerCert* der, byte* buffer)
08575 {
08576     int idx;
08577 
08578     /* signed part header */
08579     idx = SetSequence(der->total, buffer);
08580     /* version */
08581     XMEMCPY(buffer + idx, der->version, der->versionSz);
08582     idx += der->versionSz;
08583     /* subject */
08584     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
08585     idx += der->subjectSz;
08586     /* public key */
08587     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
08588     idx += der->publicKeySz;
08589     /* attributes */
08590     XMEMCPY(buffer + idx, der->attrib, der->attribSz);
08591     idx += der->attribSz;
08592     /* extensions */
08593     if (der->extensionsSz) {
08594         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
08595                                                (int)sizeof(der->extensions)));
08596         idx += der->extensionsSz;
08597     }
08598 
08599     return idx;
08600 }
08601 
08602 
08603 int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
08604                 RsaKey* rsaKey, ecc_key* eccKey)
08605 {
08606     int ret;
08607 #ifdef WOLFSSL_SMALL_STACK
08608     DerCert* der;
08609 #else
08610     DerCert der[1];
08611 #endif
08612 
08613     cert->keyType = eccKey ? ECC_KEY : RSA_KEY;
08614 
08615 #ifdef WOLFSSL_SMALL_STACK
08616     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
08617     if (der == NULL)
08618         return MEMORY_E;
08619 #endif
08620 
08621     ret = EncodeCertReq(cert, der, rsaKey, eccKey);
08622 
08623     if (ret == 0) {
08624         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
08625             ret = BUFFER_E;
08626         else
08627             ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
08628     }
08629 
08630 #ifdef WOLFSSL_SMALL_STACK
08631     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08632 #endif
08633 
08634     return ret;
08635 }
08636 
08637 #endif /* WOLFSSL_CERT_REQ */
08638 
08639 
08640 int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
08641              RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
08642 {
08643     int sigSz = 0;
08644     void* heap = NULL;
08645     CertSignCtx* certSignCtx = NULL;
08646 #ifndef WOLFSSL_ASYNC_CRYPT
08647     CertSignCtx  certSignCtx_lcl;
08648     certSignCtx = &certSignCtx_lcl;
08649     XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
08650 #endif
08651 
08652     if (requestSz < 0)
08653         return requestSz;
08654 
08655     /* locate ctx */
08656     if (rsaKey) {
08657     #ifdef WOLFSSL_ASYNC_CRYPT
08658         certSignCtx = &rsaKey->certSignCtx;
08659     #endif
08660         heap = rsaKey->heap;
08661     }
08662     else if (eccKey) {
08663     #ifdef WOLFSSL_ASYNC_CRYPT
08664         certSignCtx = &eccKey->certSignCtx;
08665     #endif
08666         heap = eccKey->heap;
08667     }
08668 
08669 #ifdef WOLFSSL_ASYNC_CRYPT
08670     if (certSignCtx == NULL) {
08671         return BAD_FUNC_ARG;
08672     }
08673 #endif
08674 
08675     if (certSignCtx->sig == NULL) {
08676         certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
08677             DYNAMIC_TYPE_TMP_BUFFER);
08678         if (certSignCtx->sig == NULL)
08679             return MEMORY_E;
08680     }
08681 
08682     sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,
08683         MAX_ENCODED_SIG_SZ, rsaKey, eccKey, rng, sType, heap);
08684     if (sigSz == WC_PENDING_E)
08685         return sigSz;
08686 
08687     if (sigSz >= 0) {
08688         if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
08689             sigSz = BUFFER_E;
08690         else
08691             sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz, sType);
08692     }
08693 
08694     XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
08695     certSignCtx->sig = NULL;
08696 
08697     return sigSz;
08698 }
08699 
08700 
08701 int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz,
08702                     RsaKey* key, WC_RNG* rng)
08703 {
08704     int ret;
08705 
08706     ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);
08707     if (ret < 0)
08708         return ret;
08709 
08710     return wc_SignCert(cert->bodySz, cert->sigType,
08711                        buffer, buffSz, key, NULL, rng);
08712 }
08713 
08714 
08715 #ifdef WOLFSSL_CERT_EXT
08716 
08717 /* Set KID from RSA or ECC public key */
08718 static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
08719                                  byte *ntruKey, word16 ntruKeySz, int kid_type)
08720 {
08721     byte    *buffer;
08722     int     bufferSz, ret;
08723 
08724 #ifndef HAVE_NTRU
08725     (void)ntruKeySz;
08726 #endif
08727 
08728     if (cert == NULL || (rsakey == NULL && eckey == NULL && ntruKey == NULL) ||
08729         (rsakey != NULL && eckey != NULL) ||
08730         (rsakey != NULL && ntruKey != NULL) ||
08731         (ntruKey != NULL && eckey != NULL) ||
08732         (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
08733         return BAD_FUNC_ARG;
08734 
08735     buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
08736                                                        DYNAMIC_TYPE_TMP_BUFFER);
08737     if (buffer == NULL)
08738         return MEMORY_E;
08739 
08740     /* RSA public key */
08741     if (rsakey != NULL)
08742         bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0);
08743 #ifdef HAVE_ECC
08744     /* ECC public key */
08745     else if (eckey != NULL)
08746         bufferSz = SetEccPublicKey(buffer, eckey, 0);
08747 #endif /* HAVE_ECC */
08748 #ifdef HAVE_NTRU
08749     /* NTRU public key */
08750     else if (ntruKey != NULL) {
08751         bufferSz = MAX_PUBLIC_KEY_SZ;
08752         ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
08753                         ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer);
08754         if (ret != NTRU_OK)
08755             bufferSz = -1;
08756     }
08757 #endif
08758     else
08759         bufferSz = -1;
08760 
08761     if (bufferSz <= 0) {
08762         XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
08763         return PUBLIC_KEY_E;
08764     }
08765 
08766     /* Compute SKID by hashing public key */
08767 #ifdef NO_SHA
08768     if (kid_type == SKID_TYPE) {
08769         ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
08770         cert->skidSz = SHA256_DIGEST_SIZE;
08771     }
08772     else if (kid_type == AKID_TYPE) {
08773         ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
08774         cert->akidSz = SHA256_DIGEST_SIZE;
08775     }
08776     else
08777         ret = BAD_FUNC_ARG;
08778 #else /* NO_SHA */
08779     if (kid_type == SKID_TYPE) {
08780         ret = wc_ShaHash(buffer, bufferSz, cert->skid);
08781         cert->skidSz = SHA_DIGEST_SIZE;
08782     }
08783     else if (kid_type == AKID_TYPE) {
08784         ret = wc_ShaHash(buffer, bufferSz, cert->akid);
08785         cert->akidSz = SHA_DIGEST_SIZE;
08786     }
08787     else
08788         ret = BAD_FUNC_ARG;
08789 #endif /* NO_SHA */
08790 
08791     XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
08792     return ret;
08793 }
08794 
08795 /* Set SKID from RSA or ECC public key */
08796 int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
08797 {
08798     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, SKID_TYPE);
08799 }
08800 
08801 #ifdef HAVE_NTRU
08802 /* Set SKID from NTRU public key */
08803 int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,
08804                                         byte *ntruKey, word16 ntruKeySz)
08805 {
08806     return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, SKID_TYPE);
08807 }
08808 #endif
08809 
08810 /* Set SKID from RSA or ECC public key */
08811 int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
08812 {
08813     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, AKID_TYPE);
08814 }
08815 
08816 
08817 #ifndef NO_FILESYSTEM
08818 
08819 /* Set SKID from public key file in PEM */
08820 int wc_SetSubjectKeyId(Cert *cert, const char* file)
08821 {
08822     int     ret, derSz;
08823     byte*   der;
08824     word32  idx;
08825     RsaKey  *rsakey = NULL;
08826     ecc_key *eckey = NULL;
08827 
08828     if (cert == NULL || file == NULL)
08829         return BAD_FUNC_ARG;
08830 
08831     der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
08832     if (der == NULL) {
08833         WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
08834         return MEMORY_E;
08835     }
08836 
08837     derSz = wolfSSL_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
08838     if (derSz <= 0)
08839     {
08840         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08841         return derSz;
08842     }
08843 
08844     /* Load PubKey in internal structure */
08845     rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
08846     if (rsakey == NULL) {
08847         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08848         return MEMORY_E;
08849     }
08850 
08851     if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
08852         WOLFSSL_MSG("wc_InitRsaKey failure");
08853         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
08854         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08855         return MEMORY_E;
08856     }
08857 
08858     idx = 0;
08859     ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
08860     if (ret != 0) {
08861         WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
08862         wc_FreeRsaKey(rsakey);
08863         XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
08864         rsakey = NULL;
08865 #ifdef HAVE_ECC
08866         /* Check to load ecc public key */
08867         eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
08868                                                               DYNAMIC_TYPE_ECC);
08869         if (eckey == NULL) {
08870             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08871             return MEMORY_E;
08872         }
08873 
08874         if (wc_ecc_init(eckey) != 0) {
08875             WOLFSSL_MSG("wc_ecc_init failure");
08876             wc_ecc_free(eckey);
08877             XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
08878             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08879             return MEMORY_E;
08880         }
08881 
08882         idx = 0;
08883         ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
08884         if (ret != 0) {
08885             WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
08886             XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08887             wc_ecc_free(eckey);
08888             return PUBLIC_KEY_E;
08889         }
08890 #else
08891         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08892         return PUBLIC_KEY_E;
08893 #endif /* HAVE_ECC */
08894     }
08895 
08896     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08897 
08898     ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
08899 
08900     wc_FreeRsaKey(rsakey);
08901     XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
08902 #ifdef HAVE_ECC
08903     wc_ecc_free(eckey);
08904     XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
08905 #endif
08906     return ret;
08907 }
08908 
08909 #endif /* NO_FILESYSTEM */
08910 
08911 /* Set AKID from certificate contains in buffer (DER encoded) */
08912 int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
08913 {
08914     int ret;
08915 
08916 #ifdef WOLFSSL_SMALL_STACK
08917     DecodedCert* decoded;
08918 #else
08919     DecodedCert decoded[1];
08920 #endif
08921 
08922     if (cert == NULL || der == NULL || derSz <= 0)
08923         return BAD_FUNC_ARG;
08924 
08925 #ifdef WOLFSSL_SMALL_STACK
08926     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
08927                                     NULL, DYNAMIC_TYPE_TMP_BUFFER);
08928     if (decoded == NULL)
08929         return MEMORY_E;
08930 #endif
08931 
08932     /* decode certificate and get SKID that will be AKID of current cert */
08933     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
08934     ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
08935     if (ret != 0) {
08936         FreeDecodedCert(decoded);
08937         #ifdef WOLFSSL_SMALL_STACK
08938             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08939         #endif
08940         return ret;
08941     }
08942 
08943     /* Subject Key Id not found !! */
08944     if (decoded->extSubjKeyIdSet == 0) {
08945         FreeDecodedCert(decoded);
08946         #ifdef WOLFSSL_SMALL_STACK
08947             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08948         #endif
08949         return ASN_NO_SKID;
08950     }
08951 
08952     /* SKID invalid size */
08953     if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
08954         FreeDecodedCert(decoded);
08955         #ifdef WOLFSSL_SMALL_STACK
08956             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08957         #endif
08958         return MEMORY_E;
08959     }
08960 
08961     /* Put the SKID of CA to AKID of certificate */
08962     XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
08963     cert->akidSz = KEYID_SIZE;
08964 
08965     FreeDecodedCert(decoded);
08966     #ifdef WOLFSSL_SMALL_STACK
08967         XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08968     #endif
08969 
08970     return 0;
08971 }
08972 
08973 
08974 #ifndef NO_FILESYSTEM
08975 
08976 /* Set AKID from certificate file in PEM */
08977 int wc_SetAuthKeyId(Cert *cert, const char* file)
08978 {
08979     int         ret;
08980     int         derSz;
08981     byte*       der;
08982 
08983     if (cert == NULL || file == NULL)
08984         return BAD_FUNC_ARG;
08985 
08986     der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
08987     if (der == NULL) {
08988         WOLFSSL_MSG("wc_SetAuthKeyId OOF Problem");
08989         return MEMORY_E;
08990     }
08991 
08992     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
08993     if (derSz <= 0)
08994     {
08995         XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
08996         return derSz;
08997     }
08998 
08999     ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);
09000     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
09001 
09002     return ret;
09003 }
09004 
09005 #endif /* NO_FILESYSTEM */
09006 
09007 /* Set KeyUsage from human readable string */
09008 int wc_SetKeyUsage(Cert *cert, const char *value)
09009 {
09010     int ret = 0;
09011     char *token, *str, *ptr;
09012     word32 len;
09013 
09014     if (cert == NULL || value == NULL)
09015         return BAD_FUNC_ARG;
09016 
09017     cert->keyUsage = 0;
09018 
09019     str = (char *)XMALLOC(XSTRLEN(value)+1, cert->heap,
09020                                                        DYNAMIC_TYPE_TMP_BUFFER);
09021     if (str == NULL)
09022         return MEMORY_E;
09023 
09024     XMEMSET(str, 0, XSTRLEN(value)+1);
09025     XSTRNCPY(str, value, XSTRLEN(value));
09026 
09027     /* parse value, and set corresponding Key Usage value */
09028     token = XSTRTOK(str, ",", &ptr);
09029     while (token != NULL)
09030     {
09031         len = (word32)XSTRLEN(token);
09032 
09033         if (!XSTRNCASECMP(token, "digitalSignature", len))
09034             cert->keyUsage |= KEYUSE_DIGITAL_SIG;
09035         else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
09036                  !XSTRNCASECMP(token, "contentCommitment", len))
09037             cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
09038         else if (!XSTRNCASECMP(token, "keyEncipherment", len))
09039             cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
09040         else if (!XSTRNCASECMP(token, "dataEncipherment", len))
09041             cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
09042         else if (!XSTRNCASECMP(token, "keyAgreement", len))
09043             cert->keyUsage |= KEYUSE_KEY_AGREE;
09044         else if (!XSTRNCASECMP(token, "keyCertSign", len))
09045             cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
09046         else if (!XSTRNCASECMP(token, "cRLSign", len))
09047             cert->keyUsage |= KEYUSE_CRL_SIGN;
09048         else if (!XSTRNCASECMP(token, "encipherOnly", len))
09049             cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
09050         else if (!XSTRNCASECMP(token, "decipherOnly", len))
09051             cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
09052         else {
09053             ret = KEYUSAGE_E;
09054             break;
09055         }
09056 
09057         token = XSTRTOK(NULL, ",", &ptr);
09058     }
09059 
09060     XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
09061     return ret;
09062 }
09063 #endif /* WOLFSSL_CERT_EXT */
09064 
09065 
09066 #ifdef WOLFSSL_ALT_NAMES
09067 
09068 /* Set Alt Names from der cert, return 0 on success */
09069 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
09070 {
09071     int ret;
09072 #ifdef WOLFSSL_SMALL_STACK
09073     DecodedCert* decoded;
09074 #else
09075     DecodedCert decoded[1];
09076 #endif
09077 
09078     if (derSz < 0)
09079         return derSz;
09080 
09081 #ifdef WOLFSSL_SMALL_STACK
09082     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
09083                                                        DYNAMIC_TYPE_TMP_BUFFER);
09084     if (decoded == NULL)
09085         return MEMORY_E;
09086 #endif
09087 
09088     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
09089     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
09090 
09091     if (ret < 0) {
09092         WOLFSSL_MSG("ParseCertRelative error");
09093     }
09094     else if (decoded->extensions) {
09095         byte   b;
09096         int    length;
09097         word32 maxExtensionsIdx;
09098 
09099         decoded->srcIdx = decoded->extensionsIdx;
09100         b = decoded->source[decoded->srcIdx++];
09101 
09102         if (b != ASN_EXTENSIONS) {
09103             ret = ASN_PARSE_E;
09104         }
09105         else if (GetLength(decoded->source, &decoded->srcIdx, &length,
09106                                                          decoded->maxIdx) < 0) {
09107             ret = ASN_PARSE_E;
09108         }
09109         else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
09110                                                          decoded->maxIdx) < 0) {
09111             ret = ASN_PARSE_E;
09112         }
09113         else {
09114             maxExtensionsIdx = decoded->srcIdx + length;
09115 
09116             while (decoded->srcIdx < maxExtensionsIdx) {
09117                 word32 oid;
09118                 word32 startIdx = decoded->srcIdx;
09119                 word32 tmpIdx;
09120 
09121                 if (GetSequence(decoded->source, &decoded->srcIdx, &length,
09122                             decoded->maxIdx) < 0) {
09123                     ret = ASN_PARSE_E;
09124                     break;
09125                 }
09126 
09127                 tmpIdx = decoded->srcIdx;
09128                 decoded->srcIdx = startIdx;
09129 
09130                 if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
09131                               oidCertExtType, decoded->maxIdx) < 0) {
09132                     ret = ASN_PARSE_E;
09133                     break;
09134                 }
09135 
09136                 if (oid == ALT_NAMES_OID) {
09137                     cert->altNamesSz = length + (tmpIdx - startIdx);
09138 
09139                     if (cert->altNamesSz < (int)sizeof(cert->altNames))
09140                         XMEMCPY(cert->altNames, &decoded->source[startIdx],
09141                                 cert->altNamesSz);
09142                     else {
09143                         cert->altNamesSz = 0;
09144                         WOLFSSL_MSG("AltNames extensions too big");
09145                         ret = ALT_NAME_E;
09146                         break;
09147                     }
09148                 }
09149                 decoded->srcIdx = tmpIdx + length;
09150             }
09151         }
09152     }
09153 
09154     FreeDecodedCert(decoded);
09155 #ifdef WOLFSSL_SMALL_STACK
09156     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09157 #endif
09158 
09159     return ret < 0 ? ret : 0;
09160 }
09161 
09162 
09163 /* Set Dates from der cert, return 0 on success */
09164 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
09165 {
09166     int ret;
09167 #ifdef WOLFSSL_SMALL_STACK
09168     DecodedCert* decoded;
09169 #else
09170     DecodedCert decoded[1];
09171 #endif
09172 
09173     WOLFSSL_ENTER("SetDatesFromCert");
09174     if (derSz < 0)
09175         return derSz;
09176 
09177 #ifdef WOLFSSL_SMALL_STACK
09178     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
09179                                                        DYNAMIC_TYPE_TMP_BUFFER);
09180     if (decoded == NULL)
09181         return MEMORY_E;
09182 #endif
09183 
09184     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
09185     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
09186 
09187     if (ret < 0) {
09188         WOLFSSL_MSG("ParseCertRelative error");
09189     }
09190     else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
09191         WOLFSSL_MSG("Couldn't extract dates");
09192         ret = -1;
09193     }
09194     else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
09195                                         decoded->afterDateLen > MAX_DATE_SIZE) {
09196         WOLFSSL_MSG("Bad date size");
09197         ret = -1;
09198     }
09199     else {
09200         XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
09201         XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
09202 
09203         cert->beforeDateSz = decoded->beforeDateLen;
09204         cert->afterDateSz  = decoded->afterDateLen;
09205     }
09206 
09207     FreeDecodedCert(decoded);
09208 
09209 #ifdef WOLFSSL_SMALL_STACK
09210     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09211 #endif
09212 
09213     return ret < 0 ? ret : 0;
09214 }
09215 
09216 
09217 #endif /* WOLFSSL_ALT_NAMES && !NO_RSA */
09218 
09219 
09220 /* Set cn name from der buffer, return 0 on success */
09221 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
09222 {
09223     int ret, sz;
09224 #ifdef WOLFSSL_SMALL_STACK
09225     DecodedCert* decoded;
09226 #else
09227     DecodedCert decoded[1];
09228 #endif
09229 
09230     if (derSz < 0)
09231         return derSz;
09232 
09233 #ifdef WOLFSSL_SMALL_STACK
09234     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
09235                                                        DYNAMIC_TYPE_TMP_BUFFER);
09236     if (decoded == NULL)
09237         return MEMORY_E;
09238 #endif
09239 
09240     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
09241     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
09242 
09243     if (ret < 0) {
09244         WOLFSSL_MSG("ParseCertRelative error");
09245     }
09246     else {
09247         if (decoded->subjectCN) {
09248             sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
09249                                                          : CTC_NAME_SIZE - 1;
09250             strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
09251             cn->commonName[sz] = 0;
09252             cn->commonNameEnc = decoded->subjectCNEnc;
09253         }
09254         if (decoded->subjectC) {
09255             sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
09256                                                         : CTC_NAME_SIZE - 1;
09257             strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE);
09258             cn->country[sz] = 0;
09259             cn->countryEnc = decoded->subjectCEnc;
09260         }
09261         if (decoded->subjectST) {
09262             sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
09263                                                          : CTC_NAME_SIZE - 1;
09264             strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE);
09265             cn->state[sz] = 0;
09266             cn->stateEnc = decoded->subjectSTEnc;
09267         }
09268         if (decoded->subjectL) {
09269             sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
09270                                                         : CTC_NAME_SIZE - 1;
09271             strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
09272             cn->locality[sz] = 0;
09273             cn->localityEnc = decoded->subjectLEnc;
09274         }
09275         if (decoded->subjectO) {
09276             sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
09277                                                         : CTC_NAME_SIZE - 1;
09278             strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE);
09279             cn->org[sz] = 0;
09280             cn->orgEnc = decoded->subjectOEnc;
09281         }
09282         if (decoded->subjectOU) {
09283             sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
09284                                                          : CTC_NAME_SIZE - 1;
09285             strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
09286             cn->unit[sz] = 0;
09287             cn->unitEnc = decoded->subjectOUEnc;
09288         }
09289         if (decoded->subjectSN) {
09290             sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
09291                                                          : CTC_NAME_SIZE - 1;
09292             strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
09293             cn->sur[sz] = 0;
09294             cn->surEnc = decoded->subjectSNEnc;
09295         }
09296         if (decoded->subjectEmail) {
09297             sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
09298                ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
09299             strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
09300             cn->email[sz] = 0;
09301         }
09302     }
09303 
09304     FreeDecodedCert(decoded);
09305 
09306 #ifdef WOLFSSL_SMALL_STACK
09307     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09308 #endif
09309 
09310     return ret < 0 ? ret : 0;
09311 }
09312 
09313 
09314 #ifndef NO_FILESYSTEM
09315 
09316 /* Set cert issuer from issuerFile in PEM */
09317 int wc_SetIssuer(Cert* cert, const char* issuerFile)
09318 {
09319     int         ret;
09320     int         derSz;
09321     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
09322 
09323     if (der == NULL) {
09324         WOLFSSL_MSG("wc_SetIssuer OOF Problem");
09325         return MEMORY_E;
09326     }
09327     derSz = wolfSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
09328     cert->selfSigned = 0;
09329     ret = SetNameFromCert(&cert->issuer, der, derSz);
09330     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
09331 
09332     return ret;
09333 }
09334 
09335 
09336 /* Set cert subject from subjectFile in PEM */
09337 int wc_SetSubject(Cert* cert, const char* subjectFile)
09338 {
09339     int         ret;
09340     int         derSz;
09341     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
09342 
09343     if (der == NULL) {
09344         WOLFSSL_MSG("wc_SetSubject OOF Problem");
09345         return MEMORY_E;
09346     }
09347     derSz = wolfSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
09348     ret = SetNameFromCert(&cert->subject, der, derSz);
09349     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
09350 
09351     return ret;
09352 }
09353 
09354 
09355 #ifdef WOLFSSL_ALT_NAMES
09356 
09357 /* Set atl names from file in PEM */
09358 int wc_SetAltNames(Cert* cert, const char* file)
09359 {
09360     int         ret;
09361     int         derSz;
09362     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
09363 
09364     if (der == NULL) {
09365         WOLFSSL_MSG("wc_SetAltNames OOF Problem");
09366         return MEMORY_E;
09367     }
09368     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
09369     ret = SetAltNamesFromCert(cert, der, derSz);
09370     XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
09371 
09372     return ret;
09373 }
09374 
09375 #endif /* WOLFSSL_ALT_NAMES */
09376 
09377 #endif /* NO_FILESYSTEM */
09378 
09379 /* Set cert issuer from DER buffer */
09380 int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
09381 {
09382     cert->selfSigned = 0;
09383     return SetNameFromCert(&cert->issuer, der, derSz);
09384 }
09385 
09386 
09387 /* Set cert subject from DER buffer */
09388 int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
09389 {
09390     return SetNameFromCert(&cert->subject, der, derSz);
09391 }
09392 
09393 
09394 #ifdef WOLFSSL_ALT_NAMES
09395 
09396 /* Set cert alt names from DER buffer */
09397 int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
09398 {
09399     return SetAltNamesFromCert(cert, der, derSz);
09400 }
09401 
09402 /* Set cert dates from DER buffer */
09403 int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
09404 {
09405     return SetDatesFromCert(cert, der, derSz);
09406 }
09407 
09408 #endif /* WOLFSSL_ALT_NAMES */
09409 
09410 #endif /* WOLFSSL_CERT_GEN */
09411 
09412 
09413 #ifdef HAVE_ECC
09414 
09415 /* Der Encode r & s ints into out, outLen is (in/out) size */
09416 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
09417 {
09418     word32 idx = 0;
09419     int    rSz;                           /* encoding size */
09420     int    sSz;
09421     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
09422 
09423     /* If the leading bit on the INTEGER is a 1, add a leading zero */
09424     int rLeadingZero = mp_leading_bit(r);
09425     int sLeadingZero = mp_leading_bit(s);
09426     int rLen = mp_unsigned_bin_size(r);   /* big int size */
09427     int sLen = mp_unsigned_bin_size(s);
09428 
09429     if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
09430                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
09431         return BUFFER_E;
09432 
09433     idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
09434 
09435     /* store r */
09436     rSz = SetASNIntMP(r, -1, &out[idx]);
09437     if (rSz < 0)
09438         return rSz;
09439     idx += rSz;
09440 
09441     /* store s */
09442     sSz = SetASNIntMP(s, -1, &out[idx]);
09443     if (sSz < 0)
09444         return sSz;
09445     idx += sSz;
09446 
09447     *outLen = idx;
09448 
09449     return 0;
09450 }
09451 
09452 
09453 /* Der Decode ECC-DSA Signature, r & s stored as big ints */
09454 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
09455 {
09456     word32 idx = 0;
09457     int    len = 0;
09458 
09459     if (GetSequence(sig, &idx, &len, sigLen) < 0) {
09460         return ASN_ECC_KEY_E;
09461     }
09462 
09463     if ((word32)len > (sigLen - idx)) {
09464         return ASN_ECC_KEY_E;
09465     }
09466 
09467     if (GetInt(r, sig, &idx, sigLen) < 0) {
09468         return ASN_ECC_KEY_E;
09469     }
09470 
09471     if (GetInt(s, sig, &idx, sigLen) < 0) {
09472         return ASN_ECC_KEY_E;
09473     }
09474 
09475     return 0;
09476 }
09477 
09478 
09479 int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
09480                         word32 inSz)
09481 {
09482     word32 oidSum;
09483     int    version, length;
09484     int    privSz, pubSz;
09485     byte   b;
09486     int    ret = 0;
09487     int    curve_id = ECC_CURVE_DEF;
09488 #ifdef WOLFSSL_SMALL_STACK
09489     byte* priv;
09490     byte* pub;
09491 #else
09492     byte priv[ECC_MAXSIZE+1];
09493     byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
09494 #endif
09495 
09496     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
09497         return BAD_FUNC_ARG;
09498 
09499     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
09500         return ASN_PARSE_E;
09501 
09502     if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
09503         return ASN_PARSE_E;
09504 
09505     b = input[*inOutIdx];
09506     *inOutIdx += 1;
09507 
09508     /* priv type */
09509     if (b != 4 && b != 6 && b != 7)
09510         return ASN_PARSE_E;
09511 
09512     if (GetLength(input, inOutIdx, &length, inSz) < 0)
09513         return ASN_PARSE_E;
09514 
09515     if (length > ECC_MAXSIZE)
09516         return BUFFER_E;
09517 
09518 #ifdef WOLFSSL_SMALL_STACK
09519     priv = (byte*)XMALLOC(ECC_MAXSIZE+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09520     if (priv == NULL)
09521         return MEMORY_E;
09522 
09523     pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
09524     if (pub == NULL) {
09525         XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09526         return MEMORY_E;
09527     }
09528 #endif
09529 
09530     /* priv key */
09531     privSz = length;
09532     XMEMCPY(priv, &input[*inOutIdx], privSz);
09533     *inOutIdx += length;
09534 
09535     if ((*inOutIdx + 1) > inSz)
09536         return BUFFER_E;
09537 
09538     /* prefix 0, may have */
09539     b = input[*inOutIdx];
09540     if (b == ECC_PREFIX_0) {
09541         *inOutIdx += 1;
09542 
09543         if (GetLength(input, inOutIdx, &length, inSz) <= 0)
09544             ret = ASN_PARSE_E;
09545         else {
09546             ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
09547             if (ret == 0) {
09548                 if ((ret = CheckCurve(oidSum)) < 0)
09549                     ret = ECC_CURVE_OID_E;
09550                 else {
09551                     curve_id = ret;
09552                     ret = 0;
09553                 }
09554             }
09555         }
09556     }
09557 
09558     if (ret == 0) {
09559         /* prefix 1 */
09560         b = input[*inOutIdx];
09561         *inOutIdx += 1;
09562 
09563         if (b != ECC_PREFIX_1) {
09564             ret = ASN_ECC_KEY_E;
09565         }
09566         else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
09567             ret = ASN_PARSE_E;
09568         }
09569         else {
09570             /* key header */
09571             ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
09572             if (ret == 0) {
09573                 /* pub key */
09574                 pubSz = length;
09575                 if (pubSz < 2*(ECC_MAXSIZE+1)) {
09576                     XMEMCPY(pub, &input[*inOutIdx], pubSz);
09577                     *inOutIdx += length;
09578                     ret = wc_ecc_import_private_key_ex(priv, privSz, pub,
09579                                                     pubSz, key, curve_id);
09580                 }
09581                 else
09582                     ret = BUFFER_E;
09583             }
09584         }
09585     }
09586 
09587 #ifdef WOLFSSL_SMALL_STACK
09588     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09589     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
09590 #endif
09591 
09592     return ret;
09593 }
09594 
09595 
09596 int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
09597                           ecc_key* key, word32 inSz)
09598 {
09599     int    length;
09600     int    ret;
09601 #ifdef ECC_CHECK_PUBLIC_KEY_OID
09602     word32 oidSum;
09603 #endif
09604 
09605     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
09606         return BAD_FUNC_ARG;
09607 
09608     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
09609         return ASN_PARSE_E;
09610 
09611     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
09612         return ASN_PARSE_E;
09613 
09614     ret = SkipObjectId(input, inOutIdx, inSz);
09615     if (ret != 0)
09616         return ret;
09617 
09618     /* ecc params information */
09619 #ifdef ECC_CHECK_PUBLIC_KEY_OID
09620     ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
09621     if (ret != 0)
09622         return ret;
09623     if (CheckCurve(oidSum) < 0)
09624         return ECC_CURVE_OID_E;
09625 #else
09626     ret = SkipObjectId(input, inOutIdx, inSz);
09627     if (ret != 0)
09628         return ret;
09629 #endif
09630 
09631     /* key header */
09632     ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
09633     if (ret != 0)
09634         return ret;
09635 
09636     /* This is the raw point data compressed or uncompressed. */
09637     if (wc_ecc_import_x963(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
09638         return ASN_ECC_KEY_E;
09639 
09640     return 0;
09641 }
09642 
09643 
09644 #ifdef WOLFSSL_KEY_GEN
09645 
09646 /* build DER formatted ECC key, include optional public key if requested,
09647  * return length on success, negative on error */
09648 static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
09649                              int pubIn)
09650 {
09651     byte   curve[MAX_ALGO_SZ+2];
09652     byte   ver[MAX_VERSION_SZ];
09653     byte   seq[MAX_SEQ_SZ];
09654     byte   *prv = NULL, *pub = NULL;
09655     int    ret, totalSz, curveSz, verSz;
09656     int    privHdrSz  = ASN_ECC_HEADER_SZ;
09657     int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
09658 
09659     word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
09660     word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
09661 
09662     if (key == NULL || output == NULL || inLen == 0)
09663         return BAD_FUNC_ARG;
09664 
09665     /* curve */
09666     curve[curveidx++] = ECC_PREFIX_0;
09667     curveidx++ /* to put the size after computation */;
09668     curveSz = SetCurve(key, curve+curveidx);
09669     if (curveSz < 0)
09670         return curveSz;
09671     /* set computed size */
09672     curve[1] = (byte)curveSz;
09673     curveidx += curveSz;
09674 
09675     /* private */
09676     privSz = key->dp->size;
09677     prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
09678                          key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09679     if (prv == NULL) {
09680         return MEMORY_E;
09681     }
09682     prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);
09683     ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
09684     if (ret < 0) {
09685         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09686         return ret;
09687     }
09688     prvidx += privSz;
09689 
09690     /* pubIn */
09691     if (pubIn) {
09692         ret = wc_ecc_export_x963(key, NULL, &pubSz);
09693         if (ret != LENGTH_ONLY_E) {
09694             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09695             return ret;
09696         }
09697 
09698         pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
09699                              key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09700         if (pub == NULL) {
09701             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09702             return MEMORY_E;
09703         }
09704 
09705         pub[pubidx++] = ECC_PREFIX_1;
09706         if (pubSz > 128) /* leading zero + extra size byte */
09707             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
09708         else /* leading zero */
09709             pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
09710 
09711         /* SetBitString adds leading zero */
09712         pubidx += SetBitString(pubSz, 0, pub + pubidx);
09713         ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
09714         if (ret != 0) {
09715             XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09716             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09717             return ret;
09718         }
09719         pubidx += pubSz;
09720     }
09721 
09722     /* make headers */
09723     verSz = SetMyVersion(1, ver, FALSE);
09724     seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
09725 
09726     totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
09727     if (totalSz > (int)inLen) {
09728         XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09729         if (pubIn) {
09730             XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09731         }
09732         return BAD_FUNC_ARG;
09733     }
09734 
09735     /* write out */
09736     /* seq */
09737     XMEMCPY(output + idx, seq, seqSz);
09738     idx = seqSz;
09739 
09740     /* ver */
09741     XMEMCPY(output + idx, ver, verSz);
09742     idx += verSz;
09743 
09744     /* private */
09745     XMEMCPY(output + idx, prv, prvidx);
09746     idx += prvidx;
09747     XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09748 
09749     /* curve */
09750     XMEMCPY(output + idx, curve, curveidx);
09751     idx += curveidx;
09752 
09753     /* pubIn */
09754     if (pubIn) {
09755         XMEMCPY(output + idx, pub, pubidx);
09756         /* idx += pubidx;  not used after write, if more data remove comment */
09757         XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
09758     }
09759 
09760     return totalSz;
09761 }
09762 
09763 
09764 /* Write a Private ecc key, including public to DER format,
09765  * length on success else < 0 */
09766 int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
09767 {
09768     return wc_BuildEccKeyDer(key, output, inLen, 1);
09769 }
09770 
09771 
09772 /* Write only private ecc key to DER format,
09773  * length on success else < 0 */
09774 int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
09775 {
09776     return wc_BuildEccKeyDer(key, output, inLen, 0);
09777 }
09778 
09779 #endif /* WOLFSSL_KEY_GEN */
09780 
09781 #endif  /* HAVE_ECC */
09782 
09783 
09784 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
09785 
09786 /* Get raw Date only, no processing, 0 on success */
09787 static int GetBasicDate(const byte* source, word32* idx, byte* date,
09788                         byte* format, int maxIdx)
09789 {
09790     int    length;
09791 
09792     WOLFSSL_ENTER("GetBasicDate");
09793 
09794     *format = source[*idx];
09795     *idx += 1;
09796     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
09797         return ASN_TIME_E;
09798 
09799     if (GetLength(source, idx, &length, maxIdx) < 0)
09800         return ASN_PARSE_E;
09801 
09802     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
09803         return ASN_DATE_SZ_E;
09804 
09805     XMEMCPY(date, &source[*idx], length);
09806     *idx += length;
09807 
09808     return 0;
09809 }
09810 
09811 #endif
09812 
09813 
09814 #ifdef HAVE_OCSP
09815 
09816 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
09817 {
09818     word32 idx = *inOutIdx;
09819     word32 len;
09820 
09821     WOLFSSL_ENTER("GetEnumerated");
09822 
09823     *value = 0;
09824 
09825     if (input[idx++] != ASN_ENUMERATED)
09826         return ASN_PARSE_E;
09827 
09828     len = input[idx++];
09829     if (len > 4)
09830         return ASN_PARSE_E;
09831 
09832     while (len--) {
09833         *value  = *value << 8 | input[idx++];
09834     }
09835 
09836     *inOutIdx = idx;
09837 
09838     return *value;
09839 }
09840 
09841 
09842 static int DecodeSingleResponse(byte* source,
09843                             word32* ioIndex, OcspResponse* resp, word32 size)
09844 {
09845     word32 idx = *ioIndex, prevIndex, oid;
09846     int length, wrapperSz;
09847     CertStatus* cs = resp->status;
09848     int ret;
09849 
09850     WOLFSSL_ENTER("DecodeSingleResponse");
09851 
09852     /* Outer wrapper of the SEQUENCE OF Single Responses. */
09853     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
09854         return ASN_PARSE_E;
09855 
09856     prevIndex = idx;
09857 
09858     /* When making a request, we only request one status on one certificate
09859      * at a time. There should only be one SingleResponse */
09860 
09861     /* Wrapper around the Single Response */
09862     if (GetSequence(source, &idx, &length, size) < 0)
09863         return ASN_PARSE_E;
09864 
09865     /* Wrapper around the CertID */
09866     if (GetSequence(source, &idx, &length, size) < 0)
09867         return ASN_PARSE_E;
09868     /* Skip the hash algorithm */
09869     if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
09870         return ASN_PARSE_E;
09871     /* Save reference to the hash of CN */
09872     ret = GetOctetString(source, &idx, &length, size);
09873     if (ret < 0)
09874         return ret;
09875     resp->issuerHash = source + idx;
09876     idx += length;
09877     /* Save reference to the hash of the issuer public key */
09878     ret = GetOctetString(source, &idx, &length, size);
09879     if (ret < 0)
09880         return ret;
09881     resp->issuerKeyHash = source + idx;
09882     idx += length;
09883 
09884     /* Get serial number */
09885     if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
09886         return ASN_PARSE_E;
09887 
09888     /* CertStatus */
09889     switch (source[idx++])
09890     {
09891         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
09892             cs->status = CERT_GOOD;
09893             idx++;
09894             break;
09895         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
09896             cs->status = CERT_REVOKED;
09897             if (GetLength(source, &idx, &length, size) < 0)
09898                 return ASN_PARSE_E;
09899             idx += length;
09900             break;
09901         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
09902             cs->status = CERT_UNKNOWN;
09903             idx++;
09904             break;
09905         default:
09906             return ASN_PARSE_E;
09907     }
09908 
09909 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
09910     cs->thisDateAsn = source + idx;
09911 #endif
09912     if (GetBasicDate(source, &idx, cs->thisDate,
09913                                                 &cs->thisDateFormat, size) < 0)
09914         return ASN_PARSE_E;
09915 
09916 #ifndef NO_ASN_TIME
09917     if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
09918         return ASN_BEFORE_DATE_E;
09919 #endif
09920 
09921     /* The following items are optional. Only check for them if there is more
09922      * unprocessed data in the singleResponse wrapper. */
09923 
09924     if (((int)(idx - prevIndex) < wrapperSz) &&
09925         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
09926     {
09927         idx++;
09928         if (GetLength(source, &idx, &length, size) < 0)
09929             return ASN_PARSE_E;
09930 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
09931         cs->nextDateAsn = source + idx;
09932 #endif
09933         if (GetBasicDate(source, &idx, cs->nextDate,
09934                                                 &cs->nextDateFormat, size) < 0)
09935             return ASN_PARSE_E;
09936 
09937 #ifndef NO_ASN_TIME
09938         if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
09939             return ASN_AFTER_DATE_E;
09940 #endif
09941     }
09942     if (((int)(idx - prevIndex) < wrapperSz) &&
09943         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
09944     {
09945         idx++;
09946         if (GetLength(source, &idx, &length, size) < 0)
09947             return ASN_PARSE_E;
09948         idx += length;
09949     }
09950 
09951     *ioIndex = idx;
09952 
09953     return 0;
09954 }
09955 
09956 static int DecodeOcspRespExtensions(byte* source,
09957                             word32* ioIndex, OcspResponse* resp, word32 sz)
09958 {
09959     word32 idx = *ioIndex;
09960     int length;
09961     int ext_bound; /* boundary index for the sequence of extensions */
09962     word32 oid;
09963     int ret;
09964 
09965     WOLFSSL_ENTER("DecodeOcspRespExtensions");
09966 
09967     if ((idx + 1) > sz)
09968         return BUFFER_E;
09969 
09970     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
09971         return ASN_PARSE_E;
09972 
09973     if (GetLength(source, &idx, &length, sz) < 0)
09974         return ASN_PARSE_E;
09975 
09976     if (GetSequence(source, &idx, &length, sz) < 0)
09977         return ASN_PARSE_E;
09978 
09979     ext_bound = idx + length;
09980 
09981     while (idx < (word32)ext_bound) {
09982         if (GetSequence(source, &idx, &length, sz) < 0) {
09983             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
09984             return ASN_PARSE_E;
09985         }
09986 
09987         oid = 0;
09988         if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
09989             WOLFSSL_MSG("\tfail: OBJECT ID");
09990             return ASN_PARSE_E;
09991         }
09992 
09993         /* check for critical flag */
09994         if (source[idx] == ASN_BOOLEAN) {
09995             WOLFSSL_MSG("\tfound optional critical flag, moving past");
09996             ret = GetBoolean(source, &idx, sz);
09997             if (ret < 0)
09998                 return ret;
09999         }
10000 
10001         ret = GetOctetString(source, &idx, &length, sz);
10002         if (ret < 0)
10003             return ret;
10004 
10005         if (oid == OCSP_NONCE_OID) {
10006             /* get data inside extra OCTET_STRING */
10007             ret = GetOctetString(source, &idx, &length, sz);
10008             if (ret < 0)
10009                 return ret;
10010 
10011             resp->nonce = source + idx;
10012             resp->nonceSz = length;
10013         }
10014 
10015         idx += length;
10016     }
10017 
10018     *ioIndex = idx;
10019     return 0;
10020 }
10021 
10022 
10023 static int DecodeResponseData(byte* source,
10024                             word32* ioIndex, OcspResponse* resp, word32 size)
10025 {
10026     word32 idx = *ioIndex, prev_idx;
10027     int length;
10028     int version;
10029     word32 responderId = 0;
10030 
10031     WOLFSSL_ENTER("DecodeResponseData");
10032 
10033     resp->response = source + idx;
10034     prev_idx = idx;
10035     if (GetSequence(source, &idx, &length, size) < 0)
10036         return ASN_PARSE_E;
10037     resp->responseSz = length + idx - prev_idx;
10038 
10039     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
10040      * item isn't an EXPLICIT[0], then set version to zero and move
10041      * onto the next item.
10042      */
10043     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
10044     {
10045         idx += 2; /* Eat the value and length */
10046         if (GetMyVersion(source, &idx, &version, size) < 0)
10047             return ASN_PARSE_E;
10048     } else
10049         version = 0;
10050 
10051     responderId = source[idx++];
10052     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
10053         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
10054     {
10055         if (GetLength(source, &idx, &length, size) < 0)
10056             return ASN_PARSE_E;
10057         idx += length;
10058     }
10059     else
10060         return ASN_PARSE_E;
10061 
10062     /* save pointer to the producedAt time */
10063     if (GetBasicDate(source, &idx, resp->producedDate,
10064                                         &resp->producedDateFormat, size) < 0)
10065         return ASN_PARSE_E;
10066 
10067     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
10068         return ASN_PARSE_E;
10069 
10070     /*
10071      * Check the length of the ResponseData against the current index to
10072      * see if there are extensions, they are optional.
10073      */
10074     if (idx - prev_idx < resp->responseSz)
10075         if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
10076             return ASN_PARSE_E;
10077 
10078     *ioIndex = idx;
10079     return 0;
10080 }
10081 
10082 
10083 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
10084 
10085 static int DecodeCerts(byte* source,
10086                             word32* ioIndex, OcspResponse* resp, word32 size)
10087 {
10088     word32 idx = *ioIndex;
10089 
10090     WOLFSSL_ENTER("DecodeCerts");
10091 
10092     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
10093     {
10094         int length;
10095 
10096         if (GetLength(source, &idx, &length, size) < 0)
10097             return ASN_PARSE_E;
10098 
10099         if (GetSequence(source, &idx, &length, size) < 0)
10100             return ASN_PARSE_E;
10101 
10102         resp->cert = source + idx;
10103         resp->certSz = length;
10104 
10105         idx += length;
10106     }
10107     *ioIndex = idx;
10108     return 0;
10109 }
10110 
10111 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
10112 
10113 
10114 static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
10115             OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
10116 {
10117     int    length;
10118     word32 idx = *ioIndex;
10119     word32 end_index;
10120     int    ret;
10121     int    sigLength;
10122 
10123     WOLFSSL_ENTER("DecodeBasicOcspResponse");
10124     (void)heap;
10125 
10126     if (GetSequence(source, &idx, &length, size) < 0)
10127         return ASN_PARSE_E;
10128 
10129     if (idx + length > size)
10130         return ASN_INPUT_E;
10131     end_index = idx + length;
10132 
10133     if (DecodeResponseData(source, &idx, resp, size) < 0)
10134         return ASN_PARSE_E;
10135 
10136     /* Get the signature algorithm */
10137     if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
10138         return ASN_PARSE_E;
10139 
10140     ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
10141     if (ret != 0)
10142         return ret;
10143 
10144     resp->sigSz = sigLength;
10145     resp->sig = source + idx;
10146     idx += sigLength;
10147 
10148     /*
10149      * Check the length of the BasicOcspResponse against the current index to
10150      * see if there are certificates, they are optional.
10151      */
10152 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
10153     if (idx < end_index)
10154     {
10155         DecodedCert cert;
10156 
10157         if (DecodeCerts(source, &idx, resp, size) < 0)
10158             return ASN_PARSE_E;
10159 
10160         InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
10161         /* Don't verify if we don't have access to Cert Manager. */
10162         ret = ParseCertRelative(&cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY,
10163                                 cm);
10164         if (ret < 0) {
10165             WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
10166             FreeDecodedCert(&cert);
10167             return ret;
10168         }
10169 
10170         /* ConfirmSignature is blocking here */
10171         ret = ConfirmSignature(&cert.sigCtx,
10172             resp->response, resp->responseSz,
10173             cert.publicKey, cert.pubKeySize, cert.keyOID,
10174             resp->sig, resp->sigSz, resp->sigOID);
10175         FreeDecodedCert(&cert);
10176 
10177         if (ret != 0) {
10178             WOLFSSL_MSG("\tOCSP Confirm signature failed");
10179             return ASN_OCSP_CONFIRM_E;
10180         }
10181     }
10182     else
10183 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
10184     {
10185         Signer* ca = NULL;
10186         int sigValid = -1;
10187 
10188         #ifndef NO_SKID
10189             ca = GetCA(cm, resp->issuerKeyHash);
10190         #else
10191             ca = GetCA(cm, resp->issuerHash);
10192         #endif
10193 
10194         if (ca) {
10195             SignatureCtx sigCtx;
10196             InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
10197 
10198             /* ConfirmSignature is blocking here */
10199             sigValid = ConfirmSignature(&sigCtx, resp->response,
10200                 resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
10201                                 resp->sig, resp->sigSz, resp->sigOID);
10202         }
10203         if (ca == NULL || sigValid != 0) {
10204             WOLFSSL_MSG("\tOCSP Confirm signature failed");
10205             return ASN_OCSP_CONFIRM_E;
10206         }
10207     }
10208 
10209     *ioIndex = idx;
10210     return 0;
10211 }
10212 
10213 
10214 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
10215                                                     byte* source, word32 inSz)
10216 {
10217     WOLFSSL_ENTER("InitOcspResponse");
10218 
10219     XMEMSET(status, 0, sizeof(CertStatus));
10220     XMEMSET(resp,   0, sizeof(OcspResponse));
10221 
10222     resp->responseStatus = -1;
10223     resp->status         = status;
10224     resp->source         = source;
10225     resp->maxIdx         = inSz;
10226 }
10227 
10228 
10229 int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
10230 {
10231     int ret;
10232     int length = 0;
10233     word32 idx = 0;
10234     byte* source = resp->source;
10235     word32 size = resp->maxIdx;
10236     word32 oid;
10237 
10238     WOLFSSL_ENTER("OcspResponseDecode");
10239 
10240     /* peel the outer SEQUENCE wrapper */
10241     if (GetSequence(source, &idx, &length, size) < 0)
10242         return ASN_PARSE_E;
10243 
10244     /* First get the responseStatus, an ENUMERATED */
10245     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
10246         return ASN_PARSE_E;
10247 
10248     if (resp->responseStatus != OCSP_SUCCESSFUL)
10249         return 0;
10250 
10251     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
10252     if (idx >= size)
10253         return ASN_INPUT_E;
10254     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
10255         return ASN_PARSE_E;
10256     if (GetLength(source, &idx, &length, size) < 0)
10257         return ASN_PARSE_E;
10258 
10259     /* Get the responseBytes SEQUENCE */
10260     if (GetSequence(source, &idx, &length, size) < 0)
10261         return ASN_PARSE_E;
10262 
10263     /* Check ObjectID for the resposeBytes */
10264     if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0)
10265         return ASN_PARSE_E;
10266     if (oid != OCSP_BASIC_OID)
10267         return ASN_PARSE_E;
10268     ret = GetOctetString(source, &idx, &length, size);
10269     if (ret < 0)
10270         return ret;
10271 
10272     ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
10273     if (ret < 0)
10274         return ret;
10275 
10276     return 0;
10277 }
10278 
10279 
10280 word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
10281 {
10282     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
10283                                        0x30, 0x01, 0x02 };
10284     byte seqArray[5][MAX_SEQ_SZ];
10285     word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
10286 
10287     WOLFSSL_ENTER("SetOcspReqExtensions");
10288 
10289     if (!req || !output || !req->nonceSz)
10290         return 0;
10291 
10292     totalSz += req->nonceSz;
10293     totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
10294     totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
10295     totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
10296     totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
10297     totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
10298 
10299     if (totalSz > size)
10300         return 0;
10301 
10302     totalSz = 0;
10303 
10304     XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
10305     totalSz += seqSz[4];
10306 
10307     XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
10308     totalSz += seqSz[3];
10309 
10310     XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
10311     totalSz += seqSz[2];
10312 
10313     XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
10314     totalSz += (word32)sizeof(NonceObjId);
10315 
10316     XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
10317     totalSz += seqSz[1];
10318 
10319     XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
10320     totalSz += seqSz[0];
10321 
10322     XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
10323     totalSz += req->nonceSz;
10324 
10325     return totalSz;
10326 }
10327 
10328 
10329 int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
10330 {
10331     byte seqArray[5][MAX_SEQ_SZ];
10332     /* The ASN.1 of the OCSP Request is an onion of sequences */
10333     byte algoArray[MAX_ALGO_SZ];
10334     byte issuerArray[MAX_ENCODED_DIG_SZ];
10335     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
10336     byte snArray[MAX_SN_SZ];
10337     byte extArray[MAX_OCSP_EXT_SZ];
10338     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
10339     int i;
10340 
10341     WOLFSSL_ENTER("EncodeOcspRequest");
10342 
10343 #ifdef NO_SHA
10344     algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
10345 #else
10346     algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
10347 #endif
10348 
10349     issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);
10350     issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);
10351     snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray);
10352     extSz       = 0;
10353 
10354     if (req->nonceSz) {
10355         /* TLS Extensions use this function too - put extensions after
10356          * ASN.1: Context Specific [2].
10357          */
10358         extSz = EncodeOcspRequestExtensions(req, extArray + 2,
10359                                             OCSP_NONCE_EXT_SZ);
10360         extSz += SetExplicit(2, extSz, extArray);
10361     }
10362 
10363     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
10364     for (i = 4; i >= 0; i--) {
10365         seqSz[i] = SetSequence(totalSz, seqArray[i]);
10366         totalSz += seqSz[i];
10367         if (i == 2) totalSz += extSz;
10368     }
10369 
10370     if (output == NULL)
10371         return totalSz;
10372     if (totalSz > size)
10373         return BUFFER_E;
10374 
10375     totalSz = 0;
10376     for (i = 0; i < 5; i++) {
10377         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
10378         totalSz += seqSz[i];
10379     }
10380 
10381     XMEMCPY(output + totalSz, algoArray, algoSz);
10382     totalSz += algoSz;
10383 
10384     XMEMCPY(output + totalSz, issuerArray, issuerSz);
10385     totalSz += issuerSz;
10386 
10387     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
10388     totalSz += issuerKeySz;
10389 
10390     XMEMCPY(output + totalSz, snArray, snSz);
10391     totalSz += snSz;
10392 
10393     if (extSz != 0) {
10394         XMEMCPY(output + totalSz, extArray, extSz);
10395         totalSz += extSz;
10396     }
10397 
10398     return totalSz;
10399 }
10400 
10401 
10402 int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
10403                                                                      void* heap)
10404 {
10405     int ret;
10406 
10407     WOLFSSL_ENTER("InitOcspRequest");
10408 
10409     if (req == NULL)
10410         return BAD_FUNC_ARG;
10411 
10412     ForceZero(req, sizeof(OcspRequest));
10413     req->heap = heap;
10414 
10415     if (cert) {
10416         XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
10417         XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
10418 
10419         req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
10420                                                      DYNAMIC_TYPE_OCSP_REQUEST);
10421         if (req->serial == NULL)
10422             return MEMORY_E;
10423 
10424         XMEMCPY(req->serial, cert->serial, cert->serialSz);
10425         req->serialSz = cert->serialSz;
10426 
10427         if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
10428             req->url = (byte*)XMALLOC(cert->extAuthInfoSz, req->heap,
10429                                                      DYNAMIC_TYPE_OCSP_REQUEST);
10430             if (req->url == NULL) {
10431                 XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
10432                 return MEMORY_E;
10433             }
10434 
10435             XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
10436             req->urlSz = cert->extAuthInfoSz;
10437         }
10438     }
10439 
10440     if (useNonce) {
10441         WC_RNG rng;
10442 
10443     #ifndef HAVE_FIPS
10444         ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
10445     #else
10446         ret = wc_InitRng(&rng);
10447     #endif
10448         if (ret != 0) {
10449             WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
10450         } else {
10451             if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
10452                 WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
10453             else
10454                 req->nonceSz = MAX_OCSP_NONCE_SZ;
10455 
10456             wc_FreeRng(&rng);
10457         }
10458     }
10459 
10460     return 0;
10461 }
10462 
10463 void FreeOcspRequest(OcspRequest* req)
10464 {
10465     WOLFSSL_ENTER("FreeOcspRequest");
10466 
10467     if (req) {
10468         if (req->serial)
10469             XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
10470 
10471         if (req->url)
10472             XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
10473     }
10474 }
10475 
10476 
10477 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
10478 {
10479     int cmp;
10480 
10481     WOLFSSL_ENTER("CompareOcspReqResp");
10482 
10483     if (req == NULL)
10484     {
10485         WOLFSSL_MSG("\tReq missing");
10486         return -1;
10487     }
10488 
10489     if (resp == NULL)
10490     {
10491         WOLFSSL_MSG("\tResp missing");
10492         return 1;
10493     }
10494 
10495     /* Nonces are not critical. The responder may not necessarily add
10496      * the nonce to the response. */
10497     if (resp->nonceSz != 0) {
10498         cmp = req->nonceSz - resp->nonceSz;
10499         if (cmp != 0)
10500         {
10501             WOLFSSL_MSG("\tnonceSz mismatch");
10502             return cmp;
10503         }
10504 
10505         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
10506         if (cmp != 0)
10507         {
10508             WOLFSSL_MSG("\tnonce mismatch");
10509             return cmp;
10510         }
10511     }
10512 
10513     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
10514     if (cmp != 0)
10515     {
10516         WOLFSSL_MSG("\tissuerHash mismatch");
10517         return cmp;
10518     }
10519 
10520     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
10521     if (cmp != 0)
10522     {
10523         WOLFSSL_MSG("\tissuerKeyHash mismatch");
10524         return cmp;
10525     }
10526 
10527     cmp = req->serialSz - resp->status->serialSz;
10528     if (cmp != 0)
10529     {
10530         WOLFSSL_MSG("\tserialSz mismatch");
10531         return cmp;
10532     }
10533 
10534     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
10535     if (cmp != 0)
10536     {
10537         WOLFSSL_MSG("\tserial mismatch");
10538         return cmp;
10539     }
10540 
10541     return 0;
10542 }
10543 
10544 #endif
10545 
10546 
10547 /* store SHA hash of NAME */
10548 WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
10549                              int maxIdx)
10550 {
10551     int    length;  /* length of all distinguished names */
10552     int    ret;
10553     word32 dummy;
10554 
10555     WOLFSSL_ENTER("GetNameHash");
10556 
10557     if (source[*idx] == ASN_OBJECT_ID) {
10558         WOLFSSL_MSG("Trying optional prefix...");
10559 
10560         if (GetLength(source, idx, &length, maxIdx) < 0)
10561             return ASN_PARSE_E;
10562 
10563         *idx += length;
10564         WOLFSSL_MSG("Got optional prefix");
10565     }
10566 
10567     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
10568      * calculated over the entire DER encoding of the Name field, including
10569      * the tag and length. */
10570     dummy = *idx;
10571     if (GetSequence(source, idx, &length, maxIdx) < 0)
10572         return ASN_PARSE_E;
10573 
10574 #ifdef NO_SHA
10575     ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
10576 #else
10577     ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
10578 #endif
10579 
10580     *idx += length;
10581 
10582     return ret;
10583 }
10584 
10585 
10586 #ifdef HAVE_CRL
10587 
10588 /* initialize decoded CRL */
10589 void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
10590 {
10591     WOLFSSL_MSG("InitDecodedCRL");
10592 
10593     dcrl->certBegin    = 0;
10594     dcrl->sigIndex     = 0;
10595     dcrl->sigLength    = 0;
10596     dcrl->signatureOID = 0;
10597     dcrl->certs        = NULL;
10598     dcrl->totalCerts   = 0;
10599     dcrl->heap         = heap;
10600     #ifdef WOLFSSL_HEAP_TEST
10601         dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
10602     #endif
10603 }
10604 
10605 
10606 /* free decoded CRL resources */
10607 void FreeDecodedCRL(DecodedCRL* dcrl)
10608 {
10609     RevokedCert* tmp = dcrl->certs;
10610 
10611     WOLFSSL_MSG("FreeDecodedCRL");
10612 
10613     while(tmp) {
10614         RevokedCert* next = tmp->next;
10615         XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
10616         tmp = next;
10617     }
10618 }
10619 
10620 
10621 /* Get Revoked Cert list, 0 on success */
10622 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
10623                       int maxIdx)
10624 {
10625     int    len;
10626     word32 end;
10627     byte   b;
10628     RevokedCert* rc;
10629 
10630     WOLFSSL_ENTER("GetRevoked");
10631 
10632     if (GetSequence(buff, idx, &len, maxIdx) < 0)
10633         return ASN_PARSE_E;
10634 
10635     end = *idx + len;
10636 
10637     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
10638                                                           DYNAMIC_TYPE_CRL);
10639     if (rc == NULL) {
10640         WOLFSSL_MSG("Alloc Revoked Cert failed");
10641         return MEMORY_E;
10642     }
10643 
10644     if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
10645                                                                 maxIdx) < 0) {
10646         XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL);
10647         return ASN_PARSE_E;
10648     }
10649 
10650     /* add to list */
10651     rc->next = dcrl->certs;
10652     dcrl->certs = rc;
10653     dcrl->totalCerts++;
10654 
10655 
10656     /* get date */
10657     b = buff[*idx];
10658     *idx += 1;
10659 
10660     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
10661         WOLFSSL_MSG("Expecting Date");
10662         return ASN_PARSE_E;
10663     }
10664 
10665     if (GetLength(buff, idx, &len, maxIdx) < 0)
10666         return ASN_PARSE_E;
10667 
10668     /* skip for now */
10669     *idx += len;
10670 
10671     if (*idx != end)  /* skip extensions */
10672         *idx = end;
10673 
10674     return 0;
10675 }
10676 
10677 
10678 /* Get CRL Signature, 0 on success */
10679 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
10680                             int maxIdx)
10681 {
10682     int    length;
10683     int    ret;
10684 
10685     WOLFSSL_ENTER("GetCRL_Signature");
10686 
10687     ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
10688     if (ret != 0)
10689         return ret;
10690     dcrl->sigLength = length;
10691 
10692     dcrl->signature = (byte*)&source[*idx];
10693     *idx += dcrl->sigLength;
10694 
10695     return 0;
10696 }
10697 
10698 
10699 /* prase crl buffer into decoded state, 0 on success */
10700 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
10701 {
10702     int     ret = 0, version, len, doNextDate = 1;
10703     word32  oid, idx = 0, dateIdx;
10704     Signer* ca = NULL;
10705 
10706     WOLFSSL_MSG("ParseCRL");
10707 
10708     /* raw crl hash */
10709     /* hash here if needed for optimized comparisons
10710      * Sha     sha;
10711      * wc_InitSha(&sha);
10712      * wc_ShaUpdate(&sha, buff, sz);
10713      * wc_ShaFinal(&sha, dcrl->crlHash); */
10714 
10715     if (GetSequence(buff, &idx, &len, sz) < 0)
10716         return ASN_PARSE_E;
10717 
10718     dcrl->certBegin = idx;
10719 
10720     if (GetSequence(buff, &idx, &len, sz) < 0)
10721         return ASN_PARSE_E;
10722     dcrl->sigIndex = len + idx;
10723 
10724     /* may have version */
10725     if (buff[idx] == ASN_INTEGER) {
10726         if (GetMyVersion(buff, &idx, &version, sz) < 0)
10727             return ASN_PARSE_E;
10728     }
10729 
10730     if (GetAlgoId(buff, &idx, &oid, oidIgnoreType, sz) < 0)
10731         return ASN_PARSE_E;
10732 
10733     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
10734         return ASN_PARSE_E;
10735 
10736     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
10737         return ASN_PARSE_E;
10738 
10739     dateIdx = idx;
10740 
10741     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
10742     {
10743 #ifndef WOLFSSL_NO_CRL_NEXT_DATE
10744         (void)dateIdx;
10745         return ASN_PARSE_E;
10746 #else
10747         dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
10748         doNextDate = 0;
10749         idx = dateIdx;
10750 #endif
10751     }
10752 
10753     if (doNextDate) {
10754 #ifndef NO_ASN_TIME
10755         if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
10756             WOLFSSL_MSG("CRL after date is no longer valid");
10757             return ASN_AFTER_DATE_E;
10758         }
10759 #endif
10760     }
10761 
10762     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
10763         if (GetSequence(buff, &idx, &len, sz) < 0)
10764             return ASN_PARSE_E;
10765 
10766         len += idx;
10767 
10768         while (idx < (word32)len) {
10769             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
10770                 return ASN_PARSE_E;
10771         }
10772     }
10773 
10774     if (idx != dcrl->sigIndex)
10775         idx = dcrl->sigIndex;   /* skip extensions */
10776 
10777     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
10778         return ASN_PARSE_E;
10779 
10780     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
10781         return ASN_PARSE_E;
10782 
10783     /* openssl doesn't add skid by default for CRLs cause firefox chokes
10784        we're not assuming it's available yet */
10785 #if !defined(NO_SKID) && defined(CRL_SKID_READY)
10786     if (dcrl->extAuthKeyIdSet)
10787         ca = GetCA(cm, dcrl->extAuthKeyId);
10788     if (ca == NULL)
10789         ca = GetCAByName(cm, dcrl->issuerHash);
10790 #else
10791     ca = GetCA(cm, dcrl->issuerHash);
10792 #endif /* !NO_SKID && CRL_SKID_READY */
10793     WOLFSSL_MSG("About to verify CRL signature");
10794 
10795     if (ca) {
10796         SignatureCtx sigCtx;
10797 
10798         WOLFSSL_MSG("Found CRL issuer CA");
10799         /* try to confirm/verify signature */
10800     #ifndef IGNORE_KEY_EXTENSIONS
10801         if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
10802             WOLFSSL_MSG("CA cannot sign CRLs");
10803             return ASN_CRL_NO_SIGNER_E;
10804         }
10805     #endif /* IGNORE_KEY_EXTENSIONS */
10806 
10807         InitSignatureCtx(&sigCtx, dcrl->heap, INVALID_DEVID);
10808         if (ConfirmSignature(&sigCtx, buff + dcrl->certBegin,
10809                 dcrl->sigIndex - dcrl->certBegin,
10810                 ca->publicKey, ca->pubKeySize, ca->keyOID,
10811                 dcrl->signature, dcrl->sigLength, dcrl->signatureOID) != 0) {
10812             WOLFSSL_MSG("CRL Confirm signature failed");
10813             return ASN_CRL_CONFIRM_E;
10814         }
10815     }
10816     else {
10817         WOLFSSL_MSG("Did NOT find CRL issuer CA");
10818         return ASN_CRL_NO_SIGNER_E;
10819     }
10820 
10821     return ret;
10822 }
10823 
10824 #endif /* HAVE_CRL */
10825 
10826 #undef ERROR_OUT
10827 
10828 #endif /* !NO_ASN */
10829 
10830 #ifdef WOLFSSL_SEP
10831 
10832 
10833 #endif /* WOLFSSL_SEP */
10834