]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/asn.c
e3d9ff44bd3c934c12cf28c3f6ed628c278110df
[freertos] / FreeRTOS-Plus / Source / WolfSSL / wolfcrypt / src / asn.c
1 /* asn.c
2  *
3  * Copyright (C) 2006-2015 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL. (formerly known as CyaSSL)
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27
28 #ifndef NO_ASN
29
30 #ifdef HAVE_RTP_SYS
31     #include "os.h"           /* dc_rtc_api needs    */
32     #include "dc_rtc_api.h"   /* to get current time */
33 #endif
34
35 #include <wolfssl/wolfcrypt/asn.h>
36 #include <wolfssl/wolfcrypt/coding.h>
37 #include <wolfssl/wolfcrypt/md2.h>
38 #include <wolfssl/wolfcrypt/hmac.h>
39 #include <wolfssl/wolfcrypt/error-crypt.h>
40 #include <wolfssl/wolfcrypt/pwdbased.h>
41 #include <wolfssl/wolfcrypt/des3.h>
42 #include <wolfssl/wolfcrypt/logging.h>
43
44 #include <wolfssl/wolfcrypt/random.h>
45
46
47 #ifndef NO_RC4
48     #include <wolfssl/wolfcrypt/arc4.h>
49 #endif
50
51 #ifdef HAVE_NTRU
52     #include "ntru_crypto.h"
53 #endif
54
55 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
56     #include <wolfssl/wolfcrypt/sha512.h>
57 #endif
58
59 #ifndef NO_SHA256
60     #include <wolfssl/wolfcrypt/sha256.h>
61 #endif
62
63 #ifdef HAVE_ECC
64     #include <wolfssl/wolfcrypt/ecc.h>
65 #endif
66
67 #ifdef WOLFSSL_DEBUG_ENCODING
68     #ifdef FREESCALE_MQX
69         #include <fio.h>
70     #else
71         #include <stdio.h>
72     #endif
73 #endif
74
75 #ifdef _MSC_VER
76     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
77     #pragma warning(disable: 4996)
78 #endif
79
80
81 #ifndef TRUE
82     #define TRUE  1
83 #endif
84 #ifndef FALSE
85     #define FALSE 0
86 #endif
87
88
89 #ifdef HAVE_RTP_SYS
90     /* uses parital <time.h> structures */
91     #define XTIME(tl)  (0)
92     #define XGMTIME(c, t) my_gmtime((c))
93     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
94 #elif defined(MICRIUM)
95     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
96         #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t))
97     #else
98         #define XVALIDATE_DATE(d, f, t) (0)
99     #endif
100     #define NO_TIME_H
101     /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
102 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
103     #include <time.h>
104     #define XTIME(t1) pic32_time((t1))
105     #define XGMTIME(c, t) gmtime((c))
106     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
107 #elif defined(FREESCALE_MQX)
108     #define XTIME(t1)  mqx_time((t1))
109     #define XGMTIME(c, t) mqx_gmtime((c), (t))
110     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
111 #elif defined(WOLFSSL_MDK_ARM)
112     #if defined(WOLFSSL_MDK5)
113         #include "cmsis_os.h"
114     #else
115         #include <rtl.h>
116     #endif
117     #undef RNG
118     #include "wolfssl_MDK_ARM.h"
119     #undef RNG
120     #define RNG wolfSSL_RNG /*for avoiding name conflict in "stm32f2xx.h" */
121     #define XTIME(tl)  (0)
122     #define XGMTIME(c, t) wolfssl_MDK_gmtime((c))
123     #define XVALIDATE_DATE(d, f, t)  ValidateDate((d), (f), (t))
124 #elif defined(USER_TIME)
125     /* user time, and gmtime compatible functions, there is a gmtime 
126        implementation here that WINCE uses, so really just need some ticks
127        since the EPOCH 
128     */
129
130     struct tm {
131     int tm_sec;     /* seconds after the minute [0-60] */
132     int tm_min;     /* minutes after the hour [0-59] */
133     int tm_hour;    /* hours since midnight [0-23] */
134     int tm_mday;    /* day of the month [1-31] */
135     int tm_mon;     /* months since January [0-11] */
136     int tm_year;    /* years since 1900 */
137     int tm_wday;    /* days since Sunday [0-6] */
138     int tm_yday;    /* days since January 1 [0-365] */
139     int tm_isdst;   /* Daylight Savings Time flag */
140     long    tm_gmtoff;  /* offset from CUT in seconds */
141     char    *tm_zone;   /* timezone abbreviation */
142     };
143     typedef long time_t;
144
145     /* forward declaration */
146     struct tm* gmtime(const time_t* timer);
147     extern time_t XTIME(time_t * timer);
148
149     #define XGMTIME(c, t) gmtime((c))
150     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
151
152     #ifdef STACK_TRAP
153         /* for stack trap tracking, don't call os gmtime on OS X/linux,
154            uses a lot of stack spce */
155         extern time_t time(time_t * timer);
156         #define XTIME(tl)  time((tl))
157     #endif /* STACK_TRAP */
158
159 #elif defined(TIME_OVERRIDES)
160     /* user would like to override time() and gmtime() functionality */
161
162     #ifndef HAVE_TIME_T_TYPE
163         typedef long time_t;
164     #endif
165     extern time_t XTIME(time_t * timer);
166
167     #ifndef HAVE_TM_TYPE
168         struct tm {
169             int  tm_sec;     /* seconds after the minute [0-60] */
170             int  tm_min;     /* minutes after the hour [0-59] */
171             int  tm_hour;    /* hours since midnight [0-23] */
172             int  tm_mday;    /* day of the month [1-31] */
173             int  tm_mon;     /* months since January [0-11] */
174             int  tm_year;    /* years since 1900 */
175             int  tm_wday;    /* days since Sunday [0-6] */
176             int  tm_yday;    /* days since January 1 [0-365] */
177             int  tm_isdst;   /* Daylight Savings Time flag */
178             long tm_gmtoff;  /* offset from CUT in seconds */
179             char *tm_zone;   /* timezone abbreviation */
180         };
181     #endif
182     extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
183
184     #ifndef HAVE_VALIDATE_DATE
185         #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
186     #endif
187 #else
188     /* default */
189     /* uses complete <time.h> facility */
190     #include <time.h>
191     #define XTIME(tl)     time((tl))
192     #define XGMTIME(c, t) gmtime((c))
193     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
194 #endif
195
196
197 #ifdef _WIN32_WCE
198 /* no time() or gmtime() even though in time.h header?? */
199
200 #include <windows.h>
201
202
203 time_t time(time_t* timer)
204 {
205     SYSTEMTIME     sysTime;
206     FILETIME       fTime;
207     ULARGE_INTEGER intTime;
208     time_t         localTime;
209
210     if (timer == NULL)
211         timer = &localTime;
212
213     GetSystemTime(&sysTime);
214     SystemTimeToFileTime(&sysTime, &fTime);
215
216     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
217     /* subtract EPOCH */
218     intTime.QuadPart -= 0x19db1ded53e8000;
219     /* to secs */
220     intTime.QuadPart /= 10000000;
221     *timer = (time_t)intTime.QuadPart;
222
223     return *timer;
224 }
225
226 #endif /*  _WIN32_WCE */
227 #if defined( _WIN32_WCE ) || defined( USER_TIME )
228
229 struct tm* gmtime(const time_t* timer)
230 {
231     #define YEAR0          1900
232     #define EPOCH_YEAR     1970
233     #define SECS_DAY       (24L * 60L * 60L)
234     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
235     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
236
237     static const int _ytab[2][12] =
238     {
239         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
240         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
241     };
242
243     static struct tm st_time;
244     struct tm* ret = &st_time;
245     time_t secs = *timer;
246     unsigned long dayclock, dayno;
247     int year = EPOCH_YEAR;
248
249     dayclock = (unsigned long)secs % SECS_DAY;
250     dayno    = (unsigned long)secs / SECS_DAY;
251
252     ret->tm_sec  = (int) dayclock % 60;
253     ret->tm_min  = (int)(dayclock % 3600) / 60;
254     ret->tm_hour = (int) dayclock / 3600;
255     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
256
257     while(dayno >= (unsigned long)YEARSIZE(year)) {
258         dayno -= YEARSIZE(year);
259         year++;
260     }
261
262     ret->tm_year = year - YEAR0;
263     ret->tm_yday = (int)dayno;
264     ret->tm_mon  = 0;
265
266     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
267         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
268         ret->tm_mon++;
269     }
270
271     ret->tm_mday  = (int)++dayno;
272     ret->tm_isdst = 0;
273
274     return ret;
275 }
276
277 #endif /* _WIN32_WCE  || USER_TIME */
278
279
280 #ifdef HAVE_RTP_SYS
281
282 #define YEAR0          1900
283
284 struct tm* my_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
285 {
286     static struct tm st_time;
287     struct tm* ret = &st_time;
288
289     DC_RTC_CALENDAR cal;
290     dc_rtc_time_get(&cal, TRUE);
291
292     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
293     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
294     ret->tm_mday  = cal.day;
295     ret->tm_hour  = cal.hour;
296     ret->tm_min   = cal.minute;
297     ret->tm_sec   = cal.second;
298
299     return ret;
300 }
301
302 #endif /* HAVE_RTP_SYS */
303
304
305 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
306
307 /*
308  * time() is just a stub in Microchip libraries. We need our own
309  * implementation. Use SNTP client to get seconds since epoch.
310  */
311 time_t pic32_time(time_t* timer)
312 {
313 #ifdef MICROCHIP_TCPIP_V5
314     DWORD sec = 0;
315 #else
316     uint32_t sec = 0;
317 #endif
318     time_t localTime;
319
320     if (timer == NULL)
321         timer = &localTime;
322
323 #ifdef MICROCHIP_MPLAB_HARMONY
324     sec = TCPIP_SNTP_UTCSecondsGet();
325 #else
326     sec = SNTPGetUTCSeconds();
327 #endif
328     *timer = (time_t) sec;
329
330     return *timer;
331 }
332
333 #endif /* MICROCHIP_TCPIP */
334
335
336 #ifdef FREESCALE_MQX
337
338 time_t mqx_time(time_t* timer)
339 {
340     time_t localTime;
341     TIME_STRUCT time_s;
342
343     if (timer == NULL)
344         timer = &localTime;
345
346     _time_get(&time_s);
347     *timer = (time_t) time_s.SECONDS;
348
349     return *timer;
350 }
351
352 /* CodeWarrior GCC toolchain only has gmtime_r(), no gmtime() */
353 struct tm* mqx_gmtime(const time_t* clock, struct tm* tmpTime)
354 {
355     return gmtime_r(clock, tmpTime);
356 }
357
358 #endif /* FREESCALE_MQX */
359
360 #ifdef WOLFSSL_TIRTOS
361
362 time_t XTIME(time_t * timer)
363 {
364     time_t sec = 0;
365
366     sec = (time_t) Seconds_get();
367
368     if (timer != NULL)
369         *timer = sec;
370
371     return sec;
372 }
373
374 #endif /* WOLFSSL_TIRTOS */
375
376 static INLINE word32 btoi(byte b)
377 {
378     return b - 0x30;
379 }
380
381
382 /* two byte date/time, add to value */
383 static INLINE void GetTime(int* value, const byte* date, int* idx)
384 {
385     int i = *idx;
386
387     *value += btoi(date[i++]) * 10;
388     *value += btoi(date[i++]);
389
390     *idx = i;
391 }
392
393
394 #if defined(MICRIUM)
395
396 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
397                                          CPU_INT08U dateType)
398 {
399     CPU_BOOLEAN  rtn_code;
400     CPU_INT32S   i;
401     CPU_INT32S   val;    
402     CPU_INT16U   year;
403     CPU_INT08U   month;
404     CPU_INT16U   day;
405     CPU_INT08U   hour;
406     CPU_INT08U   min;
407     CPU_INT08U   sec;
408
409     i    = 0;
410     year = 0u;
411
412     if (format == ASN_UTC_TIME) {
413         if (btoi(date[0]) >= 5)
414             year = 1900;
415         else
416             year = 2000;
417     }
418     else  { /* format == GENERALIZED_TIME */
419         year += btoi(date[i++]) * 1000;
420         year += btoi(date[i++]) * 100;
421     }    
422
423     val = year;
424     GetTime(&val, date, &i);
425     year = (CPU_INT16U)val;
426
427     val = 0;
428     GetTime(&val, date, &i);   
429     month = (CPU_INT08U)val;   
430
431     val = 0;
432     GetTime(&val, date, &i);  
433     day = (CPU_INT16U)val;
434
435     val = 0;
436     GetTime(&val, date, &i);  
437     hour = (CPU_INT08U)val;
438
439     val = 0;
440     GetTime(&val, date, &i);  
441     min = (CPU_INT08U)val;
442
443     val = 0;
444     GetTime(&val, date, &i);  
445     sec = (CPU_INT08U)val;
446
447     return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); 
448 }
449
450 #endif /* MICRIUM */
451
452
453 WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
454                            word32 maxIdx)
455 {
456     int     length = 0;
457     word32  i = *inOutIdx;
458     byte    b;
459
460     *len = 0;    /* default length */
461
462     if ( (i+1) > maxIdx) {   /* for first read */
463         WOLFSSL_MSG("GetLength bad index on input");
464         return BUFFER_E;
465     }
466
467     b = input[i++];
468     if (b >= ASN_LONG_LENGTH) {        
469         word32 bytes = b & 0x7F;
470
471         if ( (i+bytes) > maxIdx) {   /* for reading bytes */
472             WOLFSSL_MSG("GetLength bad long length");
473             return BUFFER_E;
474         }
475
476         while (bytes--) {
477             b = input[i++];
478             length = (length << 8) | b;
479         }
480     }
481     else
482         length = b;
483     
484     if ( (i+length) > maxIdx) {   /* for user of length */
485         WOLFSSL_MSG("GetLength value exceeds buffer length");
486         return BUFFER_E;
487     }
488
489     *inOutIdx = i;
490     if (length > 0)
491         *len = length;
492
493     return length;
494 }
495
496
497 WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
498                            word32 maxIdx)
499 {
500     int    length = -1;
501     word32 idx    = *inOutIdx;
502
503     if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
504             GetLength(input, &idx, &length, maxIdx) < 0)
505         return ASN_PARSE_E;
506
507     *len      = length;
508     *inOutIdx = idx;
509
510     return length;
511 }
512
513
514 WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
515                         word32 maxIdx)
516 {
517     int    length = -1;
518     word32 idx    = *inOutIdx;
519
520     if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
521             GetLength(input, &idx, &length, maxIdx) < 0)
522         return ASN_PARSE_E;
523
524     *len      = length;
525     *inOutIdx = idx;
526
527     return length;
528 }
529
530
531 /* winodws header clash for WinCE using GetVersion */
532 WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
533 {
534     word32 idx = *inOutIdx;
535
536     WOLFSSL_ENTER("GetMyVersion");
537
538     if (input[idx++] != ASN_INTEGER)
539         return ASN_PARSE_E;
540
541     if (input[idx++] != 0x01)
542         return ASN_VERSION_E;
543
544     *version  = input[idx++];
545     *inOutIdx = idx;
546
547     return *version;
548 }
549
550
551 #ifndef NO_PWDBASED
552 /* Get small count integer, 32 bits or less */
553 static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
554 {
555     word32 idx = *inOutIdx;
556     word32 len;
557
558     *number = 0;
559
560     if (input[idx++] != ASN_INTEGER)
561         return ASN_PARSE_E;
562
563     len = input[idx++];
564     if (len > 4)
565         return ASN_PARSE_E;
566
567     while (len--) {
568         *number  = *number << 8 | input[idx++];
569     }
570
571     *inOutIdx = idx;
572
573     return *number;
574 }
575 #endif /* !NO_PWDBASED */
576
577
578 /* May not have one, not an error */
579 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
580 {
581     word32 idx = *inOutIdx;
582
583     WOLFSSL_ENTER("GetExplicitVersion");
584     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
585         *inOutIdx = ++idx;  /* eat header */
586         return GetMyVersion(input, inOutIdx, version);
587     }
588
589     /* go back as is */
590     *version = 0;
591
592     return 0;
593 }
594
595
596 WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
597                   word32 maxIdx)
598 {
599     word32 i = *inOutIdx;
600     byte   b = input[i++];
601     int    length;
602
603     if (b != ASN_INTEGER)
604         return ASN_PARSE_E;
605
606     if (GetLength(input, &i, &length, maxIdx) < 0)
607         return ASN_PARSE_E;
608
609     if ( (b = input[i++]) == 0x00)
610         length--;
611     else
612         i--;
613
614     if (mp_init(mpi) != MP_OKAY)
615         return MP_INIT_E;
616
617     if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
618         mp_clear(mpi);
619         return ASN_GETINT_E;
620     }
621
622     *inOutIdx = i + length;
623     return 0;
624 }
625
626
627 static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
628                      word32 maxIdx)
629 {
630     int    length;
631     word32 i = *inOutIdx;
632     byte   b;
633     *oid = 0;
634     
635     b = input[i++];
636     if (b != ASN_OBJECT_ID) 
637         return ASN_OBJECT_ID_E;
638     
639     if (GetLength(input, &i, &length, maxIdx) < 0)
640         return ASN_PARSE_E;
641     
642     while(length--)
643         *oid += input[i++];
644     /* just sum it up for now */
645     
646     *inOutIdx = i;
647     
648     return 0;
649 }
650
651
652 WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
653                      word32 maxIdx)
654 {
655     int    length;
656     word32 i = *inOutIdx;
657     byte   b;
658     *oid = 0;
659    
660     WOLFSSL_ENTER("GetAlgoId");
661
662     if (GetSequence(input, &i, &length, maxIdx) < 0)
663         return ASN_PARSE_E;
664     
665     b = input[i++];
666     if (b != ASN_OBJECT_ID) 
667         return ASN_OBJECT_ID_E;
668     
669     if (GetLength(input, &i, &length, maxIdx) < 0)
670         return ASN_PARSE_E;
671     
672     while(length--) {
673         /* odd HC08 compiler behavior here when input[i++] */
674         *oid += input[i];
675         i++;
676     }
677     /* just sum it up for now */
678     
679     /* could have NULL tag and 0 terminator, but may not */
680     b = input[i++];
681     
682     if (b == ASN_TAG_NULL) {
683         b = input[i++];
684         if (b != 0)
685             return ASN_EXPECT_0_E;
686     }
687     else
688     /* go back, didn't have it */
689         i--;
690     
691     *inOutIdx = i;
692     
693     return 0;
694 }
695
696 #ifndef NO_RSA
697
698
699 #ifdef HAVE_CAVIUM
700
701 static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input,
702                         word32* inOutIdx, word32 maxIdx, void* heap)
703 {
704     word32 i = *inOutIdx;
705     byte   b = input[i++];
706     int    length;
707
708     if (b != ASN_INTEGER)
709         return ASN_PARSE_E;
710
711     if (GetLength(input, &i, &length, maxIdx) < 0)
712         return ASN_PARSE_E;
713
714     if ( (b = input[i++]) == 0x00)
715         length--;
716     else
717         i--;
718
719     *buffSz = (word16)length;
720     *buff   = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA);
721     if (*buff == NULL)
722         return MEMORY_E;
723
724     XMEMCPY(*buff, input + i, *buffSz);
725
726     *inOutIdx = i + length;
727     return 0;
728 }
729
730 static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
731                                      RsaKey* key, word32 inSz)
732 {
733     int   version, length;
734     void* h = key->heap;
735
736     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
737         return ASN_PARSE_E;
738
739     if (GetMyVersion(input, inOutIdx, &version) < 0)
740         return ASN_PARSE_E;
741
742     key->type = RSA_PRIVATE;
743
744     if (GetCaviumInt(&key->c_n,  &key->c_nSz,   input, inOutIdx, inSz, h) < 0 ||
745         GetCaviumInt(&key->c_e,  &key->c_eSz,   input, inOutIdx, inSz, h) < 0 ||
746         GetCaviumInt(&key->c_d,  &key->c_dSz,   input, inOutIdx, inSz, h) < 0 ||
747         GetCaviumInt(&key->c_p,  &key->c_pSz,   input, inOutIdx, inSz, h) < 0 ||
748         GetCaviumInt(&key->c_q,  &key->c_qSz,   input, inOutIdx, inSz, h) < 0 ||
749         GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 ||
750         GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 ||
751         GetCaviumInt(&key->c_u,  &key->c_uSz,   input, inOutIdx, inSz, h) < 0 )
752             return ASN_RSA_KEY_E;
753
754     return 0;
755 }
756
757
758 #endif /* HAVE_CAVIUM */
759
760 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
761                         word32 inSz)
762 {
763     int    version, length;
764
765 #ifdef HAVE_CAVIUM
766     if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
767         return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz);
768 #endif
769
770     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
771         return ASN_PARSE_E;
772
773     if (GetMyVersion(input, inOutIdx, &version) < 0)
774         return ASN_PARSE_E;
775
776     key->type = RSA_PRIVATE;
777
778     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
779         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
780         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
781         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
782         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
783         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
784         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
785         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
786
787     return 0;
788 }
789
790 #endif /* NO_RSA */
791
792 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
793 int ToTraditional(byte* input, word32 sz)
794 {
795     word32 inOutIdx = 0, oid;
796     int    version, length;
797
798     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
799         return ASN_PARSE_E;
800
801     if (GetMyVersion(input, &inOutIdx, &version) < 0)
802         return ASN_PARSE_E;
803
804     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
805         return ASN_PARSE_E;
806
807     if (input[inOutIdx] == ASN_OBJECT_ID) {
808         /* pkcs8 ecc uses slightly different format */
809         inOutIdx++;  /* past id */
810         if (GetLength(input, &inOutIdx, &length, sz) < 0)
811             return ASN_PARSE_E;
812         inOutIdx += length;  /* over sub id, key input will verify */
813     }
814
815     if (input[inOutIdx++] != ASN_OCTET_STRING)
816         return ASN_PARSE_E;
817
818     if (GetLength(input, &inOutIdx, &length, sz) < 0)
819         return ASN_PARSE_E;
820
821     XMEMMOVE(input, input + inOutIdx, length);
822
823     return length;
824 }
825
826
827 #ifndef NO_PWDBASED
828
829 /* Check To see if PKCS version algo is supported, set id if it is return 0
830    < 0 on error */
831 static int CheckAlgo(int first, int second, int* id, int* version)
832 {
833     *id      = ALGO_ID_E;
834     *version = PKCS5;   /* default */
835
836     if (first == 1) {
837         switch (second) {
838         case 1:
839             *id = PBE_SHA1_RC4_128;
840             *version = PKCS12;
841             return 0;
842         case 3:
843             *id = PBE_SHA1_DES3;
844             *version = PKCS12;
845             return 0;
846         default:
847             return ALGO_ID_E;
848         }
849     }
850
851     if (first != PKCS5)
852         return ASN_INPUT_E;  /* VERSION ERROR */
853
854     if (second == PBES2) {
855         *version = PKCS5v2;
856         return 0;
857     }
858
859     switch (second) {
860     case 3:                   /* see RFC 2898 for ids */
861         *id = PBE_MD5_DES;
862         return 0;
863     case 10:
864         *id = PBE_SHA1_DES;
865         return 0;
866     default:
867         return ALGO_ID_E;
868
869     }
870 }
871
872
873 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
874    < 0 on error */
875 static int CheckAlgoV2(int oid, int* id)
876 {
877     switch (oid) {
878     case 69:
879         *id = PBE_SHA1_DES;
880         return 0;
881     case 652:
882         *id = PBE_SHA1_DES3;
883         return 0;
884     default:
885         return ALGO_ID_E;
886
887     }
888 }
889
890
891 /* Decrypt intput in place from parameters based on id */
892 static int DecryptKey(const char* password, int passwordSz, byte* salt,
893                       int saltSz, int iterations, int id, byte* input,
894                       int length, int version, byte* cbcIv)
895 {
896     int typeH;
897     int derivedLen;
898     int decryptionType;
899     int ret = 0;
900 #ifdef WOLFSSL_SMALL_STACK
901     byte* key;
902 #else
903     byte key[MAX_KEY_SIZE];
904 #endif
905
906     switch (id) {
907         case PBE_MD5_DES:
908             typeH = MD5;
909             derivedLen = 16;           /* may need iv for v1.5 */
910             decryptionType = DES_TYPE;
911             break;
912
913         case PBE_SHA1_DES:
914             typeH = SHA;
915             derivedLen = 16;           /* may need iv for v1.5 */
916             decryptionType = DES_TYPE;
917             break;
918
919         case PBE_SHA1_DES3:
920             typeH = SHA;
921             derivedLen = 32;           /* may need iv for v1.5 */
922             decryptionType = DES3_TYPE;
923             break;
924
925         case PBE_SHA1_RC4_128:
926             typeH = SHA;
927             derivedLen = 16;
928             decryptionType = RC4_TYPE;
929             break;
930
931         default:
932             return ALGO_ID_E;
933     }
934
935 #ifdef WOLFSSL_SMALL_STACK
936     key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
937     if (key == NULL)
938         return MEMORY_E;
939 #endif
940
941     if (version == PKCS5v2)
942         ret = wc_PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations,
943                derivedLen, typeH);
944 #ifndef NO_SHA
945     else if (version == PKCS5)
946         ret = wc_PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
947                derivedLen, typeH);
948 #endif
949     else if (version == PKCS12) {
950         int  i, idx = 0;
951         byte unicodePasswd[MAX_UNICODE_SZ];
952
953         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
954 #ifdef WOLFSSL_SMALL_STACK
955             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
956 #endif
957             return UNICODE_SIZE_E; 
958         }
959
960         for (i = 0; i < passwordSz; i++) {
961             unicodePasswd[idx++] = 0x00;
962             unicodePasswd[idx++] = (byte)password[i];
963         }
964         /* add trailing NULL */
965         unicodePasswd[idx++] = 0x00;
966         unicodePasswd[idx++] = 0x00;
967
968         ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
969                             iterations, derivedLen, typeH, 1);
970         if (decryptionType != RC4_TYPE)
971             ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
972                                 iterations, 8, typeH, 2);
973     }
974     else {
975 #ifdef WOLFSSL_SMALL_STACK
976         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
977 #endif
978         return ALGO_ID_E;
979     }
980
981     if (ret != 0) {
982 #ifdef WOLFSSL_SMALL_STACK
983         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
984 #endif
985         return ret;
986     }
987
988     switch (decryptionType) {
989 #ifndef NO_DES3
990         case DES_TYPE:
991         {
992             Des    dec;
993             byte*  desIv = key + 8;
994
995             if (version == PKCS5v2 || version == PKCS12)
996                 desIv = cbcIv;
997
998             ret = wc_Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
999             if (ret != 0) {
1000 #ifdef WOLFSSL_SMALL_STACK
1001                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1002 #endif
1003                 return ret;
1004             }
1005
1006             wc_Des_CbcDecrypt(&dec, input, input, length);
1007             break;
1008         }
1009
1010         case DES3_TYPE:
1011         {
1012             Des3   dec;
1013             byte*  desIv = key + 24;
1014
1015             if (version == PKCS5v2 || version == PKCS12)
1016                 desIv = cbcIv;
1017             ret = wc_Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
1018             if (ret != 0) {
1019 #ifdef WOLFSSL_SMALL_STACK
1020                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1021 #endif
1022                 return ret;
1023             }
1024             ret = wc_Des3_CbcDecrypt(&dec, input, input, length);
1025             if (ret != 0) {
1026 #ifdef WOLFSSL_SMALL_STACK
1027                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1028 #endif
1029                 return ret;
1030             }
1031             break;
1032         }
1033 #endif
1034 #ifndef NO_RC4
1035         case RC4_TYPE:
1036         {
1037             Arc4    dec;
1038
1039             wc_Arc4SetKey(&dec, key, derivedLen);
1040             wc_Arc4Process(&dec, input, input, length);
1041             break;
1042         }
1043 #endif
1044
1045         default:
1046 #ifdef WOLFSSL_SMALL_STACK
1047             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1048 #endif
1049             return ALGO_ID_E; 
1050     }
1051
1052 #ifdef WOLFSSL_SMALL_STACK
1053     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1054 #endif
1055
1056     return 0;
1057 }
1058
1059
1060 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
1061    of input */
1062 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
1063 {
1064     word32 inOutIdx = 0, oid;
1065     int    first, second, length, version, saltSz, id;
1066     int    iterations = 0;
1067 #ifdef WOLFSSL_SMALL_STACK
1068     byte*  salt = NULL;
1069     byte*  cbcIv = NULL;
1070 #else
1071     byte   salt[MAX_SALT_SIZE];
1072     byte   cbcIv[MAX_IV_SIZE];
1073 #endif
1074     
1075     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
1076         return ASN_PARSE_E;
1077
1078     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
1079         return ASN_PARSE_E;
1080     
1081     first  = input[inOutIdx - 2];   /* PKCS version alwyas 2nd to last byte */
1082     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
1083
1084     if (CheckAlgo(first, second, &id, &version) < 0)
1085         return ASN_INPUT_E;  /* Algo ID error */
1086
1087     if (version == PKCS5v2) {
1088
1089         if (GetSequence(input, &inOutIdx, &length, sz) < 0)
1090             return ASN_PARSE_E;
1091
1092         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
1093             return ASN_PARSE_E;
1094
1095         if (oid != PBKDF2_OID)
1096             return ASN_PARSE_E;
1097     }
1098
1099     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
1100         return ASN_PARSE_E;
1101
1102     if (input[inOutIdx++] != ASN_OCTET_STRING)
1103         return ASN_PARSE_E;
1104     
1105     if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
1106         return ASN_PARSE_E;
1107
1108     if (saltSz > MAX_SALT_SIZE)
1109         return ASN_PARSE_E;
1110      
1111 #ifdef WOLFSSL_SMALL_STACK
1112     salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1113     if (salt == NULL)
1114         return MEMORY_E;
1115 #endif
1116
1117     XMEMCPY(salt, &input[inOutIdx], saltSz);
1118     inOutIdx += saltSz;
1119
1120     if (GetShortInt(input, &inOutIdx, &iterations) < 0) {
1121 #ifdef WOLFSSL_SMALL_STACK
1122         XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1123 #endif
1124         return ASN_PARSE_E;
1125     }
1126
1127 #ifdef WOLFSSL_SMALL_STACK
1128     cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1129     if (cbcIv == NULL) {
1130         XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1131         return MEMORY_E;
1132     }
1133 #endif
1134
1135     if (version == PKCS5v2) {
1136         /* get encryption algo */
1137         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) {
1138 #ifdef WOLFSSL_SMALL_STACK
1139             XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1140             XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1141 #endif
1142             return ASN_PARSE_E;
1143         }
1144
1145         if (CheckAlgoV2(oid, &id) < 0) {
1146 #ifdef WOLFSSL_SMALL_STACK
1147             XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1148             XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1149 #endif
1150             return ASN_PARSE_E;  /* PKCS v2 algo id error */
1151         }
1152
1153         if (input[inOutIdx++] != ASN_OCTET_STRING) {
1154 #ifdef WOLFSSL_SMALL_STACK
1155             XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1156             XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1157 #endif
1158             return ASN_PARSE_E;
1159         }
1160     
1161         if (GetLength(input, &inOutIdx, &length, sz) < 0) {
1162 #ifdef WOLFSSL_SMALL_STACK
1163             XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1164             XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1165 #endif
1166             return ASN_PARSE_E;
1167         }
1168
1169         XMEMCPY(cbcIv, &input[inOutIdx], length);
1170         inOutIdx += length;
1171     }
1172
1173     if (input[inOutIdx++] != ASN_OCTET_STRING) {
1174 #ifdef WOLFSSL_SMALL_STACK
1175         XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1176         XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1177 #endif
1178         return ASN_PARSE_E;
1179     }
1180
1181     if (GetLength(input, &inOutIdx, &length, sz) < 0) {
1182 #ifdef WOLFSSL_SMALL_STACK
1183         XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1184         XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1185 #endif
1186         return ASN_PARSE_E;
1187     }
1188
1189     if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
1190                    input + inOutIdx, length, version, cbcIv) < 0) {
1191 #ifdef WOLFSSL_SMALL_STACK
1192         XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1193         XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1194 #endif
1195         return ASN_INPUT_E;  /* decrypt failure */
1196     }
1197
1198 #ifdef WOLFSSL_SMALL_STACK
1199     XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
1200     XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1201 #endif
1202
1203     XMEMMOVE(input, input + inOutIdx, length);
1204     return ToTraditional(input, length);
1205 }
1206
1207 #endif /* NO_PWDBASED */
1208
1209 #ifndef NO_RSA
1210
1211 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
1212                        word32 inSz)
1213 {
1214     int    length;
1215
1216     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1217         return ASN_PARSE_E;
1218
1219     key->type = RSA_PUBLIC;
1220
1221 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
1222     {
1223     byte b = input[*inOutIdx];
1224     if (b != ASN_INTEGER) {
1225         /* not from decoded cert, will have algo id, skip past */
1226         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1227             return ASN_PARSE_E;
1228         
1229         b = input[(*inOutIdx)++];
1230         if (b != ASN_OBJECT_ID) 
1231             return ASN_OBJECT_ID_E;
1232         
1233         if (GetLength(input, inOutIdx, &length, inSz) < 0)
1234             return ASN_PARSE_E;
1235         
1236         *inOutIdx += length;   /* skip past */
1237         
1238         /* could have NULL tag and 0 terminator, but may not */
1239         b = input[(*inOutIdx)++];
1240         
1241         if (b == ASN_TAG_NULL) {
1242             b = input[(*inOutIdx)++];
1243             if (b != 0) 
1244                 return ASN_EXPECT_0_E;
1245         }
1246         else
1247         /* go back, didn't have it */
1248             (*inOutIdx)--;
1249         
1250         /* should have bit tag length and seq next */
1251         b = input[(*inOutIdx)++];
1252         if (b != ASN_BIT_STRING)
1253             return ASN_BITSTR_E;
1254         
1255         if (GetLength(input, inOutIdx, &length, inSz) < 0)
1256             return ASN_PARSE_E;
1257         
1258         /* could have 0 */
1259         b = input[(*inOutIdx)++];
1260         if (b != 0)
1261             (*inOutIdx)--;
1262         
1263         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1264             return ASN_PARSE_E;
1265     }  /* end if */
1266     }  /* openssl var block */
1267 #endif /* OPENSSL_EXTRA */
1268
1269     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
1270         GetInt(&key->e,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
1271
1272     return 0;
1273 }
1274
1275 /* import RSA public key elements (n, e) into RsaKey structure (key) */
1276 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
1277                              word32 eSz, RsaKey* key)
1278 {
1279     if (n == NULL || e == NULL || key == NULL)
1280         return BAD_FUNC_ARG;
1281
1282     key->type = RSA_PUBLIC;
1283
1284     if (mp_init(&key->n) != MP_OKAY)
1285         return MP_INIT_E;
1286
1287     if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
1288         mp_clear(&key->n);
1289         return ASN_GETINT_E;
1290     }
1291
1292     if (mp_init(&key->e) != MP_OKAY) {
1293         mp_clear(&key->n);
1294         return MP_INIT_E;
1295     }
1296
1297     if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
1298         mp_clear(&key->n);
1299         mp_clear(&key->e);
1300         return ASN_GETINT_E;
1301     }
1302
1303     return 0;
1304 }
1305
1306 #endif
1307
1308 #ifndef NO_DH
1309
1310 int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
1311 {
1312     int    length;
1313
1314     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1315         return ASN_PARSE_E;
1316
1317     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1318         GetInt(&key->g,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
1319
1320     return 0;
1321 }
1322
1323
1324 int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
1325                  byte* g, word32* gInOutSz)
1326 {
1327     word32 i = 0;
1328     byte   b;
1329     int    length;
1330
1331     if (GetSequence(input, &i, &length, inSz) < 0)
1332         return ASN_PARSE_E;
1333
1334     b = input[i++];
1335     if (b != ASN_INTEGER)
1336         return ASN_PARSE_E;
1337
1338     if (GetLength(input, &i, &length, inSz) < 0)
1339         return ASN_PARSE_E;
1340
1341     if ( (b = input[i++]) == 0x00)
1342         length--;
1343     else
1344         i--;
1345
1346     if (length <= (int)*pInOutSz) {
1347         XMEMCPY(p, &input[i], length);
1348         *pInOutSz = length;
1349     }
1350     else
1351         return BUFFER_E;
1352
1353     i += length;
1354
1355     b = input[i++];
1356     if (b != ASN_INTEGER)
1357         return ASN_PARSE_E;
1358
1359     if (GetLength(input, &i, &length, inSz) < 0)
1360         return ASN_PARSE_E;
1361
1362     if (length <= (int)*gInOutSz) {
1363         XMEMCPY(g, &input[i], length);
1364         *gInOutSz = length;
1365     }
1366     else
1367         return BUFFER_E;
1368
1369     return 0;
1370 }
1371
1372 #endif /* NO_DH */
1373
1374
1375 #ifndef NO_DSA
1376
1377 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1378                         word32 inSz)
1379 {
1380     int    length;
1381
1382     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1383         return ASN_PARSE_E;
1384
1385     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1386         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1387         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
1388         GetInt(&key->y,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
1389
1390     key->type = DSA_PUBLIC;
1391     return 0;
1392 }
1393
1394
1395 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1396                         word32 inSz)
1397 {
1398     int    length, version;
1399
1400     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1401         return ASN_PARSE_E;
1402
1403     if (GetMyVersion(input, inOutIdx, &version) < 0)
1404         return ASN_PARSE_E;
1405
1406     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1407         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1408         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
1409         GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
1410         GetInt(&key->x,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
1411
1412     key->type = DSA_PRIVATE;
1413     return 0;
1414 }
1415
1416 #endif /* NO_DSA */
1417
1418
1419 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
1420 {
1421     cert->publicKey       = 0;
1422     cert->pubKeySize      = 0;
1423     cert->pubKeyStored    = 0;
1424     cert->version         = 0;
1425     cert->signature       = 0;
1426     cert->subjectCN       = 0;
1427     cert->subjectCNLen    = 0;
1428     cert->subjectCNEnc    = CTC_UTF8;
1429     cert->subjectCNStored = 0;
1430     cert->weOwnAltNames   = 0;
1431     cert->altNames        = NULL;
1432 #ifndef IGNORE_NAME_CONSTRAINTS
1433     cert->altEmailNames   = NULL;
1434     cert->permittedNames  = NULL;
1435     cert->excludedNames   = NULL;
1436 #endif /* IGNORE_NAME_CONSTRAINTS */
1437     cert->issuer[0]       = '\0';
1438     cert->subject[0]      = '\0';
1439     cert->source          = source;  /* don't own */
1440     cert->srcIdx          = 0;
1441     cert->maxIdx          = inSz;    /* can't go over this index */
1442     cert->heap            = heap;
1443     XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
1444     cert->serialSz        = 0;
1445     cert->extensions      = 0;
1446     cert->extensionsSz    = 0;
1447     cert->extensionsIdx   = 0;
1448     cert->extAuthInfo     = NULL;
1449     cert->extAuthInfoSz   = 0;
1450     cert->extCrlInfo      = NULL;
1451     cert->extCrlInfoSz    = 0;
1452     XMEMSET(cert->extSubjKeyId, 0, KEYID_SIZE);
1453     cert->extSubjKeyIdSet = 0;
1454     XMEMSET(cert->extAuthKeyId, 0, KEYID_SIZE);
1455     cert->extAuthKeyIdSet = 0;
1456     cert->extKeyUsageSet  = 0;
1457     cert->extKeyUsage     = 0;
1458     cert->extExtKeyUsageSet = 0;
1459     cert->extExtKeyUsage    = 0;
1460     cert->isCA            = 0;
1461 #ifdef HAVE_PKCS7
1462     cert->issuerRaw       = NULL;
1463     cert->issuerRawLen    = 0;
1464 #endif
1465 #ifdef WOLFSSL_CERT_GEN
1466     cert->subjectSN       = 0;
1467     cert->subjectSNLen    = 0;
1468     cert->subjectSNEnc    = CTC_UTF8;
1469     cert->subjectC        = 0;
1470     cert->subjectCLen     = 0;
1471     cert->subjectCEnc     = CTC_PRINTABLE;
1472     cert->subjectL        = 0;
1473     cert->subjectLLen     = 0;
1474     cert->subjectLEnc     = CTC_UTF8;
1475     cert->subjectST       = 0;
1476     cert->subjectSTLen    = 0;
1477     cert->subjectSTEnc    = CTC_UTF8;
1478     cert->subjectO        = 0;
1479     cert->subjectOLen     = 0;
1480     cert->subjectOEnc     = CTC_UTF8;
1481     cert->subjectOU       = 0;
1482     cert->subjectOULen    = 0;
1483     cert->subjectOUEnc    = CTC_UTF8;
1484     cert->subjectEmail    = 0;
1485     cert->subjectEmailLen = 0;
1486 #endif /* WOLFSSL_CERT_GEN */
1487     cert->beforeDate      = NULL;
1488     cert->beforeDateLen   = 0;
1489     cert->afterDate       = NULL;
1490     cert->afterDateLen    = 0;
1491 #ifdef OPENSSL_EXTRA
1492     XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
1493     XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
1494     cert->extBasicConstSet = 0;
1495     cert->extBasicConstCrit = 0;
1496     cert->extBasicConstPlSet = 0;
1497     cert->pathLength = 0;
1498     cert->extSubjAltNameSet = 0;
1499     cert->extSubjAltNameCrit = 0;
1500     cert->extAuthKeyIdCrit = 0;
1501     cert->extSubjKeyIdCrit = 0;
1502     cert->extKeyUsageCrit = 0;
1503     cert->extExtKeyUsageCrit = 0;
1504     cert->extExtKeyUsageSrc = NULL;
1505     cert->extExtKeyUsageSz = 0;
1506     cert->extExtKeyUsageCount = 0;
1507     cert->extAuthKeyIdSrc = NULL;
1508     cert->extAuthKeyIdSz = 0;
1509     cert->extSubjKeyIdSrc = NULL;
1510     cert->extSubjKeyIdSz = 0;
1511 #endif /* OPENSSL_EXTRA */
1512 #if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS)
1513     cert->extNameConstraintSet = 0;
1514 #endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */
1515 #ifdef HAVE_ECC
1516     cert->pkCurveOID = 0;
1517 #endif /* HAVE_ECC */
1518 #ifdef WOLFSSL_SEP
1519     cert->deviceTypeSz = 0;
1520     cert->deviceType = NULL;
1521     cert->hwTypeSz = 0;
1522     cert->hwType = NULL;
1523     cert->hwSerialNumSz = 0;
1524     cert->hwSerialNum = NULL;
1525     #ifdef OPENSSL_EXTRA
1526         cert->extCertPolicySet = 0;
1527         cert->extCertPolicyCrit = 0;
1528     #endif /* OPENSSL_EXTRA */
1529 #endif /* WOLFSSL_SEP */
1530 }
1531
1532
1533 void FreeAltNames(DNS_entry* altNames, void* heap)
1534 {
1535     (void)heap;
1536
1537     while (altNames) {
1538         DNS_entry* tmp = altNames->next;
1539
1540         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
1541         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
1542         altNames = tmp;
1543     }
1544 }
1545
1546 #ifndef IGNORE_NAME_CONSTRAINTS
1547
1548 void FreeNameSubtrees(Base_entry* names, void* heap)
1549 {
1550     (void)heap;
1551
1552     while (names) {
1553         Base_entry* tmp = names->next;
1554
1555         XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
1556         XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
1557         names = tmp;
1558     }
1559 }
1560
1561 #endif /* IGNORE_NAME_CONSTRAINTS */
1562
1563 void FreeDecodedCert(DecodedCert* cert)
1564 {
1565     if (cert->subjectCNStored == 1)
1566         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
1567     if (cert->pubKeyStored == 1)
1568         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1569     if (cert->weOwnAltNames && cert->altNames)
1570         FreeAltNames(cert->altNames, cert->heap);
1571 #ifndef IGNORE_NAME_CONSTRAINTS
1572     if (cert->altEmailNames)
1573         FreeAltNames(cert->altEmailNames, cert->heap);
1574     if (cert->permittedNames)
1575         FreeNameSubtrees(cert->permittedNames, cert->heap);
1576     if (cert->excludedNames)
1577         FreeNameSubtrees(cert->excludedNames, cert->heap);
1578 #endif /* IGNORE_NAME_CONSTRAINTS */
1579 #ifdef WOLFSSL_SEP
1580     XFREE(cert->deviceType, cert->heap, 0);
1581     XFREE(cert->hwType, cert->heap, 0);
1582     XFREE(cert->hwSerialNum, cert->heap, 0);
1583 #endif /* WOLFSSL_SEP */
1584 #ifdef OPENSSL_EXTRA
1585     if (cert->issuerName.fullName != NULL)
1586         XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509);
1587     if (cert->subjectName.fullName != NULL)
1588         XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509);
1589 #endif /* OPENSSL_EXTRA */
1590 }
1591
1592
1593 static int GetCertHeader(DecodedCert* cert)
1594 {
1595     int ret = 0, len;
1596     byte serialTmp[EXTERNAL_SERIAL_SIZE];
1597 #if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
1598     mp_int* mpi = NULL;
1599 #else
1600     mp_int stack_mpi;
1601     mp_int* mpi = &stack_mpi;
1602 #endif
1603
1604     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1605         return ASN_PARSE_E;
1606
1607     cert->certBegin = cert->srcIdx;
1608
1609     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1610         return ASN_PARSE_E;
1611     cert->sigIndex = len + cert->srcIdx;
1612
1613     if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
1614         return ASN_PARSE_E;
1615
1616 #if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
1617     mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
1618     if (mpi == NULL)
1619         return MEMORY_E;
1620 #endif
1621
1622     if (GetInt(mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) {
1623 #if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
1624         XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1625 #endif
1626         return ASN_PARSE_E;
1627     }
1628
1629     len = mp_unsigned_bin_size(mpi);
1630     if (len < (int)sizeof(serialTmp)) {
1631         if ( (ret = mp_to_unsigned_bin(mpi, serialTmp)) == MP_OKAY) {
1632             XMEMCPY(cert->serial, serialTmp, len);
1633             cert->serialSz = len;
1634         }
1635     }
1636     mp_clear(mpi);
1637
1638 #if defined(WOLFSSL_SMALL_STACK) && defined(USE_FAST_MATH)
1639     XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1640 #endif
1641
1642     return ret;
1643 }
1644
1645 #if !defined(NO_RSA)
1646 /* Store Rsa Key, may save later, Dsa could use in future */
1647 static int StoreRsaKey(DecodedCert* cert)
1648 {
1649     int    length;
1650     word32 recvd = cert->srcIdx;
1651
1652     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1653         return ASN_PARSE_E;
1654    
1655     recvd = cert->srcIdx - recvd;
1656     length += recvd;
1657
1658     while (recvd--)
1659        cert->srcIdx--;
1660
1661     cert->pubKeySize = length;
1662     cert->publicKey = cert->source + cert->srcIdx;
1663     cert->srcIdx += length;
1664
1665     return 0;
1666 }
1667 #endif
1668
1669
1670 #ifdef HAVE_ECC
1671
1672     /* return 0 on sucess if the ECC curve oid sum is supported */
1673     static int CheckCurve(word32 oid)
1674     {
1675         int ret = 0;
1676
1677         switch (oid) {
1678 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
1679             case ECC_160R1:
1680 #endif
1681 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
1682             case ECC_192R1:
1683 #endif
1684 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
1685             case ECC_224R1:
1686 #endif
1687 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
1688             case ECC_256R1:
1689 #endif
1690 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
1691             case ECC_384R1:
1692 #endif
1693 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
1694             case ECC_521R1:
1695 #endif
1696                 break;
1697
1698             default:
1699                 ret = ALGO_ID_E;
1700         }
1701
1702         return ret;
1703     }
1704
1705 #endif /* HAVE_ECC */
1706
1707
1708 static int GetKey(DecodedCert* cert)
1709 {
1710     int length;
1711 #ifdef HAVE_NTRU
1712     int tmpIdx = cert->srcIdx;
1713 #endif
1714
1715     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1716         return ASN_PARSE_E;
1717    
1718     if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
1719         return ASN_PARSE_E;
1720
1721     switch (cert->keyOID) {
1722    #ifndef NO_RSA
1723         case RSAk:
1724         {
1725             byte b = cert->source[cert->srcIdx++];
1726             if (b != ASN_BIT_STRING)
1727                 return ASN_BITSTR_E;
1728
1729             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
1730                 return ASN_PARSE_E;
1731             b = cert->source[cert->srcIdx++];
1732             if (b != 0x00)
1733                 return ASN_EXPECT_0_E;
1734     
1735             return StoreRsaKey(cert);
1736         }
1737
1738     #endif /* NO_RSA */
1739     #ifdef HAVE_NTRU
1740         case NTRUk:
1741         {
1742             const byte* key = &cert->source[tmpIdx];
1743             byte*       next = (byte*)key;
1744             word16      keyLen;
1745             word32      rc;
1746             word32      remaining = cert->maxIdx - cert->srcIdx;
1747 #ifdef WOLFSSL_SMALL_STACK
1748             byte*       keyBlob = NULL;
1749 #else
1750             byte        keyBlob[MAX_NTRU_KEY_SZ];
1751 #endif
1752             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
1753                                 &keyLen, NULL, &next, &remaining);
1754             if (rc != NTRU_OK)
1755                 return ASN_NTRU_KEY_E;
1756             if (keyLen > MAX_NTRU_KEY_SZ)
1757                 return ASN_NTRU_KEY_E;
1758
1759 #ifdef WOLFSSL_SMALL_STACK
1760             keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
1761                                                        DYNAMIC_TYPE_TMP_BUFFER);
1762             if (keyBlob == NULL)
1763                 return MEMORY_E;
1764 #endif
1765
1766             rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
1767                                 &keyLen, keyBlob, &next, &remaining);
1768             if (rc != NTRU_OK) {
1769 #ifdef WOLFSSL_SMALL_STACK
1770                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1771 #endif
1772                 return ASN_NTRU_KEY_E;
1773             }
1774
1775             if ( (next - key) < 0) {
1776 #ifdef WOLFSSL_SMALL_STACK
1777                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1778 #endif
1779                 return ASN_NTRU_KEY_E;
1780             }
1781
1782             cert->srcIdx = tmpIdx + (int)(next - key);
1783
1784             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
1785                                               DYNAMIC_TYPE_PUBLIC_KEY);
1786             if (cert->publicKey == NULL) {
1787 #ifdef WOLFSSL_SMALL_STACK
1788                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1789 #endif
1790                 return MEMORY_E;
1791             }
1792             XMEMCPY(cert->publicKey, keyBlob, keyLen);
1793             cert->pubKeyStored = 1;
1794             cert->pubKeySize   = keyLen;
1795
1796 #ifdef WOLFSSL_SMALL_STACK
1797             XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1798 #endif
1799
1800             return 0;
1801         }
1802     #endif /* HAVE_NTRU */
1803     #ifdef HAVE_ECC
1804         case ECDSAk:
1805         {
1806             int    oidSz = 0;
1807             byte   b = cert->source[cert->srcIdx++];
1808         
1809             if (b != ASN_OBJECT_ID) 
1810                 return ASN_OBJECT_ID_E;
1811
1812             if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0)
1813                 return ASN_PARSE_E;
1814
1815             while(oidSz--)
1816                 cert->pkCurveOID += cert->source[cert->srcIdx++];
1817
1818             if (CheckCurve(cert->pkCurveOID) < 0)
1819                 return ECC_CURVE_OID_E;
1820
1821             /* key header */
1822             b = cert->source[cert->srcIdx++];
1823             if (b != ASN_BIT_STRING)
1824                 return ASN_BITSTR_E;
1825
1826             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
1827                 return ASN_PARSE_E;
1828             b = cert->source[cert->srcIdx++];
1829             if (b != 0x00)
1830                 return ASN_EXPECT_0_E;
1831
1832             /* actual key, use length - 1 since ate preceding 0 */
1833             length -= 1;
1834
1835             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
1836                                               DYNAMIC_TYPE_PUBLIC_KEY);
1837             if (cert->publicKey == NULL)
1838                 return MEMORY_E;
1839             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
1840             cert->pubKeyStored = 1;
1841             cert->pubKeySize   = length;
1842
1843             cert->srcIdx += length;
1844
1845             return 0;
1846         }
1847     #endif /* HAVE_ECC */
1848         default:
1849             return ASN_UNKNOWN_OID_E;
1850     }
1851 }
1852
1853
1854 /* process NAME, either issuer or subject */
1855 static int GetName(DecodedCert* cert, int nameType)
1856 {
1857     int    length;  /* length of all distinguished names */
1858     int    dummy;
1859     int    ret;
1860     char*  full;
1861     byte*  hash;
1862     word32 idx;
1863     #ifdef OPENSSL_EXTRA
1864         DecodedName* dName =
1865                   (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
1866     #endif /* OPENSSL_EXTRA */
1867
1868     WOLFSSL_MSG("Getting Cert Name");
1869
1870     if (nameType == ISSUER) {
1871         full = cert->issuer;
1872         hash = cert->issuerHash;
1873     }
1874     else {
1875         full = cert->subject;
1876         hash = cert->subjectHash;
1877     }
1878
1879     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
1880         WOLFSSL_MSG("Trying optional prefix...");
1881
1882         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1883             return ASN_PARSE_E;
1884
1885         cert->srcIdx += length;
1886         WOLFSSL_MSG("Got optional prefix");
1887     }
1888
1889     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
1890      * calculated over the entire DER encoding of the Name field, including
1891      * the tag and length. */
1892     idx = cert->srcIdx;
1893     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1894         return ASN_PARSE_E;
1895
1896 #ifdef NO_SHA
1897     ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
1898 #else
1899     ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
1900 #endif
1901     if (ret != 0)
1902         return ret;
1903
1904     length += cert->srcIdx;
1905     idx = 0;
1906
1907 #ifdef HAVE_PKCS7
1908     /* store pointer to raw issuer */
1909     if (nameType == ISSUER) {
1910         cert->issuerRaw = &cert->source[cert->srcIdx];
1911         cert->issuerRawLen = length - cert->srcIdx;
1912     }
1913 #endif
1914 #ifndef IGNORE_NAME_CONSTRAINTS
1915     if (nameType == SUBJECT) {
1916         cert->subjectRaw = &cert->source[cert->srcIdx];
1917         cert->subjectRawLen = length - cert->srcIdx;
1918     }
1919 #endif
1920
1921     while (cert->srcIdx < (word32)length) {
1922         byte   b;
1923         byte   joint[2];
1924         byte   tooBig = FALSE;
1925         int    oidSz;
1926
1927         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
1928             WOLFSSL_MSG("Cert name lacks set header, trying sequence");
1929         }
1930
1931         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
1932             return ASN_PARSE_E;
1933
1934         b = cert->source[cert->srcIdx++];
1935         if (b != ASN_OBJECT_ID) 
1936             return ASN_OBJECT_ID_E;
1937
1938         if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
1939             return ASN_PARSE_E;
1940
1941         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
1942
1943         /* v1 name types */
1944         if (joint[0] == 0x55 && joint[1] == 0x04) {
1945             byte   id;
1946             byte   copy = FALSE;
1947             int    strLen;
1948
1949             cert->srcIdx += 2;
1950             id = cert->source[cert->srcIdx++]; 
1951             b  = cert->source[cert->srcIdx++]; /* encoding */
1952
1953             if (GetLength(cert->source, &cert->srcIdx, &strLen,
1954                           cert->maxIdx) < 0)
1955                 return ASN_PARSE_E;
1956
1957             if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
1958                 /* include biggest pre fix header too 4 = "/serialNumber=" */
1959                 WOLFSSL_MSG("ASN Name too big, skipping");
1960                 tooBig = TRUE;
1961             }
1962
1963             if (id == ASN_COMMON_NAME) {
1964                 if (nameType == SUBJECT) {
1965                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
1966                     cert->subjectCNLen = strLen;
1967                     cert->subjectCNEnc = b;
1968                 }
1969
1970                 if (!tooBig) {
1971                     XMEMCPY(&full[idx], "/CN=", 4);
1972                     idx += 4;
1973                     copy = TRUE;
1974                 }
1975                 #ifdef OPENSSL_EXTRA
1976                     dName->cnIdx = cert->srcIdx;
1977                     dName->cnLen = strLen;
1978                 #endif /* OPENSSL_EXTRA */
1979             }
1980             else if (id == ASN_SUR_NAME) {
1981                 if (!tooBig) {
1982                     XMEMCPY(&full[idx], "/SN=", 4);
1983                     idx += 4;
1984                     copy = TRUE;
1985                 }
1986                 #ifdef WOLFSSL_CERT_GEN
1987                     if (nameType == SUBJECT) {
1988                         cert->subjectSN = (char*)&cert->source[cert->srcIdx];
1989                         cert->subjectSNLen = strLen;
1990                         cert->subjectSNEnc = b;
1991                     }
1992                 #endif /* WOLFSSL_CERT_GEN */
1993                 #ifdef OPENSSL_EXTRA
1994                     dName->snIdx = cert->srcIdx;
1995                     dName->snLen = strLen;
1996                 #endif /* OPENSSL_EXTRA */
1997             }
1998             else if (id == ASN_COUNTRY_NAME) {
1999                 if (!tooBig) {
2000                     XMEMCPY(&full[idx], "/C=", 3);
2001                     idx += 3;
2002                     copy = TRUE;
2003                 }
2004                 #ifdef WOLFSSL_CERT_GEN
2005                     if (nameType == SUBJECT) {
2006                         cert->subjectC = (char*)&cert->source[cert->srcIdx];
2007                         cert->subjectCLen = strLen;
2008                         cert->subjectCEnc = b;
2009                     }
2010                 #endif /* WOLFSSL_CERT_GEN */
2011                 #ifdef OPENSSL_EXTRA
2012                     dName->cIdx = cert->srcIdx;
2013                     dName->cLen = strLen;
2014                 #endif /* OPENSSL_EXTRA */
2015             }
2016             else if (id == ASN_LOCALITY_NAME) {
2017                 if (!tooBig) {
2018                     XMEMCPY(&full[idx], "/L=", 3);
2019                     idx += 3;
2020                     copy = TRUE;
2021                 }
2022                 #ifdef WOLFSSL_CERT_GEN
2023                     if (nameType == SUBJECT) {
2024                         cert->subjectL = (char*)&cert->source[cert->srcIdx];
2025                         cert->subjectLLen = strLen;
2026                         cert->subjectLEnc = b;
2027                     }
2028                 #endif /* WOLFSSL_CERT_GEN */
2029                 #ifdef OPENSSL_EXTRA
2030                     dName->lIdx = cert->srcIdx;
2031                     dName->lLen = strLen;
2032                 #endif /* OPENSSL_EXTRA */
2033             }
2034             else if (id == ASN_STATE_NAME) {
2035                 if (!tooBig) {
2036                     XMEMCPY(&full[idx], "/ST=", 4);
2037                     idx += 4;
2038                     copy = TRUE;
2039                 }
2040                 #ifdef WOLFSSL_CERT_GEN
2041                     if (nameType == SUBJECT) {
2042                         cert->subjectST = (char*)&cert->source[cert->srcIdx];
2043                         cert->subjectSTLen = strLen;
2044                         cert->subjectSTEnc = b;
2045                     }
2046                 #endif /* WOLFSSL_CERT_GEN */
2047                 #ifdef OPENSSL_EXTRA
2048                     dName->stIdx = cert->srcIdx;
2049                     dName->stLen = strLen;
2050                 #endif /* OPENSSL_EXTRA */
2051             }
2052             else if (id == ASN_ORG_NAME) {
2053                 if (!tooBig) {
2054                     XMEMCPY(&full[idx], "/O=", 3);
2055                     idx += 3;
2056                     copy = TRUE;
2057                 }
2058                 #ifdef WOLFSSL_CERT_GEN
2059                     if (nameType == SUBJECT) {
2060                         cert->subjectO = (char*)&cert->source[cert->srcIdx];
2061                         cert->subjectOLen = strLen;
2062                         cert->subjectOEnc = b;
2063                     }
2064                 #endif /* WOLFSSL_CERT_GEN */
2065                 #ifdef OPENSSL_EXTRA
2066                     dName->oIdx = cert->srcIdx;
2067                     dName->oLen = strLen;
2068                 #endif /* OPENSSL_EXTRA */
2069             }
2070             else if (id == ASN_ORGUNIT_NAME) {
2071                 if (!tooBig) {
2072                     XMEMCPY(&full[idx], "/OU=", 4);
2073                     idx += 4;
2074                     copy = TRUE;
2075                 }
2076                 #ifdef WOLFSSL_CERT_GEN
2077                     if (nameType == SUBJECT) {
2078                         cert->subjectOU = (char*)&cert->source[cert->srcIdx];
2079                         cert->subjectOULen = strLen;
2080                         cert->subjectOUEnc = b;
2081                     }
2082                 #endif /* WOLFSSL_CERT_GEN */
2083                 #ifdef OPENSSL_EXTRA
2084                     dName->ouIdx = cert->srcIdx;
2085                     dName->ouLen = strLen;
2086                 #endif /* OPENSSL_EXTRA */
2087             }
2088             else if (id == ASN_SERIAL_NUMBER) {
2089                 if (!tooBig) {
2090                    XMEMCPY(&full[idx], "/serialNumber=", 14);
2091                    idx += 14;
2092                    copy = TRUE;
2093                 }
2094                 #ifdef OPENSSL_EXTRA
2095                     dName->snIdx = cert->srcIdx;
2096                     dName->snLen = strLen;
2097                 #endif /* OPENSSL_EXTRA */
2098             }
2099
2100             if (copy && !tooBig) {
2101                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
2102                 idx += strLen;
2103             }
2104
2105             cert->srcIdx += strLen;
2106         }
2107         else {
2108             /* skip */
2109             byte email = FALSE;
2110             byte uid   = FALSE;
2111             int  adv;
2112
2113             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
2114                 email = TRUE;
2115
2116             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
2117                 uid = TRUE;
2118
2119             cert->srcIdx += oidSz + 1;
2120
2121             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
2122                 return ASN_PARSE_E;
2123
2124             if (adv > (int)(ASN_NAME_MAX - idx)) {
2125                 WOLFSSL_MSG("ASN name too big, skipping");
2126                 tooBig = TRUE;
2127             }
2128
2129             if (email) {
2130                 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
2131                     WOLFSSL_MSG("ASN name too big, skipping");
2132                     tooBig = TRUE;
2133                 }
2134                 if (!tooBig) {
2135                     XMEMCPY(&full[idx], "/emailAddress=", 14);
2136                     idx += 14;
2137                 }
2138
2139                 #ifdef WOLFSSL_CERT_GEN
2140                     if (nameType == SUBJECT) {
2141                         cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
2142                         cert->subjectEmailLen = adv;
2143                     }
2144                 #endif /* WOLFSSL_CERT_GEN */
2145                 #ifdef OPENSSL_EXTRA
2146                     dName->emailIdx = cert->srcIdx;
2147                     dName->emailLen = adv;
2148                 #endif /* OPENSSL_EXTRA */
2149                 #ifndef IGNORE_NAME_CONSTRAINTS
2150                     {
2151                         DNS_entry* emailName = NULL;
2152
2153                         emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
2154                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
2155                         if (emailName == NULL) {
2156                             WOLFSSL_MSG("\tOut of Memory");
2157                             return MEMORY_E;
2158                         }
2159                         emailName->name = (char*)XMALLOC(adv + 1,
2160                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
2161                         if (emailName->name == NULL) {
2162                             WOLFSSL_MSG("\tOut of Memory");
2163                             return MEMORY_E;
2164                         }
2165                         XMEMCPY(emailName->name,
2166                                               &cert->source[cert->srcIdx], adv);
2167                         emailName->name[adv] = 0;
2168
2169                         emailName->next = cert->altEmailNames;
2170                         cert->altEmailNames = emailName;
2171                     }
2172                 #endif /* IGNORE_NAME_CONSTRAINTS */
2173                 if (!tooBig) {
2174                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
2175                     idx += adv;
2176                 }
2177             }
2178
2179             if (uid) {
2180                 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
2181                     WOLFSSL_MSG("ASN name too big, skipping");
2182                     tooBig = TRUE;
2183                 }
2184                 if (!tooBig) {
2185                     XMEMCPY(&full[idx], "/UID=", 5);
2186                     idx += 5;
2187
2188                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
2189                     idx += adv;
2190                 }
2191                 #ifdef OPENSSL_EXTRA
2192                     dName->uidIdx = cert->srcIdx;
2193                     dName->uidLen = adv;
2194                 #endif /* OPENSSL_EXTRA */
2195             }
2196
2197             cert->srcIdx += adv;
2198         }
2199     }
2200     full[idx++] = 0;
2201
2202     #ifdef OPENSSL_EXTRA
2203     {
2204         int totalLen = 0;
2205
2206         if (dName->cnLen != 0)
2207             totalLen += dName->cnLen + 4;
2208         if (dName->snLen != 0)
2209             totalLen += dName->snLen + 4;
2210         if (dName->cLen != 0)
2211             totalLen += dName->cLen + 3;
2212         if (dName->lLen != 0)
2213             totalLen += dName->lLen + 3;
2214         if (dName->stLen != 0)
2215             totalLen += dName->stLen + 4;
2216         if (dName->oLen != 0)
2217             totalLen += dName->oLen + 3;
2218         if (dName->ouLen != 0)
2219             totalLen += dName->ouLen + 4;
2220         if (dName->emailLen != 0)
2221             totalLen += dName->emailLen + 14;
2222         if (dName->uidLen != 0)
2223             totalLen += dName->uidLen + 5;
2224         if (dName->serialLen != 0)
2225             totalLen += dName->serialLen + 14;
2226
2227         dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
2228         if (dName->fullName != NULL) {
2229             idx = 0;
2230
2231             if (dName->cnLen != 0) {
2232                 dName->entryCount++;
2233                 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
2234                 idx += 4;
2235                 XMEMCPY(&dName->fullName[idx],
2236                                      &cert->source[dName->cnIdx], dName->cnLen);
2237                 dName->cnIdx = idx;
2238                 idx += dName->cnLen;
2239             }
2240             if (dName->snLen != 0) {
2241                 dName->entryCount++;
2242                 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
2243                 idx += 4;
2244                 XMEMCPY(&dName->fullName[idx],
2245                                      &cert->source[dName->snIdx], dName->snLen);
2246                 dName->snIdx = idx;
2247                 idx += dName->snLen;
2248             }
2249             if (dName->cLen != 0) {
2250                 dName->entryCount++;
2251                 XMEMCPY(&dName->fullName[idx], "/C=", 3);
2252                 idx += 3;
2253                 XMEMCPY(&dName->fullName[idx],
2254                                        &cert->source[dName->cIdx], dName->cLen);
2255                 dName->cIdx = idx;
2256                 idx += dName->cLen;
2257             }
2258             if (dName->lLen != 0) {
2259                 dName->entryCount++;
2260                 XMEMCPY(&dName->fullName[idx], "/L=", 3);
2261                 idx += 3;
2262                 XMEMCPY(&dName->fullName[idx],
2263                                        &cert->source[dName->lIdx], dName->lLen);
2264                 dName->lIdx = idx;
2265                 idx += dName->lLen;
2266             }
2267             if (dName->stLen != 0) {
2268                 dName->entryCount++;
2269                 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
2270                 idx += 4;
2271                 XMEMCPY(&dName->fullName[idx],
2272                                      &cert->source[dName->stIdx], dName->stLen);
2273                 dName->stIdx = idx;
2274                 idx += dName->stLen;
2275             }
2276             if (dName->oLen != 0) {
2277                 dName->entryCount++;
2278                 XMEMCPY(&dName->fullName[idx], "/O=", 3);
2279                 idx += 3;
2280                 XMEMCPY(&dName->fullName[idx],
2281                                        &cert->source[dName->oIdx], dName->oLen);
2282                 dName->oIdx = idx;
2283                 idx += dName->oLen;
2284             }
2285             if (dName->ouLen != 0) {
2286                 dName->entryCount++;
2287                 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
2288                 idx += 4;
2289                 XMEMCPY(&dName->fullName[idx],
2290                                      &cert->source[dName->ouIdx], dName->ouLen);
2291                 dName->ouIdx = idx;
2292                 idx += dName->ouLen;
2293             }
2294             if (dName->emailLen != 0) {
2295                 dName->entryCount++;
2296                 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
2297                 idx += 14;
2298                 XMEMCPY(&dName->fullName[idx],
2299                                &cert->source[dName->emailIdx], dName->emailLen);
2300                 dName->emailIdx = idx;
2301                 idx += dName->emailLen;
2302             }
2303             if (dName->uidLen != 0) {
2304                 dName->entryCount++;
2305                 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
2306                 idx += 5;
2307                 XMEMCPY(&dName->fullName[idx],
2308                                    &cert->source[dName->uidIdx], dName->uidLen);
2309                 dName->uidIdx = idx;
2310                 idx += dName->uidLen;
2311             }
2312             if (dName->serialLen != 0) {
2313                 dName->entryCount++;
2314                 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
2315                 idx += 14;
2316                 XMEMCPY(&dName->fullName[idx],
2317                              &cert->source[dName->serialIdx], dName->serialLen);
2318                 dName->serialIdx = idx;
2319                 idx += dName->serialLen;
2320             }
2321             dName->fullName[idx] = '\0';
2322             dName->fullNameLen = totalLen;
2323         }
2324     }
2325     #endif /* OPENSSL_EXTRA */
2326
2327     return 0;
2328 }
2329
2330
2331 #ifndef NO_TIME_H
2332
2333 /* to the second */
2334 static int DateGreaterThan(const struct tm* a, const struct tm* b)
2335 {
2336     if (a->tm_year > b->tm_year)
2337         return 1;
2338
2339     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
2340         return 1;
2341     
2342     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
2343            a->tm_mday > b->tm_mday)
2344         return 1;
2345
2346     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
2347         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
2348         return 1;
2349
2350     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
2351         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
2352         a->tm_min > b->tm_min)
2353         return 1;
2354
2355     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
2356         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
2357         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
2358         return 1;
2359
2360     return 0; /* false */
2361 }
2362
2363
2364 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
2365 {
2366     return DateGreaterThan(b,a);
2367 }
2368
2369
2370 /* like atoi but only use first byte */
2371 /* Make sure before and after dates are valid */
2372 int ValidateDate(const byte* date, byte format, int dateType)
2373 {
2374     time_t ltime;
2375     struct tm  certTime;
2376     struct tm* localTime;
2377     struct tm* tmpTime = NULL;
2378     int    i = 0;
2379
2380 #if defined(FREESCALE_MQX) || defined(TIME_OVERRIDES)
2381     struct tm tmpTimeStorage;
2382     tmpTime = &tmpTimeStorage;
2383 #else
2384     (void)tmpTime;
2385 #endif
2386
2387     ltime = XTIME(0);
2388     XMEMSET(&certTime, 0, sizeof(certTime));
2389
2390     if (format == ASN_UTC_TIME) {
2391         if (btoi(date[0]) >= 5)
2392             certTime.tm_year = 1900;
2393         else
2394             certTime.tm_year = 2000;
2395     }
2396     else  { /* format == GENERALIZED_TIME */
2397         certTime.tm_year += btoi(date[i++]) * 1000;
2398         certTime.tm_year += btoi(date[i++]) * 100;
2399     }
2400
2401     /* adjust tm_year, tm_mon */
2402     GetTime((int*)&certTime.tm_year, date, &i); certTime.tm_year -= 1900;
2403     GetTime((int*)&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;
2404     GetTime((int*)&certTime.tm_mday, date, &i);
2405     GetTime((int*)&certTime.tm_hour, date, &i);
2406     GetTime((int*)&certTime.tm_min,  date, &i);
2407     GetTime((int*)&certTime.tm_sec,  date, &i);
2408
2409         if (date[i] != 'Z') {     /* only Zulu supported for this profile */
2410         WOLFSSL_MSG("Only Zulu time supported for this profile");
2411         return 0;
2412     }
2413
2414     localTime = XGMTIME(&ltime, tmpTime);
2415
2416     if (dateType == BEFORE) {
2417         if (DateLessThan(localTime, &certTime))
2418             return 0;
2419     }
2420     else
2421         if (DateGreaterThan(localTime, &certTime))
2422             return 0;
2423
2424     return 1;
2425 }
2426
2427 #endif /* NO_TIME_H */
2428
2429
2430 static int GetDate(DecodedCert* cert, int dateType)
2431 {
2432     int    length;
2433     byte   date[MAX_DATE_SIZE];
2434     byte   b;
2435     word32 startIdx = 0;
2436
2437     if (dateType == BEFORE)
2438         cert->beforeDate = &cert->source[cert->srcIdx];
2439     else
2440         cert->afterDate = &cert->source[cert->srcIdx];
2441     startIdx = cert->srcIdx;
2442
2443     b = cert->source[cert->srcIdx++];
2444     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
2445         return ASN_TIME_E;
2446
2447     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
2448         return ASN_PARSE_E;
2449
2450     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
2451         return ASN_DATE_SZ_E;
2452
2453     XMEMCPY(date, &cert->source[cert->srcIdx], length);
2454     cert->srcIdx += length;
2455
2456     if (dateType == BEFORE)
2457         cert->beforeDateLen = cert->srcIdx - startIdx;
2458     else
2459         cert->afterDateLen  = cert->srcIdx - startIdx;
2460
2461     if (!XVALIDATE_DATE(date, b, dateType)) {
2462         if (dateType == BEFORE)
2463             return ASN_BEFORE_DATE_E;
2464         else
2465             return ASN_AFTER_DATE_E;
2466     }
2467
2468     return 0;
2469 }
2470
2471
2472 static int GetValidity(DecodedCert* cert, int verify)
2473 {
2474     int length;
2475     int badDate = 0;
2476
2477     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
2478         return ASN_PARSE_E;
2479
2480     if (GetDate(cert, BEFORE) < 0 && verify)
2481         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
2482     
2483     if (GetDate(cert, AFTER) < 0 && verify)
2484         return ASN_AFTER_DATE_E;
2485    
2486     if (badDate != 0)
2487         return badDate;
2488
2489     return 0;
2490 }
2491
2492
2493 int DecodeToKey(DecodedCert* cert, int verify)
2494 {
2495     int badDate = 0;
2496     int ret;
2497
2498     if ( (ret = GetCertHeader(cert)) < 0)
2499         return ret;
2500
2501     WOLFSSL_MSG("Got Cert Header");
2502
2503     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
2504                           cert->maxIdx)) < 0)
2505         return ret;
2506
2507     WOLFSSL_MSG("Got Algo ID");
2508
2509     if ( (ret = GetName(cert, ISSUER)) < 0)
2510         return ret;
2511
2512     if ( (ret = GetValidity(cert, verify)) < 0)
2513         badDate = ret;
2514
2515     if ( (ret = GetName(cert, SUBJECT)) < 0)
2516         return ret;
2517
2518     WOLFSSL_MSG("Got Subject Name");
2519
2520     if ( (ret = GetKey(cert)) < 0)
2521         return ret;
2522
2523     WOLFSSL_MSG("Got Key");
2524
2525     if (badDate != 0)
2526         return badDate;
2527
2528     return ret;
2529 }
2530
2531
2532 static int GetSignature(DecodedCert* cert)
2533 {
2534     int    length;
2535     byte   b = cert->source[cert->srcIdx++];
2536
2537     if (b != ASN_BIT_STRING)
2538         return ASN_BITSTR_E;
2539
2540     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
2541         return ASN_PARSE_E;
2542
2543     cert->sigLength = length;
2544
2545     b = cert->source[cert->srcIdx++];
2546     if (b != 0x00)
2547         return ASN_EXPECT_0_E;
2548
2549     cert->sigLength--;
2550     cert->signature = &cert->source[cert->srcIdx];
2551     cert->srcIdx += cert->sigLength;
2552
2553     return 0;
2554 }
2555
2556
2557 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
2558 {
2559     output[0] = ASN_OCTET_STRING;
2560     output[1] = (byte)digSz;
2561     XMEMCPY(&output[2], digest, digSz);
2562
2563     return digSz + 2;
2564
2565
2566
2567 static word32 BytePrecision(word32 value)
2568 {
2569     word32 i;
2570     for (i = sizeof(value); i; --i)
2571         if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
2572             break;
2573
2574     return i;
2575 }
2576
2577
2578 WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)
2579 {
2580     word32 i = 0, j;
2581
2582     if (length < ASN_LONG_LENGTH)
2583         output[i++] = (byte)length;
2584     else {
2585         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
2586       
2587         for (j = BytePrecision(length); j; --j) {
2588             output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
2589             i++;
2590         }
2591     }
2592
2593     return i;
2594 }
2595
2596
2597 WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)
2598 {
2599     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
2600     return SetLength(len, output + 1) + 1;
2601 }
2602
2603 WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)
2604 {
2605     output[0] = ASN_OCTET_STRING;
2606     return SetLength(len, output + 1) + 1;
2607 }
2608
2609 /* Write a set header to output */
2610 WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)
2611 {
2612     output[0] = ASN_SET | ASN_CONSTRUCTED;
2613     return SetLength(len, output + 1) + 1;
2614 }
2615
2616 WOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
2617 {
2618
2619     output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
2620                     | ASN_CONTEXT_SPECIFIC | number;
2621     return SetLength(len, output + 1) + 1;
2622 }
2623
2624 WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
2625 {
2626     output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
2627     return SetLength(len, output + 1) + 1;
2628 }
2629
2630
2631 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
2632
2633 static word32 SetCurve(ecc_key* key, byte* output)
2634 {
2635
2636     /* curve types */
2637 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
2638     static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
2639                                              0x03, 0x01, 0x01};
2640 #endif
2641 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
2642     static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
2643                                             0x03, 0x01, 0x07};
2644 #endif
2645 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
2646     static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
2647                                              0x02};
2648 #endif
2649 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
2650     static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
2651                                              0x21};
2652 #endif
2653 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
2654     static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
2655                                              0x22};
2656 #endif
2657 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
2658     static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
2659                                              0x23};
2660 #endif
2661
2662     int    oidSz = 0;
2663     int    idx = 0;
2664     int    lenSz = 0;
2665     const  byte* oid = 0;
2666
2667     output[0] = ASN_OBJECT_ID;
2668     idx++;
2669
2670     switch (key->dp->size) {
2671 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
2672         case 20:
2673             oidSz = sizeof(ECC_160r1_AlgoID);
2674             oid   =        ECC_160r1_AlgoID;
2675             break;
2676 #endif
2677
2678 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
2679         case 24:
2680             oidSz = sizeof(ECC_192v1_AlgoID);
2681             oid   =        ECC_192v1_AlgoID;
2682             break;
2683 #endif
2684
2685 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
2686         case 28:
2687             oidSz = sizeof(ECC_224r1_AlgoID);
2688             oid   =        ECC_224r1_AlgoID;
2689             break;
2690 #endif
2691
2692 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
2693         case 32:
2694             oidSz = sizeof(ECC_256v1_AlgoID);
2695             oid   =        ECC_256v1_AlgoID;
2696             break;
2697 #endif
2698
2699 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
2700         case 48:
2701             oidSz = sizeof(ECC_384r1_AlgoID);
2702             oid   =        ECC_384r1_AlgoID;
2703             break;
2704 #endif
2705
2706 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
2707         case 66:
2708             oidSz = sizeof(ECC_521r1_AlgoID);
2709             oid   =        ECC_521r1_AlgoID;
2710             break;
2711 #endif
2712
2713         default:
2714             return ASN_UNKNOWN_OID_E;
2715     }
2716     lenSz = SetLength(oidSz, output+idx);
2717     idx += lenSz;
2718
2719     XMEMCPY(output+idx, oid, oidSz);
2720     idx += oidSz;
2721
2722     return idx;
2723 }
2724
2725 #endif /* HAVE_ECC && WOLFSSL_CERT_GEN */
2726
2727
2728 WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
2729 {
2730     /* adding TAG_NULL and 0 to end */
2731     
2732     /* hashTypes */
2733     static const byte shaAlgoID[]    = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
2734                                          0x05, 0x00 };
2735     static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
2736                                          0x04, 0x02, 0x01, 0x05, 0x00 };
2737     static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
2738                                          0x04, 0x02, 0x02, 0x05, 0x00 };
2739     static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
2740                                          0x04, 0x02, 0x03, 0x05, 0x00 };
2741     static const byte md5AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
2742                                          0x02, 0x05, 0x05, 0x00  };
2743     static const byte md2AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
2744                                          0x02, 0x02, 0x05, 0x00};
2745
2746     /* blkTypes, no NULL tags because IV is there instead */
2747     static const byte desCbcAlgoID[]  = { 0x2B, 0x0E, 0x03, 0x02, 0x07 };
2748     static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
2749                                           0x0D, 0x03, 0x07 };
2750
2751     /* RSA sigTypes */
2752     #ifndef NO_RSA
2753         static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
2754                                             0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
2755         static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
2756                                             0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
2757         static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
2758                                             0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
2759         static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
2760                                             0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
2761         static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
2762                                             0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
2763     #endif /* NO_RSA */
2764  
2765     /* ECDSA sigTypes */
2766     #ifdef HAVE_ECC 
2767         static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
2768                                                  0x04, 0x01, 0x05, 0x00};
2769         static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
2770                                                  0x04, 0x03, 0x02, 0x05, 0x00};
2771         static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
2772                                                  0x04, 0x03, 0x03, 0x05, 0x00};
2773         static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
2774                                                  0x04, 0x03, 0x04, 0x05, 0x00};
2775     #endif /* HAVE_ECC */
2776  
2777     /* RSA keyType */
2778     #ifndef NO_RSA
2779         static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
2780                                             0x01, 0x01, 0x01, 0x05, 0x00};
2781     #endif /* NO_RSA */
2782
2783     #ifdef HAVE_ECC 
2784         /* ECC keyType */
2785         /* no tags, so set tagSz smaller later */
2786         static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
2787                                            0x02, 0x01};
2788     #endif /* HAVE_ECC */
2789
2790     int    algoSz = 0;
2791     int    tagSz  = 2;   /* tag null and terminator */
2792     word32 idSz, seqSz;
2793     const  byte* algoName = 0;
2794     byte ID_Length[MAX_LENGTH_SZ];
2795     byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
2796
2797     if (type == hashType) {
2798         switch (algoOID) {
2799         case SHAh:
2800             algoSz = sizeof(shaAlgoID);
2801             algoName = shaAlgoID;
2802             break;
2803
2804         case SHA256h:
2805             algoSz = sizeof(sha256AlgoID);
2806             algoName = sha256AlgoID;
2807             break;
2808
2809         case SHA384h:
2810             algoSz = sizeof(sha384AlgoID);
2811             algoName = sha384AlgoID;
2812             break;
2813
2814         case SHA512h:
2815             algoSz = sizeof(sha512AlgoID);
2816             algoName = sha512AlgoID;
2817             break;
2818
2819         case MD2h:
2820             algoSz = sizeof(md2AlgoID);
2821             algoName = md2AlgoID;
2822             break;
2823
2824         case MD5h:
2825             algoSz = sizeof(md5AlgoID);
2826             algoName = md5AlgoID;
2827             break;
2828
2829         default:
2830             WOLFSSL_MSG("Unknown Hash Algo");
2831             return 0;  /* UNKOWN_HASH_E; */
2832         }
2833     }
2834     else if (type == blkType) {
2835         switch (algoOID) {
2836         case DESb:
2837             algoSz = sizeof(desCbcAlgoID);
2838             algoName = desCbcAlgoID;
2839             tagSz = 0;
2840             break;
2841         case DES3b:
2842             algoSz = sizeof(des3CbcAlgoID);
2843             algoName = des3CbcAlgoID;
2844             tagSz = 0;
2845             break;
2846         default:
2847             WOLFSSL_MSG("Unknown Block Algo");
2848             return 0;
2849         }
2850     }
2851     else if (type == sigType) {    /* sigType */
2852         switch (algoOID) {
2853         #ifndef NO_RSA
2854             case CTC_MD5wRSA:
2855                 algoSz = sizeof(md5wRSA_AlgoID);
2856                 algoName = md5wRSA_AlgoID;
2857                 break;
2858
2859             case CTC_SHAwRSA:
2860                 algoSz = sizeof(shawRSA_AlgoID);
2861                 algoName = shawRSA_AlgoID;
2862                 break;
2863
2864             case CTC_SHA256wRSA:
2865                 algoSz = sizeof(sha256wRSA_AlgoID);
2866                 algoName = sha256wRSA_AlgoID;
2867                 break;
2868
2869             case CTC_SHA384wRSA:
2870                 algoSz = sizeof(sha384wRSA_AlgoID);
2871                 algoName = sha384wRSA_AlgoID;
2872                 break;
2873
2874             case CTC_SHA512wRSA:
2875                 algoSz = sizeof(sha512wRSA_AlgoID);
2876                 algoName = sha512wRSA_AlgoID;
2877                 break;
2878         #endif /* NO_RSA */
2879         #ifdef HAVE_ECC 
2880             case CTC_SHAwECDSA:
2881                 algoSz = sizeof(shawECDSA_AlgoID);
2882                 algoName = shawECDSA_AlgoID;
2883                 break;
2884
2885             case CTC_SHA256wECDSA:
2886                 algoSz = sizeof(sha256wECDSA_AlgoID);
2887                 algoName = sha256wECDSA_AlgoID;
2888                 break;
2889
2890             case CTC_SHA384wECDSA:
2891                 algoSz = sizeof(sha384wECDSA_AlgoID);
2892                 algoName = sha384wECDSA_AlgoID;
2893                 break;
2894
2895             case CTC_SHA512wECDSA:
2896                 algoSz = sizeof(sha512wECDSA_AlgoID);
2897                 algoName = sha512wECDSA_AlgoID;
2898                 break;
2899         #endif /* HAVE_ECC */
2900         default:
2901             WOLFSSL_MSG("Unknown Signature Algo");
2902             return 0;
2903         }
2904     }
2905     else if (type == keyType) {    /* keyType */
2906         switch (algoOID) {
2907         #ifndef NO_RSA
2908             case RSAk:
2909                 algoSz = sizeof(RSA_AlgoID);
2910                 algoName = RSA_AlgoID;
2911                 break;
2912         #endif /* NO_RSA */
2913         #ifdef HAVE_ECC 
2914             case ECDSAk:
2915                 algoSz = sizeof(ECC_AlgoID);
2916                 algoName = ECC_AlgoID;
2917                 tagSz = 0;
2918                 break;
2919         #endif /* HAVE_ECC */
2920         default:
2921             WOLFSSL_MSG("Unknown Key Algo");
2922             return 0;
2923         }
2924     }
2925     else {
2926         WOLFSSL_MSG("Unknown Algo type");
2927         return 0;
2928     }
2929
2930     idSz  = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
2931     seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray); 
2932                  /* +1 for object id, curveID of curveSz follows for ecc */
2933     seqArray[seqSz++] = ASN_OBJECT_ID;
2934
2935     XMEMCPY(output, seqArray, seqSz);
2936     XMEMCPY(output + seqSz, ID_Length, idSz);
2937     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
2938
2939     return seqSz + idSz + algoSz;
2940
2941 }
2942
2943
2944 word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
2945                           int hashOID)
2946 {
2947     byte digArray[MAX_ENCODED_DIG_SZ];
2948     byte algoArray[MAX_ALGO_SZ];
2949     byte seqArray[MAX_SEQ_SZ];
2950     word32 encDigSz, algoSz, seqSz;
2951
2952     encDigSz = SetDigest(digest, digSz, digArray);
2953     algoSz   = SetAlgoID(hashOID, algoArray, hashType, 0);
2954     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
2955
2956     XMEMCPY(out, seqArray, seqSz);
2957     XMEMCPY(out + seqSz, algoArray, algoSz);
2958     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
2959
2960     return encDigSz + algoSz + seqSz;
2961 }
2962
2963
2964 int wc_GetCTC_HashOID(int type)
2965 {
2966     switch (type) {
2967 #ifdef WOLFSSL_MD2
2968         case MD2:
2969             return MD2h;
2970 #endif
2971 #ifndef NO_MD5
2972         case MD5:
2973             return MD5h;
2974 #endif
2975 #ifndef NO_SHA
2976         case SHA:
2977             return SHAh;
2978 #endif
2979 #ifndef NO_SHA256
2980         case SHA256:
2981             return SHA256h;
2982 #endif
2983 #ifdef WOLFSSL_SHA384
2984         case SHA384:
2985             return SHA384h;
2986 #endif
2987 #ifdef WOLFSSL_SHA512
2988         case SHA512:
2989             return SHA512h;
2990 #endif
2991         default:
2992             return 0;
2993     };
2994 }
2995
2996
2997 /* return true (1) or false (0) for Confirmation */
2998 static int ConfirmSignature(const byte* buf, word32 bufSz,
2999     const byte* key, word32 keySz, word32 keyOID,
3000     const byte* sig, word32 sigSz, word32 sigOID,
3001     void* heap)
3002 {
3003     int  typeH = 0, digestSz = 0, ret = 0;
3004 #ifdef WOLFSSL_SMALL_STACK
3005     byte* digest;
3006 #else
3007     byte digest[MAX_DIGEST_SIZE];
3008 #endif
3009
3010 #ifdef WOLFSSL_SMALL_STACK
3011     digest = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3012     if (digest == NULL)
3013         return 0; /* not confirmed */
3014 #endif
3015
3016     (void)key;
3017     (void)keySz;
3018     (void)sig;
3019     (void)sigSz;
3020     (void)heap;
3021
3022     switch (sigOID) {
3023     #ifndef NO_MD5
3024         case CTC_MD5wRSA:
3025         if (wc_Md5Hash(buf, bufSz, digest) == 0) {
3026             typeH    = MD5h;
3027             digestSz = MD5_DIGEST_SIZE;
3028         }
3029         break;
3030     #endif
3031     #if defined(WOLFSSL_MD2)
3032         case CTC_MD2wRSA:
3033         if (wc_Md2Hash(buf, bufSz, digest) == 0) {
3034             typeH    = MD2h;
3035             digestSz = MD2_DIGEST_SIZE;
3036         }
3037         break;
3038     #endif
3039     #ifndef NO_SHA
3040         case CTC_SHAwRSA:
3041         case CTC_SHAwDSA:
3042         case CTC_SHAwECDSA:
3043         if (wc_ShaHash(buf, bufSz, digest) == 0) {    
3044             typeH    = SHAh;
3045             digestSz = SHA_DIGEST_SIZE;                
3046         }
3047         break;
3048     #endif
3049     #ifndef NO_SHA256
3050         case CTC_SHA256wRSA:
3051         case CTC_SHA256wECDSA:
3052         if (wc_Sha256Hash(buf, bufSz, digest) == 0) {    
3053             typeH    = SHA256h;
3054             digestSz = SHA256_DIGEST_SIZE;
3055         }
3056         break;
3057     #endif
3058     #ifdef WOLFSSL_SHA512
3059         case CTC_SHA512wRSA:
3060         case CTC_SHA512wECDSA:
3061         if (wc_Sha512Hash(buf, bufSz, digest) == 0) {    
3062             typeH    = SHA512h;
3063             digestSz = SHA512_DIGEST_SIZE;
3064         }
3065         break;
3066     #endif
3067     #ifdef WOLFSSL_SHA384
3068         case CTC_SHA384wRSA:
3069         case CTC_SHA384wECDSA:
3070         if (wc_Sha384Hash(buf, bufSz, digest) == 0) {    
3071             typeH    = SHA384h;
3072             digestSz = SHA384_DIGEST_SIZE;
3073         }            
3074         break;
3075     #endif
3076         default:
3077             WOLFSSL_MSG("Verify Signautre has unsupported type");
3078     }
3079     
3080     if (typeH == 0) {
3081 #ifdef WOLFSSL_SMALL_STACK
3082         XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3083 #endif
3084         return 0; /* not confirmed */
3085     }
3086
3087     switch (keyOID) {
3088     #ifndef NO_RSA
3089         case RSAk:
3090         {
3091             word32 idx = 0;
3092             int    encodedSigSz, verifySz;
3093             byte*  out;
3094 #ifdef WOLFSSL_SMALL_STACK
3095             RsaKey* pubKey;
3096             byte* plain;
3097             byte* encodedSig;
3098 #else
3099             RsaKey pubKey[1];
3100             byte plain[MAX_ENCODED_SIG_SZ];
3101             byte encodedSig[MAX_ENCODED_SIG_SZ];
3102 #endif
3103
3104 #ifdef WOLFSSL_SMALL_STACK
3105             pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
3106                                                        DYNAMIC_TYPE_TMP_BUFFER);
3107             plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
3108                                                        DYNAMIC_TYPE_TMP_BUFFER);
3109             encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
3110                                                        DYNAMIC_TYPE_TMP_BUFFER);
3111             
3112             if (pubKey == NULL || plain == NULL || encodedSig == NULL) {
3113                 WOLFSSL_MSG("Failed to allocate memory at ConfirmSignature");
3114                 
3115                 if (pubKey)
3116                     XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3117                 if (plain)
3118                     XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3119                 if (encodedSig)
3120                     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3121                 
3122                 break; /* not confirmed */
3123             }
3124 #endif
3125
3126             if (sigSz > MAX_ENCODED_SIG_SZ) {
3127                 WOLFSSL_MSG("Verify Signautre is too big");
3128             }
3129             else if (wc_InitRsaKey(pubKey, heap) != 0) {
3130                 WOLFSSL_MSG("InitRsaKey failed");
3131             }
3132             else if (wc_RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) {
3133                 WOLFSSL_MSG("ASN Key decode error RSA");
3134             }
3135             else {
3136                 XMEMCPY(plain, sig, sigSz);
3137
3138                 if ((verifySz = wc_RsaSSL_VerifyInline(plain, sigSz, &out,
3139                                                                  pubKey)) < 0) {
3140                     WOLFSSL_MSG("Rsa SSL verify error");
3141                 }
3142                 else {
3143                     /* make sure we're right justified */
3144                     encodedSigSz =
3145                         wc_EncodeSignature(encodedSig, digest, digestSz, typeH);
3146                     if (encodedSigSz != verifySz ||
3147                                 XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
3148                         WOLFSSL_MSG("Rsa SSL verify match encode error");
3149                     }
3150                     else
3151                         ret = 1; /* match */
3152
3153                     #ifdef WOLFSSL_DEBUG_ENCODING
3154                     {
3155                         int x;
3156
3157                         printf("wolfssl encodedSig:\n");
3158
3159                         for (x = 0; x < encodedSigSz; x++) {
3160                             printf("%02x ", encodedSig[x]);
3161                             if ( (x % 16) == 15)
3162                                 printf("\n");
3163                         }
3164
3165                         printf("\n");
3166                         printf("actual digest:\n");
3167
3168                         for (x = 0; x < verifySz; x++) {
3169                             printf("%02x ", out[x]);
3170                             if ( (x % 16) == 15)
3171                                 printf("\n");
3172                         }
3173
3174                         printf("\n");
3175                     }
3176                     #endif /* WOLFSSL_DEBUG_ENCODING */
3177
3178                 }
3179
3180             }
3181
3182             wc_FreeRsaKey(pubKey);
3183
3184 #ifdef WOLFSSL_SMALL_STACK
3185             XFREE(pubKey,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
3186             XFREE(plain,      NULL, DYNAMIC_TYPE_TMP_BUFFER);
3187             XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3188 #endif
3189             break;
3190         }
3191
3192     #endif /* NO_RSA */
3193     #ifdef HAVE_ECC
3194         case ECDSAk:
3195         {
3196             int verify = 0;
3197 #ifdef WOLFSSL_SMALL_STACK
3198             ecc_key* pubKey;
3199 #else
3200             ecc_key pubKey[1];
3201 #endif
3202
3203 #ifdef WOLFSSL_SMALL_STACK
3204             pubKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
3205                                                        DYNAMIC_TYPE_TMP_BUFFER);
3206             if (pubKey == NULL) {
3207                 WOLFSSL_MSG("Failed to allocate pubKey");
3208                 break; /* not confirmed */
3209             }
3210 #endif
3211
3212             if (wc_ecc_init(pubKey) < 0) {
3213                 WOLFSSL_MSG("Failed to initialize key");
3214                 break; /* not confirmed */
3215             }
3216             if (wc_ecc_import_x963(key, keySz, pubKey) < 0) {
3217                 WOLFSSL_MSG("ASN Key import error ECC");
3218             }
3219             else {   
3220                 if (wc_ecc_verify_hash(sig, sigSz, digest, digestSz, &verify,
3221                                                                 pubKey) != 0) {
3222                     WOLFSSL_MSG("ECC verify hash error");
3223                 }
3224                 else if (1 != verify) {
3225                     WOLFSSL_MSG("ECC Verify didn't match");
3226                 } else
3227                     ret = 1; /* match */
3228
3229             }
3230             wc_ecc_free(pubKey);
3231
3232 #ifdef WOLFSSL_SMALL_STACK
3233             XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3234 #endif
3235             break;
3236         }
3237     #endif /* HAVE_ECC */
3238         default:
3239             WOLFSSL_MSG("Verify Key type unknown");
3240     }
3241     
3242 #ifdef WOLFSSL_SMALL_STACK
3243     XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3244 #endif
3245
3246     return ret;
3247 }
3248
3249
3250 #ifndef IGNORE_NAME_CONSTRAINTS
3251
3252 static int MatchBaseName(int type, const char* name, int nameSz,
3253                                                    const char* base, int baseSz)
3254 {
3255     if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
3256             name[0] == '.' || nameSz < baseSz ||
3257             (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
3258         return 0;
3259
3260     /* If an email type, handle special cases where the base is only
3261      * a domain, or is an email address itself. */
3262     if (type == ASN_RFC822_TYPE) {
3263         const char* p = NULL;
3264         int count = 0;
3265
3266         if (base[0] != '.') {
3267             p = base;
3268             count = 0;
3269
3270             /* find the '@' in the base */
3271             while (*p != '@' && count < baseSz) {
3272                 count++;
3273                 p++;
3274             }
3275
3276             /* No '@' in base, reset p to NULL */
3277             if (count >= baseSz)
3278                 p = NULL;
3279         }
3280
3281         if (p == NULL) {
3282             /* Base isn't an email address, it is a domain name,
3283              * wind the name forward one character past its '@'. */
3284             p = name;
3285             count = 0;
3286             while (*p != '@' && count < baseSz) {
3287                 count++;
3288                 p++;
3289             }
3290
3291             if (count < baseSz && *p == '@') {
3292                 name = p + 1;
3293                 nameSz -= count + 1;
3294             }
3295         }
3296     }
3297
3298     if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
3299         int szAdjust = nameSz - baseSz;
3300         name += szAdjust;
3301         nameSz -= szAdjust;
3302     }
3303
3304     while (nameSz > 0) {
3305         if (XTOLOWER((unsigned char)*name++) != 
3306                                                XTOLOWER((unsigned char)*base++))
3307             return 0;
3308         nameSz--;
3309     }
3310
3311     return 1;
3312 }
3313
3314
3315 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
3316 {
3317     if (signer == NULL || cert == NULL)
3318         return 0;
3319
3320     /* Check against the excluded list */
3321     if (signer->excludedNames) {
3322         Base_entry* base = signer->excludedNames;
3323
3324         while (base != NULL) {
3325             if (base->type == ASN_DNS_TYPE) {
3326                 DNS_entry* name = cert->altNames;
3327                 while (name != NULL) {
3328                     if (MatchBaseName(ASN_DNS_TYPE,
3329                                           name->name, (int)XSTRLEN(name->name),
3330                                           base->name, base->nameSz))
3331                         return 0;
3332                     name = name->next;
3333                 }
3334             }
3335             else if (base->type == ASN_RFC822_TYPE) {
3336                 DNS_entry* name = cert->altEmailNames;
3337                 while (name != NULL) {
3338                     if (MatchBaseName(ASN_RFC822_TYPE,
3339                                           name->name, (int)XSTRLEN(name->name),
3340                                           base->name, base->nameSz))
3341                         return 0;
3342
3343                     name = name->next;
3344                 }
3345             }
3346             else if (base->type == ASN_DIR_TYPE) {
3347                 if (cert->subjectRawLen == base->nameSz &&
3348                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
3349
3350                     return 0;
3351                 }
3352             }
3353             base = base->next;
3354         }
3355     }
3356
3357     /* Check against the permitted list */
3358     if (signer->permittedNames != NULL) {
3359         int needDns = 0;
3360         int matchDns = 0;
3361         int needEmail = 0;
3362         int matchEmail = 0;
3363         int needDir = 0;
3364         int matchDir = 0;
3365         Base_entry* base = signer->permittedNames;
3366
3367         while (base != NULL) {
3368             if (base->type == ASN_DNS_TYPE) {
3369                 DNS_entry* name = cert->altNames;
3370
3371                 if (name != NULL)
3372                     needDns = 1;
3373
3374                 while (name != NULL) {
3375                     matchDns = MatchBaseName(ASN_DNS_TYPE,
3376                                           name->name, (int)XSTRLEN(name->name),
3377                                           base->name, base->nameSz);
3378                     name = name->next;
3379                 }
3380             }
3381             else if (base->type == ASN_RFC822_TYPE) {
3382                 DNS_entry* name = cert->altEmailNames;
3383
3384                 if (name != NULL)
3385                     needEmail = 1;
3386
3387                 while (name != NULL) {
3388                     matchEmail = MatchBaseName(ASN_DNS_TYPE,
3389                                           name->name, (int)XSTRLEN(name->name),
3390                                           base->name, base->nameSz);
3391                     name = name->next;
3392                 }
3393             }
3394             else if (base->type == ASN_DIR_TYPE) {
3395                 needDir = 1;
3396                 if (cert->subjectRaw != NULL &&
3397                     cert->subjectRawLen == base->nameSz &&
3398                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
3399
3400                     matchDir = 1;
3401                 }
3402             }
3403             base = base->next;
3404         }
3405
3406         if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
3407             (needDir && !matchDir)) {
3408
3409             return 0;
3410         }
3411     }
3412
3413     return 1;
3414 }
3415
3416 #endif /* IGNORE_NAME_CONSTRAINTS */
3417
3418
3419 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
3420 {
3421     word32 idx = 0;
3422     int length = 0;
3423
3424     WOLFSSL_ENTER("DecodeAltNames");
3425
3426     if (GetSequence(input, &idx, &length, sz) < 0) {
3427         WOLFSSL_MSG("\tBad Sequence");
3428         return ASN_PARSE_E;
3429     }
3430
3431     cert->weOwnAltNames = 1;
3432
3433     while (length > 0) {
3434         byte       b = input[idx++];
3435
3436         length--;
3437
3438         /* Save DNS Type names in the altNames list. */
3439         /* Save Other Type names in the cert's OidMap */
3440         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
3441             DNS_entry* dnsEntry;
3442             int strLen;
3443             word32 lenStartIdx = idx;
3444
3445             if (GetLength(input, &idx, &strLen, sz) < 0) {
3446                 WOLFSSL_MSG("\tfail: str length");
3447                 return ASN_PARSE_E;
3448             }
3449             length -= (idx - lenStartIdx);
3450
3451             dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
3452                                         DYNAMIC_TYPE_ALTNAME);
3453             if (dnsEntry == NULL) {
3454                 WOLFSSL_MSG("\tOut of Memory");
3455                 return ASN_PARSE_E;
3456             }
3457
3458             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
3459                                          DYNAMIC_TYPE_ALTNAME);
3460             if (dnsEntry->name == NULL) {
3461                 WOLFSSL_MSG("\tOut of Memory");
3462                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3463                 return ASN_PARSE_E;
3464             }
3465
3466             XMEMCPY(dnsEntry->name, &input[idx], strLen);
3467             dnsEntry->name[strLen] = '\0';
3468
3469             dnsEntry->next = cert->altNames;
3470             cert->altNames = dnsEntry;
3471
3472             length -= strLen;
3473             idx    += strLen;
3474         }
3475 #ifndef IGNORE_NAME_CONSTRAINTS
3476         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
3477             DNS_entry* emailEntry;
3478             int strLen;
3479             word32 lenStartIdx = idx;
3480
3481             if (GetLength(input, &idx, &strLen, sz) < 0) {
3482                 WOLFSSL_MSG("\tfail: str length");
3483                 return ASN_PARSE_E;
3484             }
3485             length -= (idx - lenStartIdx);
3486
3487             emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
3488                                         DYNAMIC_TYPE_ALTNAME);
3489             if (emailEntry == NULL) {
3490                 WOLFSSL_MSG("\tOut of Memory");
3491                 return ASN_PARSE_E;
3492             }
3493
3494             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
3495                                          DYNAMIC_TYPE_ALTNAME);
3496             if (emailEntry->name == NULL) {
3497                 WOLFSSL_MSG("\tOut of Memory");
3498                 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
3499                 return ASN_PARSE_E;
3500             }
3501
3502             XMEMCPY(emailEntry->name, &input[idx], strLen);
3503             emailEntry->name[strLen] = '\0';
3504
3505             emailEntry->next = cert->altEmailNames;
3506             cert->altEmailNames = emailEntry;
3507
3508             length -= strLen;
3509             idx    += strLen;
3510         }
3511 #endif /* IGNORE_NAME_CONSTRAINTS */
3512 #ifdef WOLFSSL_SEP
3513         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
3514         {
3515             int strLen;
3516             word32 lenStartIdx = idx;
3517             word32 oid = 0;
3518
3519             if (GetLength(input, &idx, &strLen, sz) < 0) {
3520                 WOLFSSL_MSG("\tfail: other name length");
3521                 return ASN_PARSE_E;
3522             }
3523             /* Consume the rest of this sequence. */
3524             length -= (strLen + idx - lenStartIdx);
3525
3526             if (GetObjectId(input, &idx, &oid, sz) < 0) {
3527                 WOLFSSL_MSG("\tbad OID");
3528                 return ASN_PARSE_E;
3529             }
3530
3531             if (oid != HW_NAME_OID) {
3532                 WOLFSSL_MSG("\tincorrect OID");
3533                 return ASN_PARSE_E;
3534             }
3535
3536             if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3537                 WOLFSSL_MSG("\twrong type");
3538                 return ASN_PARSE_E;
3539             }
3540
3541             if (GetLength(input, &idx, &strLen, sz) < 0) {
3542                 WOLFSSL_MSG("\tfail: str len");
3543                 return ASN_PARSE_E;
3544             }
3545
3546             if (GetSequence(input, &idx, &strLen, sz) < 0) {
3547                 WOLFSSL_MSG("\tBad Sequence");
3548                 return ASN_PARSE_E;
3549             }
3550
3551             if (input[idx++] != ASN_OBJECT_ID) {
3552                 WOLFSSL_MSG("\texpected OID");
3553                 return ASN_PARSE_E;
3554             }
3555
3556             if (GetLength(input, &idx, &strLen, sz) < 0) {
3557                 WOLFSSL_MSG("\tfailed: str len");
3558                 return ASN_PARSE_E;
3559             }
3560
3561             cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
3562             if (cert->hwType == NULL) {
3563                 WOLFSSL_MSG("\tOut of Memory");
3564                 return MEMORY_E;
3565             }
3566
3567             XMEMCPY(cert->hwType, &input[idx], strLen);
3568             cert->hwTypeSz = strLen;
3569             idx += strLen;
3570
3571             if (input[idx++] != ASN_OCTET_STRING) {
3572                 WOLFSSL_MSG("\texpected Octet String");
3573                 return ASN_PARSE_E;
3574             }
3575
3576             if (GetLength(input, &idx, &strLen, sz) < 0) {
3577                 WOLFSSL_MSG("\tfailed: str len");
3578                 return ASN_PARSE_E;
3579             }
3580
3581             cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
3582             if (cert->hwSerialNum == NULL) {
3583                 WOLFSSL_MSG("\tOut of Memory");
3584                 return MEMORY_E;
3585             }
3586
3587             XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
3588             cert->hwSerialNum[strLen] = '\0';
3589             cert->hwSerialNumSz = strLen;
3590             idx += strLen;
3591         }
3592 #endif /* WOLFSSL_SEP */
3593         else {
3594             int strLen;
3595             word32 lenStartIdx = idx;
3596
3597             WOLFSSL_MSG("\tUnsupported name type, skipping");
3598
3599             if (GetLength(input, &idx, &strLen, sz) < 0) {
3600                 WOLFSSL_MSG("\tfail: unsupported name length");
3601                 return ASN_PARSE_E;
3602             }
3603             length -= (strLen + idx - lenStartIdx);
3604             idx += strLen;
3605         }
3606     }
3607     return 0;
3608 }
3609
3610
3611 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
3612 {
3613     word32 idx = 0;
3614     int length = 0;
3615
3616     WOLFSSL_ENTER("DecodeBasicCaConstraint");
3617     if (GetSequence(input, &idx, &length, sz) < 0) {
3618         WOLFSSL_MSG("\tfail: bad SEQUENCE");
3619         return ASN_PARSE_E;
3620     }
3621
3622     if (length == 0)
3623         return 0;
3624
3625     /* If the basic ca constraint is false, this extension may be named, but
3626      * left empty. So, if the length is 0, just return. */
3627
3628     if (input[idx++] != ASN_BOOLEAN)
3629     {
3630         WOLFSSL_MSG("\tfail: constraint not BOOLEAN");
3631         return ASN_PARSE_E;
3632     }
3633
3634     if (GetLength(input, &idx, &length, sz) < 0)
3635     {
3636         WOLFSSL_MSG("\tfail: length");
3637         return ASN_PARSE_E;
3638     }
3639
3640     if (input[idx++])
3641         cert->isCA = 1;
3642
3643     #ifdef OPENSSL_EXTRA
3644         /* If there isn't any more data, return. */
3645         if (idx >= (word32)sz)
3646             return 0;
3647
3648         /* Anything left should be the optional pathlength */
3649         if (input[idx++] != ASN_INTEGER) {
3650             WOLFSSL_MSG("\tfail: pathlen not INTEGER");
3651             return ASN_PARSE_E;
3652         }
3653
3654         if (input[idx++] != 1) {
3655             WOLFSSL_MSG("\tfail: pathlen too long");
3656             return ASN_PARSE_E;
3657         }
3658
3659         cert->pathLength = input[idx];
3660         cert->extBasicConstPlSet = 1;
3661     #endif /* OPENSSL_EXTRA */
3662
3663     return 0;
3664 }
3665
3666
3667 #define CRLDP_FULL_NAME 0
3668     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
3669 #define GENERALNAME_URI 6
3670     /* From RFC3280 SS4.2.1.7, GeneralName */
3671
3672 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
3673 {
3674     word32 idx = 0;
3675     int length = 0;
3676
3677     WOLFSSL_ENTER("DecodeCrlDist");
3678
3679     /* Unwrap the list of Distribution Points*/
3680     if (GetSequence(input, &idx, &length, sz) < 0)
3681         return ASN_PARSE_E;
3682
3683     /* Unwrap a single Distribution Point */
3684     if (GetSequence(input, &idx, &length, sz) < 0)
3685         return ASN_PARSE_E;
3686
3687     /* The Distribution Point has three explicit optional members
3688      *  First check for a DistributionPointName
3689      */
3690     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
3691     {
3692         idx++;
3693         if (GetLength(input, &idx, &length, sz) < 0)
3694             return ASN_PARSE_E;
3695
3696         if (input[idx] == 
3697                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
3698         {
3699             idx++;
3700             if (GetLength(input, &idx, &length, sz) < 0)
3701                 return ASN_PARSE_E;
3702
3703             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
3704             {
3705                 idx++;
3706                 if (GetLength(input, &idx, &length, sz) < 0)
3707                     return ASN_PARSE_E;
3708
3709                 cert->extCrlInfoSz = length;
3710                 cert->extCrlInfo = input + idx;
3711                 idx += length;
3712             }
3713             else
3714                 /* This isn't a URI, skip it. */
3715                 idx += length;
3716         }
3717         else
3718             /* This isn't a FULLNAME, skip it. */
3719             idx += length;
3720     }
3721
3722     /* Check for reasonFlags */
3723     if (idx < (word32)sz &&
3724         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
3725     {
3726         idx++;
3727         if (GetLength(input, &idx, &length, sz) < 0)
3728             return ASN_PARSE_E;
3729         idx += length;
3730     }
3731
3732     /* Check for cRLIssuer */
3733     if (idx < (word32)sz &&
3734         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
3735     {
3736         idx++;
3737         if (GetLength(input, &idx, &length, sz) < 0)
3738             return ASN_PARSE_E;
3739         idx += length;
3740     }
3741
3742     if (idx < (word32)sz)
3743     {
3744         WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
3745                    "but we only use the first one.");
3746     }
3747
3748     return 0;
3749 }
3750
3751
3752 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
3753 /*
3754  *  Read the first of the Authority Information Access records. If there are
3755  *  any issues, return without saving the record.
3756  */
3757 {
3758     word32 idx = 0;
3759     int length = 0;
3760     byte b;
3761     word32 oid;
3762
3763     WOLFSSL_ENTER("DecodeAuthInfo");
3764
3765     /* Unwrap the list of AIAs */
3766     if (GetSequence(input, &idx, &length, sz) < 0)
3767         return ASN_PARSE_E;
3768
3769     while (idx < (word32)sz) {
3770         /* Unwrap a single AIA */
3771         if (GetSequence(input, &idx, &length, sz) < 0)
3772             return ASN_PARSE_E;
3773
3774         oid = 0;
3775         if (GetObjectId(input, &idx, &oid, sz) < 0)
3776             return ASN_PARSE_E;
3777
3778         /* Only supporting URIs right now. */
3779         b = input[idx++];
3780         if (GetLength(input, &idx, &length, sz) < 0)
3781             return ASN_PARSE_E;
3782
3783         if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
3784             oid == AIA_OCSP_OID)
3785         {
3786             cert->extAuthInfoSz = length;
3787             cert->extAuthInfo = input + idx;
3788             break;
3789         }
3790         idx += length;
3791     }
3792
3793     return 0;
3794 }
3795
3796
3797 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
3798 {
3799     word32 idx = 0;
3800     int length = 0, ret = 0;
3801
3802     WOLFSSL_ENTER("DecodeAuthKeyId");
3803
3804     if (GetSequence(input, &idx, &length, sz) < 0) {
3805         WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
3806         return ASN_PARSE_E;
3807     }
3808
3809     if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
3810         WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
3811         return 0;
3812     }
3813
3814     if (GetLength(input, &idx, &length, sz) < 0) {
3815         WOLFSSL_MSG("\tfail: extension data length");
3816         return ASN_PARSE_E;
3817     }
3818
3819     #ifdef OPENSSL_EXTRA
3820         cert->extAuthKeyIdSrc = &input[idx];
3821         cert->extAuthKeyIdSz = length;
3822     #endif /* OPENSSL_EXTRA */
3823
3824     if (length == KEYID_SIZE) {
3825         XMEMCPY(cert->extAuthKeyId, input + idx, length);
3826     }
3827     else {
3828     #ifdef NO_SHA
3829         ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
3830     #else
3831         ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
3832     #endif
3833     }
3834
3835     return ret;
3836 }
3837
3838
3839 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
3840 {
3841     word32 idx = 0;
3842     int length = 0, ret = 0;
3843
3844     WOLFSSL_ENTER("DecodeSubjKeyId");
3845
3846     if (input[idx++] != ASN_OCTET_STRING) {
3847         WOLFSSL_MSG("\tfail: should be an OCTET STRING");
3848         return ASN_PARSE_E;
3849     }
3850
3851     if (GetLength(input, &idx, &length, sz) < 0) {
3852         WOLFSSL_MSG("\tfail: extension data length");
3853         return ASN_PARSE_E;
3854     }
3855
3856     #ifdef OPENSSL_EXTRA
3857         cert->extSubjKeyIdSrc = &input[idx];
3858         cert->extSubjKeyIdSz = length;
3859     #endif /* OPENSSL_EXTRA */
3860
3861     if (length == SIGNER_DIGEST_SIZE) {
3862         XMEMCPY(cert->extSubjKeyId, input + idx, length);
3863     }
3864     else {
3865     #ifdef NO_SHA
3866         ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
3867     #else
3868         ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
3869     #endif
3870     }
3871
3872     return ret;
3873 }
3874
3875
3876 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
3877 {
3878     word32 idx = 0;
3879     int length;
3880     byte unusedBits;
3881     WOLFSSL_ENTER("DecodeKeyUsage");
3882
3883     if (input[idx++] != ASN_BIT_STRING) {
3884         WOLFSSL_MSG("\tfail: key usage expected bit string");
3885         return ASN_PARSE_E;
3886     }
3887
3888     if (GetLength(input, &idx, &length, sz) < 0) {
3889         WOLFSSL_MSG("\tfail: key usage bad length");
3890         return ASN_PARSE_E;
3891     }
3892
3893     unusedBits = input[idx++];
3894     length--;
3895
3896     if (length == 2) {
3897         cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]);
3898         cert->extKeyUsage >>= unusedBits;
3899     }
3900     else if (length == 1)
3901         cert->extKeyUsage = (word16)(input[idx] << 1);
3902
3903     return 0;
3904 }
3905
3906
3907 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
3908 {
3909     word32 idx = 0, oid;
3910     int length;
3911
3912     WOLFSSL_ENTER("DecodeExtKeyUsage");
3913
3914     if (GetSequence(input, &idx, &length, sz) < 0) {
3915         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
3916         return ASN_PARSE_E;
3917     }
3918
3919     #ifdef OPENSSL_EXTRA
3920         cert->extExtKeyUsageSrc = input + idx;
3921         cert->extExtKeyUsageSz = length;
3922     #endif
3923
3924     while (idx < (word32)sz) {
3925         if (GetObjectId(input, &idx, &oid, sz) < 0)
3926             return ASN_PARSE_E;
3927
3928         switch (oid) {
3929             case EKU_ANY_OID:
3930                 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
3931                 break;
3932             case EKU_SERVER_AUTH_OID:
3933                 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
3934                 break;
3935             case EKU_CLIENT_AUTH_OID:
3936                 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
3937                 break;
3938             case EKU_OCSP_SIGN_OID:
3939                 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
3940                 break;
3941         }
3942
3943         #ifdef OPENSSL_EXTRA
3944             cert->extExtKeyUsageCount++;
3945         #endif
3946     }
3947
3948     return 0;
3949 }
3950
3951
3952 #ifndef IGNORE_NAME_CONSTRAINTS
3953 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
3954 {
3955     word32 idx = 0;
3956
3957     (void)heap;
3958
3959     while (idx < (word32)sz) {
3960         int seqLength, strLength;
3961         word32 nameIdx;
3962         byte b;
3963
3964         if (GetSequence(input, &idx, &seqLength, sz) < 0) {
3965             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
3966             return ASN_PARSE_E;
3967         }
3968
3969         nameIdx = idx;
3970         b = input[nameIdx++];
3971         if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
3972             WOLFSSL_MSG("\tinvalid length");
3973             return ASN_PARSE_E;
3974         }
3975
3976         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
3977             b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
3978             b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
3979
3980             Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
3981                                                     heap, DYNAMIC_TYPE_ALTNAME);
3982
3983             if (entry == NULL) {
3984                 WOLFSSL_MSG("allocate error");
3985                 return MEMORY_E;
3986             }
3987
3988             entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
3989             if (entry->name == NULL) {
3990                 WOLFSSL_MSG("allocate error");
3991                 return MEMORY_E;
3992             }
3993
3994             XMEMCPY(entry->name, &input[nameIdx], strLength);
3995             entry->nameSz = strLength;
3996             entry->type = b & 0x0F;
3997
3998             entry->next = *head;
3999             *head = entry;
4000         }
4001
4002         idx += seqLength;
4003     }
4004
4005     return 0;
4006 }
4007
4008
4009 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
4010 {
4011     word32 idx = 0;
4012     int length = 0;
4013
4014     WOLFSSL_ENTER("DecodeNameConstraints");
4015
4016     if (GetSequence(input, &idx, &length, sz) < 0) {
4017         WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4018         return ASN_PARSE_E;
4019     }
4020
4021     while (idx < (word32)sz) {
4022         byte b = input[idx++];
4023         Base_entry** subtree = NULL;
4024
4025         if (GetLength(input, &idx, &length, sz) <= 0) {
4026             WOLFSSL_MSG("\tinvalid length");
4027             return ASN_PARSE_E;
4028         }
4029
4030         if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
4031             subtree = &cert->permittedNames;
4032         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
4033             subtree = &cert->excludedNames;
4034         else {
4035             WOLFSSL_MSG("\tinvalid subtree");
4036             return ASN_PARSE_E;
4037         }
4038
4039         DecodeSubtree(input + idx, length, subtree, cert->heap);
4040
4041         idx += length;
4042     }
4043
4044     return 0;
4045 }
4046 #endif /* IGNORE_NAME_CONSTRAINTS */
4047
4048
4049 #ifdef WOLFSSL_SEP
4050     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
4051     {
4052         word32 idx = 0;
4053         int length = 0;
4054
4055         WOLFSSL_ENTER("DecodeCertPolicy");
4056
4057         /* Unwrap certificatePolicies */
4058         if (GetSequence(input, &idx, &length, sz) < 0) {
4059             WOLFSSL_MSG("\tdeviceType isn't OID");
4060             return ASN_PARSE_E;
4061         }
4062
4063         if (GetSequence(input, &idx, &length, sz) < 0) {
4064             WOLFSSL_MSG("\tdeviceType isn't OID");
4065             return ASN_PARSE_E;
4066         }
4067
4068         if (input[idx++] != ASN_OBJECT_ID) {
4069             WOLFSSL_MSG("\tdeviceType isn't OID");
4070             return ASN_PARSE_E;
4071         }
4072
4073         if (GetLength(input, &idx, &length, sz) < 0) {
4074             WOLFSSL_MSG("\tCouldn't read length of deviceType");
4075             return ASN_PARSE_E;
4076         }
4077
4078         if (length > 0) {
4079             cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
4080             if (cert->deviceType == NULL) {
4081                 WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
4082                 return MEMORY_E;
4083             }
4084             cert->deviceTypeSz = length;
4085             XMEMCPY(cert->deviceType, input + idx, length);
4086         }
4087
4088         WOLFSSL_LEAVE("DecodeCertPolicy", 0);
4089         return 0;
4090     }
4091 #endif /* WOLFSSL_SEP */
4092
4093
4094 static int DecodeCertExtensions(DecodedCert* cert)
4095 /*
4096  *  Processing the Certificate Extensions. This does not modify the current
4097  *  index. It is works starting with the recorded extensions pointer.
4098  */
4099 {
4100     word32 idx = 0;
4101     int sz = cert->extensionsSz;
4102     byte* input = cert->extensions;
4103     int length;
4104     word32 oid;
4105     byte critical = 0;
4106     byte criticalFail = 0;
4107
4108     WOLFSSL_ENTER("DecodeCertExtensions");
4109
4110     if (input == NULL || sz == 0)
4111         return BAD_FUNC_ARG;
4112
4113     if (input[idx++] != ASN_EXTENSIONS)
4114         return ASN_PARSE_E;
4115
4116     if (GetLength(input, &idx, &length, sz) < 0)
4117         return ASN_PARSE_E;
4118
4119     if (GetSequence(input, &idx, &length, sz) < 0)
4120         return ASN_PARSE_E;
4121     
4122     while (idx < (word32)sz) {
4123         if (GetSequence(input, &idx, &length, sz) < 0) {
4124             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
4125             return ASN_PARSE_E;
4126         }
4127
4128         oid = 0;
4129         if (GetObjectId(input, &idx, &oid, sz) < 0) {
4130             WOLFSSL_MSG("\tfail: OBJECT ID");
4131             return ASN_PARSE_E;
4132         }
4133
4134         /* check for critical flag */
4135         critical = 0;
4136         if (input[idx] == ASN_BOOLEAN) {
4137             int boolLength = 0;
4138             idx++;
4139             if (GetLength(input, &idx, &boolLength, sz) < 0) {
4140                 WOLFSSL_MSG("\tfail: critical boolean length");
4141                 return ASN_PARSE_E;
4142             }
4143             if (input[idx++])
4144                 critical = 1;
4145         }
4146
4147         /* process the extension based on the OID */
4148         if (input[idx++] != ASN_OCTET_STRING) {
4149             WOLFSSL_MSG("\tfail: should be an OCTET STRING");
4150             return ASN_PARSE_E;
4151         }
4152
4153         if (GetLength(input, &idx, &length, sz) < 0) {
4154             WOLFSSL_MSG("\tfail: extension data length");
4155             return ASN_PARSE_E;
4156         }
4157
4158         switch (oid) {
4159             case BASIC_CA_OID:
4160                 #ifdef OPENSSL_EXTRA
4161                     cert->extBasicConstSet = 1;
4162                     cert->extBasicConstCrit = critical;
4163                 #endif
4164                 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
4165                     return ASN_PARSE_E;
4166                 break;
4167
4168             case CRL_DIST_OID:
4169                 if (DecodeCrlDist(&input[idx], length, cert) < 0)
4170                     return ASN_PARSE_E;
4171                 break;
4172
4173             case AUTH_INFO_OID:
4174                 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
4175                     return ASN_PARSE_E;
4176                 break;
4177
4178             case ALT_NAMES_OID:
4179                 #ifdef OPENSSL_EXTRA
4180                     cert->extSubjAltNameSet = 1;
4181                     cert->extSubjAltNameCrit = critical;
4182                 #endif
4183                 if (DecodeAltNames(&input[idx], length, cert) < 0)
4184                     return ASN_PARSE_E;
4185                 break;
4186
4187             case AUTH_KEY_OID:
4188                 cert->extAuthKeyIdSet = 1;
4189                 #ifdef OPENSSL_EXTRA
4190                     cert->extAuthKeyIdCrit = critical;
4191                 #endif
4192                 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
4193                     return ASN_PARSE_E;
4194                 break;
4195
4196             case SUBJ_KEY_OID:
4197                 cert->extSubjKeyIdSet = 1;
4198                 #ifdef OPENSSL_EXTRA
4199                     cert->extSubjKeyIdCrit = critical;
4200                 #endif
4201                 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
4202                     return ASN_PARSE_E;
4203                 break;
4204
4205             case CERT_POLICY_OID:
4206                 WOLFSSL_MSG("Certificate Policy extension not supported yet.");
4207                 #ifdef WOLFSSL_SEP
4208                     #ifdef OPENSSL_EXTRA
4209                         cert->extCertPolicySet = 1;
4210                         cert->extCertPolicyCrit = critical;
4211                     #endif
4212                     if (DecodeCertPolicy(&input[idx], length, cert) < 0)
4213                         return ASN_PARSE_E;
4214                 #endif
4215                 break;
4216
4217             case KEY_USAGE_OID:
4218                 cert->extKeyUsageSet = 1;
4219                 #ifdef OPENSSL_EXTRA
4220                     cert->extKeyUsageCrit = critical;
4221                 #endif
4222                 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
4223                     return ASN_PARSE_E;
4224                 break;
4225
4226             case EXT_KEY_USAGE_OID:
4227                 cert->extExtKeyUsageSet = 1;
4228                 #ifdef OPENSSL_EXTRA
4229                     cert->extExtKeyUsageCrit = critical;
4230                 #endif
4231                 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
4232                     return ASN_PARSE_E;
4233                 break;
4234
4235             #ifndef IGNORE_NAME_CONSTRAINTS
4236             case NAME_CONS_OID:
4237                 cert->extNameConstraintSet = 1;
4238                 #ifdef OPENSSL_EXTRA
4239                     cert->extNameConstraintCrit = critical;
4240                 #endif
4241                 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
4242                     return ASN_PARSE_E;
4243                 break;
4244             #endif /* IGNORE_NAME_CONSTRAINTS */
4245
4246             case INHIBIT_ANY_OID:
4247                 WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
4248                 break;
4249
4250             default:
4251                 /* While it is a failure to not support critical extensions,
4252                  * still parse the certificate ignoring the unsupported
4253                  * extention to allow caller to accept it with the verify
4254                  * callback. */
4255                 if (critical)
4256                     criticalFail = 1;
4257                 break;
4258         }
4259         idx += length;
4260     }
4261
4262     return criticalFail ? ASN_CRIT_EXT_E : 0;
4263 }
4264
4265
4266 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
4267 {
4268     int   ret;
4269     char* ptr;
4270
4271     ret = ParseCertRelative(cert, type, verify, cm);
4272     if (ret < 0)
4273         return ret;
4274
4275     if (cert->subjectCNLen > 0) {
4276         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
4277                               DYNAMIC_TYPE_SUBJECT_CN);
4278         if (ptr == NULL)
4279             return MEMORY_E;
4280         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
4281         ptr[cert->subjectCNLen] = '\0';
4282         cert->subjectCN = ptr;
4283         cert->subjectCNStored = 1;
4284     }
4285
4286     if (cert->keyOID == RSAk &&
4287                           cert->publicKey != NULL  && cert->pubKeySize > 0) {
4288         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
4289                               DYNAMIC_TYPE_PUBLIC_KEY);
4290         if (ptr == NULL)
4291             return MEMORY_E;
4292         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
4293         cert->publicKey = (byte *)ptr;
4294         cert->pubKeyStored = 1;
4295     }
4296
4297     return ret;
4298 }
4299
4300
4301 /* from SSL proper, for locking can't do find here anymore */
4302 #ifdef __cplusplus
4303     extern "C" {
4304 #endif
4305     WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);
4306     #ifndef NO_SKID
4307         WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
4308     #endif
4309 #ifdef __cplusplus
4310     } 
4311 #endif
4312
4313
4314 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
4315 {
4316     word32 confirmOID;
4317     int    ret;
4318     int    badDate     = 0;
4319     int    criticalExt = 0;
4320
4321     if ((ret = DecodeToKey(cert, verify)) < 0) {
4322         if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
4323             badDate = ret;
4324         else
4325             return ret;
4326     }
4327
4328     WOLFSSL_MSG("Parsed Past Key");
4329
4330     if (cert->srcIdx < cert->sigIndex) {
4331         #ifndef ALLOW_V1_EXTENSIONS
4332             if (cert->version < 2) {
4333                 WOLFSSL_MSG("    v1 and v2 certs not allowed extensions");
4334                 return ASN_VERSION_E;
4335             }
4336         #endif
4337         /* save extensions */
4338         cert->extensions    = &cert->source[cert->srcIdx];
4339         cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
4340         cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
4341
4342         if ((ret = DecodeCertExtensions(cert)) < 0) {
4343             if (ret == ASN_CRIT_EXT_E)
4344                 criticalExt = ret;
4345             else
4346                 return ret;
4347         }
4348
4349         /* advance past extensions */
4350         cert->srcIdx =  cert->sigIndex;
4351     }
4352
4353     if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
4354                          cert->maxIdx)) < 0)
4355         return ret;
4356
4357     if ((ret = GetSignature(cert)) < 0)
4358         return ret;
4359
4360     if (confirmOID != cert->signatureOID)
4361         return ASN_SIG_OID_E;
4362
4363     #ifndef NO_SKID
4364         if (cert->extSubjKeyIdSet == 0
4365                           && cert->publicKey != NULL && cert->pubKeySize > 0) {
4366         #ifdef NO_SHA
4367             ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
4368                                                             cert->extSubjKeyId);
4369         #else
4370             ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
4371                                                             cert->extSubjKeyId);
4372         #endif
4373             if (ret != 0)
4374                 return ret;
4375         }
4376     #endif
4377
4378     if (verify && type != CA_TYPE) {
4379         Signer* ca = NULL;
4380         #ifndef NO_SKID
4381             if (cert->extAuthKeyIdSet)
4382                 ca = GetCA(cm, cert->extAuthKeyId);
4383             if (ca == NULL)
4384                 ca = GetCAByName(cm, cert->issuerHash);
4385         #else /* NO_SKID */
4386             ca = GetCA(cm, cert->issuerHash);
4387         #endif /* NO SKID */
4388         WOLFSSL_MSG("About to verify certificate signature");
4389  
4390         if (ca) {
4391 #ifdef HAVE_OCSP
4392             /* Need the ca's public key hash for OCSP */
4393     #ifdef NO_SHA
4394             ret = wc_Sha256Hash(ca->publicKey, ca->pubKeySize,
4395                                 cert->issuerKeyHash);
4396     #else /* NO_SHA */
4397             ret = wc_ShaHash(ca->publicKey, ca->pubKeySize,
4398                                 cert->issuerKeyHash);
4399     #endif /* NO_SHA */
4400             if (ret != 0)
4401                 return ret;
4402 #endif /* HAVE_OCSP */
4403             /* try to confirm/verify signature */
4404             if (!ConfirmSignature(cert->source + cert->certBegin,
4405                         cert->sigIndex - cert->certBegin,
4406                     ca->publicKey, ca->pubKeySize, ca->keyOID,
4407                     cert->signature, cert->sigLength, cert->signatureOID,
4408                     cert->heap)) {
4409                 WOLFSSL_MSG("Confirm signature failed");
4410                 return ASN_SIG_CONFIRM_E;
4411             }
4412 #ifndef IGNORE_NAME_CONSTRAINTS
4413             /* check that this cert's name is permitted by the signer's
4414              * name constraints */
4415             if (!ConfirmNameConstraints(ca, cert)) {
4416                 WOLFSSL_MSG("Confirm name constraint failed");
4417                 return ASN_NAME_INVALID_E;
4418             }
4419 #endif /* IGNORE_NAME_CONSTRAINTS */
4420         }
4421         else {
4422             /* no signer */
4423             WOLFSSL_MSG("No CA signer to verify with");
4424             return ASN_NO_SIGNER_E;
4425         }
4426     }
4427
4428     if (badDate != 0)
4429         return badDate;
4430
4431     if (criticalExt != 0)
4432         return criticalExt;
4433
4434     return 0;
4435 }
4436
4437
4438 /* Create and init an new signer */
4439 Signer* MakeSigner(void* heap)
4440 {
4441     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
4442                                        DYNAMIC_TYPE_SIGNER);
4443     if (signer) {
4444         signer->pubKeySize = 0;
4445         signer->keyOID     = 0;
4446         signer->publicKey  = NULL;
4447         signer->nameLen    = 0;
4448         signer->name       = NULL;
4449         #ifndef IGNORE_NAME_CONSTRAINTS
4450             signer->permittedNames = NULL;
4451             signer->excludedNames = NULL;
4452         #endif /* IGNORE_NAME_CONSTRAINTS */
4453         signer->next       = NULL;
4454     }
4455     (void)heap;
4456
4457     return signer;
4458 }
4459
4460
4461 /* Free an individual signer */
4462 void FreeSigner(Signer* signer, void* heap)
4463 {
4464     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
4465     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
4466     #ifndef IGNORE_NAME_CONSTRAINTS
4467         if (signer->permittedNames)
4468             FreeNameSubtrees(signer->permittedNames, heap);
4469         if (signer->excludedNames)
4470             FreeNameSubtrees(signer->excludedNames, heap);
4471     #endif
4472     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
4473
4474     (void)heap;
4475 }
4476
4477
4478 /* Free the whole singer table with number of rows */
4479 void FreeSignerTable(Signer** table, int rows, void* heap)
4480 {
4481     int i;
4482
4483     for (i = 0; i < rows; i++) {
4484         Signer* signer = table[i];
4485         while (signer) {
4486             Signer* next = signer->next;
4487             FreeSigner(signer, heap);
4488             signer = next;
4489         }
4490         table[i] = NULL;
4491     }
4492 }
4493
4494
4495 WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
4496 {
4497     int i = 0;
4498
4499     if (header) {
4500         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
4501         output[i++] = ASN_BIT_STRING;
4502     }
4503     output[i++] = ASN_INTEGER;
4504     output[i++] = 0x01;
4505     output[i++] = (byte)version;
4506
4507     return i;
4508 }
4509
4510
4511 WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
4512 {
4513     int result = 0;
4514
4515     WOLFSSL_ENTER("SetSerialNumber");
4516
4517     if (snSz <= EXTERNAL_SERIAL_SIZE) {
4518         output[0] = ASN_INTEGER;
4519         /* The serial number is always positive. When encoding the
4520          * INTEGER, if the MSB is 1, add a padding zero to keep the
4521          * number positive. */
4522         if (sn[0] & 0x80) {
4523             output[1] = (byte)snSz + 1;
4524             output[2] = 0;
4525             XMEMCPY(&output[3], sn, snSz);
4526             result = snSz + 3;
4527         }
4528         else {
4529             output[1] = (byte)snSz;
4530             XMEMCPY(&output[2], sn, snSz);
4531             result = snSz + 2;
4532         }
4533     }
4534     return result;
4535 }
4536
4537
4538
4539
4540 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)
4541
4542 /* convert der buffer to pem into output, can't do inplace, der and output
4543    need to be different */
4544 int wc_DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
4545              int type)
4546 {
4547 #ifdef WOLFSSL_SMALL_STACK
4548     char* header = NULL;
4549     char* footer = NULL;
4550 #else
4551     char header[80];
4552     char footer[80];
4553 #endif
4554
4555     int headerLen = 80;
4556     int footerLen = 80;
4557     int i;
4558     int err;
4559     int outLen;   /* return length or error */
4560
4561     if (der == output)      /* no in place conversion */
4562         return BAD_FUNC_ARG;
4563
4564 #ifdef WOLFSSL_SMALL_STACK
4565     header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4566     if (header == NULL)
4567         return MEMORY_E;
4568     
4569     footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4570     if (footer == NULL) {
4571         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4572         return MEMORY_E;
4573     }
4574 #endif
4575
4576     if (type == CERT_TYPE) {
4577         XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", headerLen);
4578         XSTRNCPY(footer, "-----END CERTIFICATE-----\n",   footerLen);
4579     }
4580     else if (type == PRIVATEKEY_TYPE) {
4581         XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", headerLen);
4582         XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n",   footerLen);
4583     }
4584     #ifdef HAVE_ECC
4585     else if (type == ECC_PRIVATEKEY_TYPE) {
4586         XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", headerLen);
4587         XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n",   footerLen);
4588     }
4589     #endif
4590     #ifdef WOLFSSL_CERT_REQ
4591     else if (type == CERTREQ_TYPE)
4592     {
4593         XSTRNCPY(header,
4594                        "-----BEGIN CERTIFICATE REQUEST-----\n", headerLen);
4595         XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", footerLen);
4596     }
4597     #endif
4598     else {
4599 #ifdef WOLFSSL_SMALL_STACK
4600         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4601         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4602 #endif
4603         return BAD_FUNC_ARG;
4604     }
4605
4606     headerLen = (int)XSTRLEN(header);
4607     footerLen = (int)XSTRLEN(footer);
4608
4609     if (!der || !output) {
4610 #ifdef WOLFSSL_SMALL_STACK
4611         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4612         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4613 #endif
4614         return BAD_FUNC_ARG;
4615     }
4616
4617     /* don't even try if outSz too short */
4618     if (outSz < headerLen + footerLen + derSz) {
4619 #ifdef WOLFSSL_SMALL_STACK
4620         XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4621         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4622 #endif
4623         return BAD_FUNC_ARG;
4624     }
4625
4626     /* header */
4627     XMEMCPY(output, header, headerLen);
4628     i = headerLen;
4629
4630 #ifdef WOLFSSL_SMALL_STACK
4631     XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4632 #endif
4633
4634     /* body */
4635     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
4636     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
4637 #ifdef WOLFSSL_SMALL_STACK
4638         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4639 #endif
4640         return err;
4641     }
4642     i += outLen;
4643
4644     /* footer */
4645     if ( (i + footerLen) > (int)outSz) {
4646 #ifdef WOLFSSL_SMALL_STACK
4647         XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4648 #endif
4649         return BAD_FUNC_ARG;
4650     }
4651     XMEMCPY(output + i, footer, footerLen);
4652
4653 #ifdef WOLFSSL_SMALL_STACK
4654     XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4655 #endif
4656
4657     return outLen + headerLen + footerLen;
4658 }
4659
4660
4661 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */
4662
4663
4664 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
4665
4666
4667 static mp_int* GetRsaInt(RsaKey* key, int idx)
4668 {
4669     if (idx == 0)
4670         return &key->n;
4671     if (idx == 1)
4672         return &key->e;
4673     if (idx == 2)
4674         return &key->d;
4675     if (idx == 3)
4676         return &key->p;
4677     if (idx == 4)
4678         return &key->q;
4679     if (idx == 5)
4680         return &key->dP;
4681     if (idx == 6)
4682         return &key->dQ;
4683     if (idx == 7)
4684         return &key->u;
4685
4686     return NULL;
4687 }
4688
4689
4690 /* Release Tmp RSA resources */
4691 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
4692 {
4693     int i;
4694
4695     (void)heap;
4696
4697     for (i = 0; i < RSA_INTS; i++) 
4698         XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
4699 }
4700
4701
4702 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
4703    written */
4704 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
4705 {
4706     word32 seqSz, verSz, rawLen, intTotalLen = 0;
4707     word32 sizes[RSA_INTS];
4708     int    i, j, outLen, ret = 0;
4709
4710     byte  seq[MAX_SEQ_SZ];
4711     byte  ver[MAX_VERSION_SZ];
4712     byte* tmps[RSA_INTS];
4713
4714     if (!key || !output)
4715         return BAD_FUNC_ARG;
4716
4717     if (key->type != RSA_PRIVATE)
4718         return BAD_FUNC_ARG;
4719
4720     for (i = 0; i < RSA_INTS; i++)
4721         tmps[i] = NULL;
4722
4723     /* write all big ints from key to DER tmps */
4724     for (i = 0; i < RSA_INTS; i++) {
4725         mp_int* keyInt = GetRsaInt(key, i);
4726         rawLen = mp_unsigned_bin_size(keyInt);
4727         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
4728                                  DYNAMIC_TYPE_RSA);
4729         if (tmps[i] == NULL) {
4730             ret = MEMORY_E;
4731             break;
4732         }
4733
4734         tmps[i][0] = ASN_INTEGER;
4735         sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1;  /* int tag */
4736
4737         if (sizes[i] <= MAX_SEQ_SZ) {
4738             int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
4739             if (err == MP_OKAY) {
4740                 sizes[i] += rawLen;
4741                 intTotalLen += sizes[i];
4742             }
4743             else {
4744                 ret = err;
4745                 break;
4746             }
4747         }
4748         else {
4749             ret = ASN_INPUT_E;
4750             break;
4751         }
4752     }
4753
4754     if (ret != 0) {
4755         FreeTmpRsas(tmps, key->heap);
4756         return ret;
4757     }
4758
4759     /* make headers */
4760     verSz = SetMyVersion(0, ver, FALSE);
4761     seqSz = SetSequence(verSz + intTotalLen, seq);
4762
4763     outLen = seqSz + verSz + intTotalLen;
4764     if (outLen > (int)inLen)
4765         return BAD_FUNC_ARG;
4766
4767     /* write to output */
4768     XMEMCPY(output, seq, seqSz);
4769     j = seqSz;
4770     XMEMCPY(output + j, ver, verSz);
4771     j += verSz;
4772
4773     for (i = 0; i < RSA_INTS; i++) {
4774         XMEMCPY(output + j, tmps[i], sizes[i]);
4775         j += sizes[i];
4776     }
4777     FreeTmpRsas(tmps, key->heap);
4778
4779     return outLen;
4780 }
4781
4782 #endif /* WOLFSSL_KEY_GEN && !NO_RSA */
4783
4784
4785 #if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA)
4786
4787
4788 #ifndef WOLFSSL_HAVE_MIN
4789 #define WOLFSSL_HAVE_MIN
4790
4791     static INLINE word32 min(word32 a, word32 b)
4792     {
4793         return a > b ? b : a;
4794     }
4795
4796 #endif /* WOLFSSL_HAVE_MIN */
4797
4798
4799 /* Initialize and Set Certficate defaults:
4800    version    = 3 (0x2)
4801    serial     = 0
4802    sigType    = SHA_WITH_RSA
4803    issuer     = blank
4804    daysValid  = 500
4805    selfSigned = 1 (true) use subject as issuer
4806    subject    = blank
4807 */
4808 void wc_InitCert(Cert* cert)
4809 {
4810     cert->version    = 2;   /* version 3 is hex 2 */
4811     cert->sigType    = CTC_SHAwRSA;
4812     cert->daysValid  = 500;
4813     cert->selfSigned = 1;
4814     cert->isCA       = 0;
4815     cert->bodySz     = 0;
4816 #ifdef WOLFSSL_ALT_NAMES
4817     cert->altNamesSz   = 0;
4818     cert->beforeDateSz = 0;
4819     cert->afterDateSz  = 0;
4820 #endif
4821     cert->keyType    = RSA_KEY;
4822     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
4823
4824     cert->issuer.country[0] = '\0';
4825     cert->issuer.countryEnc = CTC_PRINTABLE;
4826     cert->issuer.state[0] = '\0';
4827     cert->issuer.stateEnc = CTC_UTF8;
4828     cert->issuer.locality[0] = '\0';
4829     cert->issuer.localityEnc = CTC_UTF8;
4830     cert->issuer.sur[0] = '\0';
4831     cert->issuer.surEnc = CTC_UTF8;
4832     cert->issuer.org[0] = '\0';
4833     cert->issuer.orgEnc = CTC_UTF8;
4834     cert->issuer.unit[0] = '\0';
4835     cert->issuer.unitEnc = CTC_UTF8;
4836     cert->issuer.commonName[0] = '\0';
4837     cert->issuer.commonNameEnc = CTC_UTF8;
4838     cert->issuer.email[0] = '\0';
4839
4840     cert->subject.country[0] = '\0';
4841     cert->subject.countryEnc = CTC_PRINTABLE;
4842     cert->subject.state[0] = '\0';
4843     cert->subject.stateEnc = CTC_UTF8;
4844     cert->subject.locality[0] = '\0';
4845     cert->subject.localityEnc = CTC_UTF8;
4846     cert->subject.sur[0] = '\0';
4847     cert->subject.surEnc = CTC_UTF8;
4848     cert->subject.org[0] = '\0';
4849     cert->subject.orgEnc = CTC_UTF8;
4850     cert->subject.unit[0] = '\0';
4851     cert->subject.unitEnc = CTC_UTF8;
4852     cert->subject.commonName[0] = '\0';
4853     cert->subject.commonNameEnc = CTC_UTF8;
4854     cert->subject.email[0] = '\0';
4855
4856 #ifdef WOLFSSL_CERT_REQ
4857     cert->challengePw[0] ='\0';
4858 #endif
4859 }
4860
4861
4862 /* DER encoded x509 Certificate */
4863 typedef struct DerCert {
4864     byte size[MAX_LENGTH_SZ];          /* length encoded */
4865     byte version[MAX_VERSION_SZ];      /* version encoded */
4866     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
4867     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
4868     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
4869     byte subject[ASN_NAME_MAX];        /* subject encoded */
4870     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
4871     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
4872     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
4873     byte extensions[MAX_EXTENSIONS_SZ];  /* all extensions */
4874 #ifdef WOLFSSL_CERT_REQ
4875     byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
4876 #endif
4877     int  sizeSz;                       /* encoded size length */
4878     int  versionSz;                    /* encoded version length */
4879     int  serialSz;                     /* encoded serial length */
4880     int  sigAlgoSz;                    /* enocded sig alog length */
4881     int  issuerSz;                     /* encoded issuer length */
4882     int  subjectSz;                    /* encoded subject length */
4883     int  validitySz;                   /* encoded validity length */
4884     int  publicKeySz;                  /* encoded public key length */
4885     int  caSz;                         /* encoded CA extension length */
4886     int  extensionsSz;                 /* encoded extensions total length */
4887     int  total;                        /* total encoded lengths */
4888 #ifdef WOLFSSL_CERT_REQ
4889     int  attribSz;
4890 #endif
4891 } DerCert;
4892
4893
4894 #ifdef WOLFSSL_CERT_REQ
4895
4896 /* Write a set header to output */
4897 static word32 SetUTF8String(word32 len, byte* output)
4898 {
4899     output[0] = ASN_UTF8STRING;
4900     return SetLength(len, output + 1) + 1;
4901 }
4902
4903 #endif /* WOLFSSL_CERT_REQ */
4904
4905
4906 /* Write a serial number to output */
4907 static int SetSerial(const byte* serial, byte* output)
4908 {
4909     int length = 0;
4910
4911     output[length++] = ASN_INTEGER;
4912     length += SetLength(CTC_SERIAL_SIZE, &output[length]);
4913     XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
4914
4915     return length + CTC_SERIAL_SIZE;
4916 }
4917
4918
4919 #ifdef HAVE_ECC 
4920
4921
4922 /* Write a public ECC key to output */
4923 static int SetEccPublicKey(byte* output, ecc_key* key)
4924 {
4925     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
4926     int  algoSz;
4927     int  curveSz;
4928     int  lenSz;
4929     int  idx;
4930     word32 pubSz = ECC_BUFSIZE;
4931 #ifdef WOLFSSL_SMALL_STACK
4932     byte* algo = NULL;
4933     byte* curve = NULL;
4934     byte* pub = NULL;
4935 #else
4936     byte algo[MAX_ALGO_SZ];
4937     byte curve[MAX_ALGO_SZ];
4938     byte pub[ECC_BUFSIZE];
4939 #endif
4940
4941 #ifdef WOLFSSL_SMALL_STACK
4942     pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4943     if (pub == NULL)
4944         return MEMORY_E;
4945 #endif
4946
4947     int ret = wc_ecc_export_x963(key, pub, &pubSz);
4948     if (ret != 0) {
4949 #ifdef WOLFSSL_SMALL_STACK
4950         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4951 #endif
4952         return ret;
4953     }
4954
4955 #ifdef WOLFSSL_SMALL_STACK
4956     curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4957     if (curve == NULL) {
4958         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4959         return MEMORY_E;
4960     }
4961 #endif
4962
4963     /* headers */
4964     curveSz = SetCurve(key, curve);
4965     if (curveSz <= 0) {
4966 #ifdef WOLFSSL_SMALL_STACK
4967         XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4968         XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
4969 #endif
4970         return curveSz;
4971     }
4972
4973 #ifdef WOLFSSL_SMALL_STACK
4974     algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4975     if (algo == NULL) {
4976         XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4977         XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
4978         return MEMORY_E;
4979     }
4980 #endif
4981
4982     algoSz  = SetAlgoID(ECDSAk, algo, keyType, curveSz);
4983     lenSz   = SetLength(pubSz + 1, len);
4984     len[lenSz++] = 0;   /* trailing 0 */
4985
4986     /* write */
4987     idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output);
4988         /* 1 is for ASN_BIT_STRING */
4989     /* algo */
4990     XMEMCPY(output + idx, algo, algoSz);
4991     idx += algoSz;
4992     /* curve */
4993     XMEMCPY(output + idx, curve, curveSz);
4994     idx += curveSz;
4995     /* bit string */
4996     output[idx++] = ASN_BIT_STRING;
4997     /* length */
4998     XMEMCPY(output + idx, len, lenSz);
4999     idx += lenSz;
5000     /* pub */
5001     XMEMCPY(output + idx, pub, pubSz);
5002     idx += pubSz;
5003
5004 #ifdef WOLFSSL_SMALL_STACK
5005     XFREE(algo,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
5006     XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5007     XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
5008 #endif
5009
5010     return idx;
5011 }
5012
5013
5014 #endif /* HAVE_ECC */
5015
5016
5017 /* Write a public RSA key to output */
5018 static int SetRsaPublicKey(byte* output, RsaKey* key)
5019 {
5020 #ifdef WOLFSSL_SMALL_STACK
5021     byte* n = NULL;
5022     byte* e = NULL;
5023     byte* algo = NULL;
5024 #else
5025     byte n[MAX_RSA_INT_SZ];
5026     byte e[MAX_RSA_E_SZ];
5027     byte algo[MAX_ALGO_SZ];
5028 #endif
5029     byte seq[MAX_SEQ_SZ];
5030     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
5031     int  nSz;
5032     int  eSz;
5033     int  algoSz;
5034     int  seqSz;
5035     int  lenSz;
5036     int  idx;
5037     int  rawLen;
5038     int  leadingBit;
5039     int  err;
5040
5041     /* n */
5042 #ifdef WOLFSSL_SMALL_STACK
5043     n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5044     if (n == NULL)
5045         return MEMORY_E;
5046 #endif
5047
5048     leadingBit = mp_leading_bit(&key->n);
5049     rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
5050     n[0] = ASN_INTEGER;
5051     nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
5052
5053     if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
5054         if (leadingBit)
5055             n[nSz] = 0;
5056         err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
5057         if (err == MP_OKAY)
5058             nSz += rawLen;
5059         else {
5060 #ifdef WOLFSSL_SMALL_STACK
5061             XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5062 #endif
5063             return MP_TO_E;
5064         }
5065     }
5066     else {
5067 #ifdef WOLFSSL_SMALL_STACK
5068         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5069 #endif
5070         return BUFFER_E;
5071     }
5072
5073     /* e */
5074 #ifdef WOLFSSL_SMALL_STACK
5075     e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5076     if (e == NULL) {
5077 #ifdef WOLFSSL_SMALL_STACK
5078         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5079 #endif
5080         return MEMORY_E;
5081     }
5082 #endif
5083
5084     leadingBit = mp_leading_bit(&key->e);
5085     rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
5086     e[0] = ASN_INTEGER;
5087     eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
5088
5089     if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
5090         if (leadingBit)
5091             e[eSz] = 0;
5092         err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
5093         if (err == MP_OKAY)
5094             eSz += rawLen;
5095         else {
5096 #ifdef WOLFSSL_SMALL_STACK
5097             XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5098             XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5099 #endif
5100             return MP_TO_E;
5101         }
5102     }
5103     else {
5104 #ifdef WOLFSSL_SMALL_STACK
5105         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5106         XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5107 #endif
5108         return BUFFER_E;
5109     }
5110
5111 #ifdef WOLFSSL_SMALL_STACK
5112     algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5113     if (algo == NULL) {
5114         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5115         XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5116         return MEMORY_E;
5117     }
5118 #endif
5119
5120     /* headers */
5121     algoSz = SetAlgoID(RSAk, algo, keyType, 0);
5122     seqSz  = SetSequence(nSz + eSz, seq);
5123     lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
5124     len[lenSz++] = 0;   /* trailing 0 */
5125
5126     /* write */
5127     idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
5128         /* 1 is for ASN_BIT_STRING */
5129     /* algo */
5130     XMEMCPY(output + idx, algo, algoSz);
5131     idx += algoSz;
5132     /* bit string */
5133     output[idx++] = ASN_BIT_STRING;
5134     /* length */
5135     XMEMCPY(output + idx, len, lenSz);
5136     idx += lenSz;
5137     /* seq */
5138     XMEMCPY(output + idx, seq, seqSz);
5139     idx += seqSz;
5140     /* n */
5141     XMEMCPY(output + idx, n, nSz);
5142     idx += nSz;
5143     /* e */
5144     XMEMCPY(output + idx, e, eSz);
5145     idx += eSz;
5146
5147 #ifdef WOLFSSL_SMALL_STACK
5148     XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
5149     XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
5150     XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5151 #endif
5152
5153     return idx;
5154 }
5155
5156
5157 static INLINE byte itob(int number)
5158 {
5159     return (byte)number + 0x30;
5160 }
5161
5162
5163 /* write time to output, format */
5164 static void SetTime(struct tm* date, byte* output)
5165 {
5166     int i = 0;
5167
5168     output[i++] = itob((date->tm_year % 10000) / 1000);
5169     output[i++] = itob((date->tm_year % 1000)  /  100);
5170     output[i++] = itob((date->tm_year % 100)   /   10);
5171     output[i++] = itob( date->tm_year % 10);
5172
5173     output[i++] = itob(date->tm_mon / 10);
5174     output[i++] = itob(date->tm_mon % 10);
5175
5176     output[i++] = itob(date->tm_mday / 10);
5177     output[i++] = itob(date->tm_mday % 10);
5178
5179     output[i++] = itob(date->tm_hour / 10);
5180     output[i++] = itob(date->tm_hour % 10);
5181
5182     output[i++] = itob(date->tm_min / 10);
5183     output[i++] = itob(date->tm_min % 10);
5184
5185     output[i++] = itob(date->tm_sec / 10);
5186     output[i++] = itob(date->tm_sec % 10);
5187     
5188     output[i] = 'Z';  /* Zulu profile */
5189 }
5190
5191
5192 #ifdef WOLFSSL_ALT_NAMES
5193
5194 /* Copy Dates from cert, return bytes written */
5195 static int CopyValidity(byte* output, Cert* cert)
5196 {
5197     int seqSz;
5198
5199     WOLFSSL_ENTER("CopyValidity");
5200
5201     /* headers and output */
5202     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
5203     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
5204     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
5205                                                  cert->afterDateSz);
5206     return seqSz + cert->beforeDateSz + cert->afterDateSz;
5207 }
5208
5209 #endif
5210
5211
5212 /* for systems where mktime() doesn't normalize fully */
5213 static void RebuildTime(time_t* in, struct tm* out)
5214 {
5215     #ifdef FREESCALE_MQX
5216         out = localtime_r(in, out);
5217     #else
5218         (void)in;
5219         (void)out;
5220     #endif
5221 }
5222
5223
5224 /* Set Date validity from now until now + daysValid */
5225 static int SetValidity(byte* output, int daysValid)
5226 {
5227     byte before[MAX_DATE_SIZE];
5228     byte  after[MAX_DATE_SIZE];
5229
5230     int beforeSz;
5231     int afterSz;
5232     int seqSz;
5233
5234     time_t     ticks;
5235     time_t     normalTime;
5236     struct tm* now;
5237     struct tm* tmpTime = NULL;
5238     struct tm  local;
5239
5240 #if defined(FREESCALE_MQX) || defined(TIME_OVERRIDES)
5241     /* for use with gmtime_r */
5242     struct tm tmpTimeStorage;
5243     tmpTime = &tmpTimeStorage;
5244 #else
5245     (void)tmpTime;
5246 #endif
5247
5248     ticks = XTIME(0);
5249     now   = XGMTIME(&ticks, tmpTime);
5250
5251     /* before now */
5252     local = *now;
5253     before[0] = ASN_GENERALIZED_TIME;
5254     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
5255
5256     /* subtract 1 day for more compliance */
5257     local.tm_mday -= 1;
5258     normalTime = mktime(&local);
5259     RebuildTime(&normalTime, &local);
5260
5261     /* adjust */
5262     local.tm_year += 1900;
5263     local.tm_mon  +=    1;
5264
5265     SetTime(&local, before + beforeSz);
5266     beforeSz += ASN_GEN_TIME_SZ;
5267
5268     /* after now + daysValid */
5269     local = *now;
5270     after[0] = ASN_GENERALIZED_TIME;
5271     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
5272
5273     /* add daysValid */
5274     local.tm_mday += daysValid;
5275     normalTime = mktime(&local);
5276     RebuildTime(&normalTime, &local);
5277
5278     /* adjust */
5279     local.tm_year += 1900;
5280     local.tm_mon  +=    1;
5281
5282     SetTime(&local, after + afterSz);
5283     afterSz += ASN_GEN_TIME_SZ;
5284
5285     /* headers and output */
5286     seqSz = SetSequence(beforeSz + afterSz, output);
5287     XMEMCPY(output + seqSz, before, beforeSz);
5288     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
5289
5290     return seqSz + beforeSz + afterSz;
5291 }
5292
5293
5294 /* ASN Encoded Name field */
5295 typedef struct EncodedName {
5296     int  nameLen;                /* actual string value length */
5297     int  totalLen;               /* total encoded length */
5298     int  type;                   /* type of name */
5299     int  used;                   /* are we actually using this one */
5300     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
5301 } EncodedName;
5302
5303
5304 /* Get Which Name from index */
5305 static const char* GetOneName(CertName* name, int idx)
5306 {
5307     switch (idx) {
5308     case 0:
5309        return name->country;
5310
5311     case 1:
5312        return name->state;
5313
5314     case 2:
5315        return name->locality;
5316
5317     case 3:
5318        return name->sur;
5319
5320     case 4:
5321        return name->org;
5322
5323     case 5:
5324        return name->unit;
5325
5326     case 6:
5327        return name->commonName;
5328
5329     case 7:
5330        return name->email;
5331
5332     default:
5333        return 0;
5334     }
5335 }
5336
5337
5338 /* Get Which Name Encoding from index */
5339 static char GetNameType(CertName* name, int idx)
5340 {
5341     switch (idx) {
5342     case 0:
5343        return name->countryEnc;
5344
5345     case 1:
5346        return name->stateEnc;
5347
5348     case 2:
5349        return name->localityEnc;
5350
5351     case 3:
5352        return name->surEnc;
5353
5354     case 4:
5355        return name->orgEnc;
5356
5357     case 5:
5358        return name->unitEnc;
5359
5360     case 6:
5361        return name->commonNameEnc;
5362
5363     default:
5364        return 0;
5365     }
5366 }
5367
5368
5369 /* Get ASN Name from index */
5370 static byte GetNameId(int idx)
5371 {
5372     switch (idx) {
5373     case 0:
5374        return ASN_COUNTRY_NAME;
5375
5376     case 1:
5377        return ASN_STATE_NAME;
5378
5379     case 2:
5380        return ASN_LOCALITY_NAME;
5381
5382     case 3:
5383        return ASN_SUR_NAME;
5384
5385     case 4:
5386        return ASN_ORG_NAME;
5387
5388     case 5:
5389        return ASN_ORGUNIT_NAME;
5390
5391     case 6:
5392        return ASN_COMMON_NAME;
5393
5394     case 7:
5395        /* email uses different id type */
5396        return 0;
5397
5398     default:
5399        return 0;
5400     }
5401 }
5402
5403
5404 /* encode all extensions, return total bytes written */
5405 static int SetExtensions(byte* output, const byte* ext, int extSz, int header)
5406 {
5407     byte sequence[MAX_SEQ_SZ];
5408     byte len[MAX_LENGTH_SZ];
5409
5410     int sz = 0;
5411     int seqSz = SetSequence(extSz, sequence);
5412
5413     if (header) {
5414         int lenSz = SetLength(seqSz + extSz, len);
5415         output[0] = ASN_EXTENSIONS; /* extensions id */
5416         sz++;
5417         XMEMCPY(&output[sz], len, lenSz);  /* length */
5418         sz += lenSz;
5419     }
5420     XMEMCPY(&output[sz], sequence, seqSz);  /* sequence */
5421     sz += seqSz;
5422     XMEMCPY(&output[sz], ext, extSz);  /* extensions */
5423     sz += extSz;
5424
5425     return sz;
5426 }
5427
5428
5429 /* encode CA basic constraint true, return total bytes written */
5430 static int SetCa(byte* output)
5431 {
5432     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
5433                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
5434     
5435     XMEMCPY(output, ca, sizeof(ca));
5436
5437     return (int)sizeof(ca);
5438 }
5439
5440
5441 /* encode CertName into output, return total bytes written */
5442 static int SetName(byte* output, CertName* name)
5443 {
5444     int          totalBytes = 0, i, idx;
5445 #ifdef WOLFSSL_SMALL_STACK
5446     EncodedName* names = NULL;
5447 #else
5448     EncodedName  names[NAME_ENTRIES];
5449 #endif
5450
5451 #ifdef WOLFSSL_SMALL_STACK
5452     names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
5453                                                        DYNAMIC_TYPE_TMP_BUFFER);
5454     if (names == NULL)
5455         return MEMORY_E;
5456 #endif
5457
5458     for (i = 0; i < NAME_ENTRIES; i++) {
5459         const char* nameStr = GetOneName(name, i);
5460         if (nameStr) {
5461             /* bottom up */
5462             byte firstLen[MAX_LENGTH_SZ];
5463             byte secondLen[MAX_LENGTH_SZ];
5464             byte sequence[MAX_SEQ_SZ];
5465             byte set[MAX_SET_SZ];
5466
5467             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
5468             int strLen  = (int)XSTRLEN(nameStr);
5469             int thisLen = strLen;
5470             int firstSz, secondSz, seqSz, setSz;
5471
5472             if (strLen == 0) { /* no user data for this item */
5473                 names[i].used = 0;
5474                 continue;
5475             }
5476
5477             secondSz = SetLength(strLen, secondLen);
5478             thisLen += secondSz;
5479             if (email) {
5480                 thisLen += EMAIL_JOINT_LEN;
5481                 thisLen ++;                               /* id type */
5482                 firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
5483             }
5484             else {
5485                 thisLen++;                                 /* str type */
5486                 thisLen++;                                 /* id  type */
5487                 thisLen += JOINT_LEN;    
5488                 firstSz = SetLength(JOINT_LEN + 1, firstLen);
5489             }
5490             thisLen += firstSz;
5491             thisLen++;                                /* object id */
5492
5493             seqSz = SetSequence(thisLen, sequence);
5494             thisLen += seqSz;
5495             setSz = SetSet(thisLen, set);
5496             thisLen += setSz;
5497
5498             if (thisLen > (int)sizeof(names[i].encoded)) {
5499 #ifdef WOLFSSL_SMALL_STACK
5500                 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5501 #endif
5502                 return BUFFER_E;
5503             }
5504
5505             /* store it */
5506             idx = 0;
5507             /* set */
5508             XMEMCPY(names[i].encoded, set, setSz);
5509             idx += setSz;
5510             /* seq */
5511             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
5512             idx += seqSz;
5513             /* asn object id */
5514             names[i].encoded[idx++] = ASN_OBJECT_ID;
5515             /* first length */
5516             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
5517             idx += firstSz;
5518             if (email) {
5519                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
5520                                            0x01, 0x09, 0x01, 0x16 };
5521                 /* email joint id */
5522                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
5523                 idx += (int)sizeof(EMAIL_OID);
5524             }
5525             else {
5526                 /* joint id */
5527                 byte bType = GetNameId(i);
5528                 names[i].encoded[idx++] = 0x55;
5529                 names[i].encoded[idx++] = 0x04;
5530                 /* id type */
5531                 names[i].encoded[idx++] = bType; 
5532                 /* str type */
5533                 names[i].encoded[idx++] = GetNameType(name, i);
5534             }
5535             /* second length */
5536             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
5537             idx += secondSz;
5538             /* str value */
5539             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
5540             idx += strLen;
5541
5542             totalBytes += idx;
5543             names[i].totalLen = idx;
5544             names[i].used = 1;
5545         }
5546         else
5547             names[i].used = 0;
5548     }
5549
5550     /* header */
5551     idx = SetSequence(totalBytes, output);
5552     totalBytes += idx;
5553     if (totalBytes > ASN_NAME_MAX) {
5554 #ifdef WOLFSSL_SMALL_STACK
5555         XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5556 #endif
5557         return BUFFER_E;
5558     }
5559
5560     for (i = 0; i < NAME_ENTRIES; i++) {
5561         if (names[i].used) {
5562             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
5563             idx += names[i].totalLen;
5564         }
5565     }
5566
5567 #ifdef WOLFSSL_SMALL_STACK
5568     XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5569 #endif
5570
5571     return totalBytes;
5572 }
5573
5574 /* encode info from cert into DER encoded format */
5575 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
5576                       RNG* rng, const byte* ntruKey, word16 ntruSz)
5577 {
5578     int ret;
5579
5580     (void)eccKey;
5581     (void)ntruKey;
5582     (void)ntruSz;
5583
5584     /* init */
5585     XMEMSET(der, 0, sizeof(DerCert));
5586
5587     /* version */
5588     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
5589
5590     /* serial number */
5591     ret = wc_RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
5592     if (ret != 0)
5593         return ret;
5594
5595     cert->serial[0] = 0x01;   /* ensure positive */
5596     der->serialSz  = SetSerial(cert->serial, der->serial);
5597
5598     /* signature algo */
5599     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0);
5600     if (der->sigAlgoSz == 0)
5601         return ALGO_ID_E;
5602
5603     /* public key */
5604     if (cert->keyType == RSA_KEY) {
5605         if (rsaKey == NULL)
5606             return PUBLIC_KEY_E;
5607         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
5608         if (der->publicKeySz <= 0)
5609             return PUBLIC_KEY_E;
5610     }
5611
5612 #ifdef HAVE_ECC
5613     if (cert->keyType == ECC_KEY) {
5614         if (eccKey == NULL)
5615             return PUBLIC_KEY_E;
5616         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
5617         if (der->publicKeySz <= 0)
5618             return PUBLIC_KEY_E;
5619     }
5620 #endif /* HAVE_ECC */
5621
5622 #ifdef HAVE_NTRU
5623     if (cert->keyType == NTRU_KEY) {
5624         word32 rc;
5625         word16 encodedSz;
5626
5627         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
5628                                                    ntruKey, &encodedSz, NULL);
5629         if (rc != NTRU_OK)
5630             return PUBLIC_KEY_E;
5631         if (encodedSz > MAX_PUBLIC_KEY_SZ)
5632             return PUBLIC_KEY_E;
5633
5634         rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
5635                                          ntruKey, &encodedSz, der->publicKey);
5636         if (rc != NTRU_OK)
5637             return PUBLIC_KEY_E;
5638
5639         der->publicKeySz = encodedSz;
5640     }
5641 #endif /* HAVE_NTRU */
5642
5643     der->validitySz = 0;
5644 #ifdef WOLFSSL_ALT_NAMES
5645     /* date validity copy ? */
5646     if (cert->beforeDateSz && cert->afterDateSz) {
5647         der->validitySz = CopyValidity(der->validity, cert);
5648         if (der->validitySz == 0)
5649             return DATE_E;
5650     }
5651 #endif
5652
5653     /* date validity */
5654     if (der->validitySz == 0) {
5655         der->validitySz = SetValidity(der->validity, cert->daysValid);
5656         if (der->validitySz == 0)
5657             return DATE_E;
5658     }
5659
5660     /* subject name */
5661     der->subjectSz = SetName(der->subject, &cert->subject);
5662     if (der->subjectSz == 0)
5663         return SUBJECT_E;
5664
5665     /* issuer name */
5666     der->issuerSz = SetName(der->issuer, cert->selfSigned ?
5667              &cert->subject : &cert->issuer);
5668     if (der->issuerSz == 0)
5669         return ISSUER_E;
5670
5671     /* CA */
5672     if (cert->isCA) {
5673         der->caSz = SetCa(der->ca);
5674         if (der->caSz == 0)
5675             return CA_TRUE_E;
5676     }
5677     else
5678         der->caSz = 0;
5679
5680     /* extensions, just CA now */
5681     if (cert->isCA) {
5682         der->extensionsSz = SetExtensions(der->extensions,
5683                                           der->ca, der->caSz, TRUE);
5684         if (der->extensionsSz == 0)
5685             return EXTENSIONS_E;
5686     }
5687     else
5688         der->extensionsSz = 0;
5689
5690 #ifdef WOLFSSL_ALT_NAMES
5691     if (der->extensionsSz == 0 && cert->altNamesSz) {
5692         der->extensionsSz = SetExtensions(der->extensions, cert->altNames,
5693                                           cert->altNamesSz, TRUE);
5694         if (der->extensionsSz == 0)
5695             return EXTENSIONS_E;
5696     }
5697 #endif
5698
5699     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
5700         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
5701         der->extensionsSz;
5702
5703     return 0;
5704 }
5705
5706
5707 /* write DER encoded cert to buffer, size already checked */
5708 static int WriteCertBody(DerCert* der, byte* buffer)
5709 {
5710     int idx;
5711
5712     /* signed part header */
5713     idx = SetSequence(der->total, buffer);
5714     /* version */
5715     XMEMCPY(buffer + idx, der->version, der->versionSz);
5716     idx += der->versionSz;
5717     /* serial */
5718     XMEMCPY(buffer + idx, der->serial, der->serialSz);
5719     idx += der->serialSz;
5720     /* sig algo */
5721     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
5722     idx += der->sigAlgoSz;
5723     /* issuer */
5724     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
5725     idx += der->issuerSz;
5726     /* validity */
5727     XMEMCPY(buffer + idx, der->validity, der->validitySz);
5728     idx += der->validitySz;
5729     /* subject */
5730     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
5731     idx += der->subjectSz;
5732     /* public key */
5733     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
5734     idx += der->publicKeySz;
5735     if (der->extensionsSz) {
5736         /* extensions */
5737         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
5738                                                    sizeof(der->extensions)));
5739         idx += der->extensionsSz;
5740     }
5741
5742     return idx;
5743 }
5744
5745
5746 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
5747 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
5748                          RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
5749                          int sigAlgoType)
5750 {
5751     int encSigSz, digestSz, typeH = 0, ret = 0;
5752     byte digest[SHA256_DIGEST_SIZE]; /* max size */
5753 #ifdef WOLFSSL_SMALL_STACK
5754     byte* encSig;
5755 #else
5756     byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
5757 #endif
5758
5759     (void)digest;
5760     (void)digestSz;
5761     (void)encSig;
5762     (void)encSigSz;
5763     (void)typeH;
5764
5765     (void)buffer;
5766     (void)sz;
5767     (void)sig;
5768     (void)sigSz;
5769     (void)rsaKey;
5770     (void)eccKey;
5771     (void)rng;
5772
5773     switch (sigAlgoType) {
5774     #ifndef NO_MD5
5775         case CTC_MD5wRSA:
5776         if ((ret = wc_Md5Hash(buffer, sz, digest)) == 0) {
5777             typeH    = MD5h;
5778             digestSz = MD5_DIGEST_SIZE;
5779         }
5780         break;
5781     #endif
5782     #ifndef NO_SHA
5783         case CTC_SHAwRSA:
5784         case CTC_SHAwECDSA:
5785         if ((ret = wc_ShaHash(buffer, sz, digest)) == 0) {
5786             typeH    = SHAh;
5787             digestSz = SHA_DIGEST_SIZE;          
5788         }
5789         break;
5790     #endif
5791     #ifndef NO_SHA256
5792         case CTC_SHA256wRSA:
5793         case CTC_SHA256wECDSA:
5794         if ((ret = wc_Sha256Hash(buffer, sz, digest)) == 0) {
5795             typeH    = SHA256h;
5796             digestSz = SHA256_DIGEST_SIZE;
5797         }
5798         break;
5799     #endif
5800         default:
5801             WOLFSSL_MSG("MakeSignautre called with unsupported type");
5802             ret = ALGO_ID_E;
5803     }
5804     
5805     if (ret != 0)
5806         return ret;
5807     
5808 #ifdef WOLFSSL_SMALL_STACK
5809     encSig = (byte*)XMALLOC(MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
5810                                                  NULL, DYNAMIC_TYPE_TMP_BUFFER);
5811     if (encSig == NULL)
5812         return MEMORY_E;
5813 #endif
5814     
5815     ret = ALGO_ID_E;
5816     
5817 #ifndef NO_RSA
5818     if (rsaKey) {
5819         /* signature */
5820         encSigSz = wc_EncodeSignature(encSig, digest, digestSz, typeH);
5821         ret = wc_RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng);
5822     }
5823 #endif
5824     
5825 #ifdef HAVE_ECC
5826     if (!rsaKey && eccKey) {
5827         word32 outSz = sigSz;
5828         ret = wc_ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey);
5829
5830         if (ret == 0)
5831             ret = outSz;
5832     }
5833 #endif
5834
5835 #ifdef WOLFSSL_SMALL_STACK
5836     XFREE(encSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5837 #endif
5838
5839     return ret;
5840 }
5841
5842
5843 /* add signature to end of buffer, size of buffer assumed checked, return
5844    new length */
5845 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
5846                         int sigAlgoType)
5847 {
5848     byte seq[MAX_SEQ_SZ];
5849     int  idx = bodySz, seqSz;
5850
5851     /* algo */
5852     idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0);
5853     /* bit string */
5854     buffer[idx++] = ASN_BIT_STRING;
5855     /* length */
5856     idx += SetLength(sigSz + 1, buffer + idx);
5857     buffer[idx++] = 0;   /* trailing 0 */
5858     /* signature */
5859     XMEMCPY(buffer + idx, sig, sigSz);
5860     idx += sigSz;
5861
5862     /* make room for overall header */
5863     seqSz = SetSequence(idx, seq);
5864     XMEMMOVE(buffer + seqSz, buffer, idx);
5865     XMEMCPY(buffer, seq, seqSz);
5866
5867     return idx + seqSz;
5868 }
5869
5870
5871 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
5872 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
5873                        RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
5874                        const byte* ntruKey, word16 ntruSz)
5875 {
5876     int ret;
5877 #ifdef WOLFSSL_SMALL_STACK
5878     DerCert* der;
5879 #else
5880     DerCert der[1];
5881 #endif
5882
5883     cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY);
5884
5885 #ifdef WOLFSSL_SMALL_STACK
5886     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
5887     if (der == NULL)
5888         return MEMORY_E;
5889 #endif
5890
5891     ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz);
5892
5893     if (ret == 0) {
5894         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
5895             ret = BUFFER_E;
5896         else
5897             ret = cert->bodySz = WriteCertBody(der, derBuffer);
5898     }
5899
5900 #ifdef WOLFSSL_SMALL_STACK
5901     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5902 #endif
5903
5904     return ret;
5905 }
5906
5907
5908 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
5909 int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
5910              ecc_key* eccKey, RNG* rng)
5911 {
5912     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0);
5913 }
5914
5915
5916 #ifdef HAVE_NTRU
5917
5918 int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
5919                   const byte* ntruKey, word16 keySz, RNG* rng)
5920 {
5921     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
5922 }
5923
5924 #endif /* HAVE_NTRU */
5925
5926
5927 #ifdef WOLFSSL_CERT_REQ
5928
5929 static int SetReqAttrib(byte* output, char* pw, int extSz)
5930 {
5931     static const byte cpOid[] =
5932         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
5933                          0x09, 0x07 };
5934     static const byte erOid[] =
5935         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
5936                          0x09, 0x0e };
5937
5938     int sz      = 0; /* overall size */
5939     int cpSz    = 0; /* Challenge Password section size */
5940     int cpSeqSz = 0;
5941     int cpSetSz = 0;
5942     int cpStrSz = 0;
5943     int pwSz    = 0;
5944     int erSz    = 0; /* Extension Request section size */
5945     int erSeqSz = 0;
5946     int erSetSz = 0;
5947     byte cpSeq[MAX_SEQ_SZ];
5948     byte cpSet[MAX_SET_SZ];
5949     byte cpStr[MAX_PRSTR_SZ];
5950     byte erSeq[MAX_SEQ_SZ];
5951     byte erSet[MAX_SET_SZ];
5952
5953     output[0] = 0xa0;
5954     sz++;
5955
5956     if (pw && pw[0]) {
5957         pwSz = (int)XSTRLEN(pw);
5958         cpStrSz = SetUTF8String(pwSz, cpStr);
5959         cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
5960         cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
5961         cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
5962     }
5963
5964     if (extSz) {
5965         erSetSz = SetSet(extSz, erSet);
5966         erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
5967         erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
5968     }
5969
5970     /* Put the pieces together. */
5971     sz += SetLength(cpSz + erSz, &output[sz]);
5972
5973     if (cpSz) {
5974         XMEMCPY(&output[sz], cpSeq, cpSeqSz);
5975         sz += cpSeqSz;
5976         XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
5977         sz += sizeof(cpOid);
5978         XMEMCPY(&output[sz], cpSet, cpSetSz);
5979         sz += cpSetSz;
5980         XMEMCPY(&output[sz], cpStr, cpStrSz);
5981         sz += cpStrSz;
5982         XMEMCPY(&output[sz], pw, pwSz);
5983         sz += pwSz;
5984     }
5985
5986     if (erSz) {
5987         XMEMCPY(&output[sz], erSeq, erSeqSz);
5988         sz += erSeqSz;
5989         XMEMCPY(&output[sz], erOid, sizeof(erOid));
5990         sz += sizeof(erOid);
5991         XMEMCPY(&output[sz], erSet, erSetSz);
5992         sz += erSetSz;
5993         /* The actual extension data will be tacked onto the output later. */
5994     }
5995
5996     return sz;
5997 }
5998
5999
6000 /* encode info from cert into DER encoded format */
6001 static int EncodeCertReq(Cert* cert, DerCert* der,
6002                          RsaKey* rsaKey, ecc_key* eccKey)
6003 {
6004     (void)eccKey;
6005
6006     /* init */
6007     XMEMSET(der, 0, sizeof(DerCert));
6008
6009     /* version */
6010     der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
6011
6012     /* subject name */
6013     der->subjectSz = SetName(der->subject, &cert->subject);
6014     if (der->subjectSz == 0)
6015         return SUBJECT_E;
6016
6017     /* public key */
6018     if (cert->keyType == RSA_KEY) {
6019         if (rsaKey == NULL)
6020             return PUBLIC_KEY_E;
6021         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
6022         if (der->publicKeySz <= 0)
6023             return PUBLIC_KEY_E;
6024     }
6025
6026 #ifdef HAVE_ECC
6027     if (cert->keyType == ECC_KEY) {
6028         if (eccKey == NULL)
6029             return PUBLIC_KEY_E;
6030         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
6031         if (der->publicKeySz <= 0)
6032             return PUBLIC_KEY_E;
6033     }
6034 #endif /* HAVE_ECC */
6035
6036     /* CA */
6037     if (cert->isCA) {
6038         der->caSz = SetCa(der->ca);
6039         if (der->caSz == 0)
6040             return CA_TRUE_E;
6041     }
6042     else
6043         der->caSz = 0;
6044
6045     /* extensions, just CA now */
6046     if (cert->isCA) {
6047         der->extensionsSz = SetExtensions(der->extensions,
6048                                           der->ca, der->caSz, FALSE);
6049         if (der->extensionsSz == 0)
6050             return EXTENSIONS_E;
6051     }
6052     else
6053         der->extensionsSz = 0;
6054
6055     der->attribSz = SetReqAttrib(der->attrib,
6056                                  cert->challengePw, der->extensionsSz);
6057     if (der->attribSz == 0)
6058         return REQ_ATTRIBUTE_E;
6059
6060     der->total = der->versionSz + der->subjectSz + der->publicKeySz +
6061         der->extensionsSz + der->attribSz;
6062
6063     return 0;
6064 }
6065
6066
6067 /* write DER encoded cert req to buffer, size already checked */
6068 static int WriteCertReqBody(DerCert* der, byte* buffer)
6069 {
6070     int idx;
6071
6072     /* signed part header */
6073     idx = SetSequence(der->total, buffer);
6074     /* version */
6075     XMEMCPY(buffer + idx, der->version, der->versionSz);
6076     idx += der->versionSz;
6077     /* subject */
6078     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
6079     idx += der->subjectSz;
6080     /* public key */
6081     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
6082     idx += der->publicKeySz;
6083     /* attributes */
6084     XMEMCPY(buffer + idx, der->attrib, der->attribSz);
6085     idx += der->attribSz;
6086     /* extensions */
6087     if (der->extensionsSz) {
6088         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
6089                                                    sizeof(der->extensions)));
6090         idx += der->extensionsSz;
6091     }
6092
6093     return idx;
6094 }
6095
6096
6097 int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
6098                 RsaKey* rsaKey, ecc_key* eccKey)
6099 {
6100     int ret;
6101 #ifdef WOLFSSL_SMALL_STACK
6102     DerCert* der;
6103 #else
6104     DerCert der[1];
6105 #endif
6106
6107     cert->keyType = eccKey ? ECC_KEY : RSA_KEY;
6108
6109 #ifdef WOLFSSL_SMALL_STACK
6110     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
6111     if (der == NULL)
6112         return MEMORY_E;
6113 #endif
6114
6115     ret = EncodeCertReq(cert, der, rsaKey, eccKey);
6116
6117     if (ret == 0) {
6118         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
6119             ret = BUFFER_E;
6120         else
6121             ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
6122     }
6123
6124 #ifdef WOLFSSL_SMALL_STACK
6125     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6126 #endif
6127
6128     return ret;
6129 }
6130
6131 #endif /* WOLFSSL_CERT_REQ */
6132
6133
6134 int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
6135              RsaKey* rsaKey, ecc_key* eccKey, RNG* rng)
6136 {
6137     int sigSz;
6138 #ifdef WOLFSSL_SMALL_STACK
6139     byte* sig;
6140 #else
6141     byte sig[MAX_ENCODED_SIG_SZ];
6142 #endif
6143
6144     if (requestSz < 0)
6145         return requestSz;
6146
6147 #ifdef WOLFSSL_SMALL_STACK
6148     sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6149     if (sig == NULL)
6150         return MEMORY_E;
6151 #endif
6152
6153     sigSz = MakeSignature(buffer, requestSz, sig, MAX_ENCODED_SIG_SZ, rsaKey,
6154                           eccKey, rng, sType);
6155
6156     if (sigSz >= 0) {
6157         if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
6158             sigSz = BUFFER_E;
6159         else
6160             sigSz = AddSignature(buffer, requestSz, sig, sigSz, sType);
6161     }
6162     
6163 #ifdef WOLFSSL_SMALL_STACK
6164     XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6165 #endif
6166
6167     return sigSz;
6168 }
6169
6170
6171 int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
6172 {
6173     int ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);
6174
6175     if (ret < 0)
6176         return ret;
6177
6178     return wc_SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng);
6179 }
6180
6181
6182 #ifdef WOLFSSL_ALT_NAMES 
6183
6184 /* Set Alt Names from der cert, return 0 on success */
6185 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
6186 {
6187     int ret;
6188 #ifdef WOLFSSL_SMALL_STACK
6189     DecodedCert* decoded;
6190 #else
6191     DecodedCert decoded[1];
6192 #endif
6193
6194     if (derSz < 0)
6195         return derSz;
6196
6197 #ifdef WOLFSSL_SMALL_STACK
6198     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
6199                                                        DYNAMIC_TYPE_TMP_BUFFER);
6200     if (decoded == NULL)
6201         return MEMORY_E;
6202 #endif
6203     
6204     InitDecodedCert(decoded, (byte*)der, derSz, 0);
6205     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
6206
6207     if (ret < 0) {
6208         WOLFSSL_MSG("ParseCertRelative error");
6209     }
6210     else if (decoded->extensions) {
6211         byte   b;
6212         int    length;
6213         word32 maxExtensionsIdx;
6214
6215         decoded->srcIdx = decoded->extensionsIdx;
6216         b = decoded->source[decoded->srcIdx++];
6217         
6218         if (b != ASN_EXTENSIONS) {
6219             ret = ASN_PARSE_E;
6220         }
6221         else if (GetLength(decoded->source, &decoded->srcIdx, &length,
6222                                                          decoded->maxIdx) < 0) {
6223             ret = ASN_PARSE_E;
6224         }
6225         else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
6226                                                          decoded->maxIdx) < 0) {
6227             ret = ASN_PARSE_E;
6228         }
6229         else {
6230             maxExtensionsIdx = decoded->srcIdx + length;
6231
6232             while (decoded->srcIdx < maxExtensionsIdx) {
6233                 word32 oid;
6234                 word32 startIdx = decoded->srcIdx;
6235                 word32 tmpIdx;
6236
6237                 if (GetSequence(decoded->source, &decoded->srcIdx, &length,
6238                             decoded->maxIdx) < 0) {
6239                     ret = ASN_PARSE_E;
6240                     break;
6241                 }
6242
6243                 tmpIdx = decoded->srcIdx;
6244                 decoded->srcIdx = startIdx;
6245
6246                 if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
6247                               decoded->maxIdx) < 0) {
6248                     ret = ASN_PARSE_E;
6249                     break;
6250                 }
6251
6252                 if (oid == ALT_NAMES_OID) {
6253                     cert->altNamesSz = length + (tmpIdx - startIdx);
6254
6255                     if (cert->altNamesSz < (int)sizeof(cert->altNames))
6256                         XMEMCPY(cert->altNames, &decoded->source[startIdx],
6257                                 cert->altNamesSz);
6258                     else {
6259                         cert->altNamesSz = 0;
6260                         WOLFSSL_MSG("AltNames extensions too big");
6261                         ret = ALT_NAME_E;
6262                         break;
6263                     }
6264                 }
6265                 decoded->srcIdx = tmpIdx + length;
6266             }
6267         }
6268     }
6269
6270     FreeDecodedCert(decoded);
6271 #ifdef WOLFSSL_SMALL_STACK
6272     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6273 #endif
6274
6275     return ret < 0 ? ret : 0;
6276 }
6277
6278
6279 /* Set Dates from der cert, return 0 on success */
6280 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
6281 {
6282     int ret;
6283 #ifdef WOLFSSL_SMALL_STACK
6284     DecodedCert* decoded;
6285 #else
6286     DecodedCert decoded[1];
6287 #endif
6288
6289     WOLFSSL_ENTER("SetDatesFromCert");
6290     if (derSz < 0)
6291         return derSz;
6292     
6293 #ifdef WOLFSSL_SMALL_STACK
6294     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
6295                                                        DYNAMIC_TYPE_TMP_BUFFER);
6296     if (decoded == NULL)
6297         return MEMORY_E;
6298 #endif
6299
6300     InitDecodedCert(decoded, (byte*)der, derSz, 0);
6301     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
6302
6303     if (ret < 0) {
6304         WOLFSSL_MSG("ParseCertRelative error");
6305     }
6306     else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
6307         WOLFSSL_MSG("Couldn't extract dates");
6308         ret = -1;
6309     }
6310     else if (decoded->beforeDateLen > MAX_DATE_SIZE || 
6311                                         decoded->afterDateLen > MAX_DATE_SIZE) {
6312         WOLFSSL_MSG("Bad date size");
6313         ret = -1;
6314     }
6315     else {
6316         XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
6317         XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
6318
6319         cert->beforeDateSz = decoded->beforeDateLen;
6320         cert->afterDateSz  = decoded->afterDateLen;
6321     }
6322
6323     FreeDecodedCert(decoded);
6324
6325 #ifdef WOLFSSL_SMALL_STACK
6326     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6327 #endif
6328
6329     return ret < 0 ? ret : 0;
6330 }
6331
6332
6333 #endif /* WOLFSSL_ALT_NAMES && !NO_RSA */
6334
6335
6336 /* Set cn name from der buffer, return 0 on success */
6337 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
6338 {
6339     int ret, sz;
6340 #ifdef WOLFSSL_SMALL_STACK
6341     DecodedCert* decoded;
6342 #else
6343     DecodedCert decoded[1];
6344 #endif
6345
6346     if (derSz < 0)
6347         return derSz;
6348
6349 #ifdef WOLFSSL_SMALL_STACK
6350     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
6351                                                        DYNAMIC_TYPE_TMP_BUFFER);
6352     if (decoded == NULL)
6353         return MEMORY_E;
6354 #endif
6355
6356     InitDecodedCert(decoded, (byte*)der, derSz, 0);
6357     ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
6358
6359     if (ret < 0) {
6360         WOLFSSL_MSG("ParseCertRelative error");
6361     }
6362     else {
6363         if (decoded->subjectCN) {
6364             sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
6365                                                          : CTC_NAME_SIZE - 1;
6366             strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
6367             cn->commonName[sz] = 0;
6368             cn->commonNameEnc = decoded->subjectCNEnc;
6369         }
6370         if (decoded->subjectC) {
6371             sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
6372                                                         : CTC_NAME_SIZE - 1;
6373             strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE);
6374             cn->country[sz] = 0;
6375             cn->countryEnc = decoded->subjectCEnc;
6376         }
6377         if (decoded->subjectST) {
6378             sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
6379                                                          : CTC_NAME_SIZE - 1;
6380             strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE);
6381             cn->state[sz] = 0;
6382             cn->stateEnc = decoded->subjectSTEnc;
6383         }
6384         if (decoded->subjectL) {
6385             sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
6386                                                         : CTC_NAME_SIZE - 1;
6387             strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
6388             cn->locality[sz] = 0;
6389             cn->localityEnc = decoded->subjectLEnc;
6390         }
6391         if (decoded->subjectO) {
6392             sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
6393                                                         : CTC_NAME_SIZE - 1;
6394             strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE);
6395             cn->org[sz] = 0;
6396             cn->orgEnc = decoded->subjectOEnc;
6397         }
6398         if (decoded->subjectOU) {
6399             sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
6400                                                          : CTC_NAME_SIZE - 1;
6401             strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
6402             cn->unit[sz] = 0;
6403             cn->unitEnc = decoded->subjectOUEnc;
6404         }
6405         if (decoded->subjectSN) {
6406             sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
6407                                                          : CTC_NAME_SIZE - 1;
6408             strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
6409             cn->sur[sz] = 0;
6410             cn->surEnc = decoded->subjectSNEnc;
6411         }
6412         if (decoded->subjectEmail) {
6413             sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
6414                ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
6415             strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
6416             cn->email[sz] = 0;
6417         }
6418     }
6419
6420     FreeDecodedCert(decoded);
6421
6422 #ifdef WOLFSSL_SMALL_STACK
6423     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6424 #endif
6425
6426     return ret < 0 ? ret : 0;
6427 }
6428
6429
6430 #ifndef NO_FILESYSTEM
6431
6432 /* Set cert issuer from issuerFile in PEM */
6433 int wc_SetIssuer(Cert* cert, const char* issuerFile)
6434 {
6435     int         ret;
6436     int         derSz;
6437     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
6438
6439     if (der == NULL) {
6440         WOLFSSL_MSG("wc_SetIssuer OOF Problem");
6441         return MEMORY_E;
6442     }
6443     derSz = wolfSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
6444     cert->selfSigned = 0;
6445     ret = SetNameFromCert(&cert->issuer, der, derSz);
6446     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
6447
6448     return ret;
6449 }
6450
6451
6452 /* Set cert subject from subjectFile in PEM */
6453 int wc_SetSubject(Cert* cert, const char* subjectFile)
6454 {
6455     int         ret;
6456     int         derSz;
6457     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
6458
6459     if (der == NULL) {
6460         WOLFSSL_MSG("wc_SetSubject OOF Problem");
6461         return MEMORY_E;
6462     }
6463     derSz = wolfSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
6464     ret = SetNameFromCert(&cert->subject, der, derSz);
6465     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
6466
6467     return ret;
6468 }
6469
6470
6471 #ifdef WOLFSSL_ALT_NAMES
6472
6473 /* Set atl names from file in PEM */
6474 int wc_SetAltNames(Cert* cert, const char* file)
6475 {
6476     int         ret;
6477     int         derSz;
6478     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
6479
6480     if (der == NULL) {
6481         WOLFSSL_MSG("wc_SetAltNames OOF Problem");
6482         return MEMORY_E;
6483     }
6484     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
6485     ret = SetAltNamesFromCert(cert, der, derSz);
6486     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
6487
6488     return ret;
6489 }
6490
6491 #endif /* WOLFSSL_ALT_NAMES */
6492
6493 #endif /* NO_FILESYSTEM */
6494
6495 /* Set cert issuer from DER buffer */
6496 int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
6497 {
6498     cert->selfSigned = 0;
6499     return SetNameFromCert(&cert->issuer, der, derSz);
6500 }
6501
6502
6503 /* Set cert subject from DER buffer */
6504 int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
6505 {
6506     return SetNameFromCert(&cert->subject, der, derSz);
6507 }
6508
6509
6510 #ifdef WOLFSSL_ALT_NAMES
6511
6512 /* Set cert alt names from DER buffer */
6513 int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
6514 {
6515     return SetAltNamesFromCert(cert, der, derSz);
6516 }
6517
6518 /* Set cert dates from DER buffer */
6519 int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
6520 {
6521     return SetDatesFromCert(cert, der, derSz);
6522 }
6523
6524 #endif /* WOLFSSL_ALT_NAMES */
6525
6526 #endif /* WOLFSSL_CERT_GEN */
6527
6528
6529 #ifdef HAVE_ECC
6530
6531 /* Der Encode r & s ints into out, outLen is (in/out) size */
6532 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
6533 {
6534     word32 idx = 0;
6535     word32 rSz;                           /* encoding size */
6536     word32 sSz;
6537     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
6538
6539     /* If the leading bit on the INTEGER is a 1, add a leading zero */
6540     int rLeadingZero = mp_leading_bit(r);
6541     int sLeadingZero = mp_leading_bit(s);
6542     int rLen = mp_unsigned_bin_size(r);   /* big int size */
6543     int sLen = mp_unsigned_bin_size(s);
6544     int err;
6545
6546     if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
6547                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
6548         return BAD_FUNC_ARG;
6549
6550     idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
6551
6552     /* store r */
6553     out[idx++] = ASN_INTEGER;
6554     rSz = SetLength(rLen + rLeadingZero, &out[idx]);
6555     idx += rSz;
6556     if (rLeadingZero)
6557         out[idx++] = 0;
6558     err = mp_to_unsigned_bin(r, &out[idx]);
6559     if (err != MP_OKAY) return err;
6560     idx += rLen;
6561
6562     /* store s */
6563     out[idx++] = ASN_INTEGER;
6564     sSz = SetLength(sLen + sLeadingZero, &out[idx]);
6565     idx += sSz;
6566     if (sLeadingZero)
6567         out[idx++] = 0;
6568     err = mp_to_unsigned_bin(s, &out[idx]);
6569     if (err != MP_OKAY) return err;
6570     idx += sLen;
6571
6572     *outLen = idx;
6573
6574     return 0;
6575 }
6576
6577
6578 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */
6579 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
6580 {
6581     word32 idx = 0;
6582     int    len = 0;
6583
6584     if (GetSequence(sig, &idx, &len, sigLen) < 0)
6585         return ASN_ECC_KEY_E;
6586
6587     if ((word32)len > (sigLen - idx))
6588         return ASN_ECC_KEY_E;
6589
6590     if (GetInt(r, sig, &idx, sigLen) < 0)
6591         return ASN_ECC_KEY_E;
6592
6593     if (GetInt(s, sig, &idx, sigLen) < 0)
6594         return ASN_ECC_KEY_E;
6595
6596     return 0;
6597 }
6598
6599
6600 int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
6601                         word32 inSz)
6602 {
6603     word32 oid = 0;
6604     int    version, length;
6605     int    privSz, pubSz;
6606     byte   b;
6607     int    ret = 0;
6608 #ifdef WOLFSSL_SMALL_STACK
6609     byte* priv;
6610     byte* pub;
6611 #else
6612     byte priv[ECC_MAXSIZE];
6613     byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */
6614 #endif
6615
6616     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
6617         return BAD_FUNC_ARG;
6618
6619     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
6620         return ASN_PARSE_E;
6621
6622     if (GetMyVersion(input, inOutIdx, &version) < 0)
6623         return ASN_PARSE_E;
6624
6625     b = input[*inOutIdx];
6626     *inOutIdx += 1;
6627
6628     /* priv type */
6629     if (b != 4 && b != 6 && b != 7) 
6630         return ASN_PARSE_E;
6631
6632     if (GetLength(input, inOutIdx, &length, inSz) < 0)
6633         return ASN_PARSE_E;
6634
6635     if (length > ECC_MAXSIZE)
6636         return BUFFER_E;
6637
6638 #ifdef WOLFSSL_SMALL_STACK
6639     priv = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6640     if (priv == NULL)
6641         return MEMORY_E;
6642     
6643     pub = (byte*)XMALLOC(ECC_MAXSIZE * 2 + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6644     if (pub == NULL) {
6645         XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6646         return MEMORY_E;
6647     }
6648 #endif
6649
6650     /* priv key */
6651     privSz = length;
6652     XMEMCPY(priv, &input[*inOutIdx], privSz);
6653     *inOutIdx += length;
6654
6655     /* prefix 0, may have */
6656     b = input[*inOutIdx];
6657     if (b == ECC_PREFIX_0) {
6658         *inOutIdx += 1;
6659
6660         if (GetLength(input, inOutIdx, &length, inSz) < 0)
6661             ret = ASN_PARSE_E;
6662         else {
6663             /* object id */
6664             b = input[*inOutIdx];
6665             *inOutIdx += 1;
6666
6667             if (b != ASN_OBJECT_ID) {
6668                 ret = ASN_OBJECT_ID_E;
6669             }
6670             else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
6671                 ret = ASN_PARSE_E;
6672             }
6673             else {
6674                 while(length--) {
6675                     oid += input[*inOutIdx];
6676                     *inOutIdx += 1;
6677                 }
6678                 if (CheckCurve(oid) < 0)
6679                     ret = ECC_CURVE_OID_E;
6680             }
6681         }
6682     }
6683
6684     if (ret == 0) {
6685         /* prefix 1 */
6686         b = input[*inOutIdx];
6687         *inOutIdx += 1;
6688
6689         if (b != ECC_PREFIX_1) {
6690             ret = ASN_ECC_KEY_E;
6691         }
6692         else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
6693             ret = ASN_PARSE_E;
6694         }
6695         else {
6696             /* key header */
6697             b = input[*inOutIdx];
6698             *inOutIdx += 1;
6699             
6700             if (b != ASN_BIT_STRING) {
6701                 ret = ASN_BITSTR_E;
6702             }
6703             else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
6704                 ret = ASN_PARSE_E;
6705             }
6706             else {
6707                 b = input[*inOutIdx];
6708                 *inOutIdx += 1;
6709
6710                 if (b != 0x00) {
6711                     ret = ASN_EXPECT_0_E;
6712                 }
6713                 else {
6714                     /* pub key */
6715                     pubSz = length - 1;  /* null prefix */
6716                     if (pubSz < (ECC_MAXSIZE*2 + 1)) {
6717                         XMEMCPY(pub, &input[*inOutIdx], pubSz);
6718                         *inOutIdx += length;
6719                         ret = wc_ecc_import_private_key(priv, privSz, pub, pubSz,
6720                                                      key);
6721                     } else
6722                         ret = BUFFER_E;
6723                 }
6724             }
6725         }
6726     }
6727
6728 #ifdef WOLFSSL_SMALL_STACK
6729     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6730     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
6731 #endif
6732
6733     return ret;
6734 }
6735
6736
6737 #ifdef WOLFSSL_KEY_GEN
6738
6739 /* Write a Private ecc key to DER format, length on success else < 0 */
6740 int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
6741 {
6742     byte   curve[MAX_ALGO_SZ];
6743     byte   ver[MAX_VERSION_SZ];
6744     byte   seq[MAX_SEQ_SZ];
6745     int    ret;
6746     int    curveSz;
6747     int    verSz;
6748     int    privHdrSz  = ASN_ECC_HEADER_SZ;
6749     int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
6750     int    curveHdrSz = ASN_ECC_CONTEXT_SZ;
6751     word32 seqSz;
6752     word32 idx = 0;
6753     word32 pubSz = ECC_BUFSIZE;
6754     word32 privSz;
6755     word32 totalSz;
6756
6757     if (key == NULL || output == NULL || inLen == 0)
6758         return BAD_FUNC_ARG;
6759
6760     ret = wc_ecc_export_x963(key, NULL, &pubSz);
6761     if (ret != LENGTH_ONLY_E) {
6762         return ret;
6763     }
6764     curveSz = SetCurve(key, curve);
6765     if (curveSz < 0) {
6766         return curveSz;
6767     }
6768
6769     privSz = key->dp->size;
6770
6771     verSz = SetMyVersion(1, ver, FALSE);
6772     if (verSz < 0) {
6773         return verSz;
6774     }
6775
6776     totalSz = verSz + privSz + privHdrSz + curveSz + curveHdrSz +
6777               pubSz + pubHdrSz + 1;  /* plus null byte b4 public */
6778     seqSz = SetSequence(totalSz, seq);
6779     totalSz += seqSz;
6780
6781     if (totalSz > inLen) {
6782         return BUFFER_E;
6783     }
6784
6785     /* write it out */
6786     /* seq */
6787     XMEMCPY(output + idx, seq, seqSz);
6788     idx += seqSz;
6789
6790    /* ver */
6791     XMEMCPY(output + idx, ver, verSz);
6792     idx += verSz;
6793
6794     /* private */
6795     output[idx++] = ASN_OCTET_STRING;
6796     output[idx++] = (byte)privSz;
6797     ret = wc_ecc_export_private_only(key, output + idx, &privSz);
6798     if (ret < 0) {
6799         return ret;
6800     }
6801     idx += privSz;
6802
6803     /* curve */
6804     output[idx++] = ECC_PREFIX_0;
6805     output[idx++] = (byte)curveSz;
6806     XMEMCPY(output + idx, curve, curveSz);
6807     idx += curveSz;
6808
6809     /* public */
6810     output[idx++] = ECC_PREFIX_1;
6811     output[idx++] = (byte)pubSz + ASN_ECC_CONTEXT_SZ + 1;  /* plus null byte */
6812     output[idx++] = ASN_BIT_STRING;
6813     output[idx++] = (byte)pubSz + 1;  /* plus null byte */
6814     output[idx++] = (byte)0;          /* null byte */
6815     ret = wc_ecc_export_x963(key, output + idx, &pubSz);
6816     if (ret != 0) {
6817         return ret;
6818     }
6819     /* idx += pubSz if do more later */
6820
6821     return totalSz;
6822 }
6823
6824 #endif /* WOLFSSL_KEY_GEN */
6825
6826 #endif  /* HAVE_ECC */
6827
6828
6829 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
6830
6831 /* Get raw Date only, no processing, 0 on success */
6832 static int GetBasicDate(const byte* source, word32* idx, byte* date,
6833                         byte* format, int maxIdx)
6834 {
6835     int    length;
6836
6837     WOLFSSL_ENTER("GetBasicDate");
6838
6839     *format = source[*idx];
6840     *idx += 1;
6841     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
6842         return ASN_TIME_E;
6843
6844     if (GetLength(source, idx, &length, maxIdx) < 0)
6845         return ASN_PARSE_E;
6846
6847     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
6848         return ASN_DATE_SZ_E;
6849
6850     XMEMCPY(date, &source[*idx], length);
6851     *idx += length;
6852
6853     return 0;
6854 }
6855
6856 #endif
6857
6858
6859 #ifdef HAVE_OCSP
6860
6861 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
6862 {
6863     word32 idx = *inOutIdx;
6864     word32 len;
6865
6866     WOLFSSL_ENTER("GetEnumerated");
6867
6868     *value = 0;
6869
6870     if (input[idx++] != ASN_ENUMERATED)
6871         return ASN_PARSE_E;
6872
6873     len = input[idx++];
6874     if (len > 4)
6875         return ASN_PARSE_E;
6876
6877     while (len--) {
6878         *value  = *value << 8 | input[idx++];
6879     }
6880
6881     *inOutIdx = idx;
6882
6883     return *value;
6884 }
6885
6886
6887 static int DecodeSingleResponse(byte* source,
6888                             word32* ioIndex, OcspResponse* resp, word32 size)
6889 {
6890     word32 idx = *ioIndex, prevIndex, oid;
6891     int length, wrapperSz;
6892     CertStatus* cs = resp->status;
6893
6894     WOLFSSL_ENTER("DecodeSingleResponse");
6895
6896     /* Outer wrapper of the SEQUENCE OF Single Responses. */
6897     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
6898         return ASN_PARSE_E;
6899
6900     prevIndex = idx;
6901
6902     /* When making a request, we only request one status on one certificate
6903      * at a time. There should only be one SingleResponse */
6904
6905     /* Wrapper around the Single Response */
6906     if (GetSequence(source, &idx, &length, size) < 0)
6907         return ASN_PARSE_E;
6908
6909     /* Wrapper around the CertID */
6910     if (GetSequence(source, &idx, &length, size) < 0)
6911         return ASN_PARSE_E;
6912     /* Skip the hash algorithm */
6913     if (GetAlgoId(source, &idx, &oid, size) < 0)
6914         return ASN_PARSE_E;
6915     /* Save reference to the hash of CN */
6916     if (source[idx++] != ASN_OCTET_STRING)
6917         return ASN_PARSE_E;
6918     if (GetLength(source, &idx, &length, size) < 0)
6919         return ASN_PARSE_E;
6920     resp->issuerHash = source + idx;
6921     idx += length;
6922     /* Save reference to the hash of the issuer public key */
6923     if (source[idx++] != ASN_OCTET_STRING)
6924         return ASN_PARSE_E;
6925     if (GetLength(source, &idx, &length, size) < 0)
6926         return ASN_PARSE_E;
6927     resp->issuerKeyHash = source + idx;
6928     idx += length;
6929
6930     /* Read the serial number, it is handled as a string, not as a 
6931      * proper number. Just XMEMCPY the data over, rather than load it
6932      * as an mp_int. */
6933     if (source[idx++] != ASN_INTEGER)
6934         return ASN_PARSE_E;
6935     if (GetLength(source, &idx, &length, size) < 0)
6936         return ASN_PARSE_E;
6937     if (length <= EXTERNAL_SERIAL_SIZE)
6938     {
6939         if (source[idx] == 0)
6940         {
6941             idx++;
6942             length--;
6943         }
6944         XMEMCPY(cs->serial, source + idx, length);
6945         cs->serialSz = length;
6946     }
6947     else
6948     {
6949         return ASN_GETINT_E;
6950     }
6951     idx += length;
6952
6953     /* CertStatus */
6954     switch (source[idx++])
6955     {
6956         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
6957             cs->status = CERT_GOOD;
6958             idx++;
6959             break;
6960         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
6961             cs->status = CERT_REVOKED;
6962             if (GetLength(source, &idx, &length, size) < 0)
6963                 return ASN_PARSE_E;
6964             idx += length;
6965             break;
6966         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
6967             cs->status = CERT_UNKNOWN;
6968             idx++;
6969             break;
6970         default:
6971             return ASN_PARSE_E;
6972     }
6973
6974     if (GetBasicDate(source, &idx, cs->thisDate,
6975                                                 &cs->thisDateFormat, size) < 0)
6976         return ASN_PARSE_E;
6977     if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
6978         return ASN_BEFORE_DATE_E;
6979     
6980     /* The following items are optional. Only check for them if there is more
6981      * unprocessed data in the singleResponse wrapper. */
6982     
6983     if (((int)(idx - prevIndex) < wrapperSz) &&
6984         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
6985     {
6986         idx++;
6987         if (GetLength(source, &idx, &length, size) < 0)
6988             return ASN_PARSE_E;
6989         if (GetBasicDate(source, &idx, cs->nextDate,
6990                                                 &cs->nextDateFormat, size) < 0)
6991             return ASN_PARSE_E;
6992     }
6993     if (((int)(idx - prevIndex) < wrapperSz) &&
6994         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
6995     {
6996         idx++;
6997         if (GetLength(source, &idx, &length, size) < 0)
6998             return ASN_PARSE_E;
6999         idx += length;
7000     }
7001
7002     *ioIndex = idx;
7003
7004     return 0;
7005 }
7006
7007 static int DecodeOcspRespExtensions(byte* source,
7008                             word32* ioIndex, OcspResponse* resp, word32 sz)
7009 {
7010     word32 idx = *ioIndex;
7011     int length;
7012     int ext_bound; /* boundary index for the sequence of extensions */
7013     word32 oid;
7014
7015     WOLFSSL_ENTER("DecodeOcspRespExtensions");
7016
7017     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
7018         return ASN_PARSE_E;
7019
7020     if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
7021
7022     if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
7023    
7024     ext_bound = idx + length;
7025
7026     while (idx < (word32)ext_bound) {
7027         if (GetSequence(source, &idx, &length, sz) < 0) {
7028             WOLFSSL_MSG("\tfail: should be a SEQUENCE");
7029             return ASN_PARSE_E;
7030         }
7031
7032         oid = 0;
7033         if (GetObjectId(source, &idx, &oid, sz) < 0) {
7034             WOLFSSL_MSG("\tfail: OBJECT ID");
7035             return ASN_PARSE_E;
7036         }
7037
7038         /* check for critical flag */
7039         if (source[idx] == ASN_BOOLEAN) {
7040             WOLFSSL_MSG("\tfound optional critical flag, moving past");
7041             idx += (ASN_BOOL_SIZE + 1);
7042         }
7043
7044         /* process the extension based on the OID */
7045         if (source[idx++] != ASN_OCTET_STRING) {
7046             WOLFSSL_MSG("\tfail: should be an OCTET STRING");
7047             return ASN_PARSE_E;
7048         }
7049
7050         if (GetLength(source, &idx, &length, sz) < 0) {
7051             WOLFSSL_MSG("\tfail: extension data length");
7052             return ASN_PARSE_E;
7053         }
7054
7055         if (oid == OCSP_NONCE_OID) {
7056             resp->nonce = source + idx;
7057             resp->nonceSz = length;
7058         }
7059
7060         idx += length;
7061     }
7062
7063     *ioIndex = idx;
7064     return 0;
7065 }
7066
7067
7068 static int DecodeResponseData(byte* source,
7069                             word32* ioIndex, OcspResponse* resp, word32 size)
7070 {
7071     word32 idx = *ioIndex, prev_idx;
7072     int length;
7073     int version;
7074     word32 responderId = 0;
7075
7076     WOLFSSL_ENTER("DecodeResponseData");
7077
7078     resp->response = source + idx;
7079     prev_idx = idx;
7080     if (GetSequence(source, &idx, &length, size) < 0)
7081         return ASN_PARSE_E;
7082     resp->responseSz = length + idx - prev_idx;
7083
7084     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
7085      * item isn't an EXPLICIT[0], then set version to zero and move
7086      * onto the next item.
7087      */
7088     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
7089     {    
7090         idx += 2; /* Eat the value and length */
7091         if (GetMyVersion(source, &idx, &version) < 0)
7092             return ASN_PARSE_E;
7093     } else
7094         version = 0;
7095
7096     responderId = source[idx++];
7097     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
7098         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
7099     {
7100         if (GetLength(source, &idx, &length, size) < 0)
7101             return ASN_PARSE_E;
7102         idx += length;
7103     }
7104     else
7105         return ASN_PARSE_E;
7106     
7107     /* save pointer to the producedAt time */
7108     if (GetBasicDate(source, &idx, resp->producedDate,
7109                                         &resp->producedDateFormat, size) < 0)
7110         return ASN_PARSE_E;
7111
7112     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
7113         return ASN_PARSE_E;
7114
7115     if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
7116         return ASN_PARSE_E;
7117
7118     *ioIndex = idx;
7119     return 0;
7120 }
7121
7122
7123 static int DecodeCerts(byte* source,
7124                             word32* ioIndex, OcspResponse* resp, word32 size)
7125 {
7126     word32 idx = *ioIndex;
7127
7128     WOLFSSL_ENTER("DecodeCerts");
7129
7130     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
7131     {
7132         int length;
7133
7134         if (GetLength(source, &idx, &length, size) < 0)
7135             return ASN_PARSE_E;
7136
7137         if (GetSequence(source, &idx, &length, size) < 0)
7138             return ASN_PARSE_E;
7139
7140         resp->cert = source + idx;
7141         resp->certSz = length;
7142
7143         idx += length;
7144     }
7145     *ioIndex = idx;
7146     return 0;
7147 }
7148
7149 static int DecodeBasicOcspResponse(byte* source,
7150                             word32* ioIndex, OcspResponse* resp, word32 size)
7151 {
7152     int length;
7153     word32 idx = *ioIndex;
7154     word32 end_index;
7155
7156     WOLFSSL_ENTER("DecodeBasicOcspResponse");
7157
7158     if (GetSequence(source, &idx, &length, size) < 0)
7159         return ASN_PARSE_E;
7160
7161     if (idx + length > size)
7162         return ASN_INPUT_E;
7163     end_index = idx + length;
7164
7165     if (DecodeResponseData(source, &idx, resp, size) < 0)
7166         return ASN_PARSE_E;
7167     
7168     /* Get the signature algorithm */
7169     if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
7170         return ASN_PARSE_E;
7171
7172     /* Obtain pointer to the start of the signature, and save the size */
7173     if (source[idx++] == ASN_BIT_STRING)
7174     {
7175         int sigLength = 0;
7176         if (GetLength(source, &idx, &sigLength, size) < 0)
7177             return ASN_PARSE_E;
7178         resp->sigSz = sigLength;
7179         resp->sig = source + idx;
7180         idx += sigLength;
7181     }
7182
7183     /*
7184      * Check the length of the BasicOcspResponse against the current index to
7185      * see if there are certificates, they are optional.
7186      */
7187     if (idx < end_index)
7188     {
7189         DecodedCert cert;
7190         int ret;
7191
7192         if (DecodeCerts(source, &idx, resp, size) < 0)
7193             return ASN_PARSE_E;
7194
7195         InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
7196         ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
7197         if (ret < 0)
7198             return ret;
7199
7200         ret = ConfirmSignature(resp->response, resp->responseSz,
7201                             cert.publicKey, cert.pubKeySize, cert.keyOID,
7202                             resp->sig, resp->sigSz, resp->sigOID, NULL);
7203         FreeDecodedCert(&cert);
7204
7205         if (ret == 0)
7206         {
7207             WOLFSSL_MSG("\tOCSP Confirm signature failed");
7208             return ASN_OCSP_CONFIRM_E;
7209         }
7210     }
7211
7212     *ioIndex = idx;
7213     return 0;
7214 }
7215
7216
7217 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
7218                                                     byte* source, word32 inSz)
7219 {
7220     WOLFSSL_ENTER("InitOcspResponse");
7221
7222     resp->responseStatus = -1;
7223     resp->response = NULL;
7224     resp->responseSz = 0;
7225     resp->producedDateFormat = 0;
7226     resp->issuerHash = NULL;
7227     resp->issuerKeyHash = NULL;
7228     resp->sig = NULL;
7229     resp->sigSz = 0;
7230     resp->sigOID = 0;
7231     resp->status = status;
7232     resp->nonce = NULL;
7233     resp->nonceSz = 0;
7234     resp->source = source;
7235     resp->maxIdx = inSz;
7236 }
7237
7238
7239 int OcspResponseDecode(OcspResponse* resp)
7240 {
7241     int length = 0;
7242     word32 idx = 0;
7243     byte* source = resp->source;
7244     word32 size = resp->maxIdx;
7245     word32 oid;
7246
7247     WOLFSSL_ENTER("OcspResponseDecode");
7248
7249     /* peel the outer SEQUENCE wrapper */
7250     if (GetSequence(source, &idx, &length, size) < 0)
7251         return ASN_PARSE_E;
7252     
7253     /* First get the responseStatus, an ENUMERATED */
7254     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
7255         return ASN_PARSE_E;
7256
7257     if (resp->responseStatus != OCSP_SUCCESSFUL)
7258         return 0;
7259
7260     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
7261     if (idx >= size)
7262         return ASN_INPUT_E;
7263     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
7264         return ASN_PARSE_E;
7265     if (GetLength(source, &idx, &length, size) < 0)
7266         return ASN_PARSE_E;
7267
7268     /* Get the responseBytes SEQUENCE */
7269     if (GetSequence(source, &idx, &length, size) < 0)
7270         return ASN_PARSE_E;
7271
7272     /* Check ObjectID for the resposeBytes */
7273     if (GetObjectId(source, &idx, &oid, size) < 0)
7274         return ASN_PARSE_E;
7275     if (oid != OCSP_BASIC_OID)
7276         return ASN_PARSE_E;
7277     if (source[idx++] != ASN_OCTET_STRING)
7278         return ASN_PARSE_E;
7279
7280     if (GetLength(source, &idx, &length, size) < 0)
7281         return ASN_PARSE_E;
7282
7283     if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
7284         return ASN_PARSE_E;
7285     
7286     return 0;
7287 }
7288
7289
7290 static word32 SetOcspReqExtensions(word32 extSz, byte* output,
7291                                             const byte* nonce, word32 nonceSz)
7292 {
7293     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
7294                                        0x30, 0x01, 0x02 };
7295     byte seqArray[5][MAX_SEQ_SZ];
7296     word32 seqSz[5], totalSz;
7297
7298     WOLFSSL_ENTER("SetOcspReqExtensions");
7299
7300     if (nonce == NULL || nonceSz == 0) return 0;
7301     
7302     seqArray[0][0] = ASN_OCTET_STRING;
7303     seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
7304
7305     seqArray[1][0] = ASN_OBJECT_ID;
7306     seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
7307
7308     totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
7309
7310     seqSz[2] = SetSequence(totalSz, seqArray[2]);
7311     totalSz += seqSz[2];
7312
7313     seqSz[3] = SetSequence(totalSz, seqArray[3]);
7314     totalSz += seqSz[3];
7315
7316     seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
7317     seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
7318     totalSz += seqSz[4];
7319
7320     if (totalSz < extSz)
7321     {
7322         totalSz = 0;
7323         XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
7324         totalSz += seqSz[4];
7325         XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
7326         totalSz += seqSz[3];
7327         XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
7328         totalSz += seqSz[2];
7329         XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
7330         totalSz += seqSz[1];
7331         XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
7332         totalSz += (word32)sizeof(NonceObjId);
7333         XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
7334         totalSz += seqSz[0];
7335         XMEMCPY(output + totalSz, nonce, nonceSz);
7336         totalSz += nonceSz;
7337     }
7338
7339     return totalSz;
7340 }
7341
7342
7343 int EncodeOcspRequest(OcspRequest* req)
7344 {
7345     byte seqArray[5][MAX_SEQ_SZ];
7346     /* The ASN.1 of the OCSP Request is an onion of sequences */
7347     byte algoArray[MAX_ALGO_SZ];
7348     byte issuerArray[MAX_ENCODED_DIG_SZ];
7349     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
7350     byte snArray[MAX_SN_SZ];
7351     byte extArray[MAX_OCSP_EXT_SZ];
7352     byte* output = req->dest;
7353     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
7354     int i;
7355
7356     WOLFSSL_ENTER("EncodeOcspRequest");
7357
7358 #ifdef NO_SHA
7359     algoSz = SetAlgoID(SHA256h, algoArray, hashType, 0);
7360 #else
7361     algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
7362 #endif
7363
7364     req->issuerHash = req->cert->issuerHash;
7365     issuerSz = SetDigest(req->cert->issuerHash, KEYID_SIZE, issuerArray);
7366
7367     req->issuerKeyHash = req->cert->issuerKeyHash;
7368     issuerKeySz = SetDigest(req->cert->issuerKeyHash,
7369                                                     KEYID_SIZE, issuerKeyArray);
7370
7371     req->serial = req->cert->serial;
7372     req->serialSz = req->cert->serialSz;
7373     snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
7374
7375     extSz = 0;
7376     if (req->useNonce) {
7377         RNG rng;
7378         if (wc_InitRng(&rng) != 0) {
7379             WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
7380         } else {
7381             if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
7382                 WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
7383             else {
7384                 req->nonceSz = MAX_OCSP_NONCE_SZ;
7385                 extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
7386                                                       req->nonce, req->nonceSz);
7387             }
7388             wc_FreeRng(&rng);
7389         }
7390     }
7391
7392     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
7393
7394     for (i = 4; i >= 0; i--) {
7395         seqSz[i] = SetSequence(totalSz, seqArray[i]);
7396         totalSz += seqSz[i];
7397         if (i == 2) totalSz += extSz;
7398     }
7399     totalSz = 0;
7400     for (i = 0; i < 5; i++) {
7401         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
7402         totalSz += seqSz[i];
7403     }
7404     XMEMCPY(output + totalSz, algoArray, algoSz);
7405     totalSz += algoSz;
7406     XMEMCPY(output + totalSz, issuerArray, issuerSz);
7407     totalSz += issuerSz;
7408     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
7409     totalSz += issuerKeySz;
7410     XMEMCPY(output + totalSz, snArray, snSz);
7411     totalSz += snSz;
7412     if (extSz != 0) {
7413         XMEMCPY(output + totalSz, extArray, extSz);
7414         totalSz += extSz;
7415     }
7416
7417     return totalSz;
7418 }
7419
7420
7421 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
7422                                                     byte* dest, word32 destSz)
7423 {
7424     WOLFSSL_ENTER("InitOcspRequest");
7425
7426     req->cert = cert;
7427     req->useNonce = useNonce;
7428     req->nonceSz = 0;
7429     req->issuerHash = NULL;
7430     req->issuerKeyHash = NULL;
7431     req->serial = NULL;
7432     req->dest = dest;
7433     req->destSz = destSz;
7434 }
7435
7436
7437 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
7438 {
7439     int cmp;
7440
7441     WOLFSSL_ENTER("CompareOcspReqResp");
7442
7443     if (req == NULL)
7444     {
7445         WOLFSSL_MSG("\tReq missing");
7446         return -1;
7447     }
7448
7449     if (resp == NULL)
7450     {
7451         WOLFSSL_MSG("\tResp missing");
7452         return 1;
7453     }
7454
7455     /* Nonces are not critical. The responder may not necessarily add
7456      * the nonce to the response. */
7457     if (req->useNonce && resp->nonceSz != 0) {
7458         cmp = req->nonceSz - resp->nonceSz;
7459         if (cmp != 0)
7460         {
7461             WOLFSSL_MSG("\tnonceSz mismatch");
7462             return cmp;
7463         }
7464     
7465         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
7466         if (cmp != 0)
7467         {
7468             WOLFSSL_MSG("\tnonce mismatch");
7469             return cmp;
7470         }
7471     }
7472
7473     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
7474     if (cmp != 0)
7475     {
7476         WOLFSSL_MSG("\tissuerHash mismatch");
7477         return cmp;
7478     }
7479
7480     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
7481     if (cmp != 0)
7482     {
7483         WOLFSSL_MSG("\tissuerKeyHash mismatch");
7484         return cmp;
7485     }
7486
7487     cmp = req->serialSz - resp->status->serialSz;
7488     if (cmp != 0)
7489     {
7490         WOLFSSL_MSG("\tserialSz mismatch");
7491         return cmp;
7492     }
7493
7494     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
7495     if (cmp != 0)
7496     {
7497         WOLFSSL_MSG("\tserial mismatch");
7498         return cmp;
7499     }
7500
7501     return 0;
7502 }
7503
7504 #endif
7505
7506
7507 /* store SHA hash of NAME */
7508 WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
7509                              int maxIdx)
7510 {
7511     int    length;  /* length of all distinguished names */
7512     int    ret;
7513     word32 dummy;
7514
7515     WOLFSSL_ENTER("GetNameHash");
7516
7517     if (source[*idx] == ASN_OBJECT_ID) {
7518         WOLFSSL_MSG("Trying optional prefix...");
7519
7520         if (GetLength(source, idx, &length, maxIdx) < 0)
7521             return ASN_PARSE_E;
7522
7523         *idx += length;
7524         WOLFSSL_MSG("Got optional prefix");
7525     }
7526
7527     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
7528      * calculated over the entire DER encoding of the Name field, including
7529      * the tag and length. */
7530     dummy = *idx;
7531     if (GetSequence(source, idx, &length, maxIdx) < 0)
7532         return ASN_PARSE_E;
7533
7534 #ifdef NO_SHA
7535     ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
7536 #else
7537     ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
7538 #endif
7539
7540     *idx += length;
7541
7542     return ret;
7543 }
7544
7545
7546 #ifdef HAVE_CRL
7547
7548 /* initialize decoded CRL */
7549 void InitDecodedCRL(DecodedCRL* dcrl)
7550 {
7551     WOLFSSL_MSG("InitDecodedCRL");
7552
7553     dcrl->certBegin    = 0;
7554     dcrl->sigIndex     = 0;
7555     dcrl->sigLength    = 0;
7556     dcrl->signatureOID = 0;
7557     dcrl->certs        = NULL;
7558     dcrl->totalCerts   = 0;
7559 }
7560
7561
7562 /* free decoded CRL resources */
7563 void FreeDecodedCRL(DecodedCRL* dcrl)
7564 {
7565     RevokedCert* tmp = dcrl->certs;
7566
7567     WOLFSSL_MSG("FreeDecodedCRL");
7568
7569     while(tmp) {
7570         RevokedCert* next = tmp->next;
7571         XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
7572         tmp = next;
7573     }
7574 }
7575
7576
7577 /* Get Revoked Cert list, 0 on success */
7578 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
7579                       int maxIdx)
7580 {
7581     int    len;
7582     word32 end;
7583     byte   b;
7584     RevokedCert* rc;
7585
7586     WOLFSSL_ENTER("GetRevoked");
7587
7588     if (GetSequence(buff, idx, &len, maxIdx) < 0)
7589         return ASN_PARSE_E;
7590
7591     end = *idx + len;
7592
7593     /* get serial number */
7594     b = buff[*idx];
7595     *idx += 1;
7596
7597     if (b != ASN_INTEGER) {
7598         WOLFSSL_MSG("Expecting Integer");
7599         return ASN_PARSE_E;
7600     }
7601
7602     if (GetLength(buff, idx, &len, maxIdx) < 0)
7603         return ASN_PARSE_E;
7604
7605     if (len > EXTERNAL_SERIAL_SIZE) {
7606         WOLFSSL_MSG("Serial Size too big");
7607         return ASN_PARSE_E;
7608     }
7609
7610     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
7611     if (rc == NULL) {
7612         WOLFSSL_MSG("Alloc Revoked Cert failed");
7613         return MEMORY_E;
7614     }
7615
7616     XMEMCPY(rc->serialNumber, &buff[*idx], len);
7617     rc->serialSz = len;
7618
7619     /* add to list */
7620     rc->next = dcrl->certs;
7621     dcrl->certs = rc;
7622     dcrl->totalCerts++;
7623
7624     *idx += len;
7625
7626     /* get date */
7627     b = buff[*idx];
7628     *idx += 1;
7629
7630     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
7631         WOLFSSL_MSG("Expecting Date");
7632         return ASN_PARSE_E;
7633     }
7634
7635     if (GetLength(buff, idx, &len, maxIdx) < 0)
7636         return ASN_PARSE_E;
7637
7638     /* skip for now */
7639     *idx += len;
7640
7641     if (*idx != end)  /* skip extensions */
7642         *idx = end;
7643
7644     return 0;
7645 }
7646
7647
7648 /* Get CRL Signature, 0 on success */
7649 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
7650                             int maxIdx)
7651 {
7652     int    length;
7653     byte   b;
7654
7655     WOLFSSL_ENTER("GetCRL_Signature");
7656
7657     b = source[*idx];
7658     *idx += 1;
7659     if (b != ASN_BIT_STRING)
7660         return ASN_BITSTR_E;
7661
7662     if (GetLength(source, idx, &length, maxIdx) < 0)
7663         return ASN_PARSE_E;
7664
7665     dcrl->sigLength = length;
7666
7667     b = source[*idx];
7668     *idx += 1;
7669     if (b != 0x00)
7670         return ASN_EXPECT_0_E;
7671
7672     dcrl->sigLength--;
7673     dcrl->signature = (byte*)&source[*idx];
7674
7675     *idx += dcrl->sigLength;
7676
7677     return 0;
7678 }
7679
7680
7681 /* prase crl buffer into decoded state, 0 on success */
7682 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
7683 {
7684     int     version, len;
7685     word32  oid, idx = 0;
7686     Signer* ca = NULL;
7687
7688     WOLFSSL_MSG("ParseCRL");
7689
7690     /* raw crl hash */
7691     /* hash here if needed for optimized comparisons
7692      * Sha     sha;
7693      * wc_InitSha(&sha);
7694      * wc_ShaUpdate(&sha, buff, sz);
7695      * wc_ShaFinal(&sha, dcrl->crlHash); */
7696
7697     if (GetSequence(buff, &idx, &len, sz) < 0)
7698         return ASN_PARSE_E;
7699
7700     dcrl->certBegin = idx;
7701
7702     if (GetSequence(buff, &idx, &len, sz) < 0)
7703         return ASN_PARSE_E;
7704     dcrl->sigIndex = len + idx;
7705
7706     /* may have version */
7707     if (buff[idx] == ASN_INTEGER) {
7708         if (GetMyVersion(buff, &idx, &version) < 0)
7709             return ASN_PARSE_E;
7710     }
7711
7712     if (GetAlgoId(buff, &idx, &oid, sz) < 0)
7713         return ASN_PARSE_E;
7714
7715     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
7716         return ASN_PARSE_E;
7717
7718     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
7719         return ASN_PARSE_E;
7720
7721     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
7722         return ASN_PARSE_E;
7723
7724     if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
7725         WOLFSSL_MSG("CRL after date is no longer valid");
7726         return ASN_AFTER_DATE_E;
7727     }
7728
7729     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
7730         if (GetSequence(buff, &idx, &len, sz) < 0)
7731             return ASN_PARSE_E;
7732
7733         len += idx;
7734
7735         while (idx < (word32)len) {
7736             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
7737                 return ASN_PARSE_E;
7738         }
7739     }
7740
7741     if (idx != dcrl->sigIndex)
7742         idx = dcrl->sigIndex;   /* skip extensions */
7743
7744     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
7745         return ASN_PARSE_E;
7746
7747     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
7748         return ASN_PARSE_E;
7749
7750     /* openssl doesn't add skid by default for CRLs cause firefox chokes
7751        we're not assuming it's available yet */
7752     #if !defined(NO_SKID) && defined(CRL_SKID_READY)
7753         if (dcrl->extAuthKeyIdSet)
7754             ca = GetCA(cm, dcrl->extAuthKeyId);
7755         if (ca == NULL)
7756             ca = GetCAByName(cm, dcrl->issuerHash);
7757     #else /* NO_SKID */
7758         ca = GetCA(cm, dcrl->issuerHash);
7759     #endif /* NO_SKID */
7760     WOLFSSL_MSG("About to verify CRL signature");
7761
7762     if (ca) {
7763         WOLFSSL_MSG("Found CRL issuer CA");
7764         /* try to confirm/verify signature */
7765         #ifndef IGNORE_KEY_EXTENSIONS
7766             if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
7767                 WOLFSSL_MSG("CA cannot sign CRLs");
7768                 return ASN_CRL_NO_SIGNER_E;
7769             }
7770         #endif /* IGNORE_KEY_EXTENSIONS */
7771         if (!ConfirmSignature(buff + dcrl->certBegin,
7772                 dcrl->sigIndex - dcrl->certBegin,
7773                 ca->publicKey, ca->pubKeySize, ca->keyOID,
7774                 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
7775             WOLFSSL_MSG("CRL Confirm signature failed");
7776             return ASN_CRL_CONFIRM_E;
7777         }
7778     }
7779     else {
7780         WOLFSSL_MSG("Did NOT find CRL issuer CA");
7781         return ASN_CRL_NO_SIGNER_E;
7782     }
7783
7784     return 0;
7785 }
7786
7787 #endif /* HAVE_CRL */
7788 #endif
7789
7790 #ifdef WOLFSSL_SEP
7791
7792
7793
7794 #endif /* WOLFSSL_SEP */
7795