Ignore:
Timestamp:
Feb 7, 2019, 8:36:33 AM (5 years ago)
Author:
coas-nagasima
Message:

wolfsslを3.15.7にバージョンアップ

File:
1 edited

Legend:

Unmodified
Added
Removed
  • asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/asn.c

    r337 r372  
    3535 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
    3636 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
     37 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
     38    restore 3.13.0 behavior.
    3739 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
    3840    must still be trusted)
     
    4547 * WOLFSSL_ALT_CERT_CHAINS: Allows matching multiple CA's to validate
    4648    chain based on issuer and public key (includes signature confirmation)
     49 * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
     50    DecodedCert. Doubles up on some code but allows smaller dynamic memory
     51    usage.
    4752*/
    4853
    4954#ifndef NO_ASN
    50 
    51 #ifdef HAVE_RTP_SYS
    52     #include "os.h"           /* dc_rtc_api needs    */
    53     #include "dc_rtc_api.h"   /* to get current time */
    54 #endif
    5555
    5656#include <wolfssl/wolfcrypt/asn.h>
     
    6161#include <wolfssl/wolfcrypt/pwdbased.h>
    6262#include <wolfssl/wolfcrypt/des3.h>
     63#include <wolfssl/wolfcrypt/aes.h>
     64#include <wolfssl/wolfcrypt/wc_encrypt.h>
    6365#include <wolfssl/wolfcrypt/logging.h>
    6466
     
    7274#endif
    7375
     76#ifndef NO_PWDBASED
     77    #include <wolfssl/wolfcrypt/aes.h>
     78#endif
    7479#ifndef NO_RC4
    7580    #include <wolfssl/wolfcrypt/arc4.h>
     
    112117#endif
    113118
     119
    114120#ifdef _MSC_VER
    115121    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
     
    119125#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
    120126
    121 #ifndef NO_ASN_TIME
    122 #if defined(USER_TIME)
    123     /* Use our gmtime and time_t/struct tm types.
    124        Only needs seconds since EPOCH using XTIME function.
    125        time_t XTIME(time_t * timer) {}
    126     */
    127     #define WOLFSSL_GMTIME
    128     #define USE_WOLF_TM
    129     #define USE_WOLF_TIME_T
    130 
    131 #elif defined(TIME_OVERRIDES)
    132     /* Override XTIME() and XGMTIME() functionality.
    133        Requires user to provide these functions:
    134         time_t XTIME(time_t * timer) {}
    135         struct tm* XGMTIME(const time_t* timer, struct tm* tmp) {}
    136     */
    137     #ifndef HAVE_TIME_T_TYPE
    138         #define USE_WOLF_TIME_T
    139     #endif
    140     #ifndef HAVE_TM_TYPE
    141         #define USE_WOLF_TM
    142     #endif
    143     #define NEED_TMP_TIME
    144 
    145 #elif defined(HAVE_RTP_SYS)
    146     /* uses parital <time.h> structures */
    147     #define XTIME(tl)       (0)
    148     #define XGMTIME(c, t)   rtpsys_gmtime((c))
    149 
    150 #elif defined(MICRIUM)
    151     #include <clk.h>
    152     #include <time.h>
    153     #define XTIME(t1)       micrium_time((t1))
    154     #define WOLFSSL_GMTIME
    155 
    156 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
    157     #include <time.h>
    158     #define XTIME(t1)       pic32_time((t1))
    159     #define XGMTIME(c, t)   gmtime((c))
    160 
    161 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    162     #define XTIME(t1)       mqx_time((t1))
    163     #define HAVE_GMTIME_R
    164 
    165 #elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || \
    166         defined(FREESCALE_KSDK_FREERTOS)
    167     #include <time.h>
    168     #ifndef XTIME
    169         /*extern time_t ksdk_time(time_t* timer);*/
    170         #define XTIME(t1)   ksdk_time((t1))
    171     #endif
    172     #define XGMTIME(c, t)   gmtime((c))
    173 
    174 #elif defined(WOLFSSL_ATMEL)
    175     #define XTIME(t1)       atmel_get_curr_time_and_date((t1))
    176     #define WOLFSSL_GMTIME
    177     #define USE_WOLF_TM
    178     #define USE_WOLF_TIME_T
    179 
    180 #elif defined(IDIRECT_DEV_TIME)
    181     /*Gets the timestamp from cloak software owned by VT iDirect
    182     in place of time() from <time.h> */
    183     #include <time.h>
    184     #define XTIME(t1)       idirect_time((t1))
    185     #define XGMTIME(c, t)   gmtime((c))
    186 
    187 #elif defined(_WIN32_WCE)
    188     #include <windows.h>
    189     #define XTIME(t1)       windows_time((t1))
    190     #define WOLFSSL_GMTIME
    191 #else
    192 
    193     /* default */
    194     /* uses complete <time.h> facility */
    195     #include <time.h>
    196 #endif
    197 
    198 
    199 /* Map default time functions */
    200 #if !defined(XTIME) && !defined(TIME_OVERRIDES) && !defined(USER_TIME)
    201     #define XTIME(tl)       time((tl))
    202 #endif
    203 #if !defined(XGMTIME) && !defined(TIME_OVERRIDES)
    204     #if defined(WOLFSSL_GMTIME) || !defined(HAVE_GMTIME_R)
    205         #define XGMTIME(c, t)   gmtime((c))
    206     #else
    207         #define XGMTIME(c, t)   gmtime_r((c), (t))
    208         #define NEED_TMP_TIME
    209     #endif
    210 #endif
    211 #if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE)
    212     #define USE_WOLF_VALIDDATE
    213     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
    214 #endif
    215 
    216 /* wolf struct tm and time_t */
    217 #if defined(USE_WOLF_TM)
    218     struct tm {
    219         int  tm_sec;     /* seconds after the minute [0-60] */
    220         int  tm_min;     /* minutes after the hour [0-59] */
    221         int  tm_hour;    /* hours since midnight [0-23] */
    222         int  tm_mday;    /* day of the month [1-31] */
    223         int  tm_mon;     /* months since January [0-11] */
    224         int  tm_year;    /* years since 1900 */
    225         int  tm_wday;    /* days since Sunday [0-6] */
    226         int  tm_yday;    /* days since January 1 [0-365] */
    227         int  tm_isdst;   /* Daylight Savings Time flag */
    228         long tm_gmtoff;  /* offset from CUT in seconds */
    229         char *tm_zone;   /* timezone abbreviation */
     127#ifdef HAVE_SELFTEST
     128    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
     129    enum Asn_Misc {
     130        AES_IV_SIZE         = 16,
     131        AES_128_KEY_SIZE    = 16,
     132        AES_192_KEY_SIZE    = 24,
     133        AES_256_KEY_SIZE    = 32
    230134    };
    231 #endif /* USE_WOLF_TM */
    232 #if defined(USE_WOLF_TIME_T)
    233     typedef long time_t;
    234 #endif
    235 
    236 /* forward declarations */
    237 #if defined(USER_TIME)
    238     struct tm* gmtime(const time_t* timer);
    239     extern time_t XTIME(time_t * timer);
    240 
    241     #ifdef STACK_TRAP
    242         /* for stack trap tracking, don't call os gmtime on OS X/linux,
    243            uses a lot of stack spce */
    244         extern time_t time(time_t * timer);
    245         #define XTIME(tl)  time((tl))
    246     #endif /* STACK_TRAP */
    247 
    248 #elif defined(TIME_OVERRIDES)
    249     extern time_t XTIME(time_t * timer);
    250     extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
    251 #elif defined(WOLFSSL_GMTIME)
    252     struct tm* gmtime(const time_t* timer);
    253 #endif
    254 
    255 
    256 #if defined(_WIN32_WCE)
    257 time_t windows_time(time_t* timer)
    258 {
    259     SYSTEMTIME     sysTime;
    260     FILETIME       fTime;
    261     ULARGE_INTEGER intTime;
    262     time_t         localTime;
    263 
    264     if (timer == NULL)
    265         timer = &localTime;
    266 
    267     GetSystemTime(&sysTime);
    268     SystemTimeToFileTime(&sysTime, &fTime);
    269 
    270     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
    271     /* subtract EPOCH */
    272     intTime.QuadPart -= 0x19db1ded53e8000;
    273     /* to secs */
    274     intTime.QuadPart /= 10000000;
    275     *timer = (time_t)intTime.QuadPart;
    276 
    277     return *timer;
    278 }
    279 #endif /*  _WIN32_WCE */
    280 
    281 #if defined(WOLFSSL_GMTIME)
    282 struct tm* gmtime(const time_t* timer)
    283 {
    284     #define YEAR0          1900
    285     #define EPOCH_YEAR     1970
    286     #define SECS_DAY       (24L * 60L * 60L)
    287     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
    288     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
    289 
    290     static const int _ytab[2][12] =
    291     {
    292         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    293         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    294     };
    295 
    296     static struct tm st_time;
    297     struct tm* ret = &st_time;
    298     time_t secs = *timer;
    299     unsigned long dayclock, dayno;
    300     int year = EPOCH_YEAR;
    301 
    302     dayclock = (unsigned long)secs % SECS_DAY;
    303     dayno    = (unsigned long)secs / SECS_DAY;
    304 
    305     ret->tm_sec  = (int) dayclock % 60;
    306     ret->tm_min  = (int)(dayclock % 3600) / 60;
    307     ret->tm_hour = (int) dayclock / 3600;
    308     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
    309 
    310     while(dayno >= (unsigned long)YEARSIZE(year)) {
    311         dayno -= YEARSIZE(year);
    312         year++;
    313     }
    314 
    315     ret->tm_year = year - YEAR0;
    316     ret->tm_yday = (int)dayno;
    317     ret->tm_mon  = 0;
    318 
    319     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
    320         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
    321         ret->tm_mon++;
    322     }
    323 
    324     ret->tm_mday  = (int)++dayno;
    325     ret->tm_isdst = 0;
    326 
    327     return ret;
    328 }
    329 #endif /* WOLFSSL_GMTIME */
    330 
    331 
    332 #if defined(HAVE_RTP_SYS)
    333 #define YEAR0          1900
    334 
    335 struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
    336 {
    337     static struct tm st_time;
    338     struct tm* ret = &st_time;
    339 
    340     DC_RTC_CALENDAR cal;
    341     dc_rtc_time_get(&cal, TRUE);
    342 
    343     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
    344     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
    345     ret->tm_mday  = cal.day;
    346     ret->tm_hour  = cal.hour;
    347     ret->tm_min   = cal.minute;
    348     ret->tm_sec   = cal.second;
    349 
    350     return ret;
    351 }
    352 
    353 #endif /* HAVE_RTP_SYS */
    354 
    355 
    356 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
    357 
    358 /*
    359  * time() is just a stub in Microchip libraries. We need our own
    360  * implementation. Use SNTP client to get seconds since epoch.
    361  */
    362 time_t pic32_time(time_t* timer)
    363 {
    364 #ifdef MICROCHIP_TCPIP_V5
    365     DWORD sec = 0;
    366 #else
    367     uint32_t sec = 0;
    368 #endif
    369     time_t localTime;
    370 
    371     if (timer == NULL)
    372         timer = &localTime;
    373 
    374 #ifdef MICROCHIP_MPLAB_HARMONY
    375     sec = TCPIP_SNTP_UTCSecondsGet();
    376 #else
    377     sec = SNTPGetUTCSeconds();
    378 #endif
    379     *timer = (time_t) sec;
    380 
    381     return *timer;
    382 }
    383 
    384 #endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
    385 
    386 
    387 #if defined(MICRIUM)
    388 
    389 time_t micrium_time(time_t* timer)
    390 {
    391     CLK_TS_SEC sec;
    392 
    393     Clk_GetTS_Unix(&sec);
    394 
    395     return (time_t) sec;
    396 }
    397 
    398 #endif /* MICRIUM */
    399 
    400 
    401 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    402 
    403 time_t mqx_time(time_t* timer)
    404 {
    405     time_t localTime;
    406     TIME_STRUCT time_s;
    407 
    408     if (timer == NULL)
    409         timer = &localTime;
    410 
    411     _time_get(&time_s);
    412     *timer = (time_t) time_s.SECONDS;
    413 
    414     return *timer;
    415 }
    416 
    417 #endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
    418 
    419 
    420 #if defined(WOLFSSL_TIRTOS)
    421 
    422 time_t XTIME(time_t * timer)
    423 {
    424     time_t sec = 0;
    425 
    426     sec = (time_t) Seconds_get();
    427 
    428     if (timer != NULL)
    429         *timer = sec;
    430 
    431     return sec;
    432 }
    433 
    434 #endif /* WOLFSSL_TIRTOS */
    435 
    436 
    437 #if defined(WOLFSSL_XILINX)
    438 #include "xrtcpsu.h"
    439 
    440 time_t XTIME(time_t * timer)
    441 {
    442     time_t sec = 0;
    443     XRtcPsu_Config* con;
    444     XRtcPsu         rtc;
    445 
    446     con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
    447     if (con != NULL) {
    448         if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {
    449             sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);
    450         }
    451         else {
    452             WOLFSSL_MSG("Unable to initialize RTC");
    453         }
    454     }
    455 
    456     if (timer != NULL)
    457         *timer = sec;
    458 
    459     return sec;
    460 }
    461 
    462 #endif /* WOLFSSL_TIRTOS */
    463 
    464 
    465 /* two byte date/time, add to value */
    466 static INLINE void GetTime(int* value, const byte* date, int* idx)
    467 {
    468     int i = *idx;
    469 
    470     *value += btoi(date[i++]) * 10;
    471     *value += btoi(date[i++]);
    472 
    473     *idx = i;
    474 }
    475 
    476 
    477 #if defined(IDIRECT_DEV_TIME)
    478 
    479 extern time_t getTimestamp();
    480 
    481 time_t idirect_time(time_t * timer)
    482 {
    483     time_t sec = getTimestamp();
    484 
    485     if (timer != NULL)
    486         *timer = sec;
    487 
    488     return sec;
    489 }
    490 
    491 #endif /* IDIRECT_DEV_TIME */
    492 
    493 #endif /* !NO_ASN_TIME */
    494 
     135#endif
     136#endif
    495137
    496138WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
    497139                           word32 maxIdx)
     140{
     141    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
     142}
     143
     144
     145/* give option to check length value found against index. 1 to check 0 to not */
     146WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
     147                           word32 maxIdx, int check)
    498148{
    499149    int     length = 0;
     
    525175        length = b;
    526176
    527     if ((idx + length) > maxIdx) {   /* for user of length */
     177    if (check && (idx + length) > maxIdx) {   /* for user of length */
    528178        WOLFSSL_MSG("GetLength value exceeds buffer length");
    529179        return BUFFER_E;
     
    534184        *len = length;
    535185
     186    return length;
     187}
     188
     189
     190static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len,
     191                        word32 maxIdx, int check)
     192{
     193    word32 idx = *inOutIdx;
     194    byte   b;
     195    int    length;
     196
     197    if ((idx + 1) > maxIdx)
     198        return BUFFER_E;
     199
     200    b = input[idx++];
     201    if (b != tag)
     202        return ASN_PARSE_E;
     203
     204    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
     205        return ASN_PARSE_E;
     206
     207    *len      = length;
     208    *inOutIdx = idx;
    536209    return length;
    537210}
     
    552225                        word32 maxIdx)
    553226{
    554     word32 idx = *inOutIdx;
    555     byte   b;
    556     int    length;
    557 
    558     if ((idx + 1) > maxIdx)
    559         return BUFFER_E;
    560 
    561     b = input[idx++];
    562     if (b != tag)
    563         return ASN_PARSE_E;
    564 
    565     if (GetLength(input, &idx, &length, maxIdx) < 0)
    566         return ASN_PARSE_E;
    567 
    568     *len      = length;
    569     *inOutIdx = idx;
    570     return length;
    571 }
     227    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
     228}
     229
    572230
    573231WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
     
    576234    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
    577235                        maxIdx);
     236}
     237
     238
     239WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
     240                           word32 maxIdx, int check)
     241{
     242    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
     243                        maxIdx, check);
    578244}
    579245
     
    724390                return ASN_PARSE_E;
    725391        }
    726         else if ((input[*inOutIdx] & 0x80) == 0x80)
    727             return ASN_PARSE_E;
    728392    }
    729393
     
    759423}
    760424
     425
     426#if !defined(NO_DSA) && !defined(NO_SHA)
     427static char sigSha1wDsaName[] = "SHAwDSA";
     428#endif /* NO_DSA */
     429#ifndef NO_RSA
     430#ifdef WOLFSSL_MD2
     431    static char sigMd2wRsaName[] = "MD2wRSA";
     432#endif
     433#ifndef NO_MD5
     434    static char sigMd5wRsaName[] = "MD5wRSA";
     435#endif
     436#ifndef NO_SHA
     437    static char sigSha1wRsaName[] = "SHAwRSA";
     438#endif
     439#ifdef WOLFSSL_SHA224
     440    static char sigSha224wRsaName[] = "SHA224wRSA";
     441#endif
     442#ifndef NO_SHA256
     443    static char sigSha256wRsaName[] = "SHA256wRSA";
     444#endif
     445#ifdef WOLFSSL_SHA384
     446    static char sigSha384wRsaName[] = "SHA384wRSA";
     447#endif
     448#ifdef WOLFSSL_SHA512
     449    static char sigSha512wRsaName[] = "SHA512wRSA";
     450#endif
     451#endif /* NO_RSA */
     452#ifdef HAVE_ECC
     453#ifndef NO_SHA
     454    static char sigSha1wEcdsaName[] = "SHAwECDSA";
     455#endif
     456#ifdef WOLFSSL_SHA224
     457    static char sigSha224wEcdsaName[] = "SHA224wECDSA";
     458#endif
     459#ifndef NO_SHA256
     460    static char sigSha256wEcdsaName[] = "SHA256wECDSA";
     461#endif
     462#ifdef WOLFSSL_SHA384
     463    static char sigSha384wEcdsaName[] = "SHA384wECDSA";
     464#endif
     465#ifdef WOLFSSL_SHA512
     466    static char sigSha512wEcdsaName[] = "SHA512wECDSA";
     467#endif
     468#endif /* HAVE_ECC */
     469static char sigUnknownName[] = "Unknown";
     470
     471
     472/* Get the human readable string for a signature type
     473 *
     474 * oid  Oid value for signature
     475 */
     476char* GetSigName(int oid) {
     477    switch (oid) {
     478    #if !defined(NO_DSA) && !defined(NO_SHA)
     479        case CTC_SHAwDSA:
     480            return sigSha1wDsaName;
     481    #endif /* NO_DSA && NO_SHA */
     482    #ifndef NO_RSA
     483        #ifdef WOLFSSL_MD2
     484        case CTC_MD2wRSA:
     485            return sigMd2wRsaName;
     486        #endif
     487        #ifndef NO_MD5
     488        case CTC_MD5wRSA:
     489            return sigMd5wRsaName;
     490        #endif
     491        #ifndef NO_SHA
     492        case CTC_SHAwRSA:
     493            return sigSha1wRsaName;
     494        #endif
     495        #ifdef WOLFSSL_SHA224
     496        case CTC_SHA224wRSA:
     497            return sigSha224wRsaName;
     498        #endif
     499        #ifndef NO_SHA256
     500        case CTC_SHA256wRSA:
     501            return sigSha256wRsaName;
     502        #endif
     503        #ifdef WOLFSSL_SHA384
     504        case CTC_SHA384wRSA:
     505            return sigSha384wRsaName;
     506        #endif
     507        #ifdef WOLFSSL_SHA512
     508        case CTC_SHA512wRSA:
     509            return sigSha512wRsaName;
     510        #endif
     511    #endif /* NO_RSA */
     512    #ifdef HAVE_ECC
     513        #ifndef NO_SHA
     514        case CTC_SHAwECDSA:
     515            return sigSha1wEcdsaName;
     516        #endif
     517        #ifdef WOLFSSL_SHA224
     518        case CTC_SHA224wECDSA:
     519            return sigSha224wEcdsaName;
     520        #endif
     521        #ifndef NO_SHA256
     522        case CTC_SHA256wECDSA:
     523            return sigSha256wEcdsaName;
     524        #endif
     525        #ifdef WOLFSSL_SHA384
     526        case CTC_SHA384wECDSA:
     527            return sigSha384wEcdsaName;
     528        #endif
     529        #ifdef WOLFSSL_SHA512
     530        case CTC_SHA512wECDSA:
     531            return sigSha512wEcdsaName;
     532        #endif
     533    #endif /* HAVE_ECC */
     534        default:
     535            return sigUnknownName;
     536    }
     537}
     538
     539
    761540#if !defined(NO_DSA) || defined(HAVE_ECC) || \
    762541   (!defined(NO_RSA) && \
    763542        (defined(WOLFSSL_CERT_GEN) || \
    764         (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA))))
     543        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
    765544/* Set the DER/BER encoding of the ASN.1 INTEGER header.
    766545 *
     
    786565
    787566#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \
    788     (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
     567    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
    789568/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
    790569 * The number is assumed to be positive.
     
    906685    return *number;
    907686}
     687
     688
     689/* Set small integer, 32 bits or less. DER encoding with no leading 0s
     690 * returns total amount written including ASN tag and length byte on success */
     691static int SetShortInt(byte* input, word32* inOutIdx, word32 number,
     692                              word32 maxIdx)
     693{
     694    word32 idx = *inOutIdx;
     695    word32 len = 0;
     696    int    i;
     697    byte ar[MAX_LENGTH_SZ];
     698
     699    /* check for room for type and length bytes */
     700    if ((idx + 2) > maxIdx)
     701        return BUFFER_E;
     702
     703    input[idx++] = ASN_INTEGER;
     704    idx++; /* place holder for length byte */
     705    if (MAX_LENGTH_SZ + idx > maxIdx)
     706        return ASN_PARSE_E;
     707
     708    /* find first non zero byte */
     709    XMEMSET(ar, 0, MAX_LENGTH_SZ);
     710    c32toa(number, ar);
     711    for (i = 0; i < MAX_LENGTH_SZ; i++) {
     712        if (ar[i] != 0) {
     713            break;
     714        }
     715    }
     716
     717    /* handle case of 0 */
     718    if (i == MAX_LENGTH_SZ) {
     719        input[idx++] = 0; len++;
     720    }
     721
     722    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
     723        input[idx++] = ar[i]; len++;
     724    }
     725
     726    /* jump back to beginning of input buffer using unaltered inOutIdx value
     727     * and set number of bytes for integer, then update the index value */
     728    input[*inOutIdx + 1] = (byte)len;
     729    *inOutIdx = idx;
     730
     731    return len + 2; /* size of integer bytes plus ASN TAG and length byte */
     732}
    908733#endif /* !NO_PWDBASED */
    909734
     
    959784    return 0;
    960785}
     786
     787#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
     788    || defined(WOLFSSL_RSA_PUBLIC_ONLY)
     789#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
     790static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
     791{
     792    word32 idx = *inOutIdx;
     793    int    ret;
     794    int    length;
     795
     796    ret = GetASNInt(input, &idx, &length, maxIdx);
     797    if (ret != 0)
     798        return ret;
     799
     800    *inOutIdx = idx + length;
     801
     802    return 0;
     803}
     804#endif
     805#endif
    961806
    962807static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
     
    1008853}
    1009854
    1010 #if (!defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
    1011                           (defined(WOLFSSL_KEY_GEN) && \
    1012                            !defined(HAVE_USER_RSA)))) || \
    1013     (defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || \
    1014                            defined(WOLFSSL_KEY_GEN)))
     855/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */
     856#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
     857        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
     858    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
     859    (defined(HAVE_ED25519) && \
     860        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
     861
    1015862/* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
    1016863 *
     
    1032879    return idx;
    1033880}
     881#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
     882
     883#ifdef ASN_BER_TO_DER
     884/* Convert a BER encoding with indefinite length items to DER.
     885 *
     886 * ber    BER encoded data.
     887 * berSz  Length of BER encoded data.
     888 * der    Buffer to hold DER encoded version of data.
     889 *        NULL indicates only the length is required.
     890 * derSz  The size of the buffer to hold the DER encoded data.
     891 *        Will be set if der is NULL, otherwise the value is checked as der is
     892 *        filled.
     893 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
     894 * derSz are NULL.
     895 */
     896int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
     897{
     898    int ret;
     899    word32 i, j, k;
     900    int len, l;
     901    int indef;
     902    int depth = 0;
     903    byte type;
     904    word32 cnt, sz;
     905    word32 outSz = 0;
     906    byte lenBytes[4];
     907
     908    if (ber == NULL || derSz == NULL)
     909        return BAD_FUNC_ARG;
     910
     911    sz = 0;
     912    outSz = *derSz;
     913
     914    for (i = 0, j = 0; i < berSz; ) {
     915        /* Check that there is data for an ASN item to parse. */
     916        if (i + 2 > berSz)
     917            return ASN_PARSE_E;
     918
     919        /* End Of Content (EOC) mark end of indefinite length items.
     920         * EOCs are not encoded in DER.
     921         * Keep track of no. indefinite length items that have not been
     922         * terminated in depth.
     923         */
     924        if (ber[i] == 0 && ber[i+1] == 0) {
     925            if (depth == 0)
     926                break;
     927            if (--depth == 0)
     928                break;
     929
     930            i += 2;
     931            continue;
     932        }
     933
     934        /* Indefinite length is encoded as: 0x80 */
     935        type = ber[i];
     936        indef = ber[i+1] == ASN_INDEF_LENGTH;
     937        if (indef && (type & 0xC0) == 0 &&
     938                                   ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
     939                                   ber[i] != (ASN_SET      | ASN_CONSTRUCTED)) {
     940            /* Indefinite length OCTET STRING or other simple type.
     941             * Put all the data into one entry.
     942             */
     943
     944            /* Type no longer constructed. */
     945            type &= ~ASN_CONSTRUCTED;
     946            if (der != NULL) {
     947                /* Ensure space for type. */
     948                if (j + 1 >= outSz)
     949                    return BUFFER_E;
     950                der[j] = type;
     951            }
     952            i++; j++;
     953            /* Skip indefinite length. */
     954            i++;
     955
     956            /* There must be further ASN1 items to combine. */
     957            if (i + 2 > berSz)
     958                return ASN_PARSE_E;
     959
     960            /* Calculate length of combined data. */
     961            len = 0;
     962            k = i;
     963            while (ber[k] != 0x00) {
     964                /* Each ASN item must be the same type as the constructed. */
     965                if (ber[k] != type)
     966                    return ASN_PARSE_E;
     967                k++;
     968
     969                ret = GetLength(ber, &k, &l, berSz);
     970                if (ret < 0)
     971                    return ASN_PARSE_E;
     972                k += l;
     973                len += l;
     974
     975                /* Must at least have terminating EOC. */
     976                if (k + 2 > berSz)
     977                    return ASN_PARSE_E;
     978            }
     979            /* Ensure a valid EOC ASN item. */
     980            if (ber[k+1] != 0x00)
     981                return ASN_PARSE_E;
     982
     983            if (der == NULL) {
     984                /* Add length of ASN item length encoding and data. */
     985                j += SetLength(len, lenBytes);
     986                j += len;
     987            }
     988            else {
     989                /* Check space for encoded length. */
     990                if (SetLength(len, lenBytes) > outSz - j)
     991                    return BUFFER_E;
     992                /* Encode new length. */
     993                j += SetLength(len, der + j);
     994
     995                /* Encode data in single item. */
     996                k = i;
     997                while (ber[k] != 0x00) {
     998                    /* Skip ASN type. */
     999                    k++;
     1000
     1001                    /* Find length of data in ASN item. */
     1002                    ret = GetLength(ber, &k, &l, berSz);
     1003                    if (ret < 0)
     1004                        return ASN_PARSE_E;
     1005
     1006                    /* Ensure space for data and copy in. */
     1007                    if (j + l > outSz)
     1008                        return BUFFER_E;
     1009                    XMEMCPY(der + j, ber + k, l);
     1010                    k += l; j += l;
     1011                }
     1012            }
     1013            /* Continue conversion after EOC. */
     1014            i = k + 2;
     1015
     1016            continue;
     1017        }
     1018
     1019        if (der != NULL) {
     1020            /* Ensure space for type and at least one byte of length. */
     1021            if (j + 1 >= outSz)
     1022                return BUFFER_E;
     1023            /* Put in type. */
     1024            der[j] = ber[i];
     1025        }
     1026        i++; j++;
     1027
     1028        if (indef) {
     1029            /* Skip indefinite length. */
     1030            i++;
     1031            /* Calculate the size of the data inside constructed. */
     1032            ret = wc_BerToDer(ber + i, berSz - i, NULL, &sz);
     1033            if (ret != LENGTH_ONLY_E)
     1034                return ret;
     1035
     1036            if (der != NULL) {
     1037                /* Ensure space for encoded length. */
     1038                if (SetLength(sz, lenBytes) > outSz - j)
     1039                    return BUFFER_E;
     1040                /* Encode real length. */
     1041                j += SetLength(sz, der + j);
     1042            }
     1043            else {
     1044                /* Add size of encoded length. */
     1045                j += SetLength(sz, lenBytes);
     1046            }
     1047
     1048            /* Another EOC to find. */
     1049            depth++;
     1050        }
     1051        else {
     1052            /* Get the size of the encode length and length value. */
     1053            cnt = i;
     1054            ret = GetLength(ber, &cnt, &len, berSz);
     1055            if (ret < 0)
     1056                return ASN_PARSE_E;
     1057            cnt -= i;
     1058
     1059            /* Check there is enough data to copy out. */
     1060            if (i + cnt + len > berSz)
     1061                return ASN_PARSE_E;
     1062
     1063            if (der != NULL) {
     1064                /* Ensure space in DER buffer. */
     1065                if (j + cnt + len > outSz)
     1066                    return BUFFER_E;
     1067                /* Copy length and data into DER buffer. */
     1068                XMEMCPY(der + j, ber + i, cnt + len);
     1069            }
     1070            /* Continue conversion after this ASN item. */
     1071            i += cnt + len;
     1072            j += cnt + len;
     1073        }
     1074    }
     1075
     1076    if (depth >= 1)
     1077        return ASN_PARSE_E;
     1078
     1079    /* Return length if no buffer to write to. */
     1080    if (der == NULL) {
     1081        *derSz = j;
     1082        return LENGTH_ONLY_E;
     1083    }
     1084
     1085    return 0;
     1086}
     1087#endif
     1088
     1089#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)
     1090
     1091#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \
     1092    defined(HAVE_ECC) || defined(HAVE_ED25519)
    10341093
    10351094#ifdef WOLFSSL_CERT_EXT
     
    10671126}
    10681127#endif /* WOLFSSL_CERT_EXT */
    1069 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
    1070                                            !HAVE_USER_RSA)) */
     1128#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
     1129#endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */
    10711130
    10721131
    10731132
    10741133/* hashType */
     1134#ifdef WOLFSSL_MD2
    10751135static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
     1136#endif
     1137#ifndef NO_MD5
    10761138static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
     1139#endif
     1140#ifndef NO_SHA
    10771141static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
     1142#endif
     1143#ifdef WOLFSSL_SHA224
    10781144static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
     1145#endif
     1146#ifndef NO_SHA256
    10791147static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
     1148#endif
     1149#ifdef WOLFSSL_SHA384
    10801150static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
     1151#endif
     1152#ifdef WOLFSSL_SHA512
    10811153static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
     1154#endif
     1155
     1156/* hmacType */
     1157#ifndef NO_HMAC
     1158    #ifdef WOLFSSL_SHA224
     1159    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
     1160    #endif
     1161    #ifndef NO_SHA256
     1162    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
     1163    #endif
     1164    #ifdef WOLFSSL_SHA384
     1165    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
     1166    #endif
     1167    #ifdef WOLFSSL_SHA512
     1168    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
     1169    #endif
     1170#endif
    10821171
    10831172/* sigType */
    1084 #ifndef NO_DSA
     1173#if !defined(NO_DSA) && !defined(NO_SHA)
    10851174    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
    10861175#endif /* NO_DSA */
    10871176#ifndef NO_RSA
     1177    #ifdef WOLFSSL_MD2
    10881178    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
     1179    #endif
     1180    #ifndef NO_MD5
    10891181    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
     1182    #endif
     1183    #ifndef NO_SHA
    10901184    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
     1185    #endif
     1186    #ifdef WOLFSSL_SHA224
    10911187    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
     1188    #endif
     1189    #ifndef NO_SHA256
    10921190    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
     1191    #endif
     1192    #ifdef WOLFSSL_SHA384
    10931193    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
     1194    #endif
     1195    #ifdef WOLFSSL_SHA512
    10941196    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
     1197    #endif
    10951198#endif /* NO_RSA */
    10961199#ifdef HAVE_ECC
     1200    #ifndef NO_SHA
    10971201    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
     1202    #endif
     1203    #ifdef WOLFSSL_SHA224
    10981204    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
     1205    #endif
     1206    #ifndef NO_SHA256
    10991207    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
     1208    #endif
     1209    #ifdef WOLFSSL_SHA384
    11001210    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
     1211    #endif
     1212    #ifdef WOLFSSL_SHA512
    11011213    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
     1214    #endif
    11021215#endif /* HAVE_ECC */
    11031216#ifdef HAVE_ED25519
     
    11271240#endif /* HAVE_ECC */
    11281241
     1242#ifdef HAVE_AES_CBC
    11291243/* blkType */
     1244    #ifdef WOLFSSL_AES_128
    11301245static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
     1246    #endif
     1247    #ifdef WOLFSSL_AES_192
    11311248static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
     1249    #endif
     1250    #ifdef WOLFSSL_AES_256
    11321251static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
     1252    #endif
     1253#endif /* HAVE_AES_CBC */
     1254#ifdef HAVE_AESGCM
     1255    #ifdef WOLFSSL_AES_128
     1256    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
     1257    #endif
     1258    #ifdef WOLFSSL_AES_192
     1259    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
     1260    #endif
     1261    #ifdef WOLFSSL_AES_256
     1262    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
     1263    #endif
     1264#endif /* HAVE_AESGCM */
     1265#ifdef HAVE_AESCCM
     1266    #ifdef WOLFSSL_AES_128
     1267    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
     1268    #endif
     1269    #ifdef WOLFSSL_AES_192
     1270    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
     1271    #endif
     1272    #ifdef WOLFSSL_AES_256
     1273    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
     1274    #endif
     1275#endif /* HAVE_AESCCM */
     1276
     1277#ifndef NO_DES3
    11331278static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
    11341279static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
     1280#endif
    11351281
    11361282/* keyWrapType */
     1283#ifdef WOLFSSL_AES_128
    11371284static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
     1285#endif
     1286#ifdef WOLFSSL_AES_192
    11381287static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
     1288#endif
     1289#ifdef WOLFSSL_AES_256
    11391290static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
     1291#endif
     1292#ifdef HAVE_PKCS7
     1293/* From RFC 3211 */
     1294static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
     1295#endif
    11401296
    11411297/* cmsKeyAgreeType */
     1298#ifndef NO_SHA
    11421299static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
    11431300                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
     1301#endif
     1302#ifdef WOLFSSL_SHA224
    11441303static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
     1304#endif
     1305#ifndef NO_SHA256
    11451306static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
     1307#endif
     1308#ifdef WOLFSSL_SHA384
    11461309static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
     1310#endif
     1311#ifdef WOLFSSL_SHA512
    11471312static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
     1313#endif
    11481314
    11491315/* ocspType */
     
    11641330static const byte extInhibitAnyOid[] = {85, 29, 54};
    11651331static const byte extExtKeyUsageOid[] = {85, 29, 37};
     1332#ifndef IGNORE_NAME_CONSTRAINTS
    11661333static const byte extNameConsOid[] = {85, 29, 30};
     1334#endif
    11671335
    11681336/* certAuthInfoType */
     1337#ifdef HAVE_OCSP
    11691338static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
     1339#endif
    11701340static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
    11711341
     
    11881358static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
    11891359
    1190 static const byte* OidFromId(word32 id, word32 type, word32* oidSz)
     1360/* PKCS5 */
     1361#if !defined(NO_DES3) && !defined(NO_SHA)
     1362static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
     1363#endif
     1364static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
     1365
     1366/* PKCS12 */
     1367#if !defined(NO_RC4) && !defined(NO_SHA)
     1368static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
     1369#endif
     1370#if !defined(NO_DES3) && !defined(NO_SHA)
     1371static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
     1372#endif
     1373
     1374#ifdef HAVE_LIBZ
     1375/* zlib compression */
     1376static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
     1377#endif
     1378
     1379
     1380/* returns a pointer to the OID string on success and NULL on fail */
     1381const byte* OidFromId(word32 id, word32 type, word32* oidSz)
    11911382{
    11921383    const byte* oid = NULL;
     
    11981389        case oidHashType:
    11991390            switch (id) {
     1391            #ifdef WOLFSSL_MD2
    12001392                case MD2h:
    12011393                    oid = hashMd2hOid;
    12021394                    *oidSz = sizeof(hashMd2hOid);
    12031395                    break;
     1396            #endif
     1397            #ifndef NO_MD5
    12041398                case MD5h:
    12051399                    oid = hashMd5hOid;
    12061400                    *oidSz = sizeof(hashMd5hOid);
    12071401                    break;
     1402            #endif
     1403            #ifndef NO_SHA
    12081404                case SHAh:
    12091405                    oid = hashSha1hOid;
    12101406                    *oidSz = sizeof(hashSha1hOid);
    12111407                    break;
     1408            #endif
     1409            #ifdef WOLFSSL_SHA224
    12121410                case SHA224h:
    12131411                    oid = hashSha224hOid;
    12141412                    *oidSz = sizeof(hashSha224hOid);
    12151413                    break;
     1414            #endif
     1415            #ifndef NO_SHA256
    12161416                case SHA256h:
    12171417                    oid = hashSha256hOid;
    12181418                    *oidSz = sizeof(hashSha256hOid);
    12191419                    break;
     1420            #endif
     1421            #ifdef WOLFSSL_SHA384
    12201422                case SHA384h:
    12211423                    oid = hashSha384hOid;
    12221424                    *oidSz = sizeof(hashSha384hOid);
    12231425                    break;
     1426            #endif
     1427            #ifdef WOLFSSL_SHA512
    12241428                case SHA512h:
    12251429                    oid = hashSha512hOid;
    12261430                    *oidSz = sizeof(hashSha512hOid);
    12271431                    break;
     1432            #endif
    12281433            }
    12291434            break;
     
    12311436        case oidSigType:
    12321437            switch (id) {
    1233                 #ifndef NO_DSA
     1438                #if !defined(NO_DSA) && !defined(NO_SHA)
    12341439                case CTC_SHAwDSA:
    12351440                    oid = sigSha1wDsaOid;
     
    12381443                #endif /* NO_DSA */
    12391444                #ifndef NO_RSA
     1445                #ifdef WOLFSSL_MD2
    12401446                case CTC_MD2wRSA:
    12411447                    oid = sigMd2wRsaOid;
    12421448                    *oidSz = sizeof(sigMd2wRsaOid);
    12431449                    break;
     1450                #endif
     1451                #ifndef NO_MD5
    12441452                case CTC_MD5wRSA:
    12451453                    oid = sigMd5wRsaOid;
    12461454                    *oidSz = sizeof(sigMd5wRsaOid);
    12471455                    break;
     1456                #endif
     1457                #ifndef NO_SHA
    12481458                case CTC_SHAwRSA:
    12491459                    oid = sigSha1wRsaOid;
    12501460                    *oidSz = sizeof(sigSha1wRsaOid);
    12511461                    break;
     1462                #endif
     1463                #ifdef WOLFSSL_SHA224
    12521464                case CTC_SHA224wRSA:
    12531465                    oid = sigSha224wRsaOid;
    12541466                    *oidSz = sizeof(sigSha224wRsaOid);
    12551467                    break;
     1468                #endif
     1469                #ifndef NO_SHA256
    12561470                case CTC_SHA256wRSA:
    12571471                    oid = sigSha256wRsaOid;
    12581472                    *oidSz = sizeof(sigSha256wRsaOid);
    12591473                    break;
     1474                #endif
     1475                #ifdef WOLFSSL_SHA384
    12601476                case CTC_SHA384wRSA:
    12611477                    oid = sigSha384wRsaOid;
    12621478                    *oidSz = sizeof(sigSha384wRsaOid);
    12631479                    break;
     1480                #endif
     1481                #ifdef WOLFSSL_SHA512
    12641482                case CTC_SHA512wRSA:
    12651483                    oid = sigSha512wRsaOid;
    12661484                    *oidSz = sizeof(sigSha512wRsaOid);
    12671485                    break;
     1486                #endif /* WOLFSSL_SHA512 */
    12681487                #endif /* NO_RSA */
    12691488                #ifdef HAVE_ECC
     1489                #ifndef NO_SHA
    12701490                case CTC_SHAwECDSA:
    12711491                    oid = sigSha1wEcdsaOid;
    12721492                    *oidSz = sizeof(sigSha1wEcdsaOid);
    12731493                    break;
     1494                #endif
     1495                #ifdef WOLFSSL_SHA224
    12741496                case CTC_SHA224wECDSA:
    12751497                    oid = sigSha224wEcdsaOid;
    12761498                    *oidSz = sizeof(sigSha224wEcdsaOid);
    12771499                    break;
     1500                #endif
     1501                #ifndef NO_SHA256
    12781502                case CTC_SHA256wECDSA:
    12791503                    oid = sigSha256wEcdsaOid;
    12801504                    *oidSz = sizeof(sigSha256wEcdsaOid);
    12811505                    break;
     1506                #endif
     1507                #ifdef WOLFSSL_SHA384
    12821508                case CTC_SHA384wECDSA:
    12831509                    oid = sigSha384wEcdsaOid;
    12841510                    *oidSz = sizeof(sigSha384wEcdsaOid);
    12851511                    break;
     1512                #endif
     1513                #ifdef WOLFSSL_SHA512
    12861514                case CTC_SHA512wECDSA:
    12871515                    oid = sigSha512wEcdsaOid;
    12881516                    *oidSz = sizeof(sigSha512wEcdsaOid);
    12891517                    break;
     1518                #endif
    12901519                #endif /* HAVE_ECC */
    12911520                #ifdef HAVE_ED25519
     
    13471576        case oidBlkType:
    13481577            switch (id) {
     1578    #ifdef HAVE_AES_CBC
     1579        #ifdef WOLFSSL_AES_128
    13491580                case AES128CBCb:
    13501581                    oid = blkAes128CbcOid;
    13511582                    *oidSz = sizeof(blkAes128CbcOid);
    13521583                    break;
     1584        #endif
     1585        #ifdef WOLFSSL_AES_192
    13531586                case AES192CBCb:
    13541587                    oid = blkAes192CbcOid;
    13551588                    *oidSz = sizeof(blkAes192CbcOid);
    13561589                    break;
     1590        #endif
     1591        #ifdef WOLFSSL_AES_256
    13571592                case AES256CBCb:
    13581593                    oid = blkAes256CbcOid;
    13591594                    *oidSz = sizeof(blkAes256CbcOid);
    13601595                    break;
     1596        #endif
     1597    #endif /* HAVE_AES_CBC */
     1598    #ifdef HAVE_AESGCM
     1599        #ifdef WOLFSSL_AES_128
     1600                case AES128GCMb:
     1601                    oid = blkAes128GcmOid;
     1602                    *oidSz = sizeof(blkAes128GcmOid);
     1603                    break;
     1604        #endif
     1605        #ifdef WOLFSSL_AES_192
     1606                case AES192GCMb:
     1607                    oid = blkAes192GcmOid;
     1608                    *oidSz = sizeof(blkAes192GcmOid);
     1609                    break;
     1610        #endif
     1611        #ifdef WOLFSSL_AES_256
     1612                case AES256GCMb:
     1613                    oid = blkAes256GcmOid;
     1614                    *oidSz = sizeof(blkAes256GcmOid);
     1615                    break;
     1616        #endif
     1617    #endif /* HAVE_AESGCM */
     1618    #ifdef HAVE_AESCCM
     1619        #ifdef WOLFSSL_AES_128
     1620                case AES128CCMb:
     1621                    oid = blkAes128CcmOid;
     1622                    *oidSz = sizeof(blkAes128CcmOid);
     1623                    break;
     1624        #endif
     1625        #ifdef WOLFSSL_AES_192
     1626                case AES192CCMb:
     1627                    oid = blkAes192CcmOid;
     1628                    *oidSz = sizeof(blkAes192CcmOid);
     1629                    break;
     1630        #endif
     1631        #ifdef WOLFSSL_AES_256
     1632                case AES256CCMb:
     1633                    oid = blkAes256CcmOid;
     1634                    *oidSz = sizeof(blkAes256CcmOid);
     1635                    break;
     1636        #endif
     1637    #endif /* HAVE_AESCCM */
     1638    #ifndef NO_DES3
    13611639                case DESb:
    13621640                    oid = blkDesCbcOid;
     
    13671645                    *oidSz = sizeof(blkDes3CbcOid);
    13681646                    break;
     1647    #endif /* !NO_DES3 */
    13691648            }
    13701649            break;
     
    14271706                    *oidSz = sizeof(extExtKeyUsageOid);
    14281707                    break;
     1708            #ifndef IGNORE_NAME_CONSTRAINTS
    14291709                case NAME_CONS_OID:
    14301710                    oid = extNameConsOid;
    14311711                    *oidSz = sizeof(extNameConsOid);
    14321712                    break;
     1713            #endif
    14331714            }
    14341715            break;
     
    14361717        case oidCertAuthInfoType:
    14371718            switch (id) {
     1719            #ifdef HAVE_OCSP
    14381720                case AIA_OCSP_OID:
    14391721                    oid = extAuthInfoOcspOid;
    14401722                    *oidSz = sizeof(extAuthInfoOcspOid);
    14411723                    break;
     1724            #endif
    14421725                case AIA_CA_ISSUER_OID:
    14431726                    oid = extAuthInfoCaIssuerOid;
     
    15071790            break;
    15081791
     1792        case oidPBEType:
     1793            switch (id) {
     1794        #if !defined(NO_SHA) && !defined(NO_RC4)
     1795                case PBE_SHA1_RC4_128:
     1796                    oid = pbeSha1RC4128;
     1797                    *oidSz = sizeof(pbeSha1RC4128);
     1798                    break;
     1799        #endif
     1800        #if !defined(NO_SHA) && !defined(NO_DES3)
     1801                case PBE_SHA1_DES:
     1802                    oid = pbeSha1Des;
     1803                    *oidSz = sizeof(pbeSha1Des);
     1804                    break;
     1805
     1806        #endif
     1807        #if !defined(NO_SHA) && !defined(NO_DES3)
     1808                case PBE_SHA1_DES3:
     1809                    oid = pbeSha1Des3;
     1810                    *oidSz = sizeof(pbeSha1Des3);
     1811                    break;
     1812        #endif
     1813                case PBES2:
     1814                    oid = pbes2;
     1815                    *oidSz = sizeof(pbes2);
     1816                    break;
     1817            }
     1818            break;
     1819
    15091820        case oidKeyWrapType:
    15101821            switch (id) {
     1822            #ifdef WOLFSSL_AES_128
    15111823                case AES128_WRAP:
    15121824                    oid = wrapAes128Oid;
    15131825                    *oidSz = sizeof(wrapAes128Oid);
    15141826                    break;
     1827            #endif
     1828            #ifdef WOLFSSL_AES_192
    15151829                case AES192_WRAP:
    15161830                    oid = wrapAes192Oid;
    15171831                    *oidSz = sizeof(wrapAes192Oid);
    15181832                    break;
     1833            #endif
     1834            #ifdef WOLFSSL_AES_256
    15191835                case AES256_WRAP:
    15201836                    oid = wrapAes256Oid;
    15211837                    *oidSz = sizeof(wrapAes256Oid);
    15221838                    break;
     1839            #endif
     1840            #ifdef HAVE_PKCS7
     1841                case PWRI_KEK_WRAP:
     1842                    oid = wrapPwriKekOid;
     1843                    *oidSz = sizeof(wrapPwriKekOid);
     1844                    break;
     1845            #endif
    15231846            }
    15241847            break;
     
    15261849        case oidCmsKeyAgreeType:
    15271850            switch (id) {
     1851            #ifndef NO_SHA
    15281852                case dhSinglePass_stdDH_sha1kdf_scheme:
    15291853                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
    15301854                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
    15311855                    break;
     1856            #endif
     1857            #ifdef WOLFSSL_SHA224
    15321858                case dhSinglePass_stdDH_sha224kdf_scheme:
    15331859                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
    15341860                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
    15351861                    break;
     1862            #endif
     1863            #ifndef NO_SHA256
    15361864                case dhSinglePass_stdDH_sha256kdf_scheme:
    15371865                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
    15381866                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
    15391867                    break;
     1868            #endif
     1869            #ifdef WOLFSSL_SHA384
    15401870                case dhSinglePass_stdDH_sha384kdf_scheme:
    15411871                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
    15421872                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
    15431873                    break;
     1874            #endif
     1875            #ifdef WOLFSSL_SHA512
    15441876                case dhSinglePass_stdDH_sha512kdf_scheme:
    15451877                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
    15461878                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
    15471879                    break;
     1880            #endif
    15481881            }
    15491882            break;
     1883
     1884#ifndef NO_HMAC
     1885        case oidHmacType:
     1886            switch (id) {
     1887        #ifdef WOLFSSL_SHA224
     1888                case HMAC_SHA224_OID:
     1889                    oid = hmacSha224Oid;
     1890                    *oidSz = sizeof(hmacSha224Oid);
     1891                    break;
     1892        #endif
     1893        #ifndef NO_SHA256
     1894                case HMAC_SHA256_OID:
     1895                    oid = hmacSha256Oid;
     1896                    *oidSz = sizeof(hmacSha256Oid);
     1897                    break;
     1898        #endif
     1899        #ifdef WOLFSSL_SHA384
     1900                case HMAC_SHA384_OID:
     1901                    oid = hmacSha384Oid;
     1902                    *oidSz = sizeof(hmacSha384Oid);
     1903                    break;
     1904        #endif
     1905        #ifdef WOLFSSL_SHA512
     1906                case HMAC_SHA512_OID:
     1907                    oid = hmacSha512Oid;
     1908                    *oidSz = sizeof(hmacSha512Oid);
     1909                    break;
     1910        #endif
     1911            }
     1912            break;
     1913#endif /* !NO_HMAC */
     1914
     1915#ifdef HAVE_LIBZ
     1916        case oidCompressType:
     1917            switch (id) {
     1918                case ZLIBc:
     1919                    oid = zlibCompress;
     1920                    *oidSz = sizeof(zlibCompress);
     1921                    break;
     1922            }
     1923            break;
     1924#endif /* HAVE_LIBZ */
    15501925
    15511926        case oidIgnoreType:
     
    16822057 *         Otherwise, 0 to indicate success.
    16832058 */
    1684 static int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
     2059int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
    16852060                          word32 maxIdx)
    16862061{
     
    17102085 * returns the number of bytes added to the buffer.
    17112086 */
    1712 static int SetObjectId(int len, byte* output)
     2087int SetObjectId(int len, byte* output)
    17132088{
    17142089    int idx = 0;
     
    17582133        word32 checkOidSz;
    17592134    #ifdef ASN_DUMP_OID
    1760         int i;
     2135        word32 i;
    17612136    #endif
    17622137
     
    18362211
    18372212    /* could have NULL tag and 0 terminator, but may not */
    1838     if (input[idx] == ASN_TAG_NULL) {
     2213    if (idx < maxIdx && input[idx] == ASN_TAG_NULL) {
    18392214        ret = GetASNNull(input, &idx, maxIdx);
    18402215        if (ret != 0)
     
    18682243    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
    18692244        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
     2245#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    18702246        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
    18712247        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
    1872         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
    1873         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
     2248        GetInt(&key->q,  input, inOutIdx, inSz) < 0)
     2249#else
     2250        SkipInt(input, inOutIdx, inSz) < 0 ||
     2251        SkipInt(input, inOutIdx, inSz) < 0 ||
     2252        SkipInt(input, inOutIdx, inSz) < 0 )
     2253
     2254#endif
     2255            return ASN_RSA_KEY_E;
     2256#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
     2257    && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
     2258    if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
    18742259        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
    18752260        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
     2261#else
     2262    if (SkipInt(input, inOutIdx, inSz) < 0 ||
     2263        SkipInt(input, inOutIdx, inSz) < 0 ||
     2264        SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
     2265#endif
    18762266
    18772267#ifdef WOLFSSL_XILINX_CRYPT
     
    18882278/* Remove PKCS8 header, place inOutIdx at beginning of traditional,
    18892279 * return traditional length on success, negative on error */
    1890 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
    1891 {
    1892     word32 idx, oid;
     2280int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
     2281                           word32* algId)
     2282{
     2283    word32 idx;
    18932284    int    version, length;
    18942285    int    ret;
     
    19052296        return ASN_PARSE_E;
    19062297
    1907     if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
     2298    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
    19082299        return ASN_PARSE_E;
    19092300
     
    19222313}
    19232314
     2315int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
     2316{
     2317    word32 oid;
     2318
     2319    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
     2320}
     2321
    19242322/* Remove PKCS8 header, move beginning of traditional to beginning of input */
    1925 int ToTraditional(byte* input, word32 sz)
     2323int ToTraditional_ex(byte* input, word32 sz, word32* algId)
    19262324{
    19272325    word32 inOutIdx = 0;
     
    19312329        return BAD_FUNC_ARG;
    19322330
    1933     length = ToTraditionalInline(input, &inOutIdx, sz);
     2331    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
    19342332    if (length < 0)
    19352333        return length;
     
    19402338}
    19412339
     2340int ToTraditional(byte* input, word32 sz)
     2341{
     2342    word32 oid;
     2343
     2344    return ToTraditional_ex(input, sz, &oid);
     2345}
    19422346
    19432347/* find beginning of traditional key inside PKCS#8 unencrypted buffer
     
    19482352{
    19492353    int length;
     2354    word32 algId;
    19502355
    19512356    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
    19522357        return BAD_FUNC_ARG;
    19532358
    1954     length = ToTraditionalInline(input, inOutIdx, sz);
     2359    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
    19552360
    19562361    return length;
     
    20792484{
    20802485    int ret;
     2486    (void)keySz;
    20812487
    20822488    if (key == NULL || der == NULL) {
     
    20842490    }
    20852491
    2086     #if !defined(NO_RSA)
     2492    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
    20872493    /* test if RSA key */
    20882494    if (der->keyOID == RSAk) {
    2089         RsaKey a, b;
     2495    #ifdef WOLFSSL_SMALL_STACK
     2496        RsaKey* a = NULL;
     2497        RsaKey* b = NULL;
     2498    #else
     2499        RsaKey a[1], b[1];
     2500    #endif
    20902501        word32 keyIdx = 0;
    20912502
    2092         if ((ret = wc_InitRsaKey(&a, NULL)) < 0)
     2503    #ifdef WOLFSSL_SMALL_STACK
     2504        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
     2505        if (a == NULL)
     2506            return MEMORY_E;
     2507        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
     2508        if (b == NULL) {
     2509            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2510            return MEMORY_E;
     2511        }
     2512    #endif
     2513
     2514        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
     2515    #ifdef WOLFSSL_SMALL_STACK
     2516            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2517            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2518    #endif
    20932519            return ret;
    2094         if ((ret = wc_InitRsaKey(&b, NULL)) < 0) {
    2095             wc_FreeRsaKey(&a);
     2520        }
     2521        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
     2522            wc_FreeRsaKey(a);
     2523    #ifdef WOLFSSL_SMALL_STACK
     2524            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2525            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2526    #endif
    20962527            return ret;
    20972528        }
    2098         if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, &a, keySz)) == 0) {
     2529        if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
    20992530            WOLFSSL_MSG("Checking RSA key pair");
    21002531            keyIdx = 0; /* reset to 0 for parsing public key */
    21012532
    2102             if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, &b,
     2533            if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
    21032534                                                       der->pubKeySize)) == 0) {
    21042535                /* limit for user RSA crypto because of RsaKey
     
    21102541                /* both keys extracted successfully now check n and e
    21112542                 * values are the same. This is dereferencing RsaKey */
    2112                 if (mp_cmp(&(a.n), &(b.n)) != MP_EQ ||
    2113                     mp_cmp(&(a.e), &(b.e)) != MP_EQ) {
     2543                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
     2544                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
    21142545                    ret = MP_CMP_E;
    21152546                }
     
    21192550            }
    21202551        }
    2121         wc_FreeRsaKey(&b);
    2122         wc_FreeRsaKey(&a);
     2552        wc_FreeRsaKey(b);
     2553        wc_FreeRsaKey(a);
     2554    #ifdef WOLFSSL_SMALL_STACK
     2555        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2556        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2557    #endif
    21232558    }
    21242559    else
    2125     #endif /* NO_RSA */
    2126 
    2127     #ifdef HAVE_ECC
     2560    #endif /* !NO_RSA && !NO_ASN_CRYPT */
     2561
     2562    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    21282563    if (der->keyOID == ECDSAk) {
     2564    #ifdef WOLFSSL_SMALL_STACK
     2565        ecc_key* key_pair = NULL;
     2566        byte*    privDer;
     2567    #else
     2568        ecc_key  key_pair[1];
     2569        byte     privDer[MAX_ECC_BYTES];
     2570    #endif
     2571        word32   privSz = MAX_ECC_BYTES;
    21292572        word32  keyIdx = 0;
    2130         ecc_key key_pair;
    2131 
    2132         if ((ret = wc_ecc_init(&key_pair)) < 0)
     2573
     2574    #ifdef WOLFSSL_SMALL_STACK
     2575        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
     2576        if (key_pair == NULL)
     2577            return MEMORY_E;
     2578        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2579        if (privDer == NULL) {
     2580            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2581            return MEMORY_E;
     2582        }
     2583    #endif
     2584
     2585        if ((ret = wc_ecc_init(key_pair)) < 0) {
     2586    #ifdef WOLFSSL_SMALL_STACK
     2587            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2588            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2589    #endif
    21332590            return ret;
    2134         if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, &key_pair,
     2591        }
     2592
     2593        if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
    21352594                                                                 keySz)) == 0) {
    21362595            WOLFSSL_MSG("Checking ECC key pair");
    2137             keyIdx = 0;
    2138             if ((ret = wc_ecc_import_x963(der->publicKey, der->pubKeySize,
    2139                                                              &key_pair)) == 0) {
    2140                 /* public and private extracted successfuly no check if is
     2596
     2597            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
     2598                                                                         == 0) {
     2599                wc_ecc_free(key_pair);
     2600                ret = wc_ecc_init(key_pair);
     2601                if (ret == 0) {
     2602                    ret = wc_ecc_import_private_key((const byte*)privDer,
     2603                                            privSz, (const byte*)der->publicKey,
     2604                                            der->pubKeySize, key_pair);
     2605                }
     2606
     2607                /* public and private extracted successfuly now check if is
    21412608                 * a pair and also do sanity checks on key. wc_ecc_check_key
    21422609                 * checks that private * base generator equals pubkey */
    2143                 if ((ret = wc_ecc_check_key(&key_pair)) == 0)
     2610                if (ret == 0) {
     2611                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
    21442612                    ret = 1;
    21452613            }
    21462614        }
    2147         wc_ecc_free(&key_pair);
     2615                ForceZero(privDer, privSz);
     2616            }
     2617        }
     2618        wc_ecc_free(key_pair);
     2619    #ifdef WOLFSSL_SMALL_STACK
     2620        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2621        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2622    #endif
    21482623    }
    21492624    else
    2150     #endif /* HAVE_ECC */
    2151 
    2152     #ifdef HAVE_ED25519
     2625    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
     2626
     2627    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    21532628    if (der->keyOID == ED25519k) {
     2629    #ifdef WOLFSSL_SMALL_STACK
     2630        ed25519_key* key_pair = NULL;
     2631    #else
     2632        ed25519_key  key_pair[1];
     2633    #endif
    21542634        word32  keyIdx = 0;
    2155         ed25519_key key_pair;
    2156 
    2157         if ((ret = wc_ed25519_init(&key_pair)) < 0)
     2635
     2636    #ifdef WOLFSSL_SMALL_STACK
     2637        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
     2638                                                          DYNAMIC_TYPE_ED25519);
     2639        if (key_pair == NULL)
     2640            return MEMORY_E;
     2641    #endif
     2642
     2643        if ((ret = wc_ed25519_init(key_pair)) < 0) {
     2644    #ifdef WOLFSSL_SMALL_STACK
     2645            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
     2646    #endif
    21582647            return ret;
    2159         if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, &key_pair,
     2648        }
     2649        if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
    21602650                                                                 keySz)) == 0) {
    21612651            WOLFSSL_MSG("Checking ED25519 key pair");
    21622652            keyIdx = 0;
    21632653            if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
    2164                                                              &key_pair)) == 0) {
     2654                                                              key_pair)) == 0) {
    21652655                /* public and private extracted successfuly no check if is
    21662656                 * a pair and also do sanity checks on key. wc_ecc_check_key
    21672657                 * checks that private * base generator equals pubkey */
    2168                 if ((ret = wc_ed25519_check_key(&key_pair)) == 0)
     2658                if ((ret = wc_ed25519_check_key(key_pair)) == 0)
    21692659                    ret = 1;
    21702660            }
    21712661        }
    2172         wc_ed25519_free(&key_pair);
     2662        wc_ed25519_free(key_pair);
     2663    #ifdef WOLFSSL_SMALL_STACK
     2664        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
     2665    #endif
    21732666    }
    21742667    else
    2175     #endif
     2668    #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
    21762669    {
    21772670        ret = 0;
    21782671    }
    21792672
     2673    (void)keySz;
     2674
    21802675    return ret;
    21812676}
     
    21852680/* Check To see if PKCS version algo is supported, set id if it is return 0
    21862681   < 0 on error */
    2187 static int CheckAlgo(int first, int second, int* id, int* version)
     2682static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
    21882683{
    21892684    *id      = ALGO_ID_E;
    21902685    *version = PKCS5;   /* default */
     2686    if (blockSz) *blockSz = 8; /* default */
    21912687
    21922688    if (first == 1) {
    21932689        switch (second) {
    2194         case 1:
     2690#if !defined(NO_SHA)
     2691    #ifndef NO_RC4
     2692        case PBE_SHA1_RC4_128:
    21952693            *id = PBE_SHA1_RC4_128;
    21962694            *version = PKCS12v1;
    21972695            return 0;
    2198         case 3:
     2696    #endif
     2697    #ifndef NO_DES3
     2698        case PBE_SHA1_DES3:
    21992699            *id = PBE_SHA1_DES3;
    22002700            *version = PKCS12v1;
     2701            if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22012702            return 0;
     2703    #endif
     2704#endif /* !NO_SHA */
    22022705        default:
    22032706            return ALGO_ID_E;
     
    22142717
    22152718    switch (second) {
     2719#ifndef NO_DES3
     2720    #ifndef NO_MD5
    22162721    case 3:                   /* see RFC 2898 for ids */
    22172722        *id = PBE_MD5_DES;
     2723        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22182724        return 0;
     2725    #endif
     2726    #ifndef NO_SHA
    22192727    case 10:
    22202728        *id = PBE_SHA1_DES;
     2729        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22212730        return 0;
     2731    #endif
     2732#endif /* !NO_DES3 */
    22222733    default:
    22232734        return ALGO_ID_E;
     
    22292740/* Check To see if PKCS v2 algo is supported, set id if it is return 0
    22302741   < 0 on error */
    2231 static int CheckAlgoV2(int oid, int* id)
    2232 {
     2742static int CheckAlgoV2(int oid, int* id, int* blockSz)
     2743{
     2744    if (blockSz) *blockSz = 8; /* default */
     2745    (void)id; /* not used if AES and DES3 disabled */
    22332746    switch (oid) {
    2234     case 69:
     2747#if !defined(NO_DES3) && !defined(NO_SHA)
     2748    case DESb:
    22352749        *id = PBE_SHA1_DES;
     2750        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22362751        return 0;
    2237     case 652:
     2752    case DES3b:
    22382753        *id = PBE_SHA1_DES3;
     2754        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22392755        return 0;
     2756#endif
     2757#ifdef WOLFSSL_AES_256
     2758    case AES256CBCb:
     2759        *id = PBE_AES256_CBC;
     2760        if (blockSz) *blockSz = AES_BLOCK_SIZE;
     2761        return 0;
     2762#endif
    22402763    default:
    22412764        return ALGO_ID_E;
     
    22452768
    22462769
    2247 /* Decrypt input in place from parameters based on id */
    2248 static int DecryptKey(const char* password, int passwordSz, byte* salt,
    2249                       int saltSz, int iterations, int id, byte* input,
    2250                       int length, int version, byte* cbcIv)
    2251 {
    2252     int typeH;
    2253     int derivedLen;
    2254     int decryptionType;
    2255     int ret = 0;
    2256 #ifdef WOLFSSL_SMALL_STACK
    2257     byte* key;
    2258 #else
    2259     byte key[MAX_KEY_SIZE];
    2260 #endif
    2261 
    2262     (void)input;
    2263     (void)length;
    2264 
    2265     switch (id) {
    2266         case PBE_MD5_DES:
    2267             typeH = WC_MD5;
    2268             derivedLen = 16;           /* may need iv for v1.5 */
    2269             decryptionType = DES_TYPE;
    2270             break;
    2271 
    2272         case PBE_SHA1_DES:
    2273             typeH = WC_SHA;
    2274             derivedLen = 16;           /* may need iv for v1.5 */
    2275             decryptionType = DES_TYPE;
    2276             break;
    2277 
    2278         case PBE_SHA1_DES3:
    2279             typeH = WC_SHA;
    2280             derivedLen = 32;           /* may need iv for v1.5 */
    2281             decryptionType = DES3_TYPE;
    2282             break;
    2283 
    2284         case PBE_SHA1_RC4_128:
    2285             typeH = WC_SHA;
    2286             derivedLen = 16;
    2287             decryptionType = RC4_TYPE;
    2288             break;
    2289 
    2290         default:
    2291             return ALGO_ID_E;
    2292     }
    2293 
    2294 #ifdef WOLFSSL_SMALL_STACK
    2295     key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2296     if (key == NULL)
    2297         return MEMORY_E;
    2298 #endif
    2299 
    2300     if (version == PKCS5v2)
    2301         ret = wc_PBKDF2(key, (byte*)password, passwordSz,
    2302                         salt, saltSz, iterations, derivedLen, typeH);
    2303 #ifndef NO_SHA
    2304     else if (version == PKCS5)
    2305         ret = wc_PBKDF1(key, (byte*)password, passwordSz,
    2306                         salt, saltSz, iterations, derivedLen, typeH);
    2307 #endif
    2308     else if (version == PKCS12v1) {
    2309         int  i, idx = 0;
    2310         byte unicodePasswd[MAX_UNICODE_SZ];
    2311 
    2312         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
    2313 #ifdef WOLFSSL_SMALL_STACK
    2314             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2315 #endif
    2316             return UNICODE_SIZE_E;
    2317         }
    2318 
    2319         for (i = 0; i < passwordSz; i++) {
    2320             unicodePasswd[idx++] = 0x00;
    2321             unicodePasswd[idx++] = (byte)password[i];
    2322         }
    2323         /* add trailing NULL */
    2324         unicodePasswd[idx++] = 0x00;
    2325         unicodePasswd[idx++] = 0x00;
    2326 
    2327         ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
    2328                             iterations, derivedLen, typeH, 1);
    2329         if (decryptionType != RC4_TYPE)
    2330             ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
    2331                                 iterations, 8, typeH, 2);
    2332     }
    2333     else {
    2334 #ifdef WOLFSSL_SMALL_STACK
    2335         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2336 #endif
    2337         return ALGO_ID_E;
    2338     }
    2339 
    2340     if (ret != 0) {
    2341 #ifdef WOLFSSL_SMALL_STACK
    2342         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2343 #endif
    2344         return ret;
    2345     }
    2346 
    2347     switch (decryptionType) {
    2348 #ifndef NO_DES3
    2349         case DES_TYPE:
    2350         {
    2351             Des    dec;
    2352             byte*  desIv = key + 8;
    2353 
    2354             if (version == PKCS5v2 || version == PKCS12v1)
    2355                 desIv = cbcIv;
    2356 
    2357             ret = wc_Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
    2358             if (ret != 0) {
    2359 #ifdef WOLFSSL_SMALL_STACK
    2360                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2361 #endif
    2362                 return ret;
    2363             }
    2364 
    2365             wc_Des_CbcDecrypt(&dec, input, input, length);
    2366             break;
    2367         }
    2368 
    2369         case DES3_TYPE:
    2370         {
    2371             Des3   dec;
    2372             byte*  desIv = key + 24;
    2373 
    2374             if (version == PKCS5v2 || version == PKCS12v1)
    2375                 desIv = cbcIv;
    2376 
    2377             ret = wc_Des3Init(&dec, NULL, INVALID_DEVID);
    2378             if (ret != 0) {
    2379 #ifdef WOLFSSL_SMALL_STACK
    2380                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2381 #endif
    2382                 return ret;
    2383             }
    2384             ret = wc_Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
    2385             if (ret != 0) {
    2386 #ifdef WOLFSSL_SMALL_STACK
    2387                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2388 #endif
    2389                 return ret;
    2390             }
    2391             ret = wc_Des3_CbcDecrypt(&dec, input, input, length);
    2392             if (ret != 0) {
    2393 #ifdef WOLFSSL_SMALL_STACK
    2394                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2395 #endif
    2396                 return ret;
    2397             }
    2398             break;
    2399         }
    2400 #endif
    2401 #ifndef NO_RC4
    2402         case RC4_TYPE:
    2403         {
    2404             Arc4    dec;
    2405 
    2406             wc_Arc4SetKey(&dec, key, derivedLen);
    2407             wc_Arc4Process(&dec, input, input, length);
    2408             break;
    2409         }
    2410 #endif
    2411 
    2412         default:
    2413 #ifdef WOLFSSL_SMALL_STACK
    2414             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2415 #endif
    2416             return ALGO_ID_E;
    2417     }
    2418 
    2419 #ifdef WOLFSSL_SMALL_STACK
    2420     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2421 #endif
    2422 
    2423     return 0;
    2424 }
    2425 
    2426 
    24272770int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
    24282771        int* algoID, void* heap)
    24292772{
    24302773    word32 tmpIdx = 0;
    2431 #ifdef HAVE_ECC
    2432     ecc_key ecc;
    2433 #endif
    2434 #ifndef NO_RSA
    2435     RsaKey rsa;
    2436 #endif
    2437 #ifdef HAVE_ED25519
    2438     ed25519_key ed25519;
    2439 #endif
    2440 
    2441     if (algoID == NULL) {
     2774
     2775    if (key == NULL || algoID == NULL)
    24422776        return BAD_FUNC_ARG;
    2443     }
     2777
    24442778    *algoID = 0;
    24452779
    2446 #ifndef NO_RSA
    2447     if (wc_InitRsaKey(&rsa, heap) == 0) {
     2780    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
     2781    {
     2782        RsaKey rsa;
     2783
     2784        wc_InitRsaKey(&rsa, heap);
    24482785        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
    24492786            *algoID = RSAk;
    2450         }
     2787    }
    24512788        else {
    24522789            WOLFSSL_MSG("Not RSA DER key");
     
    24542791        wc_FreeRsaKey(&rsa);
    24552792    }
    2456     else {
    2457         WOLFSSL_MSG("GetKeyOID wc_InitRsaKey failed");
    2458     }
    2459 #endif /* NO_RSA */
    2460 #ifdef HAVE_ECC
    2461     if (*algoID != RSAk) {
     2793    #endif /* !NO_RSA && !NO_ASN_CRYPT */
     2794    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
     2795    if (*algoID == 0) {
     2796        ecc_key ecc;
     2797
    24622798        tmpIdx = 0;
    2463         if (wc_ecc_init_ex(&ecc, heap, INVALID_DEVID) == 0) {
    2464             if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
    2465                 *algoID = ECDSAk;
    2466 
    2467                 /* sanity check on arguments */
    2468                 if (curveOID == NULL || oidSz == NULL) {
    2469                     WOLFSSL_MSG("Error getting ECC curve OID");
    2470                     wc_ecc_free(&ecc);
    2471                     return BAD_FUNC_ARG;
    2472                 }
    2473 
    2474                 /* now find oid */
    2475                 if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
    2476                     WOLFSSL_MSG("Error getting ECC curve OID");
    2477                     wc_ecc_free(&ecc);
    2478                     return BAD_FUNC_ARG;
    2479                 }
    2480             }
    2481             else {
    2482                 WOLFSSL_MSG("Not ECC DER key either");
    2483             }
    2484             wc_ecc_free(&ecc);
     2799        wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);
     2800        if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
     2801            *algoID = ECDSAk;
     2802
     2803            /* now find oid */
     2804            if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
     2805                WOLFSSL_MSG("Error getting ECC curve OID");
     2806                wc_ecc_free(&ecc);
     2807                return BAD_FUNC_ARG;
     2808        }
    24852809        }
    24862810        else {
    2487             WOLFSSL_MSG("GetKeyOID wc_ecc_init_ex failed");
    2488         }
    2489     }
    2490 #endif /* HAVE_ECC */
    2491 #ifdef HAVE_ED25519
     2811            WOLFSSL_MSG("Not ECC DER key either");
     2812        }
     2813        wc_ecc_free(&ecc);
     2814    }
     2815#endif /* HAVE_ECC && !NO_ASN_CRYPT */
     2816#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    24922817    if (*algoID != RSAk && *algoID != ECDSAk) {
     2818        ed25519_key ed25519;
     2819
     2820        tmpIdx = 0;
    24932821        if (wc_ed25519_init(&ed25519) == 0) {
    24942822            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
    24952823                                                                         == 0) {
    24962824                *algoID = ED25519k;
    2497             }
    2498             else {
     2825    }
     2826    else {
    24992827                WOLFSSL_MSG("Not ED25519 DER key");
    2500             }
     2828    }
    25012829            wc_ed25519_free(&ed25519);
    2502         }
     2830    }
    25032831        else {
    25042832            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
    25052833        }
    25062834    }
    2507 #endif
     2835#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
    25082836
    25092837    /* if flag is not set then is neither RSA or ECC key that could be
     
    25142842    }
    25152843
     2844    (void)tmpIdx;
    25162845    (void)curveOID;
    25172846    (void)oidSz;
     2847    (void)keySz;
     2848    (void)heap;
    25182849
    25192850    return 1;
    25202851}
    25212852
     2853#define PKCS8_MIN_BLOCK_SIZE 8
     2854static int Pkcs8Pad(byte* buf, int sz, int blockSz)
     2855        {
     2856    int i, padSz;
     2857
     2858    /* calculate pad size */
     2859    padSz = blockSz - (sz & (blockSz - 1));
     2860
     2861    /* pad with padSz value */
     2862    if (buf) {
     2863        for (i = 0; i < padSz; i++) {
     2864            buf[sz+i] = (byte)(padSz & 0xFF);
     2865        }
     2866            }
     2867
     2868    /* return adjusted length */
     2869    return sz + padSz;
     2870        }
     2871
     2872/*
     2873 * Used when creating PKCS12 shrouded key bags
     2874 * vPKCS is the version of PKCS to use
     2875 * vAlgo is the algorithm version to use
     2876 *
     2877 * if salt is NULL a random number is generated
     2878 *
     2879 * returns the size of encrypted data on success
     2880 */
     2881int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
     2882        const char* password, int passwordSz, int vPKCS, int vAlgo,
     2883        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
     2884        {
     2885    int algoID = 0;
     2886    byte*  tmp;
     2887    word32 tmpSz = 0;
     2888    word32 sz;
     2889    word32 seqSz;
     2890    word32 inOutIdx = 0;
     2891    word32 totalSz = 0;
     2892    int    version, id;
     2893    int    ret;
     2894    int    blockSz = 0;
     2895
     2896    const byte* curveOID = NULL;
     2897    word32 oidSz   = 0;
     2898
     2899#ifdef WOLFSSL_SMALL_STACK
     2900    byte*  saltTmp = NULL;
     2901    byte*  cbcIv   = NULL;
     2902#else
     2903    byte   saltTmp[MAX_IV_SIZE];
     2904    byte   cbcIv[MAX_IV_SIZE];
     2905#endif
     2906
     2907    WOLFSSL_ENTER("UnTraditionalEnc()");
     2908
     2909    if (saltSz > MAX_SALT_SIZE)
     2910        return ASN_PARSE_E;
     2911
     2912
     2913    inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */
     2914    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
     2915        WOLFSSL_MSG("Bad/Unsupported algorithm ID");
     2916        return ASN_INPUT_E;  /* Algo ID error */
     2917            }
     2918
     2919    if (out != NULL) {
     2920        if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +
     2921                MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)
     2922                return BUFFER_E;
     2923
     2924        if (version == PKCS5v2) {
     2925            WOLFSSL_MSG("PKCS5v2 Not supported yet\n");
     2926            return ASN_VERSION_E;
     2927        }
     2928
     2929        if (salt == NULL || saltSz <= 0) {
     2930            saltSz = 8;
     2931        #ifdef WOLFSSL_SMALL_STACK
     2932            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2933            if (saltTmp == NULL)
     2934                return MEMORY_E;
     2935        #endif
     2936            salt = saltTmp;
     2937
     2938            if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     2939                WOLFSSL_MSG("Error generating random salt");
     2940#ifdef WOLFSSL_SMALL_STACK
     2941                if (saltTmp != NULL)
     2942                    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2943#endif
     2944                return ret;
     2945            }
     2946        }
     2947
     2948
     2949        /* leave room for a sequence (contains salt and iterations int) */
     2950        inOutIdx += MAX_SEQ_SZ; sz = 0;
     2951        inOutIdx += MAX_ALGO_SZ;
     2952
     2953        /* place salt in buffer */
     2954        out[inOutIdx++] = ASN_OCTET_STRING; sz++;
     2955        tmpSz = SetLength(saltSz, out + inOutIdx);
     2956        inOutIdx += tmpSz; sz += tmpSz;
     2957        XMEMCPY(out + inOutIdx, salt, saltSz);
     2958        inOutIdx += saltSz; sz += saltSz;
     2959
     2960        /* place iteration count in buffer */
     2961        ret = SetShortInt(out, &inOutIdx, itt, *outSz);
     2962        if (ret < 0) {
     2963            return ret;
     2964        }
     2965        sz += (word32)ret;
     2966
     2967        /* wind back index and set sequence then clean up buffer */
     2968        inOutIdx -= (sz + MAX_SEQ_SZ);
     2969        tmpSz = SetSequence(sz, out + inOutIdx);
     2970        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);
     2971        totalSz += tmpSz + sz; sz += tmpSz;
     2972
     2973        /* add in algo ID */
     2974        inOutIdx -= MAX_ALGO_SZ;
     2975        tmpSz =  SetAlgoID(id, out + inOutIdx, oidPBEType, sz);
     2976        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);
     2977        totalSz += tmpSz; inOutIdx += tmpSz + sz;
     2978
     2979        /* octet string containing encrypted key */
     2980        out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;
     2981    }
     2982
     2983    /* check key type and get OID if ECC */
     2984    if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {
     2985            return ret;
     2986    }
     2987
     2988    /* PKCS#8 wrapping around key */
     2989    if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)
     2990            != LENGTH_ONLY_E) {
     2991#ifdef WOLFSSL_SMALL_STACK
     2992        if (saltTmp != NULL)
     2993            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2994#endif
     2995        return MEMORY_E;
     2996            }
     2997
     2998    /* check if should return max size */
     2999    if (out == NULL) {
     3000        /* account for salt size */
     3001        if (salt == NULL || saltSz <= 0) {
     3002            tmpSz += MAX_SALT_SIZE;
     3003        }
     3004        else {
     3005            tmpSz += saltSz;
     3006        }
     3007
     3008        /* plus 3 for tags */
     3009        *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ
     3010            + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;
     3011        return LENGTH_ONLY_E;
     3012        }
     3013
     3014    /* reserve buffer for crypto and make sure it supports full blocks */
     3015    tmp = (byte*)XMALLOC(tmpSz + (blockSz-1), heap, DYNAMIC_TYPE_TMP_BUFFER);
     3016    if (tmp == NULL) {
     3017    #ifdef WOLFSSL_SMALL_STACK
     3018        if (saltTmp != NULL)
     3019            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3020#endif
     3021        return MEMORY_E;
     3022    }
     3023
     3024    if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,
     3025                    oidSz)) < 0) {
     3026        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3027        WOLFSSL_MSG("Error wrapping key with PKCS#8");
     3028    #ifdef WOLFSSL_SMALL_STACK
     3029        if (saltTmp != NULL)
     3030            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3031    #endif
     3032        return ret;
     3033    }
     3034    tmpSz = ret;
     3035
     3036    /* adjust size to pad */
     3037    tmpSz = Pkcs8Pad(tmp, tmpSz, blockSz);
     3038
     3039#ifdef WOLFSSL_SMALL_STACK
     3040    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3041    if (cbcIv == NULL) {
     3042        if (saltTmp != NULL)
     3043            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3044        XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3045        return MEMORY_E;
     3046        }
     3047#endif
     3048
     3049    /* encrypt PKCS#8 wrapped key */
     3050    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3051               tmp, tmpSz, version, cbcIv, 1)) < 0) {
     3052        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3053        WOLFSSL_MSG("Error encrypting key");
     3054#ifdef WOLFSSL_SMALL_STACK
     3055        if (saltTmp != NULL)
     3056            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3057        if (cbcIv != NULL)
     3058            XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3059#endif
     3060        return ret;  /* encryption failure */
     3061    }
     3062    totalSz += tmpSz;
     3063
     3064#ifdef WOLFSSL_SMALL_STACK
     3065    if (saltTmp != NULL)
     3066        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3067    if (cbcIv != NULL)
     3068        XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3069#endif
     3070
     3071    if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {
     3072        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3073        return BUFFER_E;
     3074}
     3075
     3076    /* set length of key and copy over encrypted key */
     3077    seqSz = SetLength(tmpSz, out + inOutIdx);
     3078    inOutIdx += seqSz; totalSz += seqSz;
     3079    XMEMCPY(out + inOutIdx, tmp, tmpSz);
     3080    XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3081
     3082    /* set total size at beginning */
     3083    sz = SetSequence(totalSz, out);
     3084    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);
     3085
     3086    (void)rng;
     3087
     3088    return totalSz + sz;
     3089}
     3090
     3091static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
     3092                     int *blkSz)
     3093{
     3094    int ret = 0;
     3095
     3096    switch (encAlgId) {
     3097#if !defined(NO_DES3) && !defined(NO_SHA)
     3098    case DESb:
     3099        *len = sizeof(blkDesCbcOid);
     3100        *oid = blkDesCbcOid;
     3101        *id = PBE_SHA1_DES;
     3102        *blkSz = 8;
     3103        break;
     3104    case DES3b:
     3105        *len = sizeof(blkDes3CbcOid);
     3106        *oid = blkDes3CbcOid;
     3107        *id = PBE_SHA1_DES3;
     3108        *blkSz = 8;
     3109        break;
     3110#endif
     3111#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
     3112    case AES256CBCb:
     3113        *len = sizeof(blkAes256CbcOid);
     3114        *oid = blkAes256CbcOid;
     3115        *id = PBE_AES256_CBC;
     3116        *blkSz = 16;
     3117        break;
     3118#endif
     3119    default:
     3120        (void)len;
     3121        (void)oid;
     3122        (void)id;
     3123        (void)blkSz;
     3124        ret = ALGO_ID_E;
     3125    }
     3126
     3127    return ret;
     3128        }
     3129
     3130/* Converts Encrypted PKCS#8 to 'traditional' (i.e. PKCS#8 removed from
     3131 * decrypted key.)
     3132 */
     3133int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
     3134        const char* password, int passwordSz, int vPKCS, int vAlgo,
     3135        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
     3136        void* heap)
     3137{
     3138    int ret = 0;
     3139    int version, blockSz, id;
     3140    word32 idx = 0, encIdx;
     3141#ifdef WOLFSSL_SMALL_STACK
     3142    byte* saltTmp = NULL;
     3143#else
     3144    byte saltTmp[MAX_SALT_SIZE];
     3145#endif
     3146    byte cbcIv[MAX_IV_SIZE];
     3147    byte *pkcs8Key = NULL;
     3148    word32 pkcs8KeySz, padSz = 0;
     3149    int algId;
     3150    const byte* curveOid = NULL;
     3151    word32 curveOidSz = 0;
     3152    const byte* pbeOid = NULL;
     3153    word32 pbeOidSz;
     3154    const byte* encOid = NULL;
     3155    int encOidSz = 0;
     3156    word32 pbeLen = 0, kdfLen = 0, encLen = 0;
     3157    word32 innerLen = 0, outerLen;
     3158
     3159    ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz);
     3160    /* create random salt if one not provided */
     3161    if (ret == 0 && (salt == NULL || saltSz <= 0)) {
     3162        saltSz = 8;
     3163    #ifdef WOLFSSL_SMALL_STACK
     3164        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3165        if (saltTmp == NULL)
     3166            return MEMORY_E;
     3167    #endif
     3168        salt = saltTmp;
     3169
     3170        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     3171            WOLFSSL_MSG("Error generating random salt");
     3172        #ifdef WOLFSSL_SMALL_STACK
     3173            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3174        #endif
     3175            return ret;
     3176    }
     3177    }
     3178
     3179    if (ret == 0) {
     3180        /* check key type and get OID if ECC */
     3181        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
     3182        if (ret == 1)
     3183            ret = 0;
     3184                }
     3185    if (ret == 0) {
     3186        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
     3187                                                                    curveOidSz);
     3188        if (ret == LENGTH_ONLY_E)
     3189            ret = 0;
     3190                }
     3191    if (ret == 0) {
     3192        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     3193        if (pkcs8Key == NULL)
     3194            ret = MEMORY_E;
     3195            }
     3196    if (ret == 0) {
     3197        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
     3198                                                          curveOid, curveOidSz);
     3199        if (ret >= 0) {
     3200            pkcs8KeySz = ret;
     3201            ret = 0;
     3202            }
     3203        }
     3204
     3205    if (ret == 0 && version == PKCS5v2)
     3206        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &id, &blockSz);
     3207
     3208    if (ret == 0) {
     3209        padSz = (blockSz - (pkcs8KeySz & (blockSz - 1))) & (blockSz - 1);
     3210        /* inner = OCT salt INT itt */
     3211        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
     3212
     3213        if (version != PKCS5v2) {
     3214            pbeOid = OidFromId(id, oidPBEType, &pbeOidSz);
     3215            /* pbe = OBJ pbse1 SEQ [ inner ] */
     3216            pbeLen = 2 + pbeOidSz + 2 + innerLen;
     3217        }
     3218        else {
     3219            pbeOid = pbes2;
     3220            pbeOidSz = sizeof(pbes2);
     3221            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
     3222            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
     3223            /* enc = OBJ enc_alg OCT iv */
     3224            encLen = 2 + encOidSz + 2 + blockSz;
     3225            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
     3226            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
     3227
     3228            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
     3229        }
     3230    }
     3231    if (ret == 0) {
     3232        /* outer = SEQ [ pbe ] OCT encrypted_PKCS#8_key */
     3233        outerLen = 2 + pbeLen;
     3234        outerLen += SetOctetString(pkcs8KeySz + padSz, out);
     3235        outerLen += pkcs8KeySz + padSz;
     3236
     3237        idx += SetSequence(outerLen, out + idx);
     3238
     3239        encIdx = idx + outerLen - pkcs8KeySz - padSz;
     3240        /* Put Encrypted content in place. */
     3241        XMEMCPY(out + encIdx, pkcs8Key, pkcs8KeySz);
     3242        if (padSz > 0) {
     3243            XMEMSET(out + encIdx + pkcs8KeySz, padSz, padSz);
     3244            pkcs8KeySz += padSz;
     3245            }
     3246        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3247                                   out + encIdx, pkcs8KeySz, version, cbcIv, 1);
     3248            }
     3249    if (ret == 0) {
     3250        if (version != PKCS5v2) {
     3251            /* PBE algorithm */
     3252            idx += SetSequence(pbeLen, out + idx);
     3253            idx += SetObjectId(pbeOidSz, out + idx);
     3254            XMEMCPY(out + idx, pbeOid, pbeOidSz);
     3255            idx += pbeOidSz;
     3256        }
     3257        else {
     3258            /* PBES2 algorithm identifier */
     3259            idx += SetSequence(pbeLen, out + idx);
     3260            idx += SetObjectId(pbeOidSz, out + idx);
     3261            XMEMCPY(out + idx, pbeOid, pbeOidSz);
     3262            idx += pbeOidSz;
     3263            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
     3264            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
     3265            /* KDF Algorithm Identifier */
     3266            idx += SetSequence(kdfLen, out + idx);
     3267            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
     3268            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
     3269            idx += sizeof(pbkdf2Oid);
     3270        }
     3271        idx += SetSequence(innerLen, out + idx);
     3272        idx += SetOctetString(saltSz, out + idx);
     3273        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
     3274        ret = SetShortInt(out, &idx, itt, *outSz);
     3275        if (ret > 0)
     3276            ret = 0;
     3277        }
     3278    if (ret == 0) {
     3279        if (version == PKCS5v2) {
     3280            /* Encryption Algorithm Identifier */
     3281            idx += SetSequence(encLen, out + idx);
     3282            idx += SetObjectId(encOidSz, out + idx);
     3283            XMEMCPY(out + idx, encOid, encOidSz);
     3284            idx += encOidSz;
     3285            /* Encryption Algorithm Parameter: CBC IV */
     3286            idx += SetOctetString(blockSz, out + idx);
     3287            XMEMCPY(out + idx, cbcIv, blockSz);
     3288            idx += blockSz;
     3289        }
     3290        idx += SetOctetString(pkcs8KeySz, out + idx);
     3291        /* Default PRF - no need to write out OID */
     3292        idx += pkcs8KeySz;
     3293
     3294        ret = idx;
     3295    }
     3296
     3297    if (pkcs8Key != NULL) {
     3298        ForceZero(pkcs8Key, pkcs8KeySz);
     3299        XFREE(pkcs8Key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     3300        }
     3301#ifdef WOLFSSL_SMALL_STACK
     3302    if (saltTmp != NULL) {
     3303        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3304    }
     3305#endif
     3306
     3307    (void)rng;
     3308
     3309    return ret;
     3310}
    25223311
    25233312/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
    25243313   of input */
    2525 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
    2526 {
    2527     word32 inOutIdx = 0, oid;
     3314int ToTraditionalEnc(byte* input, word32 sz,const char* password,
     3315                     int passwordSz, word32* algId)
     3316{
     3317    word32 inOutIdx = 0, seqEnd, oid;
    25283318    int    ret = 0, first, second, length = 0, version, saltSz, id;
    2529     int    iterations = 0;
     3319    int    iterations = 0, keySz = 0;
    25303320#ifdef WOLFSSL_SMALL_STACK
    25313321    byte*  salt = NULL;
     
    25363326#endif
    25373327
     3328    if (passwordSz < 0) {
     3329        WOLFSSL_MSG("Bad password size");
     3330        return BAD_FUNC_ARG;
     3331    }
     3332
    25383333    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
    25393334        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25403335    }
    25413336
    2542     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
     3337    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
    25433338        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25443339    }
     
    25473342    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
    25483343
    2549     if (CheckAlgo(first, second, &id, &version) < 0) {
     3344    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
    25503345        ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */
    25513346    }
     
    25683363        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25693364    }
     3365    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
     3366     * DEFAULT items. */
     3367    seqEnd = inOutIdx + length;
    25703368
    25713369    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
     
    25913389    }
    25923390
     3391    /* OPTIONAL key length */
     3392    if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
     3393        if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
     3394            ERROR_OUT(ASN_PARSE_E, exit_tte);
     3395        }
     3396    }
     3397
     3398    /* DEFAULT HMAC is SHA-1 */
     3399    if (seqEnd > inOutIdx) {
     3400        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
     3401            ERROR_OUT(ASN_PARSE_E, exit_tte);
     3402        }
     3403    }
     3404
    25933405#ifdef WOLFSSL_SMALL_STACK
    25943406    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    26003412    if (version == PKCS5v2) {
    26013413        /* get encryption algo */
    2602         /* JOHN: New type. Need a little more research. */
    26033414        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
    26043415            ERROR_OUT(ASN_PARSE_E, exit_tte);
    26053416        }
    26063417
    2607         if (CheckAlgoV2(oid, &id) < 0) {
     3418        if (CheckAlgoV2(oid, &id, NULL) < 0) {
    26083419            ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */
    26093420        }
     
    26253436        goto exit_tte;
    26263437
    2627     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
    2628                                    input + inOutIdx, length, version, cbcIv);
     3438    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
     3439                   input + inOutIdx, length, version, cbcIv, 0);
    26293440
    26303441exit_tte:
     
    26363447    if (ret == 0) {
    26373448        XMEMMOVE(input, input + inOutIdx, length);
    2638         ret = ToTraditional(input, length);
     3449        ret = ToTraditional_ex(input, length, algId);
    26393450    }
    26403451
     
    26423453}
    26433454
    2644 /* decrypt PKCS */
    2645 int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
    2646 {
    2647     word32 inOutIdx = 0, oid;
     3455
     3456/* encrypt PKCS 12 content
     3457 *
     3458 * NOTE: if out is NULL then outSz is set with the total buffer size needed and
     3459 *       the error value LENGTH_ONLY_E is returned.
     3460 *
     3461 * input      data to encrypt
     3462 * inputSz    size of input buffer
     3463 * out        buffer to hold the result
     3464 * outSz      size of out buffer
     3465 * password   password if used. Can be NULL for no password
     3466 * passwordSz size of password buffer
     3467 * vPKCS      version of PKCS i.e. PKCS5v2
     3468 * vAlgo      algorithm version
     3469 * salt       buffer holding salt if used. If NULL then a random salt is created
     3470 * saltSz     size of salt buffer if it is not NULL
     3471 * itt        number of iterations used
     3472 * rng        random number generator to use
     3473 * heap       possible heap hint for mallocs/frees
     3474 *
     3475 * returns the total size of encrypted content on success.
     3476 */
     3477int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
     3478        const char* password, int passwordSz, int vPKCS, int vAlgo,
     3479        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
     3480{
     3481    word32 sz;
     3482    word32 inOutIdx = 0;
     3483    word32 tmpIdx   = 0;
     3484    word32 totalSz  = 0;
     3485    word32 seqSz;
     3486    int    ret;
     3487    int    version, id, blockSz = 0;
     3488#ifdef WOLFSSL_SMALL_STACK
     3489    byte*  saltTmp = NULL;
     3490    byte*  cbcIv = NULL;
     3491#else
     3492    byte   saltTmp[MAX_SALT_SIZE];
     3493    byte   cbcIv[MAX_IV_SIZE];
     3494#endif
     3495
     3496    (void)heap;
     3497
     3498    WOLFSSL_ENTER("EncryptContent()");
     3499
     3500    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
     3501        return ASN_INPUT_E;  /* Algo ID error */
     3502
     3503    if (version == PKCS5v2) {
     3504        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
     3505        return BAD_FUNC_ARG;
     3506        }
     3507
     3508    if (saltSz > MAX_SALT_SIZE)
     3509        return ASN_PARSE_E;
     3510
     3511    if (outSz == NULL) {
     3512        return BAD_FUNC_ARG;
     3513    }
     3514
     3515    if (out == NULL) {
     3516        sz = inputSz;
     3517        switch (id) {
     3518        #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA))
     3519            case PBE_MD5_DES:
     3520            case PBE_SHA1_DES:
     3521            case PBE_SHA1_DES3:
     3522                /* set to block size of 8 for DES operations. This rounds up
     3523                 * to the nearest multiple of 8 */
     3524                sz &= 0xfffffff8;
     3525                sz += 8;
     3526                break;
     3527        #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */
     3528        #if !defined(NO_RC4) && !defined(NO_SHA)
     3529            case PBE_SHA1_RC4_128:
     3530                break;
     3531        #endif
     3532            case -1:
     3533                break;
     3534
     3535            default:
     3536                return ALGO_ID_E;
     3537        }
     3538
     3539        if (saltSz <= 0) {
     3540            sz += MAX_SALT_SIZE;
     3541        }
     3542        else {
     3543            sz += saltSz;
     3544        }
     3545
     3546        /* add 2 for tags */
     3547        totalSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
     3548            MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2;
     3549
     3550        /* adjust size to pad */
     3551        totalSz = Pkcs8Pad(NULL, totalSz, blockSz);
     3552
     3553        /* return result */
     3554        *outSz = totalSz;
     3555
     3556        return LENGTH_ONLY_E;
     3557    }
     3558
     3559    if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz)
     3560        return BUFFER_E;
     3561
     3562    sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0);
     3563    inOutIdx += sz; totalSz += sz;
     3564    tmpIdx = inOutIdx;
     3565    tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */
     3566    out[tmpIdx++] = ASN_OCTET_STRING;
     3567
     3568    /* create random salt if one not provided */
     3569    if (salt == NULL || saltSz <= 0) {
     3570        saltSz = 8;
     3571    #ifdef WOLFSSL_SMALL_STACK
     3572        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3573        if (saltTmp == NULL)
     3574            return MEMORY_E;
     3575    #endif
     3576        salt = saltTmp;
     3577
     3578        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     3579            WOLFSSL_MSG("Error generating random salt");
     3580        #ifdef WOLFSSL_SMALL_STACK
     3581            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3582        #endif
     3583            return ret;
     3584        }
     3585    }
     3586
     3587    if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) {
     3588    #ifdef WOLFSSL_SMALL_STACK
     3589        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3590    #endif
     3591        return BUFFER_E;
     3592    }
     3593
     3594    sz = SetLength(saltSz, out + tmpIdx);
     3595    tmpIdx += sz;
     3596
     3597    XMEMCPY(out + tmpIdx, salt, saltSz);
     3598    tmpIdx += saltSz;
     3599
     3600    /* place iteration setting in buffer */
     3601    ret = SetShortInt(out, &tmpIdx, itt, *outSz);
     3602    if (ret < 0) {
     3603    #ifdef WOLFSSL_SMALL_STACK
     3604        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3605    #endif
     3606        return ret;
     3607    }
     3608
     3609    /* rewind and place sequence */
     3610    sz = tmpIdx - inOutIdx - MAX_SEQ_SZ;
     3611    seqSz = SetSequence(sz, out + inOutIdx);
     3612    XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz);
     3613    inOutIdx += seqSz; totalSz += seqSz;
     3614    inOutIdx += sz; totalSz += sz;
     3615
     3616#ifdef WOLFSSL_SMALL_STACK
     3617    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3618    if (cbcIv == NULL) {
     3619        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3620        return MEMORY_E;
     3621    }
     3622#endif
     3623
     3624    if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)
     3625        return BUFFER_E;
     3626
     3627    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; totalSz++;
     3628    sz = SetLength(inputSz, out + inOutIdx);
     3629    inOutIdx += sz; totalSz += sz;
     3630
     3631    /* get pad size and verify buffer room */
     3632    sz = Pkcs8Pad(NULL, inputSz, blockSz);
     3633    if (sz + inOutIdx > *outSz)
     3634        return BUFFER_E;
     3635
     3636    /* copy input to output buffer and pad end */
     3637    XMEMCPY(out + inOutIdx, input, inputSz);
     3638    sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);
     3639    totalSz += sz;
     3640
     3641    /* encrypt */
     3642    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3643                   out + inOutIdx, sz, version, cbcIv, 1)) < 0) {
     3644
     3645    #ifdef WOLFSSL_SMALL_STACK
     3646        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
     3647        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3648    #endif
     3649        return ret;  /* encrypt failure */
     3650    }
     3651
     3652#ifdef WOLFSSL_SMALL_STACK
     3653    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
     3654    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3655#endif
     3656
     3657    (void)rng;
     3658
     3659    return totalSz;
     3660}
     3661
     3662
     3663/* decrypt PKCS
     3664 *
     3665 * NOTE: input buffer is overwritten with decrypted data!
     3666 *
     3667 * input[in/out] data to decrypt and results are written to
     3668 * sz            size of input buffer
     3669 * password      password if used. Can be NULL for no password
     3670 * passwordSz    size of password buffer
     3671 *
     3672 * returns the total size of decrypted content on success.
     3673 */
     3674int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
     3675{
     3676    word32 inOutIdx = 0, seqEnd, oid;
    26483677    int    ret = 0;
    26493678    int    first, second, length = 0, version, saltSz, id;
    2650     int    iterations = 0;
     3679    int    iterations = 0, keySz = 0;
    26513680#ifdef WOLFSSL_SMALL_STACK
    26523681    byte*  salt = NULL;
     
    26573686#endif
    26583687
    2659     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
     3688    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
    26603689        ERROR_OUT(ASN_PARSE_E, exit_dc);
    26613690    }
     
    26643693    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
    26653694
    2666     if (CheckAlgo(first, second, &id, &version) < 0) {
     3695    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
    26673696        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
    26683697    }
     
    26853714        ERROR_OUT(ASN_PARSE_E, exit_dc);
    26863715    }
     3716    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
     3717     * DEFAULT items. */
     3718    seqEnd = inOutIdx + length;
    26873719
    26883720    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
     
    27083740    }
    27093741
     3742    /* OPTIONAL key length */
     3743    if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
     3744        if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
     3745            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3746        }
     3747    }
     3748
     3749    /* DEFAULT HMAC is SHA-1 */
     3750    if (seqEnd > inOutIdx) {
     3751        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
     3752            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3753        }
     3754    }
     3755
    27103756#ifdef WOLFSSL_SMALL_STACK
    27113757    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    27173763    if (version == PKCS5v2) {
    27183764        /* get encryption algo */
    2719         /* JOHN: New type. Need a little more research. */
    27203765        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
    27213766            ERROR_OUT(ASN_PARSE_E, exit_dc);
    27223767        }
    27233768
    2724         if (CheckAlgoV2(oid, &id) < 0) {
     3769        if (CheckAlgoV2(oid, &id, NULL) < 0) {
    27253770            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
    27263771        }
     
    27303775            goto exit_dc;
    27313776
     3777        if (length > MAX_IV_SIZE) {
     3778            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3779        }
     3780
    27323781        XMEMCPY(cbcIv, &input[inOutIdx], length);
    27333782        inOutIdx += length;
     
    27423791    }
    27433792
    2744     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
    2745                                    input + inOutIdx, length, version, cbcIv);
     3793    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
     3794                   input + inOutIdx, length, version, cbcIv, 0);
    27463795
    27473796exit_dc:
     
    27643813
    27653814#ifndef HAVE_USER_RSA
    2766 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
    2767                        word32 inSz)
    2768 {
     3815int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
     3816    const byte** n, word32* nSz, const byte** e, word32* eSz)
     3817{
     3818    int ret = 0;
    27693819    int  length;
    27703820#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
    27713821    byte b;
    27723822#endif
    2773     int ret;
    2774 
    2775     if (input == NULL || inOutIdx == NULL || key == NULL)
     3823
     3824    if (input == NULL || inOutIdx == NULL)
    27763825        return BAD_FUNC_ARG;
    27773826
    27783827    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
    27793828        return ASN_PARSE_E;
    2780 
    2781     key->type = RSA_PUBLIC;
    27823829
    27833830#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
     
    27953842
    27963843        /* Option NULL ASN.1 tag */
     3844        if (*inOutIdx  >= inSz) {
     3845            return BUFFER_E;
     3846        }
    27973847        if (input[*inOutIdx] == ASN_TAG_NULL) {
    27983848            ret = GetASNNull(input, inOutIdx, inSz);
     
    28113861#endif /* OPENSSL_EXTRA */
    28123862
    2813     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0)
     3863    /* Get modulus */
     3864    ret = GetASNInt(input, inOutIdx, &length, inSz);
     3865    if (ret < 0) {
    28143866        return ASN_RSA_KEY_E;
    2815     if (GetInt(&key->e,  input, inOutIdx, inSz) < 0) {
    2816         mp_clear(&key->n);
     3867    }
     3868    if (nSz)
     3869        *nSz = length;
     3870    if (n)
     3871        *n = &input[*inOutIdx];
     3872    *inOutIdx += length;
     3873
     3874    /* Get exponent */
     3875    ret = GetASNInt(input, inOutIdx, &length, inSz);
     3876    if (ret < 0) {
    28173877        return ASN_RSA_KEY_E;
    28183878    }
    2819 
    2820 #ifdef WOLFSSL_XILINX_CRYPT
    2821     if (wc_InitRsaHw(key) != 0) {
    2822         return BAD_STATE_E;
    2823     }
    2824 #endif
    2825 
    2826     return 0;
     3879    if (eSz)
     3880        *eSz = length;
     3881    if (e)
     3882        *e = &input[*inOutIdx];
     3883    *inOutIdx += length;
     3884
     3885    return ret;
     3886    }
     3887
     3888int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
     3889                       word32 inSz)
     3890{
     3891    int ret;
     3892    const byte *n = NULL, *e = NULL;
     3893    word32 nSz = 0, eSz = 0;
     3894
     3895    if (key == NULL)
     3896        return BAD_FUNC_ARG;
     3897
     3898    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
     3899    if (ret == 0) {
     3900        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
     3901    }
     3902
     3903    return ret;
    28273904}
    28283905
     
    28433920        return ASN_GETINT_E;
    28443921    }
     3922#ifdef HAVE_WOLF_BIGINT
     3923    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
     3924        mp_clear(&key->n);
     3925        return ASN_GETINT_E;
     3926    }
     3927#endif /* HAVE_WOLF_BIGINT */
    28453928
    28463929    if (mp_init(&key->e) != MP_OKAY) {
     
    28543937        return ASN_GETINT_E;
    28553938    }
     3939#ifdef HAVE_WOLF_BIGINT
     3940    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
     3941        mp_clear(&key->n);
     3942        mp_clear(&key->e);
     3943        return ASN_GETINT_E;
     3944    }
     3945#endif /* HAVE_WOLF_BIGINT */
    28563946
    28573947#ifdef WOLFSSL_XILINX_CRYPT
     
    28643954}
    28653955#endif /* HAVE_USER_RSA */
    2866 #endif
     3956#endif /* !NO_RSA */
    28673957
    28683958#ifndef NO_DH
     
    29944084
    29954085/* Release Tmp DSA resources */
    2996 static INLINE void FreeTmpDsas(byte** tmps, void* heap)
     4086static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
    29974087{
    29984088    int i;
     
    30764166
    30774167
    3078 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
     4168void InitDecodedCert(DecodedCert* cert,
     4169                     const byte* source, word32 inSz, void* heap)
    30794170{
    30804171    if (cert != NULL) {
     
    31364227        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
    31374228    if (cert->pubKeyStored == 1)
    3138         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
     4229        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
    31394230    if (cert->weOwnAltNames && cert->altNames)
    31404231        FreeAltNames(cert->altNames, cert->heap);
     
    31524243    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
    31534244#endif /* WOLFSSL_SEP */
    3154 #ifdef OPENSSL_EXTRA
     4245#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    31554246    if (cert->issuerName.fullName != NULL)
    31564247        XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
     
    32314322{
    32324323    int length;
    3233 #ifdef HAVE_NTRU
     4324#if defined(HAVE_ECC) || defined(HAVE_NTRU)
    32344325    int tmpIdx = cert->srcIdx;
    32354326#endif
     
    32644355            word32      rc;
    32654356            word32      remaining = cert->maxIdx - cert->srcIdx;
     4357            byte*       publicKey;
    32664358#ifdef WOLFSSL_SMALL_STACK
    32674359            byte*       keyBlob = NULL;
     
    32774369
    32784370#ifdef WOLFSSL_SMALL_STACK
    3279             keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
     4371            keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,
    32804372                                     DYNAMIC_TYPE_TMP_BUFFER);
    32814373            if (keyBlob == NULL)
     
    32874379            if (rc != NTRU_OK) {
    32884380#ifdef WOLFSSL_SMALL_STACK
    3289                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4381                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    32904382#endif
    32914383                return ASN_NTRU_KEY_E;
     
    32944386            if ( (next - key) < 0) {
    32954387#ifdef WOLFSSL_SMALL_STACK
    3296                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4388                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    32974389#endif
    32984390                return ASN_NTRU_KEY_E;
     
    33014393            cert->srcIdx = tmpIdx + (int)(next - key);
    33024394
    3303             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
     4395            publicKey = (byte*)XMALLOC(keyLen, cert->heap,
    33044396                                              DYNAMIC_TYPE_PUBLIC_KEY);
    3305             if (cert->publicKey == NULL) {
     4397            if (publicKey == NULL) {
    33064398#ifdef WOLFSSL_SMALL_STACK
    3307                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4399                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    33084400#endif
    33094401                return MEMORY_E;
    33104402            }
    3311             XMEMCPY(cert->publicKey, keyBlob, keyLen);
     4403            XMEMCPY(publicKey, keyBlob, keyLen);
     4404            cert->publicKey = publicKey;
    33124405            cert->pubKeyStored = 1;
    33134406            cert->pubKeySize   = keyLen;
    33144407
    33154408#ifdef WOLFSSL_SMALL_STACK
    3316             XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4409            XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    33174410#endif
    33184411
     
    33244417        {
    33254418            int ret;
    3326 
     4419            byte seq[5];
     4420            int pubLen = length + 1 + SetLength(length, seq);
     4421            byte* publicKey;
     4422
     4423            if (cert->source[cert->srcIdx] !=
     4424                                             (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
    33274425            if (GetObjectId(cert->source, &cert->srcIdx,
    33284426                            &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
     
    33374435            if (ret != 0)
    33384436                return ret;
    3339 
    3340             cert->publicKey = (byte*)XMALLOC(length, cert->heap,
     4437            }
     4438
     4439            publicKey = (byte*)XMALLOC(pubLen, cert->heap,
    33414440                                             DYNAMIC_TYPE_PUBLIC_KEY);
    3342             if (cert->publicKey == NULL)
     4441            if (publicKey == NULL)
    33434442                return MEMORY_E;
    3344             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
     4443            XMEMCPY(publicKey, &cert->source[tmpIdx], pubLen);
     4444            cert->publicKey = publicKey;
    33454445            cert->pubKeyStored = 1;
    3346             cert->pubKeySize   = length;
    3347 
    3348             cert->srcIdx += length;
     4446            cert->pubKeySize   = pubLen;
     4447
     4448            cert->srcIdx = tmpIdx + pubLen;
    33494449
    33504450            return 0;
     
    33544454        case ED25519k:
    33554455        {
     4456            byte* publicKey;
    33564457            int ret;
    33574458
     
    33634464                return ret;
    33644465
    3365             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
     4466            publicKey = (byte*) XMALLOC(length, cert->heap,
    33664467                                              DYNAMIC_TYPE_PUBLIC_KEY);
    3367             if (cert->publicKey == NULL)
     4468            if (publicKey == NULL)
    33684469                return MEMORY_E;
    3369             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
     4470            XMEMCPY(publicKey, &cert->source[cert->srcIdx], length);
     4471            cert->publicKey = publicKey;
    33704472            cert->pubKeyStored = 1;
    33714473            cert->pubKeySize   = length;
     
    33804482    }
    33814483}
     4484
     4485#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4486WOLFSSL_LOCAL int OBJ_sn2nid(const char *sn)
     4487{
     4488    static const struct {
     4489        const char *sn;
     4490        int  nid;
     4491    } sn2nid[] = {
     4492        {WOLFSSL_COMMON_NAME, NID_commonName},
     4493        {WOLFSSL_COUNTRY_NAME, NID_countryName},
     4494        {WOLFSSL_LOCALITY_NAME, NID_localityName},
     4495        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
     4496        {WOLFSSL_ORG_NAME, NID_organizationName},
     4497        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
     4498        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
     4499        {NULL, -1}};
     4500
     4501    int i;
     4502    WOLFSSL_ENTER("OBJ_osn2nid");
     4503    #ifdef HAVE_ECC
     4504    /* Nginx uses this OpenSSL string. */
     4505    if (XSTRNCMP(sn, "prime256v1", 10) == 0)
     4506        sn = "SECP256R1";
     4507    if (XSTRNCMP(sn, "secp384r1", 10) == 0)
     4508        sn = "SECP384R1";
     4509    /* find based on name and return NID */
     4510    for (i = 0; i < ecc_sets[i].size; i++) {
     4511        if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
     4512            return ecc_sets[i].id;
     4513        }
     4514    }
     4515    #endif
     4516
     4517    for(i=0; sn2nid[i].sn != NULL; i++) {
     4518        if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {
     4519            return sn2nid[i].nid;
     4520        }
     4521    }
     4522
     4523    return NID_undef;
     4524}
     4525#endif
    33824526
    33834527/* process NAME, either issuer or subject */
     
    33904534    byte*  hash;
    33914535    word32 idx;
    3392     #ifdef OPENSSL_EXTRA
     4536    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    33934537        DecodedName* dName =
    33944538                  (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
     4539        int dcnum = 0;
    33954540    #endif /* OPENSSL_EXTRA */
    33964541
     
    34044549        full = cert->subject;
    34054550        hash = cert->subjectHash;
     4551    }
     4552
     4553    if (cert->srcIdx >= cert->maxIdx) {
     4554        return BUFFER_E;
    34064555    }
    34074556
     
    34214570        return ASN_PARSE_E;
    34224571
    3423 #ifdef NO_SHA
    3424     ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
    3425 #else
    3426     ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
    3427 #endif
     4572    ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);
    34284573    if (ret != 0)
    34294574        return ret;
     
    34324577    idx = 0;
    34334578
    3434 #ifdef HAVE_PKCS7
     4579#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
    34354580    /* store pointer to raw issuer */
    34364581    if (nameType == ISSUER) {
     
    34714616        /* v1 name types */
    34724617        if (joint[0] == 0x55 && joint[1] == 0x04) {
     4618            const char*  copy = NULL;
     4619            int    strLen;
    34734620            byte   id;
    3474             byte   copy = FALSE;
    3475             int    strLen;
    34764621
    34774622            cert->srcIdx += 2;
     
    34964641                }
    34974642
    3498                 if (!tooBig) {
    3499                     XMEMCPY(&full[idx], "/CN=", 4);
    3500                     idx += 4;
    3501                     copy = TRUE;
    3502                 }
    3503                 #ifdef OPENSSL_EXTRA
     4643                copy = WOLFSSL_COMMON_NAME;
     4644                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35044645                    dName->cnIdx = cert->srcIdx;
    35054646                    dName->cnLen = strLen;
     
    35074648            }
    35084649            else if (id == ASN_SUR_NAME) {
    3509                 if (!tooBig) {
    3510                     XMEMCPY(&full[idx], "/SN=", 4);
    3511                     idx += 4;
    3512                     copy = TRUE;
    3513                 }
     4650                copy = WOLFSSL_SUR_NAME;
    35144651                #ifdef WOLFSSL_CERT_GEN
    35154652                    if (nameType == SUBJECT) {
     
    35194656                    }
    35204657                #endif /* WOLFSSL_CERT_GEN */
    3521                 #ifdef OPENSSL_EXTRA
     4658                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35224659                    dName->snIdx = cert->srcIdx;
    35234660                    dName->snLen = strLen;
     
    35254662            }
    35264663            else if (id == ASN_COUNTRY_NAME) {
    3527                 if (!tooBig) {
    3528                     XMEMCPY(&full[idx], "/C=", 3);
    3529                     idx += 3;
    3530                     copy = TRUE;
    3531                 }
     4664                copy = WOLFSSL_COUNTRY_NAME;
    35324665                #ifdef WOLFSSL_CERT_GEN
    35334666                    if (nameType == SUBJECT) {
     
    35374670                    }
    35384671                #endif /* WOLFSSL_CERT_GEN */
    3539                 #ifdef OPENSSL_EXTRA
     4672                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35404673                    dName->cIdx = cert->srcIdx;
    35414674                    dName->cLen = strLen;
     
    35434676            }
    35444677            else if (id == ASN_LOCALITY_NAME) {
    3545                 if (!tooBig) {
    3546                     XMEMCPY(&full[idx], "/L=", 3);
    3547                     idx += 3;
    3548                     copy = TRUE;
    3549                 }
     4678                copy = WOLFSSL_LOCALITY_NAME;
    35504679                #ifdef WOLFSSL_CERT_GEN
    35514680                    if (nameType == SUBJECT) {
     
    35554684                    }
    35564685                #endif /* WOLFSSL_CERT_GEN */
    3557                 #ifdef OPENSSL_EXTRA
     4686                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35584687                    dName->lIdx = cert->srcIdx;
    35594688                    dName->lLen = strLen;
     
    35614690            }
    35624691            else if (id == ASN_STATE_NAME) {
    3563                 if (!tooBig) {
    3564                     XMEMCPY(&full[idx], "/ST=", 4);
    3565                     idx += 4;
    3566                     copy = TRUE;
    3567                 }
     4692                copy = WOLFSSL_STATE_NAME;
    35684693                #ifdef WOLFSSL_CERT_GEN
    35694694                    if (nameType == SUBJECT) {
     
    35734698                    }
    35744699                #endif /* WOLFSSL_CERT_GEN */
    3575                 #ifdef OPENSSL_EXTRA
     4700                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35764701                    dName->stIdx = cert->srcIdx;
    35774702                    dName->stLen = strLen;
     
    35794704            }
    35804705            else if (id == ASN_ORG_NAME) {
    3581                 if (!tooBig) {
    3582                     XMEMCPY(&full[idx], "/O=", 3);
    3583                     idx += 3;
    3584                     copy = TRUE;
    3585                 }
     4706                copy = WOLFSSL_ORG_NAME;
    35864707                #ifdef WOLFSSL_CERT_GEN
    35874708                    if (nameType == SUBJECT) {
     
    35914712                    }
    35924713                #endif /* WOLFSSL_CERT_GEN */
    3593                 #ifdef OPENSSL_EXTRA
     4714                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35944715                    dName->oIdx = cert->srcIdx;
    35954716                    dName->oLen = strLen;
     
    35974718            }
    35984719            else if (id == ASN_ORGUNIT_NAME) {
    3599                 if (!tooBig) {
    3600                     XMEMCPY(&full[idx], "/OU=", 4);
    3601                     idx += 4;
    3602                     copy = TRUE;
    3603                 }
     4720                copy = WOLFSSL_ORGUNIT_NAME;
    36044721                #ifdef WOLFSSL_CERT_GEN
    36054722                    if (nameType == SUBJECT) {
     
    36094726                    }
    36104727                #endif /* WOLFSSL_CERT_GEN */
    3611                 #ifdef OPENSSL_EXTRA
     4728                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36124729                    dName->ouIdx = cert->srcIdx;
    36134730                    dName->ouLen = strLen;
     
    36154732            }
    36164733            else if (id == ASN_SERIAL_NUMBER) {
    3617                 if (!tooBig) {
    3618                    XMEMCPY(&full[idx], "/serialNumber=", 14);
    3619                    idx += 14;
    3620                    copy = TRUE;
     4734                copy = WOLFSSL_SERIAL_NUMBER;
     4735                #ifdef WOLFSSL_CERT_GEN
     4736                    if (nameType == SUBJECT) {
     4737                        cert->subjectSND = (char*)&cert->source[cert->srcIdx];
     4738                        cert->subjectSNDLen = strLen;
     4739                        cert->subjectSNDEnc = b;
    36214740                }
    3622                 #ifdef OPENSSL_EXTRA
     4741                #endif /* WOLFSSL_CERT_GEN */
     4742                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36234743                    dName->snIdx = cert->srcIdx;
    36244744                    dName->snLen = strLen;
    36254745                #endif /* OPENSSL_EXTRA */
    36264746            }
    3627 
     4747        #ifdef WOLFSSL_CERT_EXT
     4748            else if (id == ASN_BUS_CAT) {
     4749                copy = WOLFSSL_BUS_CAT;
     4750            #ifdef WOLFSSL_CERT_GEN
     4751                if (nameType == SUBJECT) {
     4752                    cert->subjectBC = (char*)&cert->source[cert->srcIdx];
     4753                    cert->subjectBCLen = strLen;
     4754                    cert->subjectBCEnc = b;
     4755                }
     4756            #endif /* WOLFSSL_CERT_GEN */
     4757            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4758                dName->bcIdx = cert->srcIdx;
     4759                dName->bcLen = strLen;
     4760            #endif /* OPENSSL_EXTRA */
     4761            }
     4762        #endif /* WOLFSSL_CERT_EXT */
    36284763            if (copy && !tooBig) {
     4764                XMEMCPY(&full[idx], copy, XSTRLEN(copy));
     4765                idx += (word32)XSTRLEN(copy);
     4766            #ifdef WOLFSSL_WPAS
     4767                full[idx] = '=';
     4768                idx++;
     4769            #endif
    36294770                XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
    36304771                idx += strLen;
     
    36334774            cert->srcIdx += strLen;
    36344775        }
     4776    #ifdef WOLFSSL_CERT_EXT
     4777        else if ((0 == XMEMCMP(&cert->source[cert->srcIdx], ASN_JOI_PREFIX,
     4778                               XSTRLEN(ASN_JOI_PREFIX))) &&
     4779                 ((cert->source[cert->srcIdx + XSTRLEN(ASN_JOI_PREFIX)] ==
     4780                         ASN_JOI_C) ||
     4781                  (cert->source[cert->srcIdx + XSTRLEN(ASN_JOI_PREFIX)] ==
     4782                          ASN_JOI_ST)))
     4783        {
     4784            int strLen;
     4785            byte id;
     4786            const char* copy = NULL;
     4787
     4788            cert->srcIdx += 10;
     4789            id = cert->source[cert->srcIdx++];
     4790            b = cert->source[cert->srcIdx++]; /* encoding */
     4791
     4792            if (GetLength(cert->source, &cert->srcIdx, &strLen,
     4793                          cert->maxIdx) < 0)
     4794                return ASN_PARSE_E;
     4795
     4796            if ((strLen + strlen(WOLFSSL_JOI_ST)) > (ASN_NAME_MAX - idx)) {
     4797                WOLFSSL_MSG("ASN Name too big, skipping");
     4798                tooBig = TRUE;
     4799            }
     4800
     4801            /* Check for jurisdiction of incorporation country name */
     4802            if (id == ASN_JOI_C) {
     4803                copy = WOLFSSL_JOI_C;
     4804                #ifdef WOLFSSL_CERT_GEN
     4805                    if (nameType == SUBJECT) {
     4806                        cert->subjectJC = (char*)&cert->source[cert->srcIdx];
     4807                        cert->subjectJCLen = strLen;
     4808                        cert->subjectJCEnc = b;
     4809                    }
     4810                #endif /* WOLFSSL_CERT_GEN */
     4811                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4812                    dName->jcIdx = cert->srcIdx;
     4813                    dName->jcLen = strLen;
     4814                #endif /* OPENSSL_EXTRA */
     4815            }
     4816
     4817            /* Check for jurisdiction of incorporation state name */
     4818            else if (id == ASN_JOI_ST) {
     4819                copy = WOLFSSL_JOI_ST;
     4820                #ifdef WOLFSSL_CERT_GEN
     4821                    if (nameType == SUBJECT) {
     4822                        cert->subjectJS = (char*)&cert->source[cert->srcIdx];
     4823                        cert->subjectJSLen = strLen;
     4824                        cert->subjectJSEnc = b;
     4825                    }
     4826                #endif /* WOLFSSL_CERT_GEN */
     4827                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4828                    dName->jsIdx = cert->srcIdx;
     4829                    dName->jsLen = strLen;
     4830                #endif /* OPENSSL_EXTRA */
     4831            }
     4832
     4833            if ((copy != NULL) && (tooBig != 1)) {
     4834                XMEMCPY(&full[idx], copy, XSTRLEN(copy));
     4835                idx += (word32)XSTRLEN(copy);
     4836            #ifdef WOLFSSL_WPAS
     4837                full[idx] = '=';
     4838                idx++;
     4839            #endif
     4840                XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
     4841                idx += strLen;
     4842            }
     4843
     4844            cert->srcIdx += strLen;
     4845        }
     4846    #endif /* WOLFSSL_CERT_EXT */
    36354847        else {
    36364848            /* skip */
    36374849            byte email = FALSE;
    3638             byte uid   = FALSE;
     4850            byte pilot = FALSE;
     4851            byte id    = 0;
    36394852            int  adv;
    36404853
     
    36424855                email = TRUE;
    36434856
    3644             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
    3645                 uid = TRUE;
     4857            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
     4858                /* last value of OID is the type of pilot attribute */
     4859                id    = cert->source[cert->srcIdx + oidSz - 1];
     4860                pilot = TRUE;
     4861            }
    36464862
    36474863            cert->srcIdx += oidSz + 1;
     
    36714887                    }
    36724888                #endif /* WOLFSSL_CERT_GEN */
    3673                 #ifdef OPENSSL_EXTRA
     4889                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36744890                    dName->emailIdx = cert->srcIdx;
    36754891                    dName->emailLen = adv;
     
    36854901                            return MEMORY_E;
    36864902                        }
     4903                        emailName->type = 0;
    36874904                        emailName->name = (char*)XMALLOC(adv + 1,
    36884905                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
     
    36924909                            return MEMORY_E;
    36934910                        }
     4911                        emailName->len = adv;
    36944912                        XMEMCPY(emailName->name,
    36954913                                              &cert->source[cert->srcIdx], adv);
    3696                         emailName->name[adv] = 0;
     4914                        emailName->name[adv] = '\0';
    36974915
    36984916                        emailName->next = cert->altEmailNames;
     
    37064924            }
    37074925
    3708             if (uid) {
     4926            if (pilot) {
    37094927                if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
    37104928                    WOLFSSL_MSG("ASN name too big, skipping");
     
    37124930                }
    37134931                if (!tooBig) {
     4932                    switch (id) {
     4933                        case ASN_USER_ID:
    37144934                    XMEMCPY(&full[idx], "/UID=", 5);
    37154935                    idx += 5;
    3716 
     4936                        #if defined(OPENSSL_EXTRA) || \
     4937                            defined(OPENSSL_EXTRA_X509_SMALL)
     4938                            dName->uidIdx = cert->srcIdx;
     4939                            dName->uidLen = adv;
     4940                        #endif /* OPENSSL_EXTRA */
     4941                            break;
     4942
     4943                        case ASN_DOMAIN_COMPONENT:
     4944                            XMEMCPY(&full[idx], "/DC=", 4);
     4945                            idx += 4;
     4946                        #if defined(OPENSSL_EXTRA) || \
     4947                            defined(OPENSSL_EXTRA_X509_SMALL)
     4948                            dName->dcIdx[dcnum] = cert->srcIdx;
     4949                            dName->dcLen[dcnum] = adv;
     4950                            dName->dcNum = dcnum + 1;
     4951                            dcnum++;
     4952                        #endif /* OPENSSL_EXTRA */
     4953                            break;
     4954
     4955                        default:
     4956                            WOLFSSL_MSG("Unknown pilot attribute type");
     4957                            return ASN_PARSE_E;
     4958                    }
    37174959                    XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
    37184960                    idx += adv;
    37194961                }
    3720                 #ifdef OPENSSL_EXTRA
    3721                     dName->uidIdx = cert->srcIdx;
    3722                     dName->uidLen = adv;
    3723                 #endif /* OPENSSL_EXTRA */
    37244962            }
    37254963
     
    37294967    full[idx++] = 0;
    37304968
    3731     #ifdef OPENSSL_EXTRA
     4969    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    37324970    {
    37334971        int totalLen = 0;
     4972        int i = 0;
    37344973
    37354974        if (dName->cnLen != 0)
     
    37534992        if (dName->serialLen != 0)
    37544993            totalLen += dName->serialLen + 14;
     4994        if (dName->dcNum != 0){
     4995            for (i = 0;i < dName->dcNum;i++)
     4996                totalLen += dName->dcLen[i] + 4;
     4997        }
    37554998
    37564999        dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
     
    37615004            if (dName->cnLen != 0) {
    37625005                dName->entryCount++;
    3763                 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
     5006                XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);
     5007                dName->cnNid = OBJ_sn2nid((const char *)WOLFSSL_COMMON_NAME);
    37645008                idx += 4;
    37655009                XMEMCPY(&dName->fullName[idx],
     
    37705014            if (dName->snLen != 0) {
    37715015                dName->entryCount++;
    3772                 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
     5016                XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);
     5017                dName->snNid = OBJ_sn2nid((const char *)WOLFSSL_SUR_NAME);
    37735018                idx += 4;
    37745019                XMEMCPY(&dName->fullName[idx],
     
    37795024            if (dName->cLen != 0) {
    37805025                dName->entryCount++;
    3781                 XMEMCPY(&dName->fullName[idx], "/C=", 3);
     5026                XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);
     5027                dName->cNid = OBJ_sn2nid((const char *)WOLFSSL_COUNTRY_NAME);
    37825028                idx += 3;
    37835029                XMEMCPY(&dName->fullName[idx],
     
    37885034            if (dName->lLen != 0) {
    37895035                dName->entryCount++;
    3790                 XMEMCPY(&dName->fullName[idx], "/L=", 3);
     5036                XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);
     5037                dName->lNid = OBJ_sn2nid((const char *)WOLFSSL_LOCALITY_NAME);
    37915038                idx += 3;
    37925039                XMEMCPY(&dName->fullName[idx],
     
    37975044            if (dName->stLen != 0) {
    37985045                dName->entryCount++;
    3799                 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
     5046                XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);
     5047                dName->stNid = OBJ_sn2nid((const char *)WOLFSSL_STATE_NAME);
    38005048                idx += 4;
    38015049                XMEMCPY(&dName->fullName[idx],
     
    38065054            if (dName->oLen != 0) {
    38075055                dName->entryCount++;
    3808                 XMEMCPY(&dName->fullName[idx], "/O=", 3);
     5056                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);
     5057                dName->oNid = OBJ_sn2nid((const char *)WOLFSSL_ORG_NAME);
    38095058                idx += 3;
    38105059                XMEMCPY(&dName->fullName[idx],
     
    38155064            if (dName->ouLen != 0) {
    38165065                dName->entryCount++;
    3817                 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
     5066                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);
     5067                dName->ouNid = OBJ_sn2nid((const char *)WOLFSSL_ORGUNIT_NAME);
    38185068                idx += 4;
    38195069                XMEMCPY(&dName->fullName[idx],
     
    38255075                dName->entryCount++;
    38265076                XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
     5077                dName->emailNid = OBJ_sn2nid((const char *)"/emailAddress=");
    38275078                idx += 14;
    38285079                XMEMCPY(&dName->fullName[idx],
     
    38315082                idx += dName->emailLen;
    38325083            }
     5084            for (i = 0;i < dName->dcNum;i++){
     5085                if (dName->dcLen[i] != 0) {
     5086                    dName->entryCount++;
     5087                    XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);
     5088                    idx += 4;
     5089                    XMEMCPY(&dName->fullName[idx],
     5090                                    &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
     5091                    dName->dcIdx[i] = idx;
     5092                    idx += dName->dcLen[i];
     5093                }
     5094            }
    38335095            if (dName->uidLen != 0) {
    38345096                dName->entryCount++;
    38355097                XMEMCPY(&dName->fullName[idx], "/UID=", 5);
     5098                dName->uidNid = OBJ_sn2nid((const char *)"/UID=");
    38365099                idx += 5;
    38375100                XMEMCPY(&dName->fullName[idx],
     
    38425105            if (dName->serialLen != 0) {
    38435106                dName->entryCount++;
    3844                 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
     5107                XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);
     5108                dName->serialNid = OBJ_sn2nid((const char *)WOLFSSL_SERIAL_NUMBER);
    38455109                idx += 14;
    38465110                XMEMCPY(&dName->fullName[idx],
     
    38605124
    38615125#ifndef NO_ASN_TIME
    3862 #if !defined(NO_TIME_H) && defined(USE_WOLF_VALIDDATE)
    3863 
    3864 /* to the second */
    3865 static int DateGreaterThan(const struct tm* a, const struct tm* b)
    3866 {
    3867     if (a->tm_year > b->tm_year)
    3868         return 1;
    3869 
    3870     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
    3871         return 1;
    3872 
    3873     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3874            a->tm_mday > b->tm_mday)
    3875         return 1;
    3876 
    3877     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3878         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
    3879         return 1;
    3880 
    3881     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3882         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
    3883         a->tm_min > b->tm_min)
    3884         return 1;
    3885 
    3886     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3887         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
    3888         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
    3889         return 1;
    3890 
    3891     return 0; /* false */
    3892 }
    3893 
    3894 
    3895 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
    3896 {
    3897     return DateGreaterThan(b,a);
    3898 }
    3899 
    3900 
    3901 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    3902 int GetTimeString(byte* date, int format, char* buf, int len)
    3903 {
    3904     struct tm t;
    3905     int idx = 0;
    3906 
    3907     if (!ExtractDate(date, format, &t, &idx)) {
    3908         return 0;
    3909     }
    3910 
    3911     if (date[idx] != 'Z') {
    3912         WOLFSSL_MSG("UTCtime, not Zulu") ;
    3913         return 0;
    3914     }
    3915 
    3916     /* place month in buffer */
    3917     buf[0] = '\0';
    3918     switch(t.tm_mon) {
    3919         case 0:  XSTRNCAT(buf, "Jan ", 4); break;
    3920         case 1:  XSTRNCAT(buf, "Feb ", 4); break;
    3921         case 2:  XSTRNCAT(buf, "Mar ", 4); break;
    3922         case 3:  XSTRNCAT(buf, "Apr ", 4); break;
    3923         case 4:  XSTRNCAT(buf, "May ", 4); break;
    3924         case 5:  XSTRNCAT(buf, "Jun ", 4); break;
    3925         case 6:  XSTRNCAT(buf, "Jul ", 4); break;
    3926         case 7:  XSTRNCAT(buf, "Aug ", 4); break;
    3927         case 8:  XSTRNCAT(buf, "Sep ", 4); break;
    3928         case 9:  XSTRNCAT(buf, "Oct ", 4); break;
    3929         case 10: XSTRNCAT(buf, "Nov ", 4); break;
    3930         case 11: XSTRNCAT(buf, "Dec ", 4); break;
    3931         default:
    3932             return 0;
    3933 
    3934     }
    3935     idx = 4; /* use idx now for char buffer */
    3936     buf[idx] = ' ';
    3937 
    3938     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
    3939               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
    3940 
    3941     return 1;
    3942 }
    3943 #endif /* WOLFSSL_MYSQL_COMPATIBLE */
     5126
     5127/* two byte date/time, add to value */
     5128static WC_INLINE void GetTime(int* value, const byte* date, int* idx)
     5129{
     5130    int i = *idx;
     5131
     5132    *value += btoi(date[i++]) * 10;
     5133    *value += btoi(date[i++]);
     5134
     5135    *idx = i;
     5136}
    39445137
    39455138int ExtractDate(const unsigned char* date, unsigned char format,
     
    39575150        certTime->tm_year += btoi(date[*idx]) * 1000; *idx = *idx + 1;
    39585151        certTime->tm_year += btoi(date[*idx]) * 100;  *idx = *idx + 1;
    3959     }
     5152}
    39605153
    39615154    /* adjust tm_year, tm_mon */
     
    39705163}
    39715164
     5165
     5166#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
     5167    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     5168int GetTimeString(byte* date, int format, char* buf, int len)
     5169{
     5170    struct tm t;
     5171    int idx = 0;
     5172
     5173    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
     5174        return 0;
     5175    }
     5176
     5177    if (date[idx] != 'Z') {
     5178        WOLFSSL_MSG("UTCtime, not Zulu") ;
     5179        return 0;
     5180    }
     5181
     5182    /* place month in buffer */
     5183    buf[0] = '\0';
     5184    switch(t.tm_mon) {
     5185        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
     5186        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
     5187        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
     5188        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
     5189        case 4:  XSTRNCAT(buf, "May ", 5); break;
     5190        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
     5191        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
     5192        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
     5193        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
     5194        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
     5195        case 10: XSTRNCAT(buf, "Nov ", 5); break;
     5196        case 11: XSTRNCAT(buf, "Dec ", 5); break;
     5197        default:
     5198            return 0;
     5199
     5200    }
     5201    idx = 4; /* use idx now for char buffer */
     5202
     5203    XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
     5204              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
     5205
     5206    return 1;
     5207}
     5208#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
     5209
     5210
     5211#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
     5212
     5213/* Set current time string, either UTC or GeneralizedTime.
     5214 * (void*) tm should be a pointer to time_t, output is placed in buf.
     5215 *
     5216 * Return time string length placed in buf on success, negative on error */
     5217int GetAsnTimeString(void* currTime, byte* buf, word32 len)
     5218{
     5219    struct tm* ts      = NULL;
     5220    struct tm* tmpTime = NULL;
     5221#if defined(NEED_TMP_TIME)
     5222    struct tm tmpTimeStorage;
     5223    tmpTime = &tmpTimeStorage;
     5224#else
     5225    (void)tmpTime;
     5226#endif
     5227    byte* data_ptr  = buf;
     5228    word32 data_len = 0;
     5229    int year, mon, day, hour, mini, sec;
     5230
     5231    WOLFSSL_ENTER("SetAsnTimeString");
     5232
     5233    if (buf == NULL || len == 0)
     5234        return BAD_FUNC_ARG;
     5235
     5236    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
     5237    if (ts == NULL){
     5238        WOLFSSL_MSG("failed to get time data.");
     5239        return ASN_TIME_E;
     5240    }
     5241
     5242    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
     5243     * the null terminator. ASN encoded values leave off the terminator. */
     5244
     5245    if (ts->tm_year >= 50 && ts->tm_year < 150) {
     5246        /* UTC Time */
     5247        char utc_str[ASN_UTC_TIME_SIZE];
     5248        data_len = ASN_UTC_TIME_SIZE - 1 + 2;
     5249
     5250        if (len < data_len)
     5251            return BUFFER_E;
     5252
     5253        if (ts->tm_year >= 50 && ts->tm_year < 100) {
     5254            year = ts->tm_year;
     5255        } else if (ts->tm_year >= 100 && ts->tm_year < 150) {
     5256            year = ts->tm_year - 100;
     5257        }
     5258        else {
     5259            WOLFSSL_MSG("unsupported year range");
     5260            return BAD_FUNC_ARG;
     5261    }
     5262        mon  = ts->tm_mon + 1;
     5263        day  = ts->tm_mday;
     5264        hour = ts->tm_hour;
     5265        mini = ts->tm_min;
     5266        sec  = ts->tm_sec;
     5267        XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
     5268                  "%02d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
     5269        *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
     5270        /* -1 below excludes null terminator */
     5271        *data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;
     5272        XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);
     5273
     5274    } else {
     5275        /* GeneralizedTime */
     5276        char gt_str[ASN_GENERALIZED_TIME_SIZE];
     5277        data_len = ASN_GENERALIZED_TIME_SIZE - 1 + 2;
     5278
     5279        if (len < data_len)
     5280            return BUFFER_E;
     5281
     5282        year = ts->tm_year + 1900;
     5283        mon  = ts->tm_mon + 1;
     5284        day  = ts->tm_mday;
     5285        hour = ts->tm_hour;
     5286        mini = ts->tm_min;
     5287        sec  = ts->tm_sec;
     5288        XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
     5289                  "%4d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
     5290        *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
     5291        /* -1 below excludes null terminator */
     5292        *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;
     5293        XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);
     5294    }
     5295
     5296    return data_len;
     5297}
     5298
     5299#endif /* !NO_ASN_TIME && HAVE_PKCS7 */
     5300
     5301
     5302#if defined(USE_WOLF_VALIDDATE)
     5303
     5304/* to the second */
     5305static int DateGreaterThan(const struct tm* a, const struct tm* b)
     5306{
     5307    if (a->tm_year > b->tm_year)
     5308        return 1;
     5309
     5310    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
     5311        return 1;
     5312
     5313    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5314           a->tm_mday > b->tm_mday)
     5315        return 1;
     5316
     5317    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5318        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
     5319        return 1;
     5320
     5321    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5322        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
     5323        a->tm_min > b->tm_min)
     5324        return 1;
     5325
     5326    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5327        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
     5328        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
     5329    return 1;
     5330
     5331    return 0; /* false */
     5332}
     5333
     5334
     5335static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
     5336{
     5337    return DateGreaterThan(b,a);
     5338}
    39725339
    39735340/* like atoi but only use first byte */
     
    40465413    return 1;
    40475414}
    4048 #endif /* !NO_TIME_H && USE_WOLF_VALIDDATE */
     5415#endif /* USE_WOLF_VALIDDATE */
    40495416
    40505417int wc_GetTime(void* timePtr, word32 timeSize)
     
    40675434#endif /* !NO_ASN_TIME */
    40685435
    4069 static int GetDate(DecodedCert* cert, int dateType)
     5436
     5437/* Get date buffer, format and length. Returns 0=success or error */
     5438static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
     5439                        byte* pFormat, int* pLength, word32 maxIdx)
    40705440{
    40715441    int    length;
     5442    byte format;
     5443
     5444    if (source == NULL || idx == NULL)
     5445        return BAD_FUNC_ARG;
     5446
     5447    /* get ASN format header */
     5448    if (*idx+1 > maxIdx)
     5449        return BUFFER_E;
     5450    format = source[*idx];
     5451    *idx += 1;
     5452    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
     5453        return ASN_TIME_E;
     5454
     5455    /* get length */
     5456    if (GetLength(source, idx, &length, maxIdx) < 0)
     5457        return ASN_PARSE_E;
     5458    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
     5459        return ASN_DATE_SZ_E;
     5460
     5461    /* return format, date and length */
     5462    if (pFormat)
     5463        *pFormat = format;
     5464    if (pDate)
     5465        *pDate = &source[*idx];
     5466    if (pLength)
     5467        *pLength = length;
     5468
     5469    *idx += length;
     5470
     5471    return 0;
     5472}
     5473
     5474static int GetDate(DecodedCert* cert, int dateType, int verify)
     5475{
     5476    int    ret, length;
     5477    const byte *datePtr = NULL;
    40725478    byte   date[MAX_DATE_SIZE];
    4073     byte   b;
     5479    byte   format;
    40745480    word32 startIdx = 0;
    4075 
    4076     XMEMSET(date, 0, MAX_DATE_SIZE);
    40775481
    40785482    if (dateType == BEFORE)
     
    40825486    startIdx = cert->srcIdx;
    40835487
    4084     b = cert->source[cert->srcIdx++];
    4085     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
    4086         return ASN_TIME_E;
    4087 
    4088     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
    4089         return ASN_PARSE_E;
    4090 
    4091     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
    4092         return ASN_DATE_SZ_E;
    4093 
    4094     XMEMCPY(date, &cert->source[cert->srcIdx], length);
    4095     cert->srcIdx += length;
     5488    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
     5489                      &length, cert->maxIdx);
     5490    if (ret < 0)
     5491        return ret;
     5492
     5493    XMEMSET(date, 0, MAX_DATE_SIZE);
     5494    XMEMCPY(date, datePtr, length);
    40965495
    40975496    if (dateType == BEFORE)
     
    41015500
    41025501#ifndef NO_ASN_TIME
    4103     if (!XVALIDATE_DATE(date, b, dateType)) {
     5502    if (verify != NO_VERIFY && !XVALIDATE_DATE(date, format, dateType)) {
    41045503        if (dateType == BEFORE)
    41055504            return ASN_BEFORE_DATE_E;
     
    41075506            return ASN_AFTER_DATE_E;
    41085507    }
     5508#else
     5509    (void)verify;
    41095510#endif
    41105511
     
    41205521        return ASN_PARSE_E;
    41215522
    4122     if (GetDate(cert, BEFORE) < 0 && verify != NO_VERIFY)
     5523    if (GetDate(cert, BEFORE, verify) < 0)
    41235524        badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
    41245525
    4125     if (GetDate(cert, AFTER) < 0 && verify != NO_VERIFY)
     5526    if (GetDate(cert, AFTER, verify) < 0)
    41265527        return ASN_AFTER_DATE_E;
    41275528
     
    41315532    return 0;
    41325533}
     5534
     5535
     5536int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
     5537    byte* format, int* length)
     5538{
     5539    int ret;
     5540    word32 idx = 0;
     5541
     5542    ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
     5543    if (ret < 0)
     5544        return ret;
     5545
     5546    return 0;
     5547}
     5548
     5549#ifndef NO_ASN_TIME
     5550int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
     5551    struct tm* timearg)
     5552{
     5553    int idx = 0;
     5554    (void)length;
     5555    if (!ExtractDate(date, format, timearg, &idx))
     5556        return ASN_TIME_E;
     5557    return 0;
     5558}
     5559
     5560#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
     5561int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
     5562{
     5563    int ret = 0;
     5564    const byte* date;
     5565    byte format;
     5566    int length;
     5567
     5568    if (cert == NULL)
     5569        return BAD_FUNC_ARG;
     5570
     5571    if (before && cert->beforeDateSz > 0) {
     5572        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
     5573                             &format, &length);
     5574        if (ret == 0)
     5575            ret = wc_GetDateAsCalendarTime(date, length, format, before);
     5576    }
     5577    if (after && cert->afterDateSz > 0) {
     5578        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
     5579                             &format, &length);
     5580        if (ret == 0)
     5581            ret = wc_GetDateAsCalendarTime(date, length, format, after);
     5582    }
     5583
     5584    return ret;
     5585}
     5586#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
     5587#endif /* !NO_ASN_TIME */
    41335588
    41345589
     
    42675722
    42685723
    4269 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
     5724#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
    42705725
    42715726static int SetCurve(ecc_key* key, byte* output)
     
    43065761}
    43075762
    4308 #endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
    4309 
    4310 
    4311 static INLINE int IsSigAlgoECDSA(int algoOID)
     5763#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
     5764
     5765
     5766#ifdef HAVE_ECC
     5767static WC_INLINE int IsSigAlgoECDSA(int algoOID)
    43125768{
    43135769    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
     
    43195775    return 0;
    43205776}
     5777#endif
    43215778
    43225779WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
     
    43285785
    43295786    tagSz = (type == oidHashType ||
    4330              (type == oidSigType && !IsSigAlgoECDSA(algoOID) &&
    4331                                          algoOID != ED25519k) ||
     5787             (type == oidSigType
     5788        #ifdef HAVE_ECC
     5789              && !IsSigAlgoECDSA(algoOID)
     5790        #endif
     5791        #ifdef HAVE_ED25519
     5792              && algoOID != ED25519k
     5793        #endif
     5794              ) ||
    43325795             (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
    43335796
     
    43755838int wc_GetCTC_HashOID(int type)
    43765839{
    4377     switch (type) {
    4378 #ifdef WOLFSSL_MD2
    4379         case MD2:
    4380             return MD2h;
    4381 #endif
    4382 #ifndef NO_MD5
    4383         case WC_MD5:
    4384             return MD5h;
    4385 #endif
    4386 #ifndef NO_SHA
    4387         case WC_SHA:
    4388             return SHAh;
    4389 #endif
    4390 #ifdef WOLFSSL_SHA224
    4391         case WC_SHA224:
    4392             return SHA224h;
    4393 #endif
    4394 #ifndef NO_SHA256
    4395         case WC_SHA256:
    4396             return SHA256h;
    4397 #endif
    4398 #ifdef WOLFSSL_SHA384
    4399         case WC_SHA384:
    4400             return SHA384h;
    4401 #endif
    4402 #ifdef WOLFSSL_SHA512
    4403         case WC_SHA512:
    4404             return SHA512h;
    4405 #endif
    4406         default:
    4407             return 0;
    4408     };
     5840    int ret;
     5841    enum wc_HashType hType;
     5842
     5843    hType = wc_HashTypeConvert(type);
     5844    ret = wc_HashGetOID(hType);
     5845    if (ret < 0)
     5846        ret = 0; /* backwards compatibility */
     5847
     5848    return ret;
    44095849}
    44105850
     
    44335873    }
    44345874#endif
     5875#ifndef NO_ASN_CRYPT
    44355876    if (sigCtx->key.ptr) {
    44365877        switch (sigCtx->keyOID) {
     
    44585899        sigCtx->key.ptr = NULL;
    44595900    }
     5901#endif
    44605902
    44615903    /* reset state, we are done */
     
    44635905}
    44645906
     5907#ifndef NO_ASN_CRYPT
    44655908static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
    44665909                            byte* digest, int* typeH, int* digestSz, int verify)
     
    45495992    return ret;
    45505993}
     5994#endif /* !NO_ASN_CRYPT */
    45515995
    45525996/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
     
    45706014    WOLFSSL_ENTER("ConfirmSignature");
    45716015
     6016#ifndef NO_ASN_CRYPT
    45726017    switch (sigCtx->state) {
    45736018        case SIG_STATE_BEGIN:
    45746019        {
     6020            sigCtx->keyOID = keyOID; /* must set early for cleanup */
     6021
    45756022            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
    45766023                                                    DYNAMIC_TYPE_DIGEST);
     
    45976044        case SIG_STATE_KEY:
    45986045        {
    4599             sigCtx->keyOID = keyOID;
    4600 
    46016046            switch (keyOID) {
    46026047            #ifndef NO_RSA
     
    46376082                case ECDSAk:
    46386083                {
     6084                    word32 idx = 0;
     6085
    46396086                    sigCtx->verify = 0;
    46406087                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
     
    46476094                        goto exit_cs;
    46486095                    }
    4649                     if ((ret = wc_ecc_import_x963(key, keySz,
    4650                                                         sigCtx->key.ecc)) < 0) {
     6096                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
     6097                                                                         keySz);
     6098                    if (ret < 0) {
    46516099                        WOLFSSL_MSG("ASN Key import error ECC");
    46526100                        goto exit_cs;
     
    46966144        #ifdef WOLFSSL_ASYNC_CRYPT
    46976145            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
    4698                 /* make sure event is intialized */
     6146                /* make sure event is initialized */
    46996147                WOLF_EVENT* event = &sigCtx->asyncDev->event;
    47006148                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
     
    47116159                case RSAk:
    47126160                {
     6161                #ifdef HAVE_PK_CALLBACKS
     6162                    if (sigCtx->pkCbRsa) {
     6163                        ret = sigCtx->pkCbRsa(
     6164                                sigCtx->plain, sigSz, &sigCtx->out,
     6165                                key, keySz,
     6166                                sigCtx->pkCtxRsa);
     6167                    }
     6168                    else
     6169                #endif /* HAVE_PK_CALLBACKS */
     6170                    {
    47136171                    ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
    47146172                                                &sigCtx->out, sigCtx->key.rsa);
     6173                    }
    47156174                    break;
    47166175                }
     
    47196178                case ECDSAk:
    47206179                {
     6180                #ifdef HAVE_PK_CALLBACKS
     6181                    if (sigCtx->pkCbEcc) {
     6182                        ret = sigCtx->pkCbEcc(
     6183                                sig, sigSz,
     6184                                sigCtx->digest, sigCtx->digestSz,
     6185                                key, keySz, &sigCtx->verify,
     6186                                sigCtx->pkCtxEcc);
     6187                    }
     6188                    else
     6189                #endif /* HAVE_PK_CALLBACKS */
     6190                    {
    47216191                    ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
    4722                         sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
     6192                                            sigCtx->digestSz, &sigCtx->verify,
     6193                                            sigCtx->key.ecc);
     6194                    }
    47236195                    break;
    47246196                }
     
    47696241                    encodedSigSz = wc_EncodeSignature(encodedSig,
    47706242                            sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
    4771                     if (encodedSigSz == verifySz &&
     6243                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
    47726244                        XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
    47736245                        ret = 0;
     
    48206292exit_cs:
    48216293
     6294#endif /* !NO_ASN_CRYPT */
     6295
     6296    (void)keyOID;
     6297    (void)sigOID;
     6298
    48226299    WOLFSSL_LEAVE("ConfirmSignature", ret);
    48236300
     
    49116388                    while (name != NULL) {
    49126389                        if (MatchBaseName(ASN_DNS_TYPE,
    4913                                           name->name, (int)XSTRLEN(name->name),
     6390                                          name->name, name->len,
    49146391                                          base->name, base->nameSz)) {
    49156392                            return 0;
     
    49246401                    while (name != NULL) {
    49256402                        if (MatchBaseName(ASN_RFC822_TYPE,
    4926                                           name->name, (int)XSTRLEN(name->name),
     6403                                          name->name, name->len,
    49276404                                          base->name, base->nameSz)) {
    49286405                            return 0;
     
    49686445                    while (name != NULL) {
    49696446                        matchDns = MatchBaseName(ASN_DNS_TYPE,
    4970                                           name->name, (int)XSTRLEN(name->name),
     6447                                          name->name, name->len,
    49716448                                          base->name, base->nameSz);
    49726449                        name = name->next;
     
    49836460                    while (name != NULL) {
    49846461                        matchEmail = MatchBaseName(ASN_DNS_TYPE,
    4985                                           name->name, (int)XSTRLEN(name->name),
     6462                                          name->name, name->len,
    49866463                                          base->name, base->nameSz);
    49876464                        name = name->next;
     
    50176494#endif /* IGNORE_NAME_CONSTRAINTS */
    50186495
    5019 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
     6496static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
    50206497{
    50216498    word32 idx = 0;
     
    50566533            }
    50576534
     6535            dnsEntry->type = ASN_DNS_TYPE;
    50586536            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
    50596537                                         DYNAMIC_TYPE_ALTNAME);
     
    50636541                return MEMORY_E;
    50646542            }
    5065 
     6543            dnsEntry->len = strLen;
    50666544            XMEMCPY(dnsEntry->name, &input[idx], strLen);
    50676545            dnsEntry->name[strLen] = '\0';
     
    50926570            }
    50936571
     6572            emailEntry->type = ASN_RFC822_TYPE;
    50946573            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
    50956574                                         DYNAMIC_TYPE_ALTNAME);
     
    50996578                return MEMORY_E;
    51006579            }
    5101 
     6580            emailEntry->len = strLen;
    51026581            XMEMCPY(emailEntry->name, &input[idx], strLen);
    51036582            emailEntry->name[strLen] = '\0';
     
    51056584            emailEntry->next = cert->altEmailNames;
    51066585            cert->altEmailNames = emailEntry;
     6586
     6587            length -= strLen;
     6588            idx    += strLen;
     6589        }
     6590        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
     6591            DNS_entry* uriEntry;
     6592            int strLen;
     6593            word32 lenStartIdx = idx;
     6594
     6595            WOLFSSL_MSG("\tPutting URI into list but not using");
     6596            if (GetLength(input, &idx, &strLen, sz) < 0) {
     6597                WOLFSSL_MSG("\tfail: str length");
     6598                return ASN_PARSE_E;
     6599            }
     6600            length -= (idx - lenStartIdx);
     6601
     6602            /* check that strLen at index is not past input buffer */
     6603            if (strLen + (int)idx > sz) {
     6604                return BUFFER_E;
     6605            }
     6606
     6607        #ifndef WOLFSSL_NO_ASN_STRICT
     6608            /* Verify RFC 5280 Sec 4.2.1.6 rule:
     6609                "The name MUST NOT be a relative URI" */
     6610
     6611            {
     6612                int i;
     6613
     6614                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
     6615                for (i = 0; i < strLen; i++) {
     6616                    if (input[idx + i] == ':') {
     6617                        break;
     6618                    }
     6619                    if (input[idx + i] == '/') {
     6620                        i = strLen; /* error, found relative path since '/' was
     6621                                     * encountered before ':'. Returning error
     6622                                     * value in next if statement. */
     6623                    }
     6624                }
     6625
     6626                /* test if no ':' char was found and test that the next two
     6627                 * chars are // to match the pattern "://" */
     6628                if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
     6629                                        input[idx + i + 2] != '/')) {
     6630                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
     6631                    return ASN_ALT_NAME_E;
     6632                }
     6633            }
     6634        #endif
     6635
     6636            uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
     6637                                        DYNAMIC_TYPE_ALTNAME);
     6638            if (uriEntry == NULL) {
     6639                WOLFSSL_MSG("\tOut of Memory");
     6640                return MEMORY_E;
     6641            }
     6642
     6643            uriEntry->type = ASN_URI_TYPE;
     6644            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
     6645                                         DYNAMIC_TYPE_ALTNAME);
     6646            if (uriEntry->name == NULL) {
     6647                WOLFSSL_MSG("\tOut of Memory");
     6648                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
     6649                return MEMORY_E;
     6650            }
     6651            uriEntry->len = strLen;
     6652            XMEMCPY(uriEntry->name, &input[idx], strLen);
     6653            uriEntry->name[strLen] = '\0';
     6654
     6655            uriEntry->next = cert->altNames;
     6656            cert->altNames = uriEntry;
    51076657
    51086658            length -= strLen;
     
    52016751}
    52026752
    5203 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
     6753static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
    52046754{
    52056755    word32 idx = 0;
     
    52486798    /* From RFC3280 SS4.2.1.7, GeneralName */
    52496799
    5250 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
     6800static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
    52516801{
    52526802    word32 idx = 0;
     
    53296879
    53306880
    5331 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
     6881static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
    53326882/*
    53336883 *  Read the first of the Authority Information Access records. If there are
     
    53756925
    53766926
    5377 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
     6927static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
    53786928{
    53796929    word32 idx = 0;
     
    53976947    }
    53986948
    5399 #ifdef OPENSSL_EXTRA
     6949#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54006950    cert->extAuthKeyIdSrc = &input[idx];
    54016951    cert->extAuthKeyIdSz = length;
     
    54056955        XMEMCPY(cert->extAuthKeyId, input + idx, length);
    54066956    }
    5407     else {
    5408     #ifdef NO_SHA
    5409         ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
    5410     #else
    5411         ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
    5412     #endif
    5413     }
     6957    else
     6958        ret = CalcHashId(input + idx, length, cert->extAuthKeyId);
    54146959
    54156960    return ret;
     
    54176962
    54186963
    5419 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
     6964static int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)
    54206965{
    54216966    word32 idx = 0;
     
    54316976        return ret;
    54326977
    5433     #ifdef OPENSSL_EXTRA
     6978    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54346979        cert->extSubjKeyIdSrc = &input[idx];
    54356980        cert->extSubjKeyIdSz = length;
    54366981    #endif /* OPENSSL_EXTRA */
    54376982
    5438     if (length == SIGNER_DIGEST_SIZE) {
     6983    if (length == KEYID_SIZE) {
    54396984        XMEMCPY(cert->extSubjKeyId, input + idx, length);
    54406985    }
    5441     else {
    5442     #ifdef NO_SHA
    5443         ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
    5444     #else
    5445         ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
    5446     #endif
    5447     }
     6986    else
     6987        ret = CalcHashId(input + idx, length, cert->extSubjKeyId);
    54486988
    54496989    return ret;
     
    54516991
    54526992
    5453 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
     6993static int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)
    54546994{
    54556995    word32 idx = 0;
     
    54707010
    54717011
    5472 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
     7012static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)
    54737013{
    54747014    word32 idx = 0, oid;
    5475     int length;
    5476 
    5477     WOLFSSL_ENTER("DecodeExtKeyUsage");
     7015    int length, ret;
     7016
     7017    WOLFSSL_MSG("DecodeExtKeyUsage");
    54787018
    54797019    if (GetSequence(input, &idx, &length, sz) < 0) {
     
    54827022    }
    54837023
    5484 #ifdef OPENSSL_EXTRA
     7024#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54857025    cert->extExtKeyUsageSrc = input + idx;
    54867026    cert->extExtKeyUsageSz = length;
     
    54887028
    54897029    while (idx < (word32)sz) {
    5490         if (GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz) < 0)
    5491             return ASN_PARSE_E;
     7030        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
     7031        if (ret == ASN_UNKNOWN_OID_E)
     7032            continue;
     7033        else if (ret < 0)
     7034            return ret;
    54927035
    54937036        switch (oid) {
     
    55157058        }
    55167059
    5517     #ifdef OPENSSL_EXTRA
     7060    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    55187061        cert->extExtKeyUsageCount++;
    55197062    #endif
     
    55267069#ifndef IGNORE_NAME_CONSTRAINTS
    55277070#define ASN_TYPE_MASK 0xF
    5528 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
     7071static int DecodeSubtree(const byte* input, int sz,
     7072                         Base_entry** head, void* heap)
    55297073{
    55307074    word32 idx = 0;
     
    55937137
    55947138
    5595 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
     7139static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)
    55967140{
    55977141    word32 idx = 0;
     
    56327176#endif /* IGNORE_NAME_CONSTRAINTS */
    56337177
    5634 
    5635 #if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)
     7178#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)
    56367179
    56377180static int Word32ToString(char* d, word32 number)
     
    56697212/* Decode ITU-T X.690 OID format to a string representation
    56707213 * return string length */
    5671 static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
     7214int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
    56727215{
    56737216    word32 val, idx = 0, nb_bytes;
     
    57167259    }
    57177260
    5718     return 0;
     7261    return (int)w_bytes;
    57197262}
    57207263#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
     
    57227265#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
    57237266    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
    5724     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
     7267    static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)
    57257268    {
    57267269        word32 idx = 0;
     
    57787321        #elif defined(WOLFSSL_CERT_EXT)
    57797322                /* decode cert policy */
    5780                 if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb],
    5781                                     MAX_CERTPOL_SZ, input + idx, length) != 0) {
     7323                if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
     7324                                    input + idx, length) <= 0) {
    57827325                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
    57837326                    return ASN_PARSE_E;
     
    58177360#endif /* WOLFSSL_SEP */
    58187361
     7362/* Macro to check if bit is set, if not sets and return success.
     7363    Otherwise returns failure */
     7364/* Macro required here because bit-field operation */
     7365#ifndef WOLFSSL_NO_ASN_STRICT
     7366    #define VERIFY_AND_SET_OID(bit) \
     7367        if (bit == 0) \
     7368            bit = 1; \
     7369        else \
     7370            return ASN_OBJECT_ID_E;
     7371#else
     7372    /* With no strict defined, the verify is skipped */
     7373#define VERIFY_AND_SET_OID(bit) bit = 1;
     7374#endif
     7375
    58197376static int DecodeCertExtensions(DecodedCert* cert)
    58207377/*
     
    58237380 */
    58247381{
    5825     int ret;
     7382    int ret = 0;
    58267383    word32 idx = 0;
    58277384    int sz = cert->extensionsSz;
    5828     byte* input = cert->extensions;
     7385    const byte* input = cert->extensions;
    58297386    int length;
    58307387    word32 oid;
     
    58857442        switch (oid) {
    58867443            case BASIC_CA_OID:
    5887                 #ifdef OPENSSL_EXTRA
    5888                     cert->extBasicConstSet = 1;
     7444                VERIFY_AND_SET_OID(cert->extBasicConstSet);
     7445                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    58897446                    cert->extBasicConstCrit = critical;
    58907447                #endif
     
    58947451
    58957452            case CRL_DIST_OID:
    5896                 #ifdef OPENSSL_EXTRA
    5897                     cert->extCRLdistSet  = 1;
     7453                VERIFY_AND_SET_OID(cert->extCRLdistSet);
     7454                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    58987455                    cert->extCRLdistCrit = critical;
    58997456                #endif
     
    59037460
    59047461            case AUTH_INFO_OID:
    5905                 #ifdef OPENSSL_EXTRA
    5906                     cert->extAuthInfoSet  = 1;
     7462                VERIFY_AND_SET_OID(cert->extAuthInfoSet);
     7463                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59077464                    cert->extAuthInfoCrit = critical;
    59087465                #endif
     
    59127469
    59137470            case ALT_NAMES_OID:
    5914                 #ifdef OPENSSL_EXTRA
    5915                     cert->extSubjAltNameSet = 1;
     7471                VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
     7472                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59167473                    cert->extSubjAltNameCrit = critical;
    59177474                #endif
    5918                 if (DecodeAltNames(&input[idx], length, cert) < 0)
    5919                     return ASN_PARSE_E;
     7475                ret = DecodeAltNames(&input[idx], length, cert);
     7476                if (ret < 0)
     7477                    return ret;
    59207478                break;
    59217479
    59227480            case AUTH_KEY_OID:
    5923                 cert->extAuthKeyIdSet = 1;
    5924                 #ifdef OPENSSL_EXTRA
     7481                VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
     7482                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59257483                    cert->extAuthKeyIdCrit = critical;
     7484                #endif
     7485                #ifndef WOLFSSL_ALLOW_CRIT_SKID
     7486                    /* This check is added due to RFC 5280 section 4.2.1.1
     7487                     * stating that conforming CA's must mark this extension
     7488                     * as non-critical. When parsing extensions check that
     7489                     * certificate was made in compliance with this. */
     7490                    if (critical) {
     7491                        WOLFSSL_MSG("Critical Auth Key ID is not allowed");
     7492                        WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
     7493                        return ASN_CRIT_EXT_E;
     7494                    }
    59267495                #endif
    59277496                if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
     
    59307499
    59317500            case SUBJ_KEY_OID:
    5932                 cert->extSubjKeyIdSet = 1;
    5933                 #ifdef OPENSSL_EXTRA
     7501                VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
     7502                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59347503                    cert->extSubjKeyIdCrit = critical;
    59357504                #endif
     
    59527521            case CERT_POLICY_OID:
    59537522                #ifdef WOLFSSL_SEP
    5954                     #ifdef OPENSSL_EXTRA
    5955                         cert->extCertPolicySet = 1;
     7523                    VERIFY_AND_SET_OID(cert->extCertPolicySet);
     7524                    #if defined(OPENSSL_EXTRA) || \
     7525                        defined(OPENSSL_EXTRA_X509_SMALL)
    59567526                        cert->extCertPolicyCrit = critical;
    59577527                    #endif
     
    59677537
    59687538            case KEY_USAGE_OID:
    5969                 cert->extKeyUsageSet = 1;
    5970                 #ifdef OPENSSL_EXTRA
     7539                VERIFY_AND_SET_OID(cert->extKeyUsageSet);
     7540                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59717541                    cert->extKeyUsageCrit = critical;
    59727542                #endif
     
    59767546
    59777547            case EXT_KEY_USAGE_OID:
    5978                 cert->extExtKeyUsageSet = 1;
    5979                 #ifdef OPENSSL_EXTRA
     7548                VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
     7549                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59807550                    cert->extExtKeyUsageCrit = critical;
    59817551                #endif
     
    59867556            #ifndef IGNORE_NAME_CONSTRAINTS
    59877557            case NAME_CONS_OID:
    5988                 cert->extNameConstraintSet = 1;
    5989                 #ifdef OPENSSL_EXTRA
     7558            #ifndef WOLFSSL_NO_ASN_STRICT
     7559                /* Verify RFC 5280 Sec 4.2.1.10 rule:
     7560                    "The name constraints extension,
     7561                    which MUST be used only in a CA certificate" */
     7562                if (!cert->isCA) {
     7563                    WOLFSSL_MSG("Name constraints allowed only for CA certs");
     7564                    return ASN_NAME_INVALID_E;
     7565                }
     7566            #endif
     7567                VERIFY_AND_SET_OID(cert->extNameConstraintSet);
     7568                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59907569                    cert->extNameConstraintCrit = critical;
    59917570                #endif
     
    59967575
    59977576            case INHIBIT_ANY_OID:
     7577                VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
    59987578                WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
    59997579                break;
    60007580
    60017581            default:
     7582            #ifndef WOLFSSL_NO_ASN_STRICT
    60027583                /* While it is a failure to not support critical extensions,
    60037584                 * still parse the certificate ignoring the unsupported
     
    60067587                if (critical)
    60077588                    criticalFail = 1;
     7589            #endif
    60087590                break;
    60097591        }
     
    60487630}
    60497631
     7632
    60507633/* from SSL proper, for locking can't do find here anymore */
    60517634#ifdef __cplusplus
     
    61017684#endif
    61027685
     7686#ifdef WOLFSSL_SMALL_CERT_VERIFY
     7687/* Only quick step through the certificate to find fields that are then used
     7688 * in certificate signature verification.
     7689 * Must use the signature OID from the signed part of the certificate.
     7690 *
     7691 * This is only for minimizing dynamic memory usage during TLS certificate
     7692 * chain processing.
     7693 * Doesn't support:
     7694 *   OCSP Only: alt lookup using subject and pub key w/o sig check
     7695 */
     7696int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
     7697{
     7698#ifndef WOLFSSL_SMALL_STACK
     7699    SignatureCtx  sigCtx[1];
     7700#else
     7701    SignatureCtx* sigCtx;
     7702#endif
     7703    byte          hash[KEYID_SIZE];
     7704    Signer*       ca = NULL;
     7705    word32        idx = 0;
     7706    int           len;
     7707    word32        tbsCertIdx;
     7708    word32        sigIndex;
     7709    word32        signatureOID;
     7710    word32        oid;
     7711    word32        issuerIdx;
     7712    word32        issuerSz;
     7713#ifndef NO_SKID
     7714    int           extLen;
     7715    word32        extIdx;
     7716    word32        extEndIdx;
     7717    int           extAuthKeyIdSet = 0;
     7718#endif
     7719    int    ret = 0;
     7720
     7721    if (cert == NULL) {
     7722        return BAD_FUNC_ARG;
     7723    }
     7724
     7725#ifdef WOLFSSL_SMALL_STACK
     7726    sigCtx = XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
     7727    if (sigCtx == NULL)
     7728        return MEMORY_E;
     7729#endif
     7730    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
     7731
     7732    /* Certificate SEQUENCE */
     7733    if (GetSequence(cert, &idx, &len, certSz) < 0)
     7734        ret = ASN_PARSE_E;
     7735    if (ret == 0) {
     7736        tbsCertIdx = idx;
     7737
     7738        /* TBSCertificate SEQUENCE */
     7739        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7740            ret = ASN_PARSE_E;
     7741            }
     7742    if (ret == 0) {
     7743        sigIndex = len + idx;
     7744
     7745        if ((idx + 1) > certSz)
     7746            ret = BUFFER_E;
     7747    }
     7748    if (ret == 0) {
     7749        /* version - optional */
     7750        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
     7751            idx++;
     7752            if (GetLength(cert, &idx, &len, certSz) < 0)
     7753                ret = ASN_PARSE_E;
     7754            idx += len;
     7755        }
     7756            }
     7757
     7758    if (ret == 0) {
     7759        /* serialNumber */
     7760        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
     7761            ret = ASN_PARSE_E;
     7762        }
     7763    if (ret == 0) {
     7764        idx += len;
     7765
     7766        /* signature */
     7767        if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
     7768            ret = ASN_PARSE_E;
     7769    }
     7770
     7771    if (ret == 0) {
     7772        issuerIdx = idx;
     7773        /* issuer */
     7774        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7775            ret = ASN_PARSE_E;
     7776    }
     7777    if (ret == 0) {
     7778        issuerSz = len + idx - issuerIdx;
     7779    }
     7780#ifndef NO_SKID
     7781    if (ret == 0) {
     7782        idx += len;
     7783
     7784        /* validity */
     7785        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7786            ret = ASN_PARSE_E;
     7787    }
     7788    if (ret == 0) {
     7789        idx += len;
     7790
     7791        /* subject */
     7792        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7793            ret = ASN_PARSE_E;
     7794    }
     7795    if (ret == 0) {
     7796        idx += len;
     7797
     7798        /* subjectPublicKeyInfo */
     7799        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7800            ret = ASN_PARSE_E;
     7801    }
     7802    if (ret == 0) {
     7803        idx += len;
     7804
     7805        if ((idx + 1) > certSz)
     7806            ret = BUFFER_E;
     7807    }
     7808    if (ret == 0) {
     7809        /* issuerUniqueID - optional */
     7810        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
     7811            idx++;
     7812            if (GetLength(cert, &idx, &len, certSz) < 0)
     7813                ret = ASN_PARSE_E;
     7814            idx += len;
     7815        }
     7816    }
     7817    if (ret == 0) {
     7818        if ((idx + 1) > certSz)
     7819            ret = BUFFER_E;
     7820    }
     7821    if (ret == 0) {
     7822        /* subjectUniqueID - optional */
     7823        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
     7824            idx++;
     7825            if (GetLength(cert, &idx, &len, certSz) < 0)
     7826                ret = ASN_PARSE_E;
     7827            idx += len;
     7828        }
     7829    }
     7830
     7831    if (ret == 0) {
     7832        if ((idx + 1) > certSz)
     7833            ret = BUFFER_E;
     7834    }
     7835    /* extensions - optional */
     7836    if (ret == 0 && cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
     7837        idx++;
     7838        if (GetLength(cert, &idx, &extLen, certSz) < 0)
     7839            ret = ASN_PARSE_E;
     7840        if (ret == 0) {
     7841            if (GetSequence(cert, &idx, &extLen, certSz) < 0)
     7842                ret = ASN_PARSE_E;
     7843        }
     7844        if (ret == 0) {
     7845            extEndIdx = idx + extLen;
     7846
     7847            /* Check each extension for the ones we want. */
     7848            while (ret == 0 && idx < extEndIdx) {
     7849                if (GetSequence(cert, &idx, &len, certSz) < 0)
     7850                    ret = ASN_PARSE_E;
     7851                if (ret == 0) {
     7852                    extIdx = idx;
     7853                    if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
     7854                                                                  certSz) < 0) {
     7855                        ret = ASN_PARSE_E;
     7856                    }
     7857                }
     7858                if (ret == 0) {
     7859                    if (cert[extIdx] == ASN_BOOLEAN) {
     7860                        if (GetBoolean(cert, &extIdx, certSz) < 0)
     7861                            ret = ASN_PARSE_E;
     7862                    }
     7863                }
     7864                if (ret == 0) {
     7865                    if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
     7866                        ret = ASN_PARSE_E;
     7867                }
     7868
     7869                if (ret == 0) {
     7870                    switch (oid) {
     7871                    case AUTH_KEY_OID:
     7872                        extAuthKeyIdSet = 1;
     7873                        if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
     7874                            ret = ASN_PARSE_E;
     7875
     7876                        if (ret == 0 &&
     7877                                 cert[extIdx++] == (ASN_CONTEXT_SPECIFIC | 0)) {
     7878                            if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
     7879                                ret = ASN_PARSE_E;
     7880                            if (ret == 0) {
     7881                                if (extLen == KEYID_SIZE)
     7882                                    XMEMCPY(hash, cert + extIdx, extLen);
     7883                                else {
     7884                                    ret = CalcHashId(cert + extIdx, extLen,
     7885                                                                          hash);
     7886                                }
     7887                            }
     7888                        }
     7889                        break;
     7890
     7891                    default:
     7892                        break;
     7893                    }
     7894                }
     7895                idx += len;
     7896            }
     7897        }
     7898    }
     7899
     7900    if (ret == 0) {
     7901        if (extAuthKeyIdSet)
     7902            ca = GetCA(cm, hash);
     7903        if (ca == NULL) {
     7904            ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
     7905            if (ret == 0)
     7906                ca = GetCAByName(cm, hash);
     7907        }
     7908    }
     7909#else
     7910    if (ret == 0) {
     7911        ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
     7912        if (ret == 0)
     7913            ca = GetCA(cm, hash);
     7914    }
     7915#endif /* !NO_SKID */
     7916    if (ca == NULL)
     7917        ret = ASN_NO_SIGNER_E;
     7918
     7919    if (ret == 0) {
     7920        idx = sigIndex;
     7921        /* signatureAlgorithm */
     7922        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
     7923            ret = ASN_PARSE_E;
     7924    }
     7925    if (ret == 0) {
     7926        if (oid != signatureOID)
     7927            ret = ASN_SIG_OID_E;
     7928    }
     7929    if (ret == 0) {
     7930        /* signatureValue */
     7931        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
     7932            ret = ASN_PARSE_E;
     7933    }
     7934
     7935    if (ret == 0) {
     7936        ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, sigIndex - tbsCertIdx,
     7937                               ca->publicKey, ca->pubKeySize, ca->keyOID,
     7938                               cert + idx, len, signatureOID);
     7939        if (ret != WC_PENDING_E) {
     7940            WOLFSSL_MSG("Confirm signature failed");
     7941        }
     7942    }
     7943
     7944#ifdef WOLFSSL_SMALL_STACK
     7945    if (sigCtx != NULL)
     7946        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
     7947#endif
     7948    return ret;
     7949}
     7950#endif /* WOLFSSL_SMALL_CERT_VERIFY */
     7951
    61037952int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
    61047953{
     
    61077956    int    criticalExt = 0;
    61087957    word32 confirmOID;
     7958    int    selfSigned = 0;
    61097959
    61107960    if (cert == NULL) {
     
    61598009        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
    61608010                                                        cert->pubKeySize > 0) {
    6161         #ifdef NO_SHA
    6162             ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
     8011            ret = CalcHashId(cert->publicKey, cert->pubKeySize,
    61638012                                                            cert->extSubjKeyId);
    6164         #else
    6165             ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
    6166                                                             cert->extSubjKeyId);
    6167         #endif /* NO_SHA */
    61688013            if (ret != 0)
    61698014                return ret;
     
    61978042    #else
    61988043            cert->ca = GetCA(cm, cert->issuerHash);
     8044            if (XMEMCMP(cert->issuerHash, cert->subjectHash, KEYID_SIZE) == 0)
     8045                selfSigned = 1;
    61998046    #endif /* !NO_SKID */
    62008047
    62018048            WOLFSSL_MSG("About to verify certificate signature");
    62028049            if (cert->ca) {
    6203                 if (cert->isCA) {
    6204                     if (cert->ca->pathLengthSet) {
     8050                if (cert->isCA && cert->ca->pathLengthSet) {
     8051                    if (selfSigned) {
     8052                        if (cert->ca->pathLength != 0) {
     8053                           WOLFSSL_MSG("Root CA with path length > 0");
     8054                           return ASN_PATHLEN_INV_E;
     8055                        }
     8056                    }
     8057                    else {
    62058058                        if (cert->ca->pathLength == 0) {
    62068059                            WOLFSSL_MSG("CA with path length 0 signing a CA");
    62078060                            return ASN_PATHLEN_INV_E;
    62088061                        }
    6209                         if (cert->pathLengthSet &&
    6210                             cert->pathLength >= cert->ca->pathLength) {
     8062                        else if (cert->pathLength >= cert->ca->pathLength) {
    62118063
    62128064                            WOLFSSL_MSG("CA signing CA with longer path length");
     
    62188070        #ifdef HAVE_OCSP
    62198071                /* Need the CA's public key hash for OCSP */
    6220             #ifdef NO_SHA
    6221                 ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
     8072            ret = CalcHashId(cert->ca->publicKey, cert->ca->pubKeySize,
    62228073                                                           cert->issuerKeyHash);
    6223             #else
    6224                 ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
    6225                                                            cert->issuerKeyHash);
    6226             #endif /* NO_SHA */
    62278074                if (ret != 0)
    62288075                    return ret;
     
    62478094                    return ret;
    62488095                }
     8096            }
    62498097            #ifndef IGNORE_NAME_CONSTRAINTS
     8098            if (verify == VERIFY || verify == VERIFY_OCSP ||
     8099                                                        verify == VERIFY_NAME) {
    62508100                /* check that this cert's name is permitted by the signer's
    62518101                 * name constraints */
     
    62548104                    return ASN_NAME_INVALID_E;
    62558105                }
    6256             #endif /* IGNORE_NAME_CONSTRAINTS */
    6257             }
     8106            }
     8107        #endif /* IGNORE_NAME_CONSTRAINTS */
    62588108        }
    62598109        else {
     
    62948144        signer->pathLengthSet = 0;
    62958145        signer->pathLength = 0;
     8146    #ifdef WOLFSSL_SIGNER_DER_CERT
     8147        signer->derCert    = NULL;
     8148    #endif
    62968149        signer->next       = NULL;
    62978150    }
     
    63068159{
    63078160    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
    6308     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
     8161    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
    63098162#ifndef IGNORE_NAME_CONSTRAINTS
    63108163    if (signer->permittedNames)
     
    63128165    if (signer->excludedNames)
    63138166        FreeNameSubtrees(signer->excludedNames, heap);
     8167#endif
     8168#ifdef WOLFSSL_SIGNER_DER_CERT
     8169    FreeDer(&signer->derCert);
    63148170#endif
    63158171    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
     
    64768332
    64778333
    6478 
    6479 const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
    6480 const char* END_CERT           = "-----END CERTIFICATE-----";
    6481 const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
    6482 const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
    6483 const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
    6484 const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
    6485 const char* BEGIN_DSA_PARAM    = "-----BEGIN DSA PARAMETERS-----";
    6486 const char* END_DSA_PARAM      = "-----END DSA PARAMETERS-----";
    6487 const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
    6488 const char* END_X509_CRL       = "-----END X509 CRL-----";
    6489 const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
    6490 const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
    6491 const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
    6492 const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
    6493 const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
    6494 const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
    6495 const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
    6496 const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
    6497 const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
    6498 const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
    6499 const char* BEGIN_PUB_KEY      = "-----BEGIN PUBLIC KEY-----";
    6500 const char* END_PUB_KEY        = "-----END PUBLIC KEY-----";
    6501 const char* BEGIN_EDDSA_PRIV   = "-----BEGIN EDDSA PRIVATE KEY-----";
    6502 const char* END_EDDSA_PRIV     = "-----END EDDSA PRIVATE KEY-----";
    6503 
    6504 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA)
     8334int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
     8335{
     8336    int ret = BAD_FUNC_ARG;
     8337    if (pDer) {
     8338        int dynType = 0;
     8339        DerBuffer* der;
     8340
     8341        /* Determine dynamic type */
     8342        switch (type) {
     8343            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
     8344            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
     8345            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
     8346            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
     8347            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
     8348            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
     8349            default:        dynType = DYNAMIC_TYPE_KEY;  break;
     8350        }
     8351
     8352        /* Setup new buffer */
     8353        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
     8354        if (*pDer == NULL) {
     8355            return MEMORY_E;
     8356        }
     8357        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
     8358
     8359        der = *pDer;
     8360        der->type = type;
     8361        der->dynType = dynType; /* Cache this for FreeDer */
     8362        der->heap = heap;
     8363        der->buffer = (byte*)der + sizeof(DerBuffer);
     8364        der->length = length;
     8365        ret = 0; /* Success */
     8366    }
     8367    return ret;
     8368}
     8369
     8370void FreeDer(DerBuffer** pDer)
     8371{
     8372    if (pDer && *pDer)
     8373    {
     8374        DerBuffer* der = (DerBuffer*)*pDer;
     8375
     8376        /* ForceZero private keys */
     8377        if (der->type == PRIVATEKEY_TYPE) {
     8378            ForceZero(der->buffer, der->length);
     8379}
     8380        der->buffer = NULL;
     8381        der->length = 0;
     8382        XFREE(der, der->heap, der->dynType);
     8383
     8384        *pDer = NULL;
     8385    }
     8386}
     8387
     8388int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
     8389{
     8390    return AllocDer(pDer, length, type, heap);
     8391}
     8392void wc_FreeDer(DerBuffer** pDer)
     8393{
     8394    FreeDer(pDer);
     8395}
     8396
     8397
     8398#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
     8399
     8400/* Max X509 header length indicates the max length + 2 ('\n', '\0') */
     8401#define MAX_X509_HEADER_SZ  (37 + 2)
     8402
     8403const char* const BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
     8404const char* const END_CERT             = "-----END CERTIFICATE-----";
     8405#ifdef WOLFSSL_CERT_REQ
     8406    const char* const BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
     8407    const char* const END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
     8408#endif
     8409#ifndef NO_DH
     8410    const char* const BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
     8411    const char* const END_DH_PARAM     = "-----END DH PARAMETERS-----";
     8412#endif
     8413#ifndef NO_DSA
     8414    const char* const BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
     8415    const char* const END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
     8416#endif
     8417const char* const BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
     8418const char* const END_X509_CRL         = "-----END X509 CRL-----";
     8419const char* const BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
     8420const char* const END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
     8421const char* const BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
     8422const char* const END_PRIV_KEY         = "-----END PRIVATE KEY-----";
     8423const char* const BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
     8424const char* const END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
     8425#ifdef HAVE_ECC
     8426    const char* const BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
     8427    const char* const END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
     8428#endif
     8429#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA)
     8430    const char* const BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
     8431    const char* const END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
     8432#endif
     8433const char* const BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
     8434const char* const END_PUB_KEY          = "-----END PUBLIC KEY-----";
     8435#ifdef HAVE_ED25519
     8436    const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
     8437    const char* const END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
     8438#endif
     8439#ifdef HAVE_CRL
     8440    const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----";
     8441    const char* const END_CRL   = "-----END X509 CRL-----";
     8442#endif
     8443
     8444
     8445static WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine)
     8446{
     8447    /* eat end of line characters */
     8448    while (line < endOfLine &&
     8449              (line[0] == '\r' || line[0] == '\n')) {
     8450        line++;
     8451    }
     8452    return line;
     8453    }
     8454
     8455int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
     8456{
     8457    int ret = BAD_FUNC_ARG;
     8458
     8459    switch (type) {
     8460        case CA_TYPE:       /* same as below */
     8461        case TRUSTED_PEER_TYPE:
     8462        case CERT_TYPE:
     8463            if (header) *header = BEGIN_CERT;
     8464            if (footer) *footer = END_CERT;
     8465            ret = 0;
     8466            break;
     8467
     8468        case CRL_TYPE:
     8469            if (header) *header = BEGIN_X509_CRL;
     8470            if (footer) *footer = END_X509_CRL;
     8471            ret = 0;
     8472            break;
     8473    #ifndef NO_DH
     8474        case DH_PARAM_TYPE:
     8475            if (header) *header = BEGIN_DH_PARAM;
     8476            if (footer) *footer = END_DH_PARAM;
     8477            ret = 0;
     8478            break;
     8479    #endif
     8480    #ifndef NO_DSA
     8481        case DSA_PARAM_TYPE:
     8482            if (header) *header = BEGIN_DSA_PARAM;
     8483            if (footer) *footer = END_DSA_PARAM;
     8484            ret = 0;
     8485            break;
     8486    #endif
     8487    #ifdef WOLFSSL_CERT_REQ
     8488        case CERTREQ_TYPE:
     8489            if (header) *header = BEGIN_CERT_REQ;
     8490            if (footer) *footer = END_CERT_REQ;
     8491            ret = 0;
     8492            break;
     8493    #endif
     8494    #ifndef NO_DSA
     8495        case DSA_TYPE:
     8496        case DSA_PRIVATEKEY_TYPE:
     8497            if (header) *header = BEGIN_DSA_PRIV;
     8498            if (footer) *footer = END_DSA_PRIV;
     8499            ret = 0;
     8500            break;
     8501    #endif
     8502    #ifdef HAVE_ECC
     8503        case ECC_TYPE:
     8504        case ECC_PRIVATEKEY_TYPE:
     8505            if (header) *header = BEGIN_EC_PRIV;
     8506            if (footer) *footer = END_EC_PRIV;
     8507            ret = 0;
     8508            break;
     8509    #endif
     8510        case RSA_TYPE:
     8511        case PRIVATEKEY_TYPE:
     8512            if (header) *header = BEGIN_RSA_PRIV;
     8513            if (footer) *footer = END_RSA_PRIV;
     8514            ret = 0;
     8515            break;
     8516    #ifdef HAVE_ED25519
     8517        case ED25519_TYPE:
     8518        case EDDSA_PRIVATEKEY_TYPE:
     8519            if (header) *header = BEGIN_EDDSA_PRIV;
     8520            if (footer) *footer = END_EDDSA_PRIV;
     8521            ret = 0;
     8522            break;
     8523    #endif
     8524        case PUBLICKEY_TYPE:
     8525            if (header) *header = BEGIN_PUB_KEY;
     8526            if (footer) *footer = END_PUB_KEY;
     8527            ret = 0;
     8528            break;
     8529        case PKCS8_PRIVATEKEY_TYPE:
     8530            if (header) *header = BEGIN_PRIV_KEY;
     8531            if (footer) *footer = END_PRIV_KEY;
     8532            ret = 0;
     8533            break;
     8534        case PKCS8_ENC_PRIVATEKEY_TYPE:
     8535            if (header) *header = BEGIN_ENC_PRIV_KEY;
     8536            if (footer) *footer = END_ENC_PRIV_KEY;
     8537            ret = 0;
     8538            break;
     8539        default:
     8540            break;
     8541    }
     8542    return ret;
     8543}
     8544
     8545#ifdef WOLFSSL_ENCRYPTED_KEYS
     8546
     8547static const char* const kProcTypeHeader = "Proc-Type";
     8548static const char* const kDecInfoHeader = "DEK-Info";
     8549
     8550#ifdef WOLFSSL_PEM_TO_DER
     8551#ifndef NO_DES3
     8552    static const char* const kEncTypeDes = "DES-CBC";
     8553    static const char* const kEncTypeDes3 = "DES-EDE3-CBC";
     8554#endif
     8555#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
     8556    static const char* const kEncTypeAesCbc128 = "AES-128-CBC";
     8557#endif
     8558#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
     8559    static const char* const kEncTypeAesCbc192 = "AES-192-CBC";
     8560#endif
     8561#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
     8562    static const char* const kEncTypeAesCbc256 = "AES-256-CBC";
     8563#endif
     8564
     8565int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
     8566{
     8567    int ret = 0;
     8568
     8569    if (info == NULL || cipherInfo == NULL)
     8570        return BAD_FUNC_ARG;
     8571
     8572    /* determine cipher information */
     8573#ifndef NO_DES3
     8574    if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
     8575        info->cipherType = WC_CIPHER_DES;
     8576        info->keySz = DES_KEY_SIZE;
     8577        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
     8578    }
     8579    else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
     8580        info->cipherType = WC_CIPHER_DES3;
     8581        info->keySz = DES3_KEY_SIZE;
     8582        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
     8583    }
     8584    else
     8585#endif /* !NO_DES3 */
     8586#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
     8587    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
     8588        info->cipherType = WC_CIPHER_AES_CBC;
     8589        info->keySz = AES_128_KEY_SIZE;
     8590        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8591    }
     8592    else
     8593#endif
     8594#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
     8595    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
     8596        info->cipherType = WC_CIPHER_AES_CBC;
     8597        info->keySz = AES_192_KEY_SIZE;
     8598        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8599    }
     8600    else
     8601#endif
     8602#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
     8603    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
     8604        info->cipherType = WC_CIPHER_AES_CBC;
     8605        info->keySz = AES_256_KEY_SIZE;
     8606        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8607    }
     8608    else
     8609#endif
     8610    {
     8611        ret = NOT_COMPILED_IN;
     8612    }
     8613    return ret;
     8614}
     8615
     8616int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz)
     8617{
     8618    int err = 0;
     8619    char*  bufferStart;
     8620    char*  bufferEnd;
     8621    char*  line;
     8622    word32 lineSz;
     8623    char*  finish;
     8624    word32 finishSz;
     8625    char*  start = NULL;
     8626    word32 startSz;
     8627    char*  newline = NULL;
     8628
     8629    if (info == NULL || pBuffer == NULL || bufSz == 0)
     8630        return BAD_FUNC_ARG;
     8631
     8632    bufferStart = *pBuffer;
     8633    bufferEnd = bufferStart + bufSz;
     8634
     8635    /* find encrypted info marker */
     8636    line = XSTRNSTR(bufferStart, kProcTypeHeader,
     8637                    min((word32)bufSz, PEM_LINE_LEN));
     8638    if (line != NULL) {
     8639        if (line >= bufferEnd) {
     8640            return BUFFER_E;
     8641        }
     8642
     8643        lineSz = (word32)(bufferEnd - line);
     8644
     8645        /* find DEC-Info marker */
     8646        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
     8647
     8648        if (start == NULL)
     8649            return BUFFER_E;
     8650
     8651        /* skip dec-info and ": " */
     8652        start += XSTRLEN(kDecInfoHeader);
     8653        if (start >= bufferEnd)
     8654            return BUFFER_E;
     8655
     8656        if (start[0] == ':') {
     8657            start++;
     8658            if (start >= bufferEnd)
     8659                return BUFFER_E;
     8660        }
     8661        if (start[0] == ' ')
     8662            start++;
     8663
     8664        startSz = (word32)(bufferEnd - start);
     8665        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
     8666
     8667        if ((start != NULL) && (finish != NULL) && (start < finish)) {
     8668            if (finish >= bufferEnd) {
     8669                return BUFFER_E;
     8670            }
     8671
     8672            finishSz = (word32)(bufferEnd - finish);
     8673            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
     8674
     8675            /* get cipher name */
     8676            if (NAME_SZ < (finish - start)) /* buffer size of info->name */
     8677                return BUFFER_E;
     8678            if (XMEMCPY(info->name, start, finish - start) == NULL)
     8679                return BUFFER_E;
     8680            info->name[finish - start] = '\0'; /* null term */
     8681
     8682            /* populate info */
     8683            err = wc_EncryptedInfoGet(info, info->name);
     8684            if (err != 0)
     8685                return err;
     8686
     8687            /* get IV */
     8688            if (finishSz < info->ivSz + 1)
     8689                return BUFFER_E;
     8690
     8691            if (newline == NULL) {
     8692                newline = XSTRNSTR(finish, "\n", min(finishSz,
     8693                                                     PEM_LINE_LEN));
     8694            }
     8695            if ((newline != NULL) && (newline > finish)) {
     8696                info->ivSz = (word32)(newline - (finish + 1));
     8697                if (XMEMCPY(info->iv, finish + 1, info->ivSz) == NULL)
     8698                    return BUFFER_E;
     8699                info->set = 1;
     8700            }
     8701            else
     8702                return BUFFER_E;
     8703        }
     8704        else
     8705            return BUFFER_E;
     8706
     8707        /* eat end of line characters */
     8708        newline = SkipEndOfLineChars(newline, bufferEnd);
     8709
     8710        /* return new headerEnd */
     8711        if (pBuffer)
     8712            *pBuffer = newline;
     8713    }
     8714
     8715    return err;
     8716}
     8717#endif /* WOLFSSL_PEM_TO_DER */
     8718
     8719#ifdef WOLFSSL_DER_TO_PEM
     8720static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
     8721{
     8722    if (cipherInfo != NULL) {
     8723        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
     8724
     8725        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
     8726            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
     8727
     8728        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
     8729            /* strncat's src length needs to include the NULL */
     8730            XSTRNCAT(dest, kProcTypeHeader, 10);
     8731            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
     8732            XSTRNCAT(dest, kDecInfoHeader, 9);
     8733            XSTRNCAT(dest, ": ", 3);
     8734            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
     8735            XSTRNCAT(dest, "\n\n", 4);
     8736        }
     8737    }
     8738    return 0;
     8739}
     8740#endif /* WOLFSSL_DER_TO_PEM */
     8741#endif /* WOLFSSL_ENCRYPTED_KEYS */
     8742
     8743#ifdef WOLFSSL_DER_TO_PEM
    65058744
    65068745/* Used for compatibility API */
     
    65168755             byte *cipher_info, int type)
    65178756{
     8757    const char* headerStr = NULL;
     8758    const char* footerStr = NULL;
    65188759#ifdef WOLFSSL_SMALL_STACK
    65198760    char* header = NULL;
    65208761    char* footer = NULL;
    65218762#else
    6522     char header[40 + HEADER_ENCRYPTED_KEY_SIZE];
    6523     char footer[40];
    6524 #endif
    6525 
    6526     int headerLen = 40 + HEADER_ENCRYPTED_KEY_SIZE;
    6527     int footerLen = 40;
     8763    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
     8764    char footer[MAX_X509_HEADER_SZ];
     8765#endif
     8766    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
     8767    int footerLen = MAX_X509_HEADER_SZ;
    65288768    int i;
    65298769    int err;
    65308770    int outLen;   /* return length or error */
    65318771
     8772    (void)cipher_info;
     8773
    65328774    if (der == output)      /* no in place conversion */
    65338775        return BAD_FUNC_ARG;
     8776
     8777    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
     8778    if (err != 0)
     8779        return err;
    65348780
    65358781#ifdef WOLFSSL_SMALL_STACK
     
    65448790    }
    65458791#endif
    6546     if (type == CERT_TYPE) {
    6547         XSTRNCPY(header, BEGIN_CERT, headerLen);
    6548         XSTRNCAT(header, "\n", 1);
    6549 
    6550         XSTRNCPY(footer, END_CERT, footerLen);
    6551         XSTRNCAT(footer, "\n", 1);
    6552     }
    6553     else if (type == PRIVATEKEY_TYPE) {
    6554         XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen);
    6555         XSTRNCAT(header, "\n", 1);
    6556 
    6557         XSTRNCPY(footer, END_RSA_PRIV, footerLen);
    6558         XSTRNCAT(footer, "\n", 1);
    6559     }
    6560 #ifndef NO_DSA
    6561     else if (type == DSA_PRIVATEKEY_TYPE) {
    6562         XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen);
    6563         XSTRNCAT(header, "\n", 1);
    6564 
    6565         XSTRNCPY(footer, END_DSA_PRIV, footerLen);
    6566         XSTRNCAT(footer, "\n", 1);
    6567     }
    6568 #endif
    6569 #ifdef HAVE_ECC
    6570     else if (type == ECC_PRIVATEKEY_TYPE) {
    6571         XSTRNCPY(header, BEGIN_EC_PRIV, headerLen);
    6572         XSTRNCAT(header, "\n", 1);
    6573 
    6574         XSTRNCPY(footer, END_EC_PRIV, footerLen);
    6575         XSTRNCAT(footer, "\n", 1);
    6576     }
    6577 #endif
    6578 #ifdef HAVE_ED25519
    6579     else if (type == EDDSA_PRIVATEKEY_TYPE) {
    6580         XSTRNCPY(header, BEGIN_EDDSA_PRIV, headerLen);
    6581         XSTRNCAT(header, "\n", 1);
    6582 
    6583         XSTRNCPY(footer, END_EDDSA_PRIV, footerLen);
    6584         XSTRNCAT(footer, "\n", 1);
    6585     }
    6586 #endif
    6587 #ifdef WOLFSSL_CERT_REQ
    6588     else if (type == CERTREQ_TYPE)
    6589     {
    6590         XSTRNCPY(header, BEGIN_CERT_REQ, headerLen);
    6591         XSTRNCAT(header, "\n", 1);
    6592 
    6593         XSTRNCPY(footer, END_CERT_REQ, footerLen);
    6594         XSTRNCAT(footer, "\n", 1);
    6595     }
    6596 #endif
    6597 #ifdef HAVE_CRL
    6598     else if (type == CRL_TYPE)
    6599     {
    6600         XSTRNCPY(header, BEGIN_X509_CRL, headerLen);
    6601         XSTRNCAT(header, "\n", 1);
    6602 
    6603         XSTRNCPY(footer, END_X509_CRL, footerLen);
    6604         XSTRNCAT(footer, "\n", 1);
    6605     }
    6606 #endif
    6607     else {
    6608 #ifdef WOLFSSL_SMALL_STACK
     8792
     8793    /* build header and footer based on type */
     8794    XSTRNCPY(header, headerStr, headerLen - 1);
     8795    header[headerLen - 1] = 0;
     8796    XSTRNCPY(footer, footerStr, footerLen - 1);
     8797    footer[footerLen - 1] = 0;
     8798
     8799    /* add new line to end */
     8800    XSTRNCAT(header, "\n", 2);
     8801    XSTRNCAT(footer, "\n", 2);
     8802
     8803#ifdef WOLFSSL_ENCRYPTED_KEYS
     8804    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
     8805    if (err != 0) {
     8806    #ifdef WOLFSSL_SMALL_STACK
    66098807        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    66108808        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6611 #endif
    6612         return BAD_FUNC_ARG;
    6613     }
    6614 
    6615     /* extra header information for encrypted key */
    6616     if (cipher_info != NULL) {
    6617         size_t cipherInfoStrLen = XSTRLEN((char*)cipher_info);
    6618         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (23+10+2))
    6619             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (23+10+2);
    6620 
    6621         XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23);
    6622         XSTRNCAT(header, "DEK-Info: ", 10);
    6623         XSTRNCAT(header, (char*)cipher_info, cipherInfoStrLen);
    6624         XSTRNCAT(header, "\n\n", 2);
    6625     }
     8809    #endif
     8810        return err;
     8811    }
     8812#endif
    66268813
    66278814    headerLen = (int)XSTRLEN(header);
     
    66938880}
    66948881
    6695 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN || OPENSSL_EXTRA */
     8882#endif /* WOLFSSL_DER_TO_PEM */
     8883
     8884#ifdef WOLFSSL_PEM_TO_DER
     8885
     8886/* Remove PEM header/footer, convert to ASN1, store any encrypted data
     8887   info->consumed tracks of PEM bytes consumed in case multiple parts */
     8888int PemToDer(const unsigned char* buff, long longSz, int type,
     8889              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
     8890{
     8891    const char* header      = NULL;
     8892    const char* footer      = NULL;
     8893    char*       headerEnd;
     8894    char*       footerEnd;
     8895    char*       consumedEnd;
     8896    char*       bufferEnd   = (char*)(buff + longSz);
     8897    long        neededSz;
     8898    int         ret         = 0;
     8899    int         sz          = (int)longSz;
     8900    int         encrypted_key = 0;
     8901    DerBuffer*  der;
     8902    word32      algId = 0;
     8903
     8904    WOLFSSL_ENTER("PemToDer");
     8905
     8906    /* get PEM header and footer based on type */
     8907    ret = wc_PemGetHeaderFooter(type, &header, &footer);
     8908    if (ret != 0)
     8909        return ret;
     8910
     8911    /* map header if not found for type */
     8912    for (;;) {
     8913        headerEnd = XSTRNSTR((char*)buff, header, sz);
     8914
     8915        if (headerEnd || type != PRIVATEKEY_TYPE) {
     8916            break;
     8917        } else
     8918        if (header == BEGIN_RSA_PRIV) {
     8919            header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
     8920        } else
     8921        if (header == BEGIN_PRIV_KEY) {
     8922            header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
     8923        } else
     8924#ifdef HAVE_ECC
     8925        if (header == BEGIN_ENC_PRIV_KEY) {
     8926            header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
     8927        } else
     8928        if (header == BEGIN_EC_PRIV) {
     8929            header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
     8930        } else
     8931#endif
     8932#ifdef HAVE_ED25519
     8933    #ifdef HAVE_ECC
     8934        if (header == BEGIN_DSA_PRIV)
     8935    #else
     8936        if (header == BEGIN_ENC_PRIV_KEY)
     8937    #endif
     8938        {
     8939            header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;
     8940        } else
     8941#endif
     8942#ifdef HAVE_CRL
     8943        if (type == CRL_TYPE) {
     8944            header =  BEGIN_CRL;        footer = END_CRL;
     8945        } else
     8946#endif
     8947        {
     8948            break;
     8949        }
     8950    }
     8951
     8952    if (!headerEnd) {
     8953        WOLFSSL_MSG("Couldn't find PEM header");
     8954        return ASN_NO_PEM_HEADER;
     8955    }
     8956
     8957    headerEnd += XSTRLEN(header);
     8958
     8959    /* eat end of line characters */
     8960    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
     8961
     8962    if (type == PRIVATEKEY_TYPE) {
     8963        if (eccKey) {
     8964        #ifdef HAVE_ECC
     8965            *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0;
     8966        #else
     8967            *eccKey = 0;
     8968        #endif
     8969        }
     8970    }
     8971
     8972#ifdef WOLFSSL_ENCRYPTED_KEYS
     8973    if (info) {
     8974        ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
     8975        if (ret < 0)
     8976            return ret;
     8977        if (info->set)
     8978            encrypted_key = 1;
     8979    }
     8980#endif /* WOLFSSL_ENCRYPTED_KEYS */
     8981
     8982    /* find footer */
     8983    footerEnd = XSTRNSTR((char*)buff, footer, sz);
     8984    if (!footerEnd) {
     8985        if (info)
     8986            info->consumed = longSz; /* No more certs if no footer */
     8987        return BUFFER_E;
     8988    }
     8989
     8990    consumedEnd = footerEnd + XSTRLEN(footer);
     8991
     8992    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
     8993        /* eat end of line characters */
     8994        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
     8995        /* skip possible null term */
     8996        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
     8997            consumedEnd++;
     8998    }
     8999
     9000    if (info)
     9001        info->consumed = (long)(consumedEnd - (char*)buff);
     9002
     9003    /* set up der buffer */
     9004    neededSz = (long)(footerEnd - headerEnd);
     9005    if (neededSz > sz || neededSz <= 0)
     9006        return BUFFER_E;
     9007
     9008    ret = AllocDer(pDer, (word32)neededSz, type, heap);
     9009    if (ret < 0) {
     9010        return ret;
     9011    }
     9012    der = *pDer;
     9013
     9014    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
     9015                      der->buffer, &der->length) < 0)
     9016        return BUFFER_E;
     9017
     9018    if ((header == BEGIN_PRIV_KEY
     9019#ifdef HAVE_ECC
     9020         || header == BEGIN_EC_PRIV
     9021#endif
     9022        ) && !encrypted_key)
     9023    {
     9024        /* pkcs8 key, convert and adjust length */
     9025        if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
     9026            der->length = ret;
     9027        }
     9028        else {
     9029            /* ignore failure here and assume key is not pkcs8 wrapped */
     9030        }
     9031
     9032        return 0;
     9033    }
     9034
     9035#ifdef WOLFSSL_ENCRYPTED_KEYS
     9036    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
     9037        int   passwordSz = NAME_SZ;
     9038    #ifdef WOLFSSL_SMALL_STACK
     9039        char* password = NULL;
     9040    #else
     9041        char  password[NAME_SZ];
     9042    #endif
     9043
     9044        if (!info || !info->passwd_cb) {
     9045            WOLFSSL_MSG("No password callback set");
     9046            return NO_PASSWORD;
     9047        }
     9048
     9049    #ifdef WOLFSSL_SMALL_STACK
     9050        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
     9051        if (password == NULL)
     9052            return MEMORY_E;
     9053    #endif
     9054
     9055        /* get password */
     9056        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
     9057            info->passwd_userdata);
     9058        if (ret >= 0) {
     9059            passwordSz = ret;
     9060
     9061            /* convert and adjust length */
     9062            if (header == BEGIN_ENC_PRIV_KEY) {
     9063            #ifndef NO_PWDBASED
     9064                ret = ToTraditionalEnc(der->buffer, der->length,
     9065                                       password, passwordSz, &algId);
     9066
     9067                if (ret >= 0) {
     9068                    der->length = ret;
     9069                    if ((algId == ECDSAk) && (eccKey != NULL)) {
     9070                        *eccKey = 1;
     9071                    }
     9072                    ret = 0;
     9073                }
     9074            #else
     9075                ret = NOT_COMPILED_IN;
     9076            #endif
     9077            }
     9078            /* decrypt the key */
     9079            else {
     9080                ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
     9081                    (byte*)password, passwordSz, WC_MD5);
     9082            }
     9083            ForceZero(password, passwordSz);
     9084        }
     9085
     9086    #ifdef WOLFSSL_SMALL_STACK
     9087        XFREE(password, heap, DYNAMIC_TYPE_STRING);
     9088    #endif
     9089    }
     9090#endif /* WOLFSSL_ENCRYPTED_KEYS */
     9091
     9092    return ret;
     9093}
     9094
     9095int wc_PemToDer(const unsigned char* buff, long longSz, int type,
     9096              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
     9097{
     9098    return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
     9099}
     9100
     9101
     9102/* our KeyPemToDer password callback, password in userData */
     9103static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
     9104{
     9105    (void)rw;
     9106
     9107    if (userdata == NULL)
     9108        return 0;
     9109
     9110    XSTRNCPY(passwd, (char*)userdata, sz);
     9111    return min((word32)sz, (word32)XSTRLEN((char*)userdata));
     9112}
     9113
     9114/* Return bytes written to buff or < 0 for error */
     9115int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
     9116                        unsigned char* buff, int buffSz, const char* pass)
     9117{
     9118    int            eccKey = 0;
     9119    int            ret;
     9120    DerBuffer*     der = NULL;
     9121#ifdef WOLFSSL_SMALL_STACK
     9122    EncryptedInfo* info = NULL;
     9123#else
     9124    EncryptedInfo  info[1];
     9125#endif
     9126
     9127    WOLFSSL_ENTER("wc_KeyPemToDer");
     9128
     9129    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9130        WOLFSSL_MSG("Bad pem der args");
     9131        return BAD_FUNC_ARG;
     9132    }
     9133
     9134#ifdef WOLFSSL_SMALL_STACK
     9135    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
     9136                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
     9137    if (info == NULL)
     9138        return MEMORY_E;
     9139#endif
     9140
     9141    XMEMSET(info, 0, sizeof(EncryptedInfo));
     9142    info->passwd_cb = OurPasswordCb;
     9143    info->passwd_userdata = (void*)pass;
     9144
     9145    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
     9146
     9147#ifdef WOLFSSL_SMALL_STACK
     9148    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
     9149#endif
     9150
     9151    if (ret < 0) {
     9152        WOLFSSL_MSG("Bad Pem To Der");
     9153    }
     9154    else {
     9155        if (der->length <= (word32)buffSz) {
     9156            XMEMCPY(buff, der->buffer, der->length);
     9157            ret = der->length;
     9158        }
     9159        else {
     9160            WOLFSSL_MSG("Bad der length");
     9161            ret = BAD_FUNC_ARG;
     9162        }
     9163    }
     9164
     9165    FreeDer(&der);
     9166    return ret;
     9167}
     9168
     9169
     9170/* Return bytes written to buff or < 0 for error */
     9171int wc_CertPemToDer(const unsigned char* pem, int pemSz,
     9172                        unsigned char* buff, int buffSz, int type)
     9173{
     9174    int            eccKey = 0;
     9175    int            ret;
     9176    DerBuffer*     der = NULL;
     9177
     9178    WOLFSSL_ENTER("wc_CertPemToDer");
     9179
     9180    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9181        WOLFSSL_MSG("Bad pem der args");
     9182        return BAD_FUNC_ARG;
     9183    }
     9184
     9185    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
     9186        WOLFSSL_MSG("Bad cert type");
     9187        return BAD_FUNC_ARG;
     9188    }
     9189
     9190
     9191    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
     9192    if (ret < 0) {
     9193        WOLFSSL_MSG("Bad Pem To Der");
     9194    }
     9195    else {
     9196        if (der->length <= (word32)buffSz) {
     9197            XMEMCPY(buff, der->buffer, der->length);
     9198            ret = der->length;
     9199        }
     9200        else {
     9201            WOLFSSL_MSG("Bad der length");
     9202            ret = BAD_FUNC_ARG;
     9203        }
     9204    }
     9205
     9206    FreeDer(&der);
     9207    return ret;
     9208}
     9209
     9210#endif /* WOLFSSL_PEM_TO_DER */
     9211#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
     9212
     9213
     9214#ifdef WOLFSSL_PEM_TO_DER
     9215#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
     9216/* Return bytes written to buff or < 0 for error */
     9217int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
     9218                           unsigned char* buff, int buffSz)
     9219{
     9220    int ret;
     9221    DerBuffer* der = NULL;
     9222
     9223    WOLFSSL_ENTER("wc_PubKeyPemToDer");
     9224
     9225    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9226        WOLFSSL_MSG("Bad pem der args");
     9227        return BAD_FUNC_ARG;
     9228    }
     9229
     9230    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
     9231    if (ret < 0) {
     9232        WOLFSSL_MSG("Bad Pem To Der");
     9233    }
     9234    else {
     9235        if (der->length <= (word32)buffSz) {
     9236            XMEMCPY(buff, der->buffer, der->length);
     9237            ret = der->length;
     9238        }
     9239        else {
     9240            WOLFSSL_MSG("Bad der length");
     9241            ret = BAD_FUNC_ARG;
     9242        }
     9243    }
     9244
     9245    FreeDer(&der);
     9246    return ret;
     9247}
     9248#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
     9249#endif /* WOLFSSL_PEM_TO_DER */
     9250
     9251#ifndef NO_FILESYSTEM
     9252
     9253#ifdef WOLFSSL_CERT_GEN
     9254/* load pem cert from file into der buffer, return der size or error */
     9255int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
     9256{
     9257#ifdef WOLFSSL_SMALL_STACK
     9258    byte   staticBuffer[1]; /* force XMALLOC */
     9259#else
     9260    byte   staticBuffer[FILE_BUFFER_SIZE];
     9261#endif
     9262    byte*  fileBuf = staticBuffer;
     9263    int    dynamic = 0;
     9264    int    ret     = 0;
     9265    long   sz      = 0;
     9266    XFILE  file;
     9267    DerBuffer* converted = NULL;
     9268
     9269    WOLFSSL_ENTER("wc_PemCertToDer");
     9270
     9271    if (fileName == NULL) {
     9272        ret = BAD_FUNC_ARG;
     9273    }
     9274    else {
     9275        file = XFOPEN(fileName, "rb");
     9276        if (file == XBADFILE) {
     9277            ret = BUFFER_E;
     9278        }
     9279    }
     9280
     9281    if (ret == 0) {
     9282        if(XFSEEK(file, 0, XSEEK_END) != 0)
     9283            ret = BUFFER_E;
     9284        sz = XFTELL(file);
     9285        XREWIND(file);
     9286
     9287        if (sz <= 0) {
     9288            ret = BUFFER_E;
     9289        }
     9290        else if (sz > (long)sizeof(staticBuffer)) {
     9291        #ifdef WOLFSSL_STATIC_MEMORY
     9292            WOLFSSL_MSG("File was larger then static buffer");
     9293            return MEMORY_E;
     9294        #endif
     9295            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
     9296            if (fileBuf == NULL)
     9297                ret = MEMORY_E;
     9298            else
     9299                dynamic = 1;
     9300        }
     9301
     9302        if (ret == 0) {
     9303            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
     9304                ret = BUFFER_E;
     9305            }
     9306        #ifdef WOLFSSL_PEM_TO_DER
     9307            else {
     9308                ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,  0, NULL,NULL);
     9309            }
     9310        #endif
     9311
     9312            if (ret == 0) {
     9313                if (converted->length < (word32)derSz) {
     9314                    XMEMCPY(derBuf, converted->buffer, converted->length);
     9315                    ret = converted->length;
     9316                }
     9317                else
     9318                    ret = BUFFER_E;
     9319            }
     9320
     9321            FreeDer(&converted);
     9322        }
     9323
     9324        XFCLOSE(file);
     9325        if (dynamic)
     9326            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
     9327    }
     9328
     9329    return ret;
     9330}
     9331#endif /* WOLFSSL_CERT_GEN */
     9332
     9333#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
     9334/* load pem public key from file into der buffer, return der size or error */
     9335int wc_PemPubKeyToDer(const char* fileName,
     9336                           unsigned char* derBuf, int derSz)
     9337{
     9338#ifdef WOLFSSL_SMALL_STACK
     9339    byte   staticBuffer[1]; /* force XMALLOC */
     9340#else
     9341    byte   staticBuffer[FILE_BUFFER_SIZE];
     9342#endif
     9343    byte*  fileBuf = staticBuffer;
     9344    int    dynamic = 0;
     9345    int    ret     = 0;
     9346    long   sz      = 0;
     9347    XFILE  file;
     9348    DerBuffer* converted = NULL;
     9349
     9350    WOLFSSL_ENTER("wc_PemPubKeyToDer");
     9351
     9352    if (fileName == NULL) {
     9353        ret = BAD_FUNC_ARG;
     9354    }
     9355    else {
     9356        file = XFOPEN(fileName, "rb");
     9357        if (file == XBADFILE) {
     9358            ret = BUFFER_E;
     9359        }
     9360    }
     9361
     9362    if (ret == 0) {
     9363        if(XFSEEK(file, 0, XSEEK_END) != 0)
     9364            ret = BUFFER_E;
     9365        sz = XFTELL(file);
     9366        XREWIND(file);
     9367
     9368        if (sz <= 0) {
     9369            ret = BUFFER_E;
     9370        }
     9371        else if (sz > (long)sizeof(staticBuffer)) {
     9372        #ifdef WOLFSSL_STATIC_MEMORY
     9373            WOLFSSL_MSG("File was larger then static buffer");
     9374            return MEMORY_E;
     9375        #endif
     9376            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
     9377            if (fileBuf == NULL)
     9378                ret = MEMORY_E;
     9379            else
     9380                dynamic = 1;
     9381        }
     9382        if (ret == 0) {
     9383            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
     9384                ret = BUFFER_E;
     9385            }
     9386        #ifdef WOLFSSL_PEM_TO_DER
     9387            else {
     9388                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
     9389                               0, NULL, NULL);
     9390            }
     9391        #endif
     9392
     9393            if (ret == 0) {
     9394                if (converted->length < (word32)derSz) {
     9395                    XMEMCPY(derBuf, converted->buffer, converted->length);
     9396                    ret = converted->length;
     9397                }
     9398                else
     9399                    ret = BUFFER_E;
     9400    }
     9401
     9402            FreeDer(&converted);
     9403    }
     9404
     9405        XFCLOSE(file);
     9406        if (dynamic)
     9407            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
     9408    }
     9409
     9410    return ret;
     9411}
     9412#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
     9413
     9414#endif /* !NO_FILESYSTEM */
     9415
    66969416
    66979417#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
    6698         (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)))
     9418    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
    66999419/* USER RSA ifdef portions used instead of refactor in consideration for
    67009420   possible fips build */
     
    67239443    /* n */
    67249444#ifdef WOLFSSL_SMALL_STACK
    6725     n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9445    n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67269446    if (n == NULL)
    67279447        return MEMORY_E;
     
    67359455    if (nSz < 0) {
    67369456#ifdef WOLFSSL_SMALL_STACK
    6737         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9457        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67389458#endif
    67399459        return nSz;
     
    67429462    /* e */
    67439463#ifdef WOLFSSL_SMALL_STACK
    6744     e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9464    e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67459465    if (e == NULL) {
    67469466#ifdef WOLFSSL_SMALL_STACK
    6747         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9467        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67489468#endif
    67499469        return MEMORY_E;
     
    67589478    if (eSz < 0) {
    67599479#ifdef WOLFSSL_SMALL_STACK
    6760         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6761         XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9480        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9481        XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67629482#endif
    67639483        return eSz;
     
    67699489    if ( (seqSz + nSz + eSz) > outLen) {
    67709490#ifdef WOLFSSL_SMALL_STACK
    6771         XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6772         XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9491        XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9492        XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67739493#endif
    67749494        return BUFFER_E;
     
    67819501        byte* algo = NULL;
    67829502
    6783         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9503        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67849504        if (algo == NULL) {
    6785             XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6786             XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9505            XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9506            XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67879507            return MEMORY_E;
    67889508        }
     
    67989518        if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
    67999519            #ifdef WOLFSSL_SMALL_STACK
    6800                 XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6801                 XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6802                 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9520                XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9521                XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9522                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    68039523            #endif
    68049524
     
    68139533        idx += bitStringSz;
    68149534#ifdef WOLFSSL_SMALL_STACK
    6815         XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9535        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    68169536#endif
    68179537    }
     
    68309550
    68319551#ifdef WOLFSSL_SMALL_STACK
    6832     XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6833     XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6834 #endif
     9552    XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9553    XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9554#endif
     9555
     9556    return idx;
     9557}
     9558
     9559int RsaPublicKeyDerSize(RsaKey* key, int with_header)
     9560{
     9561    byte* dummy = NULL;
     9562    byte seq[MAX_SEQ_SZ];
     9563    byte bitString[1 + MAX_LENGTH_SZ + 1];
     9564    int  nSz;
     9565    int  eSz;
     9566    int  seqSz;
     9567    int  bitStringSz;
     9568    int  idx;
     9569
     9570    if (key == NULL)
     9571        return BAD_FUNC_ARG;
     9572
     9573    /* n */
     9574    dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9575    if (dummy == NULL)
     9576        return MEMORY_E;
     9577
     9578#ifdef HAVE_USER_RSA
     9579    nSz = SetASNIntRSA(key->n, dummy);
     9580#else
     9581    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, dummy);
     9582#endif
     9583    XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9584    if (nSz < 0) {
     9585        return nSz;
     9586    }
     9587
     9588    /* e */
     9589    dummy = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9590    if (dummy == NULL) {
     9591        XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9592        return MEMORY_E;
     9593    }
     9594
     9595#ifdef HAVE_USER_RSA
     9596    eSz = SetASNIntRSA(key->e, dummy);
     9597#else
     9598    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, dummy);
     9599#endif
     9600    XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9601    if (eSz < 0) {
     9602        return eSz;
     9603    }
     9604
     9605    seqSz  = SetSequence(nSz + eSz, seq);
     9606
     9607    /* headers */
     9608    if (with_header) {
     9609        int  algoSz;
     9610        dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9611        if (dummy == NULL)
     9612            return MEMORY_E;
     9613
     9614        algoSz = SetAlgoID(RSAk, dummy, oidKeyType, 0);
     9615        bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
     9616
     9617        idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, dummy);
     9618        XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9619
     9620        /* algo */
     9621        idx += algoSz;
     9622        /* bit string */
     9623        idx += bitStringSz;
     9624    }
     9625    else
     9626        idx = 0;
     9627
     9628    /* seq */
     9629    idx += seqSz;
     9630    /* n */
     9631    idx += nSz;
     9632    /* e */
     9633    idx += eSz;
    68359634
    68369635    return idx;
     
    68419640
    68429641#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
    6843 
    68449642
    68459643static mp_int* GetRsaInt(RsaKey* key, int idx)
     
    68679665
    68689666/* Release Tmp RSA resources */
    6869 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
     9667static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
    68709668{
    68719669    int i;
     
    69299727
    69309728    outLen = seqSz + verSz + intTotalLen;
    6931     if (outLen > (int)inLen)
     9729    if (outLen > (int)inLen) {
     9730        FreeTmpRsas(tmps, key->heap);
    69329731        return BAD_FUNC_ARG;
     9732    }
    69339733
    69349734    /* write to output */
     
    69469746    return outLen;
    69479747}
    6948 
    6949 
     9748#endif
     9749
     9750#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
    69509751/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
    69519752   written */
     
    69559756}
    69569757
    6957 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
     9758#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
    69589759
    69599760
     
    69719772int wc_InitCert(Cert* cert)
    69729773{
     9774#ifdef WOLFSSL_MULTI_ATTRIB
     9775    int i = 0;
     9776#endif
    69739777    if (cert == NULL) {
    69749778        return BAD_FUNC_ARG;
    69759779    }
    69769780
     9781    XMEMSET(cert, 0, sizeof(Cert));
     9782
    69779783    cert->version    = 2;   /* version 3 is hex 2 */
     9784#ifndef NO_SHA
    69789785    cert->sigType    = CTC_SHAwRSA;
     9786#elif !defined(NO_SHA256)
     9787    cert->sigType    = CTC_SHA256wRSA;
     9788#else
     9789    cert->sigType    = 0;
     9790#endif
    69799791    cert->daysValid  = 500;
    69809792    cert->selfSigned = 1;
    6981     cert->isCA       = 0;
    6982     cert->bodySz     = 0;
    6983 #ifdef WOLFSSL_ALT_NAMES
    6984     cert->altNamesSz   = 0;
    6985     cert->beforeDateSz = 0;
    6986     cert->afterDateSz  = 0;
    6987 #endif
    6988 #ifdef WOLFSSL_CERT_EXT
    6989     cert->skidSz = 0;
    6990     cert->akidSz = 0;
    6991     cert->keyUsage = 0;
    6992     cert->extKeyUsage = 0;
    6993     cert->certPoliciesNb = 0;
    6994     XMEMSET(cert->akid, 0, CTC_MAX_AKID_SIZE);
    6995     XMEMSET(cert->skid, 0, CTC_MAX_SKID_SIZE);
    6996     XMEMSET(cert->certPolicies, 0, CTC_MAX_CERTPOL_NB*CTC_MAX_CERTPOL_SZ);
    6997 #endif
    69989793    cert->keyType    = RSA_KEY;
    6999     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
    7000     cert->serialSz = 0;
    7001 
    7002     cert->issuer.country[0] = '\0';
     9794
    70039795    cert->issuer.countryEnc = CTC_PRINTABLE;
    7004     cert->issuer.state[0] = '\0';
    70059796    cert->issuer.stateEnc = CTC_UTF8;
    7006     cert->issuer.locality[0] = '\0';
    70079797    cert->issuer.localityEnc = CTC_UTF8;
    7008     cert->issuer.sur[0] = '\0';
    70099798    cert->issuer.surEnc = CTC_UTF8;
    7010     cert->issuer.org[0] = '\0';
    70119799    cert->issuer.orgEnc = CTC_UTF8;
    7012     cert->issuer.unit[0] = '\0';
    70139800    cert->issuer.unitEnc = CTC_UTF8;
    7014     cert->issuer.commonName[0] = '\0';
    70159801    cert->issuer.commonNameEnc = CTC_UTF8;
    7016     cert->issuer.email[0] = '\0';
    7017 
    7018     cert->subject.country[0] = '\0';
     9802
    70199803    cert->subject.countryEnc = CTC_PRINTABLE;
    7020     cert->subject.state[0] = '\0';
    70219804    cert->subject.stateEnc = CTC_UTF8;
    7022     cert->subject.locality[0] = '\0';
    70239805    cert->subject.localityEnc = CTC_UTF8;
    7024     cert->subject.sur[0] = '\0';
    70259806    cert->subject.surEnc = CTC_UTF8;
    7026     cert->subject.org[0] = '\0';
    70279807    cert->subject.orgEnc = CTC_UTF8;
    7028     cert->subject.unit[0] = '\0';
    70299808    cert->subject.unitEnc = CTC_UTF8;
    7030     cert->subject.commonName[0] = '\0';
    70319809    cert->subject.commonNameEnc = CTC_UTF8;
    7032     cert->subject.email[0] = '\0';
    7033 
    7034 #ifdef WOLFSSL_CERT_REQ
    7035     cert->challengePw[0] ='\0';
    7036 #endif
     9810
     9811#ifdef WOLFSSL_MULTI_ATTRIB
     9812    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
     9813        cert->issuer.name[i].type   = CTC_UTF8;
     9814        cert->subject.name[i].type  = CTC_UTF8;
     9815    }
     9816#endif /* WOLFSSL_MULTI_ATTRIB */
     9817
    70379818#ifdef WOLFSSL_HEAP_TEST
    70389819    cert->heap = (void*)WOLFSSL_HEAP_TEST;
    7039 #else
    7040     cert->heap = NULL;
    70419820#endif
    70429821
     
    70499828    byte size[MAX_LENGTH_SZ];          /* length encoded */
    70509829    byte version[MAX_VERSION_SZ];      /* version encoded */
    7051     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
     9830    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
    70529831    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
    70539832    byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
     
    71109889#endif /*WOLFSSL_CERT_GEN */
    71119890
    7112 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
     9891
     9892#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
    71139893
    71149894/* Write a public ECC key to output */
     
    71309910    byte pub[ECC_BUFSIZE];
    71319911#endif
     9912    int ret;
    71329913
    71339914#ifdef WOLFSSL_SMALL_STACK
    7134     pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9915    pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71359916    if (pub == NULL)
    71369917        return MEMORY_E;
    71379918#endif
    71389919
    7139     int ret = wc_ecc_export_x963(key, pub, &pubSz);
     9920    ret = wc_ecc_export_x963(key, pub, &pubSz);
    71409921    if (ret != 0) {
    71419922#ifdef WOLFSSL_SMALL_STACK
    7142         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9923        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71439924#endif
    71449925        return ret;
     
    71489929    if (with_header) {
    71499930#ifdef WOLFSSL_SMALL_STACK
    7150         curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9931        curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71519932        if (curve == NULL) {
    7152             XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9933            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71539934            return MEMORY_E;
    71549935        }
     
    71579938        if (curveSz <= 0) {
    71589939#ifdef WOLFSSL_SMALL_STACK
    7159             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7160             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9940            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9941            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71619942#endif
    71629943            return curveSz;
     
    71649945
    71659946#ifdef WOLFSSL_SMALL_STACK
    7166         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9947        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71679948        if (algo == NULL) {
    7168             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7169             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9949            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9950            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71709951            return MEMORY_E;
    71719952        }
     
    71959976#ifdef WOLFSSL_SMALL_STACK
    71969977    if (with_header) {
    7197         XFREE(algo,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7198         XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7199     }
    7200     XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9978        XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9979        XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9980    }
     9981    XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    72019982#endif
    72029983
     
    724110022    return SetEccPublicKey(output, key, with_AlgCurve);
    724210023}
    7243 #endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
     10024#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
    724410025
    724510026#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \
     
    727110052    if (ret != 0) {
    727210053#ifdef WOLFSSL_SMALL_STACK
    7273         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     10054        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    727410055#endif
    727510056        return ret;
     
    728110062        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    728210063        if (algo == NULL) {
    7283             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     10064            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    728410065            return MEMORY_E;
    728510066        }
     
    735110132#ifdef WOLFSSL_CERT_GEN
    735210133
    7353 static INLINE byte itob(int number)
     10134static WC_INLINE byte itob(int number)
    735410135{
    735510136    return (byte)number + 0x30;
     
    740610187
    740710188
    7408 /* for systems where mktime() doesn't normalize fully */
    7409 static void RebuildTime(time_t* in, struct tm* out)
    7410 {
    7411     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    7412         out = localtime_r(in, out);
    7413     #else
    7414         (void)in;
    7415         (void)out;
    7416     #endif
    7417 }
    7418 
    7419 
    742010189/* Set Date validity from now until now + daysValid
    742110190 * return size in bytes written to output, 0 on error */
     
    742910198    int seqSz;
    743010199
    7431     time_t     ticks;
    7432     time_t     normalTime;
    7433     struct tm* now;
     10200    time_t now;
     10201    time_t then;
    743410202    struct tm* tmpTime = NULL;
    7435     struct tm  local;
     10203    struct tm* expandedTime;
     10204    struct tm localTime;
    743610205
    743710206#if defined(NEED_TMP_TIME)
     
    744310212#endif
    744410213
    7445     ticks = XTIME(0);
    7446     now   = XGMTIME(&ticks, tmpTime);
    7447 
    7448     if (now == NULL) {
     10214    now = XTIME(0);
     10215
     10216    /* before now */
     10217    before[0] = ASN_GENERALIZED_TIME;
     10218    beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
     10219
     10220    /* subtract 1 day of seconds for more compliance */
     10221    then = now - 86400;
     10222    expandedTime = XGMTIME(&then, tmpTime);
     10223    if (expandedTime == NULL) {
    744910224        WOLFSSL_MSG("XGMTIME failed");
    745010225        return 0;   /* error */
    745110226    }
    7452 
    7453     /* before now */
    7454     local = *now;
    7455     before[0] = ASN_GENERALIZED_TIME;
    7456     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
    7457 
    7458     /* subtract 1 day for more compliance */
    7459     local.tm_mday -= 1;
    7460     normalTime = mktime(&local);
    7461     RebuildTime(&normalTime, &local);
     10227    localTime = *expandedTime;
    746210228
    746310229    /* adjust */
    7464     local.tm_year += 1900;
    7465     local.tm_mon +=    1;
    7466 
    7467     SetTime(&local, before + beforeSz);
     10230    localTime.tm_year += 1900;
     10231    localTime.tm_mon +=    1;
     10232
     10233    SetTime(&localTime, before + beforeSz);
    746810234    beforeSz += ASN_GEN_TIME_SZ;
    746910235
    7470     /* after now + daysValid */
    7471     local = *now;
    747210236    after[0] = ASN_GENERALIZED_TIME;
    747310237    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
    747410238
    7475     /* add daysValid */
    7476     local.tm_mday += daysValid;
    7477     normalTime = mktime(&local);
    7478     RebuildTime(&normalTime, &local);
     10239    /* add daysValid of seconds */
     10240    then = now + (daysValid * 86400);
     10241    expandedTime = XGMTIME(&then, tmpTime);
     10242    if (expandedTime == NULL) {
     10243        WOLFSSL_MSG("XGMTIME failed");
     10244        return 0;   /* error */
     10245    }
     10246    localTime = *expandedTime;
    747910247
    748010248    /* adjust */
    7481     local.tm_year += 1900;
    7482     local.tm_mon  +=    1;
    7483 
    7484     SetTime(&local, after + afterSz);
     10249    localTime.tm_year += 1900;
     10250    localTime.tm_mon  +=    1;
     10251
     10252    SetTime(&localTime, after + afterSz);
    748510253    afterSz += ASN_GEN_TIME_SZ;
    748610254
     
    753010298
    753110299    case 7:
     10300       return name->serialDev;
     10301
     10302#ifdef WOLFSSL_CERT_EXT
     10303    case 8:
     10304       return name->busCat;
     10305
     10306    case 9:
     10307#else
     10308    case 8:
     10309#endif
    753210310       return name->email;
    753310311
     
    756310341       return name->commonNameEnc;
    756410342
     10343    case 7:
     10344       return name->serialDevEnc;
     10345
     10346#ifdef WOLFSSL_CERT_EXT
     10347    case 8:
     10348       return name->busCatEnc;
     10349
     10350    case 9:
     10351#else
     10352    case 8:
     10353#endif
     10354        /* FALL THROUGH */
     10355        /* The last index, email name, does not have encoding type.
     10356           The empty case here is to keep track of it for future reference. */
    756510357    default:
    756610358       return 0;
     
    759510387
    759610388    case 7:
    7597        /* email uses different id type */
    7598        return 0;
     10389       return ASN_SERIAL_NUMBER;
     10390
     10391#ifdef WOLFSSL_CERT_EXT
     10392    case 8:
     10393        return ASN_BUS_CAT;
     10394
     10395    case 9:
     10396#else
     10397    case 8:
     10398#endif
     10399        return ASN_EMAIL_NAME;
    759910400
    760010401    default:
     
    781410615
    781510616/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
    7816 static int SetExtKeyUsage(byte* output, word32 outSz, byte input)
     10617static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
    781710618{
    781810619    int idx = 0, oidListSz = 0, totalSz, ret = 0;
     
    785110652            ret |= SetOjectIdValue(output, outSz, &idx,
    785210653                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
     10654    #ifdef WOLFSSL_EKU_OID
     10655        /* iterate through OID values */
     10656        if (input & EXTKEYUSE_USER) {
     10657            int i, sz;
     10658            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
     10659                sz = cert->extKeyUsageOIDSz[i];
     10660                if (sz > 0) {
     10661                    ret |= SetOjectIdValue(output, outSz, &idx,
     10662                        cert->extKeyUsageOID[i], sz);
     10663                }
     10664            }
     10665        }
     10666    #endif /* WOLFSSL_EKU_OID */
    785310667    }
    785410668    if (ret != 0)
     
    787510689    idx += oidListSz;
    787610690
     10691    (void)cert;
    787710692    return idx;
    787810693}
     
    789410709        return MEMORY_E;
    789510710
    7896     XSTRNCPY(str, in, len);
    7897     str[len] = 0x00;
     10711    XSTRNCPY(str, in, len+1);
    789810712
    789910713    nb_val = 0;
     
    803310847#endif /* WOLFSL_ALT_NAMES */
    803410848
     10849/* Encodes one attribute of the name (issuer/subject)
     10850 *
     10851 * name     structure to hold result of encoding
     10852 * nameStr  value to be encoded
     10853 * nameType type of encoding i.e CTC_UTF8
     10854 * type     id of attribute i.e ASN_COMMON_NAME
     10855 *
     10856 * returns length on success
     10857 */
     10858static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
     10859        byte type)
     10860{
     10861    word32 idx = 0;
     10862
     10863    if (nameStr) {
     10864        /* bottom up */
     10865        byte firstLen[1 + MAX_LENGTH_SZ];
     10866        byte secondLen[MAX_LENGTH_SZ];
     10867        byte sequence[MAX_SEQ_SZ];
     10868        byte set[MAX_SET_SZ];
     10869
     10870        int strLen  = (int)XSTRLEN(nameStr);
     10871        int thisLen = strLen;
     10872        int firstSz, secondSz, seqSz, setSz;
     10873
     10874        if (strLen == 0) { /* no user data for this item */
     10875            name->used = 0;
     10876            return 0;
     10877        }
     10878
     10879        /* Restrict country code size */
     10880        if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
     10881            return ASN_COUNTRY_SIZE_E;
     10882        }
     10883
     10884        secondSz = SetLength(strLen, secondLen);
     10885        thisLen += secondSz;
     10886        switch (type) {
     10887            case ASN_EMAIL_NAME: /* email */
     10888                thisLen += EMAIL_JOINT_LEN;
     10889                firstSz  = EMAIL_JOINT_LEN;
     10890                break;
     10891
     10892            case ASN_DOMAIN_COMPONENT:
     10893                thisLen += PILOT_JOINT_LEN;
     10894                firstSz  = PILOT_JOINT_LEN;
     10895                break;
     10896
     10897            default:
     10898                thisLen++;                                 /* str type */
     10899                thisLen += JOINT_LEN;
     10900                firstSz  = JOINT_LEN + 1;
     10901        }
     10902        thisLen++; /* id  type */
     10903        firstSz  = SetObjectId(firstSz, firstLen);
     10904        thisLen += firstSz;
     10905
     10906        seqSz = SetSequence(thisLen, sequence);
     10907        thisLen += seqSz;
     10908        setSz = SetSet(thisLen, set);
     10909        thisLen += setSz;
     10910
     10911        if (thisLen > (int)sizeof(name->encoded)) {
     10912            return BUFFER_E;
     10913        }
     10914
     10915        /* store it */
     10916        idx = 0;
     10917        /* set */
     10918        XMEMCPY(name->encoded, set, setSz);
     10919        idx += setSz;
     10920        /* seq */
     10921        XMEMCPY(name->encoded + idx, sequence, seqSz);
     10922        idx += seqSz;
     10923        /* asn object id */
     10924        XMEMCPY(name->encoded + idx, firstLen, firstSz);
     10925        idx += firstSz;
     10926        switch (type) {
     10927            case ASN_EMAIL_NAME:
     10928                {
     10929                    const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
     10930                                       0x01, 0x09, 0x01, 0x16 };
     10931                    /* email joint id */
     10932                    XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
     10933                    idx += (int)sizeof(EMAIL_OID);
     10934                }
     10935                break;
     10936
     10937            case ASN_DOMAIN_COMPONENT:
     10938                {
     10939                    const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
     10940                                    0x93, 0xF2, 0x2C, 0x64, 0x01
     10941                    };
     10942
     10943                    XMEMCPY(name->encoded + idx, PILOT_OID,
     10944                                                     sizeof(PILOT_OID));
     10945                    idx += (int)sizeof(PILOT_OID);
     10946                    /* id type */
     10947                    name->encoded[idx++] = type;
     10948                    /* str type */
     10949                    name->encoded[idx++] = nameType;
     10950                }
     10951                break;
     10952
     10953            default:
     10954                name->encoded[idx++] = 0x55;
     10955                name->encoded[idx++] = 0x04;
     10956                /* id type */
     10957                name->encoded[idx++] = type;
     10958                /* str type */
     10959                name->encoded[idx++] = nameType;
     10960        }
     10961        /* second length */
     10962        XMEMCPY(name->encoded + idx, secondLen, secondSz);
     10963        idx += secondSz;
     10964        /* str value */
     10965        XMEMCPY(name->encoded + idx, nameStr, strLen);
     10966        idx += strLen;
     10967
     10968        name->type = type;
     10969        name->totalLen = idx;
     10970        name->used = 1;
     10971    }
     10972    else
     10973        name->used = 0;
     10974
     10975    return idx;
     10976}
    803510977
    803610978/* encode CertName into output, return total bytes written */
     
    804310985    EncodedName  names[NAME_ENTRIES];
    804410986#endif
     10987#ifdef WOLFSSL_MULTI_ATTRIB
     10988    EncodedName addNames[CTC_MAX_ATTRIB];
     10989    int j, type;
     10990#endif
    804510991
    804610992    if (output == NULL || name == NULL)
     
    805811004
    805911005    for (i = 0; i < NAME_ENTRIES; i++) {
     11006        int ret;
    806011007        const char* nameStr = GetOneName(name, i);
    8061         if (nameStr) {
    8062             /* bottom up */
    8063             byte firstLen[1 + MAX_LENGTH_SZ];
    8064             byte secondLen[MAX_LENGTH_SZ];
    8065             byte sequence[MAX_SEQ_SZ];
    8066             byte set[MAX_SET_SZ];
    8067 
    8068             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
    8069             int strLen  = (int)XSTRLEN(nameStr);
    8070             int thisLen = strLen;
    8071             int firstSz, secondSz, seqSz, setSz;
    8072 
    8073             if (strLen == 0) { /* no user data for this item */
    8074                 names[i].used = 0;
    8075                 continue;
    8076             }
    8077 
    8078             /* Restrict country code size */
    8079             if (i == 0 && strLen != CTC_COUNTRY_SIZE) {
     11008
     11009        ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
     11010                          GetNameId(i));
     11011        if (ret < 0) {
    808011012#ifdef WOLFSSL_SMALL_STACK
    808111013                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    808211014#endif
    8083                 return ASN_COUNTRY_SIZE_E;
    8084             }
    8085 
    8086             secondSz = SetLength(strLen, secondLen);
    8087             thisLen += secondSz;
    8088             if (email) {
    8089                 thisLen += EMAIL_JOINT_LEN;
    8090                 thisLen ++;                               /* id type */
    8091                 firstSz  = SetObjectId(EMAIL_JOINT_LEN, firstLen);
    8092             }
    8093             else {
    8094                 thisLen++;                                 /* str type */
    8095                 thisLen++;                                 /* id  type */
    8096                 thisLen += JOINT_LEN;
    8097                 firstSz  = SetObjectId(JOINT_LEN + 1, firstLen);
    8098             }
    8099             thisLen += firstSz;
    8100 
    8101             seqSz = SetSequence(thisLen, sequence);
    8102             thisLen += seqSz;
    8103             setSz = SetSet(thisLen, set);
    8104             thisLen += setSz;
    8105 
    8106             if (thisLen > (int)sizeof(names[i].encoded)) {
     11015                return BUFFER_E;
     11016            }
     11017        totalBytes += ret;
     11018            }
     11019#ifdef WOLFSSL_MULTI_ATTRIB
     11020    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
     11021        if (name->name[i].sz > 0) {
     11022            int ret;
     11023            ret = wc_EncodeName(&addNames[i], name->name[i].value,
     11024                        name->name[i].type, name->name[i].id);
     11025            if (ret < 0) {
    810711026#ifdef WOLFSSL_SMALL_STACK
    810811027                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    811011029                return BUFFER_E;
    811111030            }
    8112 
    8113             /* store it */
    8114             idx = 0;
    8115             /* set */
    8116             XMEMCPY(names[i].encoded, set, setSz);
    8117             idx += setSz;
    8118             /* seq */
    8119             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
    8120             idx += seqSz;
    8121             /* asn object id */
    8122             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
    8123             idx += firstSz;
    8124             if (email) {
    8125                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
    8126                                            0x01, 0x09, 0x01, 0x16 };
    8127                 /* email joint id */
    8128                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
    8129                 idx += (int)sizeof(EMAIL_OID);
     11031            totalBytes += ret;
    813011032            }
    813111033            else {
    8132                 /* joint id */
    8133                 byte bType = GetNameId(i);
    8134                 names[i].encoded[idx++] = 0x55;
    8135                 names[i].encoded[idx++] = 0x04;
    8136                 /* id type */
    8137                 names[i].encoded[idx++] = bType;
    8138                 /* str type */
    8139                 names[i].encoded[idx++] = GetNameType(name, i);
    8140             }
    8141             /* second length */
    8142             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
    8143             idx += secondSz;
    8144             /* str value */
    8145             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
    8146             idx += strLen;
    8147 
    8148             totalBytes += idx;
    8149             names[i].totalLen = idx;
    8150             names[i].used = 1;
    8151         }
    8152         else
    8153             names[i].used = 0;
    8154     }
     11034            addNames[i].used = 0;
     11035        }
     11036    }
     11037#endif /* WOLFSSL_MULTI_ATTRIB */
    815511038
    815611039    /* header */
     
    816511048
    816611049    for (i = 0; i < NAME_ENTRIES; i++) {
     11050    #ifdef WOLFSSL_MULTI_ATTRIB
     11051        type = GetNameId(i);
     11052
     11053        /* list all DC values before OUs */
     11054        if (type == ASN_ORGUNIT_NAME) {
     11055            type = ASN_DOMAIN_COMPONENT;
     11056            for (j = 0; j < CTC_MAX_ATTRIB; j++) {
     11057                if (name->name[j].sz > 0 && type == name->name[j].id) {
     11058                    if (outputSz < (word32)(idx+addNames[j].totalLen)) {
     11059                    #ifdef WOLFSSL_SMALL_STACK
     11060                        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11061                    #endif
     11062                        return BUFFER_E;
     11063                    }
     11064
     11065                    XMEMCPY(output + idx, addNames[j].encoded,
     11066                            addNames[j].totalLen);
     11067                    idx += addNames[j].totalLen;
     11068                }
     11069            }
     11070            type = ASN_ORGUNIT_NAME;
     11071        }
     11072
     11073        /* write all similar types to the buffer */
     11074        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
     11075            if (name->name[j].sz > 0 && type == name->name[j].id) {
     11076                if (outputSz < (word32)(idx+addNames[j].totalLen)) {
     11077                #ifdef WOLFSSL_SMALL_STACK
     11078                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11079                #endif
     11080                    return BUFFER_E;
     11081                }
     11082
     11083                XMEMCPY(output + idx, addNames[j].encoded,
     11084                        addNames[j].totalLen);
     11085                idx += addNames[j].totalLen;
     11086            }
     11087        }
     11088    #endif /* WOLFSSL_MULTI_ATTRIB */
     11089
    816711090        if (names[i].used) {
    816811091            if (outputSz < (word32)(idx+names[i].totalLen)) {
     
    829611219
    829711220    /* subject name */
    8298     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
     11221#ifdef WOLFSSL_CERT_EXT
     11222    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
     11223        /* Use the raw subject */
     11224        int idx;
     11225
     11226        der->subjectSz = min(sizeof(der->subject),
     11227                (word32)XSTRLEN((const char*)cert->sbjRaw));
     11228        /* header */
     11229        idx = SetSequence(der->subjectSz, der->subject);
     11230        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
     11231            return SUBJECT_E;
     11232        }
     11233
     11234        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
     11235                der->subjectSz);
     11236        der->subjectSz += idx;
     11237    }
     11238    else
     11239#endif
     11240    {
     11241        /* Use the name structure */
     11242        der->subjectSz = SetName(der->subject, sizeof(der->subject),
     11243                &cert->subject);
     11244    }
    829911245    if (der->subjectSz <= 0)
    830011246        return SUBJECT_E;
    830111247
    830211248    /* issuer name */
    8303     der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
    8304              &cert->subject : &cert->issuer);
     11249#ifdef WOLFSSL_CERT_EXT
     11250    if (XSTRLEN((const char*)cert->issRaw) > 0) {
     11251        /* Use the raw issuer */
     11252        int idx;
     11253
     11254        der->issuerSz = min(sizeof(der->issuer),
     11255                (word32)XSTRLEN((const char*)cert->issRaw));
     11256        /* header */
     11257        idx = SetSequence(der->issuerSz, der->issuer);
     11258        if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
     11259            return ISSUER_E;
     11260        }
     11261
     11262        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
     11263                der->issuerSz);
     11264        der->issuerSz += idx;
     11265    }
     11266    else
     11267#endif
     11268    {
     11269        /* Use the name structure */
     11270        der->issuerSz = SetName(der->issuer, sizeof(der->issuer),
     11271                cert->selfSigned ? &cert->subject : &cert->issuer);
     11272    }
    830511273    if (der->issuerSz <= 0)
    830611274        return ISSUER_E;
     
    833811306    if (cert->skidSz) {
    833911307        /* check the provided SKID size */
    8340         if (cert->skidSz > (int)sizeof(der->skid))
     11308        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
    834111309            return SKID_E;
    834211310
     
    835611324    if (cert->akidSz) {
    835711325        /* check the provided AKID size */
    8358         if (cert->akidSz > (int)sizeof(der->akid))
     11326        if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
    835911327            return AKID_E;
    836011328
     
    838311351    /* Extended Key Usage */
    838411352    if (cert->extKeyUsage != 0){
    8385         der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
     11353        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
    838611354                                sizeof(der->extKeyUsage), cert->extKeyUsage);
    838711355        if (der->extKeyUsageSz <= 0)
     
    868711655
    868811656#ifdef WOLFSSL_SMALL_STACK
    8689     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11657    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    869011658    if (der == NULL)
    869111659        return MEMORY_E;
     
    870211670
    870311671#ifdef WOLFSSL_SMALL_STACK
    8704     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11672    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    870511673#endif
    870611674
     
    874111709                  const byte* ntruKey, word16 keySz, WC_RNG* rng)
    874211710{
    8743     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
     11711    return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);
    874411712}
    874511713
     
    888911857    if (cert->skidSz) {
    889011858        /* check the provided SKID size */
    8891         if (cert->skidSz > (int)sizeof(der->skid))
     11859        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
    889211860            return SKID_E;
    889311861
     
    891611884    /* Extended Key Usage */
    891711885    if (cert->extKeyUsage != 0){
    8918         der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
     11886        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
    891911887                                sizeof(der->extKeyUsage), cert->extKeyUsage);
    892011888        if (der->extKeyUsageSz <= 0)
     
    904112009
    904212010#ifdef WOLFSSL_SMALL_STACK
    9043     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12011    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
     12012                                                    DYNAMIC_TYPE_TMP_BUFFER);
    904412013    if (der == NULL)
    904512014        return MEMORY_E;
     
    905612025
    905712026#ifdef WOLFSSL_SMALL_STACK
    9058     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12027    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    905912028#endif
    906012029
     
    914012109    sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,
    914112110        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap);
    9142     if (sigSz == WC_PENDING_E)
     12111    if (sigSz == WC_PENDING_E) {
     12112        /* Not free'ing certSignCtx->sig here because it could still be in use
     12113         * with async operations. */
    914312114        return sigSz;
     12115    }
    914412116
    914512117    if (sigSz >= 0) {
     
    914712119            sigSz = BUFFER_E;
    914812120        else
    9149             sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz, sType);
     12121            sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz,
     12122                                 sType);
    915012123    }
    915112124
     
    919612169
    919712170#ifdef WOLFSSL_CERT_EXT
     12171
     12172/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
     12173   The raw subject pointer will only be valid while "cert" is valid. */
     12174int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
     12175{
     12176    int rc = BAD_FUNC_ARG;
     12177    if ((subjectRaw != NULL) && (cert != NULL)) {
     12178        *subjectRaw = cert->sbjRaw;
     12179        rc = 0;
     12180    }
     12181    return rc;
     12182}
    919812183
    919912184/* Set KID from public key */
     
    925212237
    925312238    /* Compute SKID by hashing public key */
    9254 #ifdef NO_SHA
    925512239    if (kid_type == SKID_TYPE) {
    9256         ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
    9257         cert->skidSz = WC_SHA256_DIGEST_SIZE;
     12240        ret = CalcHashId(buffer, bufferSz, cert->skid);
     12241        cert->skidSz = KEYID_SIZE;
    925812242    }
    925912243    else if (kid_type == AKID_TYPE) {
    9260         ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
    9261         cert->akidSz = WC_SHA256_DIGEST_SIZE;
     12244        ret = CalcHashId(buffer, bufferSz, cert->akid);
     12245        cert->akidSz = KEYID_SIZE;
    926212246    }
    926312247    else
    926412248        ret = BAD_FUNC_ARG;
    9265 #else /* NO_SHA */
    9266     if (kid_type == SKID_TYPE) {
    9267         ret = wc_ShaHash(buffer, bufferSz, cert->skid);
    9268         cert->skidSz = WC_SHA_DIGEST_SIZE;
    9269     }
    9270     else if (kid_type == AKID_TYPE) {
    9271         ret = wc_ShaHash(buffer, bufferSz, cert->akid);
    9272         cert->akidSz = WC_SHA_DIGEST_SIZE;
    9273     }
    9274     else
    9275         ret = BAD_FUNC_ARG;
    9276 #endif /* NO_SHA */
    927712249
    927812250    XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     
    933712309
    933812310
    9339 #ifndef NO_FILESYSTEM
     12311#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
    934012312
    934112313/* Set SKID from public key file in PEM */
     
    935712329    }
    935812330
    9359     derSz = wolfSSL_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
     12331    derSz = wc_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
    936012332    if (derSz <= 0)
    936112333    {
     
    941312385            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
    941412386            wc_ecc_free(eckey);
     12387            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
    941512388            return PUBLIC_KEY_E;
    941612389        }
     
    943612409}
    943712410
    9438 #endif /* NO_FILESYSTEM */
     12411#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
    943912412
    944012413/* Set AKID from certificate contains in buffer (DER encoded) */
     
    945412427#ifdef WOLFSSL_SMALL_STACK
    945512428    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
    9456                                     NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12429                                    cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    945712430    if (decoded == NULL)
    945812431        return MEMORY_E;
     
    946012433
    946112434    /* decode certificate and get SKID that will be AKID of current cert */
    9462     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12435    InitDecodedCert(decoded, der, derSz, NULL);
    946312436    ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
    946412437    if (ret != 0) {
    946512438        FreeDecodedCert(decoded);
    946612439        #ifdef WOLFSSL_SMALL_STACK
    9467             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12440            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    946812441        #endif
    946912442        return ret;
     
    947412447        FreeDecodedCert(decoded);
    947512448        #ifdef WOLFSSL_SMALL_STACK
    9476             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12449            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    947712450        #endif
    947812451        return ASN_NO_SKID;
     
    948312456        FreeDecodedCert(decoded);
    948412457        #ifdef WOLFSSL_SMALL_STACK
    9485             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12458            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    948612459        #endif
    948712460        return MEMORY_E;
     
    949412467    FreeDecodedCert(decoded);
    949512468    #ifdef WOLFSSL_SMALL_STACK
    9496         XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12469        XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    949712470    #endif
    949812471
     
    951912492    }
    952012493
    9521     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
     12494    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
    952212495    if (derSz <= 0)
    952312496    {
     
    953212505}
    953312506
    9534 #endif /* NO_FILESYSTEM */
     12507#endif /* !NO_FILESYSTEM */
    953512508
    953612509/* Set KeyUsage from human readable string */
     
    954612519    cert->keyUsage = 0;
    954712520
    9548     str = (char*)XMALLOC(XSTRLEN(value)+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     12521    len = (word32)XSTRLEN(value);
     12522    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    954912523    if (str == NULL)
    955012524        return MEMORY_E;
    955112525
    9552     XMEMSET(str, 0, XSTRLEN(value)+1);
    9553     XSTRNCPY(str, value, XSTRLEN(value));
     12526    XSTRNCPY(str, value, len+1);
    955412527
    955512528    /* parse value, and set corresponding Key Usage value */
     
    960512578    cert->extKeyUsage = 0;
    960612579
    9607     str = (char*)XMALLOC(XSTRLEN(value)+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     12580    len = (word32)XSTRLEN(value);
     12581    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    960812582    if (str == NULL)
    960912583        return MEMORY_E;
    961012584
    9611     XMEMSET(str, 0, XSTRLEN(value)+1);
    9612     XSTRNCPY(str, value, XSTRLEN(value));
     12585    XSTRNCPY(str, value, len+1);
    961312586
    961412587    /* parse value, and set corresponding Key Usage value */
     
    964712620    return ret;
    964812621}
     12622
     12623#ifdef WOLFSSL_EKU_OID
     12624/*
     12625 * cert structure to set EKU oid in
     12626 * oid  the oid in byte representation
     12627 * sz   size of oid buffer
     12628 * idx  index of array to place oid
     12629 *
     12630 * returns 0 on success
     12631 */
     12632int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
     12633        void* heap)
     12634{
     12635    byte oid[MAX_OID_SZ];
     12636    word32 oidSz = MAX_OID_SZ;
     12637
     12638    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
     12639        WOLFSSL_MSG("Either idx or sz was too large");
     12640        return BAD_FUNC_ARG;
     12641    }
     12642
     12643    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
     12644        return BUFFER_E;
     12645    }
     12646
     12647    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
     12648    cert->extKeyUsageOIDSz[idx] = oidSz;
     12649    cert->extKeyUsage |= EXTKEYUSE_USER;
     12650
     12651    return 0;
     12652}
     12653#endif /* WOLFSSL_EKU_OID */
    964912654#endif /* WOLFSSL_CERT_EXT */
    965012655
     
    966612671
    966712672#ifdef WOLFSSL_SMALL_STACK
    9668     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12673    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
    966912674                                                       DYNAMIC_TYPE_TMP_BUFFER);
    967012675    if (decoded == NULL)
     
    967212677#endif
    967312678
    9674     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12679    InitDecodedCert(decoded, der, derSz, NULL);
    967512680    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    967612681
     
    974012745    FreeDecodedCert(decoded);
    974112746#ifdef WOLFSSL_SMALL_STACK
    9742     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12747    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    974312748#endif
    974412749
     
    976212767
    976312768#ifdef WOLFSSL_SMALL_STACK
    9764     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12769    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
    976512770                                                       DYNAMIC_TYPE_TMP_BUFFER);
    976612771    if (decoded == NULL)
     
    976812773#endif
    976912774
    9770     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12775    InitDecodedCert(decoded, der, derSz, NULL);
    977112776    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    977212777
     
    979412799
    979512800#ifdef WOLFSSL_SMALL_STACK
    9796     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12801    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    979712802#endif
    979812803
     
    982212827#endif
    982312828
    9824     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12829    InitDecodedCert(decoded, der, derSz, NULL);
    982512830    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    982612831
     
    983312838                                                         : CTC_NAME_SIZE - 1;
    983412839            XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
    9835             cn->commonName[sz] = 0;
     12840            cn->commonName[sz] = '\0';
    983612841            cn->commonNameEnc = decoded->subjectCNEnc;
    983712842        }
     
    984012845                                                        : CTC_NAME_SIZE - 1;
    984112846            XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
    9842             cn->country[sz] = 0;
     12847            cn->country[sz] = '\0';
    984312848            cn->countryEnc = decoded->subjectCEnc;
    984412849        }
     
    984712852                                                         : CTC_NAME_SIZE - 1;
    984812853            XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
    9849             cn->state[sz] = 0;
     12854            cn->state[sz] = '\0';
    985012855            cn->stateEnc = decoded->subjectSTEnc;
    985112856        }
     
    985412859                                                        : CTC_NAME_SIZE - 1;
    985512860            XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
    9856             cn->locality[sz] = 0;
     12861            cn->locality[sz] = '\0';
    985712862            cn->localityEnc = decoded->subjectLEnc;
    985812863        }
     
    986112866                                                        : CTC_NAME_SIZE - 1;
    986212867            XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
    9863             cn->org[sz] = 0;
     12868            cn->org[sz] = '\0';
    986412869            cn->orgEnc = decoded->subjectOEnc;
    986512870        }
     
    986812873                                                         : CTC_NAME_SIZE - 1;
    986912874            XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
    9870             cn->unit[sz] = 0;
     12875            cn->unit[sz] = '\0';
    987112876            cn->unitEnc = decoded->subjectOUEnc;
    987212877        }
     
    987512880                                                         : CTC_NAME_SIZE - 1;
    987612881            XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
    9877             cn->sur[sz] = 0;
     12882            cn->sur[sz] = '\0';
    987812883            cn->surEnc = decoded->subjectSNEnc;
    987912884        }
     12885        if (decoded->subjectSND) {
     12886            sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
     12887                                                         : CTC_NAME_SIZE - 1;
     12888            XSTRNCPY(cn->serialDev, decoded->subjectSND, CTC_NAME_SIZE);
     12889            cn->serialDev[sz] = '\0';
     12890            cn->serialDevEnc = decoded->subjectSNDEnc;
     12891        }
     12892    #ifdef WOLFSSL_CERT_EXT
     12893        if (decoded->subjectBC) {
     12894            sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
     12895                                                         : CTC_NAME_SIZE - 1;
     12896            XSTRNCPY(cn->busCat, decoded->subjectBC, CTC_NAME_SIZE);
     12897            cn->busCat[sz] = '\0';
     12898            cn->busCatEnc = decoded->subjectBCEnc;
     12899        }
     12900        if (decoded->subjectJC) {
     12901            sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
     12902                                                         : CTC_NAME_SIZE - 1;
     12903            XSTRNCPY(cn->joiC, decoded->subjectJC, CTC_NAME_SIZE);
     12904            cn->joiC[sz] = '\0';
     12905            cn->joiCEnc = decoded->subjectJCEnc;
     12906        }
     12907        if (decoded->subjectJS) {
     12908            sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
     12909                                                         : CTC_NAME_SIZE - 1;
     12910            XSTRNCPY(cn->joiSt, decoded->subjectJS, CTC_NAME_SIZE);
     12911            cn->joiSt[sz] = '\0';
     12912            cn->joiStEnc = decoded->subjectJSEnc;
     12913        }
     12914    #endif
    988012915        if (decoded->subjectEmail) {
    988112916            sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
    988212917               ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
    988312918            XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
    9884             cn->email[sz] = 0;
     12919            cn->email[sz] = '\0';
    988512920        }
    988612921    }
     
    989512930}
    989612931
     12932#ifdef WOLFSSL_CERT_EXT
     12933/* Set raw subject from der buffer, return 0 on success */
     12934static int SetSubjectRawFromCert(byte* sbjRaw, const byte* der, int derSz)
     12935{
     12936    int ret;
     12937#ifdef WOLFSSL_SMALL_STACK
     12938    DecodedCert* decoded;
     12939#else
     12940    DecodedCert decoded[1];
     12941#endif
     12942
     12943    if ((derSz < 0) || (sbjRaw == NULL)) {
     12944        return BAD_FUNC_ARG;
     12945    }
     12946
     12947#ifdef WOLFSSL_SMALL_STACK
     12948    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12949                                                       DYNAMIC_TYPE_TMP_BUFFER);
     12950    if (decoded == NULL) {
     12951        return MEMORY_E;
     12952    }
     12953#endif
     12954
     12955    InitDecodedCert(decoded, der, derSz, NULL);
     12956    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
     12957
     12958    if (ret < 0) {
     12959        WOLFSSL_MSG("ParseCertRelative error");
     12960    }
     12961#ifndef IGNORE_NAME_CONSTRAINT
     12962    else {
     12963        if ((decoded->subjectRaw) &&
     12964            (decoded->subjectRawLen <= (int)sizeof(CertName))) {
     12965            XMEMCPY(sbjRaw, decoded->subjectRaw, decoded->subjectRawLen);
     12966        }
     12967        }
     12968#else
     12969    else {
     12970        /* Fields are not accessible */
     12971        ret = -1;
     12972        WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw subject");
     12973    }
     12974#endif
     12975
     12976    FreeDecodedCert(decoded);
     12977
     12978#ifdef WOLFSSL_SMALL_STACK
     12979    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12980#endif
     12981
     12982    return ret < 0 ? ret : 0;
     12983}
     12984
     12985/* Set raw issuer from der buffer, return 0 on success */
     12986static int SetIssuerRawFromCert(byte* issuerRaw, const byte* der, int derSz)
     12987{
     12988    int ret;
     12989#ifdef WOLFSSL_SMALL_STACK
     12990    DecodedCert* decoded;
     12991#else
     12992    DecodedCert decoded[1];
     12993#endif
     12994
     12995    if ((derSz < 0) || (issuerRaw == NULL)) {
     12996        return BAD_FUNC_ARG;
     12997    }
     12998
     12999#ifdef WOLFSSL_SMALL_STACK
     13000    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     13001                                                       DYNAMIC_TYPE_TMP_BUFFER);
     13002    if (decoded == NULL) {
     13003        return MEMORY_E;
     13004    }
     13005#endif
     13006
     13007    InitDecodedCert(decoded, der, derSz, NULL);
     13008    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
     13009
     13010    if (ret < 0) {
     13011        WOLFSSL_MSG("ParseCertRelative error");
     13012    }
     13013#ifndef IGNORE_NAME_CONSTRAINT
     13014    else {
     13015        if ((decoded->issuerRaw) &&
     13016            (decoded->issuerRawLen <= (int)sizeof(CertName))) {
     13017            XMEMCPY(issuerRaw, decoded->issuerRaw, decoded->issuerRawLen);
     13018        }
     13019    }
     13020#else
     13021    else {
     13022        /* Fields are not accessible */
     13023        ret = -1;
     13024        WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw issuer");
     13025    }
     13026#endif
     13027
     13028    FreeDecodedCert(decoded);
     13029
     13030#ifdef WOLFSSL_SMALL_STACK
     13031    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13032#endif
     13033
     13034    return ret < 0 ? ret : 0;
     13035}
     13036#endif /* WOLFSSL_CERT_EXT */
    989713037
    989813038#ifndef NO_FILESYSTEM
     
    990313043    int         ret;
    990413044    int         derSz;
    9905     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9906 
     13045    byte*       der;
     13046
     13047    if (cert == NULL) {
     13048        return BAD_FUNC_ARG;
     13049    }
     13050
     13051    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    990713052    if (der == NULL) {
    990813053        WOLFSSL_MSG("wc_SetIssuer OOF Problem");
    990913054        return MEMORY_E;
    991013055    }
    9911     derSz = wolfSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
     13056    derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);
    991213057    cert->selfSigned = 0;
    991313058    ret = SetNameFromCert(&cert->issuer, der, derSz);
     
    992313068    int         ret;
    992413069    int         derSz;
    9925     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9926 
     13070    byte*       der;
     13071
     13072    if (cert == NULL) {
     13073        return BAD_FUNC_ARG;
     13074    }
     13075
     13076    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    992713077    if (der == NULL) {
    992813078        WOLFSSL_MSG("wc_SetSubject OOF Problem");
    992913079        return MEMORY_E;
    993013080    }
    9931     derSz = wolfSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
     13081
     13082    derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);
    993213083    ret = SetNameFromCert(&cert->subject, der, derSz);
    993313084    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
     
    993613087}
    993713088
    9938 
    993913089#ifdef WOLFSSL_ALT_NAMES
    994013090
    9941 /* Set atl names from file in PEM */
     13091/* Set alt names from file in PEM */
    994213092int wc_SetAltNames(Cert* cert, const char* file)
    994313093{
    994413094    int         ret;
    994513095    int         derSz;
    9946     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9947 
     13096    byte*       der;
     13097
     13098    if (cert == NULL) {
     13099        return BAD_FUNC_ARG;
     13100    }
     13101
     13102    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    994813103    if (der == NULL) {
    994913104        WOLFSSL_MSG("wc_SetAltNames OOF Problem");
    995013105        return MEMORY_E;
    995113106    }
    9952     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
     13107    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
    995313108    ret = SetAltNamesFromCert(cert, der, derSz);
    995413109    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
     
    995913114#endif /* WOLFSSL_ALT_NAMES */
    996013115
    9961 #endif /* NO_FILESYSTEM */
     13116#endif /* !NO_FILESYSTEM */
    996213117
    996313118/* Set cert issuer from DER buffer */
    996413119int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
    996513120{
     13121    if (cert == NULL) {
     13122        return BAD_FUNC_ARG;
     13123    }
     13124
    996613125    cert->selfSigned = 0;
    996713126    return SetNameFromCert(&cert->issuer, der, derSz);
    996813127}
    996913128
    9970 
    997113129/* Set cert subject from DER buffer */
    997213130int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
    997313131{
     13132    if (cert == NULL) {
     13133        return BAD_FUNC_ARG;
     13134    }
     13135
    997413136    return SetNameFromCert(&cert->subject, der, derSz);
    997513137}
    9976 
     13138#ifdef WOLFSSL_CERT_EXT
     13139/* Set cert raw subject from DER buffer */
     13140int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
     13141{
     13142    int ret;
     13143
     13144    if (cert == NULL) {
     13145        ret = BAD_FUNC_ARG;
     13146    }
     13147    else {
     13148        ret = SetSubjectRawFromCert(cert->sbjRaw, der, derSz);
     13149    }
     13150    return ret;
     13151}
     13152
     13153/* Set cert raw issuer from DER buffer */
     13154int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
     13155{
     13156    int ret;
     13157
     13158    if (cert == NULL) {
     13159        ret = BAD_FUNC_ARG;
     13160    }
     13161    else {
     13162        ret = SetIssuerRawFromCert(cert->issRaw, der, derSz);
     13163    }
     13164    return ret;
     13165}
     13166#endif
    997713167
    997813168#ifdef WOLFSSL_ALT_NAMES
     
    1008813278        return ASN_PARSE_E;
    1008913279
     13280    if (*inOutIdx >= inSz)
     13281        return ASN_PARSE_E;
     13282
    1009013283    b = input[*inOutIdx];
    1009113284    *inOutIdx += 1;
     
    1010213295
    1010313296#ifdef WOLFSSL_SMALL_STACK
    10104     priv = (byte*)XMALLOC(ECC_MAXSIZE+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13297    priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1010513298    if (priv == NULL)
    1010613299        return MEMORY_E;
    1010713300
    10108     pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13301    pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1010913302    if (pub == NULL) {
    10110         XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13303        XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1011113304        return MEMORY_E;
    1011213305    }
     
    1017513368
    1017613369#ifdef WOLFSSL_SMALL_STACK
    10177     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    10178     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13370    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13371    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1017913372#endif
    1018013373
     
    1018213375}
    1018313376
     13377
     13378#ifdef WOLFSSL_CUSTOM_CURVES
     13379static void ByteToHex(byte n, char* str)
     13380{
     13381    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
     13382                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
     13383
     13384    str[0] = hexChar[n >> 4];
     13385    str[1] = hexChar[n & 0xf];
     13386}
     13387
     13388/* returns 0 on success */
     13389static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
     13390                          word32 inSz, void* heap, int heapType)
     13391{
     13392    int len;
     13393    int i;
     13394    char* str;
     13395
     13396    if (*inOutIdx >= inSz) {
     13397        return BUFFER_E;
     13398    }
     13399
     13400    if (input[*inOutIdx] == ASN_INTEGER) {
     13401        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
     13402            return ASN_PARSE_E;
     13403    }
     13404    else {
     13405        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
     13406            return ASN_PARSE_E;
     13407    }
     13408
     13409    str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
     13410    for (i=0; i<len; i++)
     13411        ByteToHex(input[*inOutIdx + i], str + i*2);
     13412    str[len*2] = '\0';
     13413
     13414    *inOutIdx += len;
     13415    *out = str;
     13416
     13417    return 0;
     13418}
     13419#endif /* WOLFSSL_CUSTOM_CURVES */
    1018413420
    1018513421int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
     
    1018813424    int    length;
    1018913425    int    ret;
    10190 #ifdef ECC_CHECK_PUBLIC_KEY_OID
     13426    int    curve_id = ECC_CURVE_DEF;
    1019113427    word32 oidSum;
    10192 #endif
    1019313428
    1019413429    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
     
    1020513440        return ret;
    1020613441
     13442    if (*inOutIdx >= inSz) {
     13443        return BUFFER_E;
     13444    }
     13445
     13446    if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
     13447#ifdef WOLFSSL_CUSTOM_CURVES
     13448        ecc_set_type* curve;
     13449        int len;
     13450        char* point;
     13451
     13452        ret = 0;
     13453
     13454        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
     13455                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13456        if (curve == NULL)
     13457            ret = MEMORY_E;
     13458
     13459        if (ret == 0) {
     13460            XMEMSET(curve, 0, sizeof(*curve));
     13461            curve->name = "Custom";
     13462            curve->id = ECC_CURVE_CUSTOM;
     13463
     13464            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13465                ret = ASN_PARSE_E;
     13466        }
     13467
     13468        if (ret == 0) {
     13469            GetInteger7Bit(input, inOutIdx, inSz);
     13470            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13471                ret = ASN_PARSE_E;
     13472        }
     13473        if (ret == 0) {
     13474            SkipObjectId(input, inOutIdx, inSz);
     13475            ret = ASNToHexString(input, inOutIdx, (char**)&curve->prime, inSz,
     13476                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13477        }
     13478        if (ret == 0) {
     13479            curve->size = (int)XSTRLEN(curve->prime) / 2;
     13480
     13481            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13482                ret = ASN_PARSE_E;
     13483        }
     13484        if (ret == 0) {
     13485            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Af, inSz,
     13486                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13487        }
     13488        if (ret == 0) {
     13489            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Bf, inSz,
     13490                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13491        }
     13492        if (ret == 0) {
     13493            if (*inOutIdx < inSz && input[*inOutIdx] == ASN_BIT_STRING) {
     13494                len = 0;
     13495                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
     13496                *inOutIdx += len;
     13497            }
     13498        }
     13499        if (ret == 0) {
     13500            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
     13501                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13502
     13503            /* sanity check that point buffer is not smaller than the expected
     13504             * size to hold ( 0 4 || Gx || Gy )
     13505             * where Gx and Gy are each the size of curve->size * 2 */
     13506            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
     13507                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13508                ret = BUFFER_E;
     13509            }
     13510        }
     13511        if (ret == 0) {
     13512            curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
     13513                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13514            curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
     13515                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13516            if (curve->Gx == NULL || curve->Gy == NULL) {
     13517                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13518                ret = MEMORY_E;
     13519            }
     13520        }
     13521        if (ret == 0) {
     13522            XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
     13523            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
     13524                                                               curve->size * 2);
     13525            ((char*)curve->Gx)[curve->size * 2] = '\0';
     13526            ((char*)curve->Gy)[curve->size * 2] = '\0';
     13527            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13528            ret = ASNToHexString(input, inOutIdx, (char**)&curve->order, inSz,
     13529                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13530        }
     13531        if (ret == 0) {
     13532            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
     13533
     13534            curve->oid = NULL;
     13535            curve->oidSz = 0;
     13536            curve->oidSum = 0;
     13537
     13538            if (wc_ecc_set_custom_curve(key, curve) < 0) {
     13539                ret = ASN_PARSE_E;
     13540            }
     13541            key->deallocSet = 1;
     13542            curve = NULL;
     13543        }
     13544        if (curve != NULL)
     13545            wc_ecc_free_curve(curve, key->heap);
     13546
     13547        if (ret < 0)
     13548            return ret;
     13549#else
     13550        return ASN_PARSE_E;
     13551#endif /* WOLFSSL_CUSTOM_CURVES */
     13552    }
     13553    else {
    1020713554    /* ecc params information */
    10208 #ifdef ECC_CHECK_PUBLIC_KEY_OID
    1020913555    ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
    1021013556    if (ret != 0)
    1021113557        return ret;
    10212     if (CheckCurve(oidSum) < 0)
     13558
     13559        /* get curve id */
     13560        curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
     13561        if (curve_id < 0)
    1021313562        return ECC_CURVE_OID_E;
    10214 #else
    10215     ret = SkipObjectId(input, inOutIdx, inSz);
     13563    }
     13564
     13565    /* key header */
     13566    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
    1021613567    if (ret != 0)
    1021713568        return ret;
    10218 #endif
    10219 
    10220     /* key header */
    10221     ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
    10222     if (ret != 0)
    10223         return ret;
    1022413569
    1022513570    /* This is the raw point data compressed or uncompressed. */
    10226     if (wc_ecc_import_x963(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
     13571    if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key,
     13572                                                            curve_id) != 0) {
    1022713573        return ASN_ECC_KEY_E;
     13574}
     13575
     13576    *inOutIdx += length;
    1022813577
    1022913578    return 0;
    1023013579}
    1023113580
    10232 
    10233 #ifdef WOLFSSL_KEY_GEN
    10234 
     13581#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    1023513582/* build DER formatted ECC key, include optional public key if requested,
    1023613583 * return length on success, negative on error */
     
    1035013697}
    1035113698
    10352 
    1035313699/* Write a Private ecc key, including public to DER format,
    1035413700 * length on success else < 0 */
     
    1036613712}
    1036713713
    10368 #endif /* WOLFSSL_KEY_GEN */
    10369 
     13714/* Write only private ecc key to unencrypted PKCS#8 format.
     13715 *
     13716 * If output is NULL, places required PKCS#8 buffer size in outLen and
     13717 * returns LENGTH_ONLY_E.
     13718 *
     13719 * return length on success else < 0 */
     13720int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
     13721{
     13722    int ret, tmpDerSz;
     13723    int algoID = 0;
     13724    word32 oidSz = 0;
     13725    word32 pkcs8Sz = 0;
     13726    const byte* curveOID = NULL;
     13727    byte* tmpDer = NULL;
     13728
     13729    if (key == NULL || outLen == NULL)
     13730        return BAD_FUNC_ARG;
     13731
     13732    /* set algoID, get curve OID */
     13733    algoID = ECDSAk;
     13734    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
     13735    if (ret < 0)
     13736        return ret;
     13737
     13738    /* temp buffer for plain DER key */
     13739    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13740    if (tmpDer == NULL)
     13741        return MEMORY_E;
     13742
     13743    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
     13744
     13745    tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
     13746    if (tmpDerSz < 0) {
     13747        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13748        return tmpDerSz;
     13749    }
     13750
     13751    /* get pkcs8 expected output size */
     13752    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
     13753                            curveOID, oidSz);
     13754    if (ret != LENGTH_ONLY_E) {
     13755        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13756        return ret;
     13757    }
     13758
     13759    if (output == NULL) {
     13760        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13761        *outLen = pkcs8Sz;
     13762        return LENGTH_ONLY_E;
     13763
     13764    } else if (*outLen < pkcs8Sz) {
     13765        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13766        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
     13767        return BUFFER_E;
     13768    }
     13769
     13770    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
     13771                            algoID, curveOID, oidSz);
     13772    if (ret < 0) {
     13773        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13774        return ret;
     13775    }
     13776
     13777    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13778
     13779    *outLen = ret;
     13780    return ret;
     13781}
     13782
     13783#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
    1037013784#endif  /* HAVE_ECC */
    1037113785
     
    1038413798        return BAD_FUNC_ARG;
    1038513799
    10386     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
    10387         return ASN_PARSE_E;
     13800    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
    1038813801    endKeyIdx = *inOutIdx + length;
    1038913802
     
    1040513818    if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
    1040613819        return ASN_PARSE_E;
     13820
     13821        priv = input + *inOutIdx;
     13822        *inOutIdx += privSz;
     13823    }
     13824    else {
     13825        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
     13826            return ASN_PARSE_E;
     13827
    1040713828    priv = input + *inOutIdx;
    1040813829    *inOutIdx += privSz;
     13830        endKeyIdx = *inOutIdx;
     13831    }
    1040913832
    1041013833    if (endKeyIdx == (int)*inOutIdx) {
     
    1043513858    int    length;
    1043613859    int    ret;
    10437 #ifdef ECC_CHECK_PUBLIC_KEY_OID
    10438     word32 oidSum;
    10439 #endif
    1044013860
    1044113861    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
     
    1054813968                        byte* format, int maxIdx)
    1054913969{
    10550     int    length;
     13970    int    ret, length;
     13971    const byte *datePtr = NULL;
    1055113972
    1055213973    WOLFSSL_ENTER("GetBasicDate");
    1055313974
    10554     *format = source[*idx];
    10555     *idx += 1;
    10556     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
    10557         return ASN_TIME_E;
    10558 
    10559     if (GetLength(source, idx, &length, maxIdx) < 0)
    10560         return ASN_PARSE_E;
    10561 
    10562     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
    10563         return ASN_DATE_SZ_E;
    10564 
    10565     XMEMCPY(date, &source[*idx], length);
    10566     *idx += length;
     13975    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
     13976    if (ret < 0)
     13977        return ret;
     13978
     13979    XMEMCPY(date, datePtr, length);
    1056713980
    1056813981    return 0;
    1056913982}
    1057013983
    10571 #endif
     13984#endif /* HAVE_OCSP || HAVE_CRL */
    1057213985
    1057313986
     
    1066714080    }
    1066814081
    10669 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     14082#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    1067014083    cs->thisDateAsn = source + idx;
    1067114084#endif
     
    1068814101        if (GetLength(source, &idx, &length, size) < 0)
    1068914102            return ASN_PARSE_E;
    10690 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     14103#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    1069114104        cs->nextDateAsn = source + idx;
    1069214105#endif
     
    1093714350            else {
    1093814351                WOLFSSL_MSG("\tOCSP Responder key usage check failed");
    10939 
     14352    #ifdef OPENSSL_EXTRA
     14353                resp->verifyError = OCSP_BAD_ISSUER;
     14354    #else
    1094014355                FreeDecodedCert(&cert);
    1094114356                return BAD_OCSP_RESPONDER;
     14357    #endif
    1094214358            }
    1094314359        }
     
    1120714623
    1120814624        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
    11209             req->url = (byte*)XMALLOC(cert->extAuthInfoSz, req->heap,
     14625            req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,
    1121014626                                                     DYNAMIC_TYPE_OCSP_REQUEST);
    1121114627            if (req->url == NULL) {
     
    1121614632            XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
    1121714633            req->urlSz = cert->extAuthInfoSz;
     14634            req->url[req->urlSz] = 0;
    1121814635        }
    1121914636    }
     
    1124914666        if (req->serial)
    1125014667            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
     14668        req->serial = NULL;
    1125114669
    1125214670        if (req->url)
    1125314671            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
     14672        req->url = NULL;
    1125414673    }
    1125514674}
     
    1132314742}
    1132414743
    11325 #endif
     14744#endif /* HAVE_OCSP */
    1132614745
    1132714746
     
    1135314772        return ASN_PARSE_E;
    1135414773
    11355 #ifdef NO_SHA
    11356     ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
    11357 #else
    11358     ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
    11359 #endif
     14774    ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
    1136014775
    1136114776    *idx += length;
     
    1140414819                      int maxIdx)
    1140514820{
    11406     int    len;
     14821    int    ret, len;
    1140714822    word32 end;
    1140814823    byte   b;
     
    1143414849    dcrl->totalCerts++;
    1143514850
    11436 
    1143714851    /* get date */
    11438     b = buff[*idx];
    11439     *idx += 1;
    11440 
    11441     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
     14852    ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
     14853    if (ret < 0) {
    1144214854        WOLFSSL_MSG("Expecting Date");
    11443         return ASN_PARSE_E;
    11444     }
    11445 
    11446     if (GetLength(buff, idx, &len, maxIdx) < 0)
    11447         return ASN_PARSE_E;
    11448 
    11449     /* skip for now */
    11450     *idx += len;
     14855        return ret;
     14856    }
    1145114857
    1145214858    if (*idx != end)  /* skip extensions */
     
    1161015016#endif /* HAVE_CRL */
    1161115017
     15018
     15019
     15020#ifdef WOLFSSL_CERT_PIV
     15021
     15022int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
     15023{
     15024    int length = 0;
     15025    word32 idx = 0;
     15026
     15027    WOLFSSL_ENTER("wc_ParseCertPIV");
     15028
     15029    if (piv == NULL || buf == NULL || totalSz == 0)
     15030        return BAD_FUNC_ARG;
     15031
     15032    XMEMSET(piv, 0, sizeof(wc_CertPIV));
     15033
     15034    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
     15035    /* Certificate (0A 82 05FA) */
     15036    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
     15037        /* Identiv Type PIV card */
     15038        piv->isIdentiv = 1;
     15039
     15040        piv->cert =   &buf[idx];
     15041        piv->certSz = length;
     15042        idx += length;
     15043
     15044        /* Nonce (0B 14) */
     15045        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
     15046            piv->nonce =   &buf[idx];
     15047            piv->nonceSz = length;
     15048            idx += length;
     15049        }
     15050
     15051        /* Signed Nonce (0C 82 0100) */
     15052        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
     15053            piv->signedNonce =   &buf[idx];
     15054            piv->signedNonceSz = length;
     15055            idx += length;
     15056        }
     15057
     15058        idx = 0;
     15059        buf = piv->cert;
     15060        totalSz = piv->certSz;
     15061    }
     15062
     15063    /* Certificate Buffer Total Size (53 82 05F6) */
     15064    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
     15065                                                   &length, totalSz) < 0) {
     15066        return ASN_PARSE_E;
     15067    }
     15068    /* PIV Certificate (70 82 05ED) */
     15069    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
     15070                                                         totalSz) < 0) {
     15071        return ASN_PARSE_E;
     15072    }
     15073
     15074    /* Capture certificate buffer pointer and length */
     15075    piv->cert =   &buf[idx];
     15076    piv->certSz = length;
     15077    idx += length;
     15078
     15079    /* PIV Certificate Info (71 01 00) */
     15080    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
     15081                                                        totalSz) >= 0) {
     15082        if (length >= 1) {
     15083            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
     15084            piv->isX509 =      (buf[idx] & ASN_PIV_CERT_INFO_ISX509);
     15085        }
     15086        idx += length;
     15087    }
     15088
     15089    /* PIV Error Detection (FE 00) */
     15090    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
     15091                                                        totalSz) >= 0) {
     15092        piv->certErrDet =   &buf[idx];
     15093        piv->certErrDetSz = length;
     15094        idx += length;
     15095    }
     15096
     15097    return 0;
     15098}
     15099
     15100#endif /* WOLFSSL_CERT_PIV */
     15101
     15102
    1161215103#undef ERROR_OUT
    1161315104
Note: See TracChangeset for help on using the changeset viewer.