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