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