]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/asn.c
87ece4bf436ebb8bdab2f89ee6e18ce48f6215af
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / asn.c
1 /* asn.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifdef THREADX
27     #include "os.h"           /* dc_rtc_api needs    */
28     #include "dc_rtc_api.h"   /* to get current time */
29 #endif
30
31 #include <cyassl/ctaocrypt/asn.h>
32 #include <cyassl/ctaocrypt/coding.h>
33 #include <cyassl/ctaocrypt/sha.h>
34 #include <cyassl/ctaocrypt/md5.h>
35 #include <cyassl/ctaocrypt/md2.h>
36 #include <cyassl/ctaocrypt/error.h>
37 #include <cyassl/ctaocrypt/pwdbased.h>
38 #include <cyassl/ctaocrypt/des3.h>
39 #include <cyassl/ctaocrypt/sha256.h>
40 #include <cyassl/ctaocrypt/sha512.h>
41 #include <cyassl/ctaocrypt/logging.h>
42 #include <cyassl/ctaocrypt/random.h>
43
44 #ifdef HAVE_NTRU
45     #include "crypto_ntru.h"
46 #endif
47
48 #ifdef HAVE_ECC
49     #include <cyassl/ctaocrypt/ecc.h>
50 #endif
51
52
53 #ifdef _MSC_VER
54     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
55     #pragma warning(disable: 4996)
56 #endif
57
58
59 #ifndef TRUE
60 enum {
61     FALSE = 0,
62     TRUE  = 1
63 };
64 #endif
65
66
67 #ifndef min
68
69     static INLINE word32 min(word32 a, word32 b)
70     {
71         return a > b ? b : a;
72     }
73
74 #endif /* min */
75
76
77 #ifdef THREADX
78     /* uses parital <time.h> structures */
79     #define XTIME(tl)  (0)
80     #define XGMTIME(c) my_gmtime((c))
81     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
82 #elif defined(MICRIUM)
83     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
84         #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t))
85     #else
86         #define XVALIDATE_DATE(d, f, t) (0)
87     #endif
88     #define NO_TIME_H
89     /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
90 #elif defined(USER_TIME)
91     /* no <time.h> structures used */
92     #define NO_TIME_H
93     /* user time, and gmtime compatible functions, there is a gmtime 
94        implementation here that WINCE uses, so really just need some ticks
95        since the EPOCH 
96     */
97 #else
98     /* default */
99     /* uses complete <time.h> facility */
100     #include <time.h> 
101     #define XTIME(tl)  time((tl))
102     #define XGMTIME(c) gmtime((c))
103     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
104 #endif
105
106
107 #ifdef _WIN32_WCE
108 /* no time() or gmtime() even though in time.h header?? */
109
110 #include <windows.h>
111
112
113 time_t time(time_t* timer)
114 {
115     SYSTEMTIME     sysTime;
116     FILETIME       fTime;
117     ULARGE_INTEGER intTime;
118     time_t         localTime;
119
120     if (timer == NULL)
121         timer = &localTime;
122
123     GetSystemTime(&sysTime);
124     SystemTimeToFileTime(&sysTime, &fTime);
125     
126     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
127     /* subtract EPOCH */
128     intTime.QuadPart -= 0x19db1ded53e8000;
129     /* to secs */
130     intTime.QuadPart /= 10000000;
131     *timer = (time_t)intTime.QuadPart;
132
133     return *timer;
134 }
135
136
137
138 struct tm* gmtime(const time_t* timer)
139 {
140     #define YEAR0          1900
141     #define EPOCH_YEAR     1970
142     #define SECS_DAY       (24L * 60L * 60L)
143     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
144     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
145
146     static const int _ytab[2][12] =
147     {
148         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
149         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
150     };
151
152     static struct tm st_time;
153     struct tm* ret = &st_time;
154     time_t time = *timer;
155     unsigned long dayclock, dayno;
156     int year = EPOCH_YEAR;
157
158     dayclock = (unsigned long)time % SECS_DAY;
159     dayno    = (unsigned long)time / SECS_DAY;
160
161     ret->tm_sec  =  dayclock % 60;
162     ret->tm_min  = (dayclock % 3600) / 60;
163     ret->tm_hour =  dayclock / 3600;
164     ret->tm_wday = (dayno + 4) % 7;        /* day 0 a Thursday */
165
166     while(dayno >= (unsigned long)YEARSIZE(year)) {
167         dayno -= YEARSIZE(year);
168         year++;
169     }
170
171     ret->tm_year = year - YEAR0;
172     ret->tm_yday = dayno;
173     ret->tm_mon  = 0;
174
175     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
176         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
177         ret->tm_mon++;
178     }
179
180     ret->tm_mday  = ++dayno;
181     ret->tm_isdst = 0;
182
183     return ret;
184 }
185
186 #endif /* _WIN32_WCE */
187
188
189 #ifdef  THREADX
190
191 #define YEAR0          1900
192
193 struct tm* my_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
194 {
195     static struct tm st_time;
196     struct tm* ret = &st_time;
197
198     DC_RTC_CALENDAR cal;
199     dc_rtc_time_get(&cal, TRUE);
200
201     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
202     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
203     ret->tm_mday  = cal.day;
204     ret->tm_hour  = cal.hour;
205     ret->tm_min   = cal.minute;
206     ret->tm_sec   = cal.second;
207
208     return ret;
209 }
210
211 #endif /* THREADX */
212
213
214 static INLINE word32 btoi(byte b)
215 {
216     return b - 0x30;
217 }
218
219
220 /* two byte date/time, add to value */
221 static INLINE void GetTime(int* value, const byte* date, int* idx)
222 {
223     int i = *idx;
224
225     *value += btoi(date[i++]) * 10;
226     *value += btoi(date[i++]);
227
228     *idx = i;
229 }
230
231
232 #if defined(MICRIUM)
233
234 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
235                                          CPU_INT08U dateType)
236 {
237     CPU_BOOLEAN  rtn_code;
238     CPU_INT32S   i;
239     CPU_INT32S   val;    
240     CPU_INT16U   year;
241     CPU_INT08U   month;
242     CPU_INT16U   day;
243     CPU_INT08U   hour;
244     CPU_INT08U   min;
245     CPU_INT08U   sec;
246
247     i    = 0;
248     year = 0u;
249
250     if (format == ASN_UTC_TIME) {
251         if (btoi(date[0]) >= 5)
252             year = 1900;
253         else
254             year = 2000;
255     }
256     else  { /* format == GENERALIZED_TIME */
257         year += btoi(date[i++]) * 1000;
258         year += btoi(date[i++]) * 100;
259     }    
260
261     val = year;
262     GetTime(&val, date, &i);
263     year = (CPU_INT16U)val;
264
265     val = 0;
266     GetTime(&val, date, &i);   
267     month = (CPU_INT08U)val;   
268
269     val = 0;
270     GetTime(&val, date, &i);  
271     day = (CPU_INT16U)val;
272
273     val = 0;
274     GetTime(&val, date, &i);  
275     hour = (CPU_INT08U)val;
276
277     val = 0;
278     GetTime(&val, date, &i);  
279     min = (CPU_INT08U)val;
280
281     val = 0;
282     GetTime(&val, date, &i);  
283     sec = (CPU_INT08U)val;
284
285     return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); 
286 }
287
288 #endif /* MICRIUM */
289
290
291 static int GetLength(const byte* input, word32* inOutIdx, int* len,
292                      word32 maxIdx)
293 {
294     int     length = 0;
295     word32  i = *inOutIdx;
296     byte    b;
297
298     if ( (i+1) > maxIdx) {   /* for first read */
299         CYASSL_MSG("GetLength bad index on input");
300         return BUFFER_E;
301     }
302
303     b = input[i++];
304     if (b >= ASN_LONG_LENGTH) {        
305         word32 bytes = b & 0x7F;
306
307         if ( (i+bytes) > maxIdx) {   /* for reading bytes */
308             CYASSL_MSG("GetLength bad long length");
309             return BUFFER_E;
310         }
311
312         while (bytes--) {
313             b = input[i++];
314             length = (length << 8) | b;
315         }
316     }
317     else
318         length = b;
319     
320     if ( (i+length) > maxIdx) {   /* for user of length */
321         CYASSL_MSG("GetLength value exceeds buffer length");
322         return BUFFER_E;
323     }
324
325     *inOutIdx = i;
326     *len      = length;
327
328     return length;
329 }
330
331
332 static int GetSequence(const byte* input, word32* inOutIdx, int* len,
333                        word32 maxIdx)
334 {
335     int    length = -1;
336     word32 idx    = *inOutIdx;
337
338     if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
339             GetLength(input, &idx, &length, maxIdx) < 0)
340         return ASN_PARSE_E;
341
342     *len      = length;
343     *inOutIdx = idx;
344
345     return length;
346 }
347
348
349 static int GetSet(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
350 {
351     int    length = -1;
352     word32 idx    = *inOutIdx;
353
354     if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
355             GetLength(input, &idx, &length, maxIdx) < 0)
356         return ASN_PARSE_E;
357
358     *len      = length;
359     *inOutIdx = idx;
360
361     return length;
362 }
363
364
365 /* winodws header clash for WinCE using GetVersion */
366 static int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
367 {
368     word32 idx = *inOutIdx;
369
370     CYASSL_ENTER("GetMyVersion");
371
372     if (input[idx++] != ASN_INTEGER)
373         return ASN_PARSE_E;
374
375     if (input[idx++] != 0x01)
376         return ASN_VERSION_E;
377
378     *version  = input[idx++];
379     *inOutIdx = idx;
380
381     return *version;
382 }
383
384
385 /* Get small count integer, 32 bits or less */
386 static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
387 {
388     word32 idx = *inOutIdx;
389     word32 len;
390
391     *number = 0;
392
393     if (input[idx++] != ASN_INTEGER)
394         return ASN_PARSE_E;
395
396     len = input[idx++];
397     if (len > 4)
398         return ASN_PARSE_E;
399
400     while (len--) {
401         *number  = *number << 8 | input[idx++];
402     }
403
404     *inOutIdx = idx;
405
406     return *number;
407 }
408
409
410 /* May not have one, not an error */
411 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
412 {
413     word32 idx = *inOutIdx;
414
415     CYASSL_ENTER("GetExplicitVersion");
416     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
417         *inOutIdx = ++idx;  /* eat header */
418         return GetMyVersion(input, inOutIdx, version);
419     }
420
421     /* go back as is */
422     *version = 0;
423
424     return 0;
425 }
426
427
428 static int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
429                   word32 maxIdx)
430 {
431     word32 i = *inOutIdx;
432     byte   b = input[i++];
433     int    length;
434
435     if (b != ASN_INTEGER)
436         return ASN_PARSE_E;
437
438     if (GetLength(input, &i, &length, maxIdx) < 0)
439         return ASN_PARSE_E;
440
441     if ( (b = input[i++]) == 0x00)
442         length--;
443     else
444         i--;
445
446     mp_init(mpi); 
447     if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
448         mp_clear(mpi);
449         return ASN_GETINT_E;
450     }
451
452     *inOutIdx = i + length;
453     return 0;
454 }
455
456
457 static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
458                      word32 maxIdx)
459 {
460     int    length;
461     word32 i = *inOutIdx;
462     byte   b;
463     *oid = 0;
464     
465     b = input[i++];
466     if (b != ASN_OBJECT_ID) 
467         return ASN_OBJECT_ID_E;
468     
469     if (GetLength(input, &i, &length, maxIdx) < 0)
470         return ASN_PARSE_E;
471     
472     while(length--)
473         *oid += input[i++];
474     /* just sum it up for now */
475     
476     *inOutIdx = i;
477     
478     return 0;
479 }
480
481
482 static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
483                      word32 maxIdx)
484 {
485     int    length;
486     word32 i = *inOutIdx;
487     byte   b;
488     *oid = 0;
489    
490     CYASSL_ENTER("GetAlgoId");
491
492     if (GetSequence(input, &i, &length, maxIdx) < 0)
493         return ASN_PARSE_E;
494     
495     b = input[i++];
496     if (b != ASN_OBJECT_ID) 
497         return ASN_OBJECT_ID_E;
498     
499     if (GetLength(input, &i, &length, maxIdx) < 0)
500         return ASN_PARSE_E;
501     
502     while(length--)
503         *oid += input[i++];
504     /* just sum it up for now */
505     
506     /* could have NULL tag and 0 terminator, but may not */
507     b = input[i++];
508     
509     if (b == ASN_TAG_NULL) {
510         b = input[i++];
511         if (b != 0) 
512             return ASN_EXPECT_0_E;
513     }
514     else
515     /* go back, didn't have it */
516         i--;
517     
518     *inOutIdx = i;
519     
520     return 0;
521 }
522
523
524 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
525                         word32 inSz)
526 {
527     int    version, length;
528
529     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
530         return ASN_PARSE_E;
531
532     if (GetMyVersion(input, inOutIdx, &version) < 0)
533         return ASN_PARSE_E;
534
535     key->type = RSA_PRIVATE;
536
537     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
538         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
539         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
540         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
541         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
542         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
543         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
544         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
545
546     return 0;
547 }
548
549
550 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
551 int ToTraditional(byte* input, word32 sz)
552 {
553     word32 inOutIdx = 0, oid;
554     int    version, length;
555
556     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
557         return ASN_PARSE_E;
558
559     if (GetMyVersion(input, &inOutIdx, &version) < 0)
560         return ASN_PARSE_E;
561     
562     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
563         return ASN_PARSE_E;
564
565     if (input[inOutIdx] == ASN_OBJECT_ID) {
566         /* pkcs8 ecc uses slightly different format */
567         inOutIdx++;  /* past id */
568         if (GetLength(input, &inOutIdx, &length, sz) < 0)
569             return ASN_PARSE_E;
570         inOutIdx += length;  /* over sub id, key input will verify */
571     }
572     
573     if (input[inOutIdx++] != ASN_OCTET_STRING)
574         return ASN_PARSE_E;
575     
576     if (GetLength(input, &inOutIdx, &length, sz) < 0)
577         return ASN_PARSE_E;
578     
579     XMEMMOVE(input, input + inOutIdx, length);
580
581     return 0;
582 }
583
584
585 #ifndef NO_PWDBASED
586
587 /* Check To see if PKCS version algo is supported, set id if it is return 0
588    < 0 on error */
589 static int CheckAlgo(int first, int second, int* id, int* version)
590 {
591     *id      = ALGO_ID_E;
592     *version = PKCS5;   /* default */
593
594     if (first == 1) {
595         switch (second) {
596         case 1:
597             *id = PBE_SHA1_RC4_128;
598             *version = PKCS12;
599             return 0;
600         case 3:
601             *id = PBE_SHA1_DES3;
602             *version = PKCS12;
603             return 0;
604         default:
605             return ALGO_ID_E;
606         }
607     }
608
609     if (first != PKCS5)
610         return ASN_INPUT_E;  /* VERSION ERROR */
611
612     if (second == PBES2) {
613         *version = PKCS5v2;
614         return 0;
615     }
616
617     switch (second) {
618     case 3:                   /* see RFC 2898 for ids */
619         *id = PBE_MD5_DES;
620         return 0;
621     case 10:
622         *id = PBE_SHA1_DES;
623         return 0;
624     default:
625         return ALGO_ID_E;
626
627     }
628 }
629
630
631 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
632    < 0 on error */
633 static int CheckAlgoV2(int oid, int* id)
634 {
635     switch (oid) {
636     case 69:
637         *id = PBE_SHA1_DES;
638         return 0;
639     case 652:
640         *id = PBE_SHA1_DES3;
641         return 0;
642     default:
643         return ALGO_ID_E;
644
645     }
646 }
647
648
649 /* Decrypt intput in place from parameters based on id */
650 static int DecryptKey(const char* password, int passwordSz, byte* salt,
651                       int saltSz, int iterations, int id, byte* input,
652                       int length, int version, byte* cbcIv)
653 {
654     byte   key[MAX_KEY_SIZE];
655     int    typeH;
656     int    derivedLen;
657     int    decryptionType;
658     int    ret = 0; 
659
660     switch (id) {
661         case PBE_MD5_DES:
662             typeH = MD5;
663             derivedLen = 16;           /* may need iv for v1.5 */
664             decryptionType = DES_TYPE;
665             break;
666
667         case PBE_SHA1_DES:
668             typeH = SHA;
669             derivedLen = 16;           /* may need iv for v1.5 */
670             decryptionType = DES_TYPE;
671             break;
672
673         case PBE_SHA1_DES3:
674             typeH = SHA;
675             derivedLen = 32;           /* may need iv for v1.5 */
676             decryptionType = DES3_TYPE;
677             break;
678
679         case PBE_SHA1_RC4_128:
680             typeH = SHA;
681             derivedLen = 16;
682             decryptionType = RC4_TYPE;
683             break;
684
685         default:
686             return ALGO_ID_E;
687     }
688
689     if (version == PKCS5v2)
690         ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations,
691                derivedLen, typeH);
692     else if (version == PKCS5)
693         ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
694                derivedLen, typeH);
695     else if (version == PKCS12) {
696         int  i, idx = 0;
697         byte unicodePasswd[MAX_UNICODE_SZ];
698
699         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd))
700             return UNICODE_SIZE_E; 
701
702         for (i = 0; i < passwordSz; i++) {
703             unicodePasswd[idx++] = 0x00;
704             unicodePasswd[idx++] = (byte)password[i];
705         }
706         /* add trailing NULL */
707         unicodePasswd[idx++] = 0x00;
708         unicodePasswd[idx++] = 0x00;
709
710         ret =  PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
711                             iterations, derivedLen, typeH, 1);
712         if (decryptionType != RC4_TYPE)
713             ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
714                                 iterations, 8, typeH, 2);
715     }
716
717     if (ret != 0)
718         return ret;
719
720     switch (decryptionType) {
721 #ifndef NO_DES3
722         case DES_TYPE:
723         {
724             Des    dec;
725             byte*  desIv = key + 8;
726
727             if (version == PKCS5v2 || version == PKCS12)
728                 desIv = cbcIv;
729             Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
730             Des_CbcDecrypt(&dec, input, input, length);
731             break;
732         }
733
734         case DES3_TYPE:
735         {
736             Des3   dec;
737             byte*  desIv = key + 24;
738
739             if (version == PKCS5v2 || version == PKCS12)
740                 desIv = cbcIv;
741             Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
742             Des3_CbcDecrypt(&dec, input, input, length);
743             break;
744         }
745 #endif
746         case RC4_TYPE:
747         {
748             Arc4    dec;
749
750             Arc4SetKey(&dec, key, derivedLen);
751             Arc4Process(&dec, input, input, length);
752             break;
753         }
754
755         default:
756             return ALGO_ID_E; 
757     }
758
759     return 0;
760 }
761
762
763 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
764    of input */
765 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
766 {
767     word32 inOutIdx = 0, oid;
768     int    first, second, length, iterations, saltSz, id;
769     int    version;
770     byte   salt[MAX_SALT_SIZE];
771     byte   cbcIv[MAX_IV_SIZE];
772     
773     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
774         return ASN_PARSE_E;
775
776     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
777         return ASN_PARSE_E;
778     
779     first  = input[inOutIdx - 2];   /* PKCS version alwyas 2nd to last byte */
780     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
781
782     if (CheckAlgo(first, second, &id, &version) < 0)
783         return ASN_INPUT_E;  /* Algo ID error */
784
785     if (version == PKCS5v2) {
786
787         if (GetSequence(input, &inOutIdx, &length, sz) < 0)
788             return ASN_PARSE_E;
789
790         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
791             return ASN_PARSE_E;
792
793         if (oid != PBKDF2_OID)
794             return ASN_PARSE_E;
795     }
796
797     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
798         return ASN_PARSE_E;
799
800     if (input[inOutIdx++] != ASN_OCTET_STRING)
801         return ASN_PARSE_E;
802     
803     if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
804         return ASN_PARSE_E;
805
806     if (saltSz > MAX_SALT_SIZE)
807         return ASN_PARSE_E;
808      
809     XMEMCPY(salt, &input[inOutIdx], saltSz);
810     inOutIdx += saltSz;
811
812     if (GetShortInt(input, &inOutIdx, &iterations) < 0)
813         return ASN_PARSE_E;
814
815     if (version == PKCS5v2) {
816         /* get encryption algo */
817         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
818             return ASN_PARSE_E;
819
820         if (CheckAlgoV2(oid, &id) < 0)
821             return ASN_PARSE_E;  /* PKCS v2 algo id error */
822
823         if (input[inOutIdx++] != ASN_OCTET_STRING)
824             return ASN_PARSE_E;
825     
826         if (GetLength(input, &inOutIdx, &length, sz) < 0)
827             return ASN_PARSE_E;
828
829         XMEMCPY(cbcIv, &input[inOutIdx], length);
830         inOutIdx += length;
831     }
832
833     if (input[inOutIdx++] != ASN_OCTET_STRING)
834         return ASN_PARSE_E;
835     
836     if (GetLength(input, &inOutIdx, &length, sz) < 0)
837         return ASN_PARSE_E;
838
839     if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
840                    input + inOutIdx, length, version, cbcIv) < 0)
841         return ASN_INPUT_E;  /* decrypt failure */
842
843     XMEMMOVE(input, input + inOutIdx, length);
844     return ToTraditional(input, length);
845 }
846
847 #endif /* NO_PWDBASED */
848
849
850 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
851                        word32 inSz)
852 {
853     int    length;
854
855     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
856         return ASN_PARSE_E;
857
858     key->type = RSA_PUBLIC;
859
860 #ifdef OPENSSL_EXTRA
861     {
862     byte b = input[*inOutIdx];
863     if (b != ASN_INTEGER) {
864         /* not from decoded cert, will have algo id, skip past */
865         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
866             return ASN_PARSE_E;
867         
868         b = input[(*inOutIdx)++];
869         if (b != ASN_OBJECT_ID) 
870             return ASN_OBJECT_ID_E;
871         
872         if (GetLength(input, inOutIdx, &length, inSz) < 0)
873             return ASN_PARSE_E;
874         
875         *inOutIdx += length;   /* skip past */
876         
877         /* could have NULL tag and 0 terminator, but may not */
878         b = input[(*inOutIdx)++];
879         
880         if (b == ASN_TAG_NULL) {
881             b = input[(*inOutIdx)++];
882             if (b != 0) 
883                 return ASN_EXPECT_0_E;
884         }
885         else
886         /* go back, didn't have it */
887             (*inOutIdx)--;
888         
889         /* should have bit tag length and seq next */
890         b = input[(*inOutIdx)++];
891         if (b != ASN_BIT_STRING)
892             return ASN_BITSTR_E;
893         
894         if (GetLength(input, inOutIdx, &length, inSz) < 0)
895             return ASN_PARSE_E;
896         
897         /* could have 0 */
898         b = input[(*inOutIdx)++];
899         if (b != 0)
900             (*inOutIdx)--;
901         
902         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
903             return ASN_PARSE_E;
904     }  /* end if */
905     }  /* openssl var block */
906 #endif /* OPENSSL_EXTRA */
907
908     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
909         GetInt(&key->e,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
910
911     return 0;
912 }
913
914
915 #ifndef NO_DH
916
917 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
918 {
919     int    length;
920
921     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
922         return ASN_PARSE_E;
923
924     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
925         GetInt(&key->g,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
926
927     return 0;
928 }
929
930 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
931 {
932     /* may have leading 0 */
933     if (p[0] == 0) {
934         pSz--; p++;
935     }
936
937     if (g[0] == 0) {
938         gSz--; g++;
939     }
940
941     mp_init(&key->p);
942     if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
943         mp_clear(&key->p);
944         return ASN_DH_KEY_E;
945     }
946
947     mp_init(&key->g);
948     if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
949         mp_clear(&key->p);
950         return ASN_DH_KEY_E;
951     }
952
953     return 0;
954 }
955
956
957 #ifdef OPENSSL_EXTRA
958
959 int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
960                  byte* g, word32* gInOutSz)
961 {
962     word32 i = 0;
963     byte   b;
964     int    length;
965
966     if (GetSequence(input, &i, &length, inSz) < 0)
967         return ASN_PARSE_E;
968
969     b = input[i++];
970     if (b != ASN_INTEGER)
971         return ASN_PARSE_E;
972
973     if (GetLength(input, &i, &length, inSz) < 0)
974         return ASN_PARSE_E;
975
976     if ( (b = input[i++]) == 0x00)
977         length--;
978     else
979         i--;
980
981     if (length <= (int)*pInOutSz) {
982         XMEMCPY(p, &input[i], length);
983         *pInOutSz = length;
984     }
985     else
986         return BUFFER_E;
987
988     i += length;
989
990     b = input[i++];
991     if (b != ASN_INTEGER)
992         return ASN_PARSE_E;
993
994     if (GetLength(input, &i, &length, inSz) < 0)
995         return ASN_PARSE_E;
996
997     if (length <= (int)*gInOutSz) {
998         XMEMCPY(g, &input[i], length);
999         *gInOutSz = length;
1000     }
1001     else
1002         return BUFFER_E;
1003
1004     return 0;
1005 }
1006
1007 #endif /* OPENSSL_EXTRA */
1008 #endif /* NO_DH */
1009
1010
1011 #ifndef NO_DSA
1012
1013 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1014                         word32 inSz)
1015 {
1016     int    length;
1017
1018     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1019         return ASN_PARSE_E;
1020
1021     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1022         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1023         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
1024         GetInt(&key->y,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
1025
1026     key->type = DSA_PUBLIC;
1027     return 0;
1028 }
1029
1030
1031 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
1032                         word32 inSz)
1033 {
1034     int    length, version;
1035
1036     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1037         return ASN_PARSE_E;
1038
1039     if (GetMyVersion(input, inOutIdx, &version) < 0)
1040         return ASN_PARSE_E;
1041
1042     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
1043         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
1044         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
1045         GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
1046         GetInt(&key->x,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
1047
1048     key->type = DSA_PRIVATE;
1049     return 0;
1050 }
1051
1052 #endif /* NO_DSA */
1053
1054
1055 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
1056 {
1057     cert->publicKey       = 0;
1058     cert->pubKeyStored    = 0;
1059     cert->signature       = 0;
1060     cert->subjectCN       = 0;
1061     cert->subjectCNLen    = 0;
1062     cert->subjectCNStored = 0;
1063     cert->altNames        = NULL;
1064     cert->issuer[0]       = '\0';
1065     cert->subject[0]      = '\0';
1066     cert->source          = source;  /* don't own */
1067     cert->srcIdx          = 0;
1068     cert->maxIdx          = inSz;    /* can't go over this index */
1069     cert->heap            = heap;
1070     XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
1071     cert->serialSz        = 0;
1072     cert->extensions      = 0;
1073     cert->extensionsSz    = 0;
1074     cert->extensionsIdx   = 0;
1075     cert->extAuthInfo     = NULL;
1076     cert->extAuthInfoSz   = 0;
1077     cert->extCrlInfo      = NULL;
1078     cert->extCrlInfoSz    = 0;
1079     cert->isCA            = 0;
1080 #ifdef CYASSL_CERT_GEN
1081     cert->subjectSN       = 0;
1082     cert->subjectSNLen    = 0;
1083     cert->subjectC        = 0;
1084     cert->subjectCLen     = 0;
1085     cert->subjectL        = 0;
1086     cert->subjectLLen     = 0;
1087     cert->subjectST       = 0;
1088     cert->subjectSTLen    = 0;
1089     cert->subjectO        = 0;
1090     cert->subjectOLen     = 0;
1091     cert->subjectOU       = 0;
1092     cert->subjectOULen    = 0;
1093     cert->subjectEmail    = 0;
1094     cert->subjectEmailLen = 0;
1095     cert->beforeDate      = 0;
1096     cert->beforeDateLen   = 0;
1097     cert->afterDate       = 0;
1098     cert->afterDateLen    = 0;
1099 #endif /* CYASSL_CERT_GEN */
1100 }
1101
1102
1103 void FreeAltNames(DNS_entry* altNames, void* heap)
1104 {
1105     (void)heap;
1106
1107     while (altNames) {
1108         DNS_entry* tmp = altNames->next;
1109
1110         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
1111         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
1112         altNames = tmp;
1113     }
1114 }
1115
1116
1117 void FreeDecodedCert(DecodedCert* cert)
1118 {
1119     if (cert->subjectCNStored == 1)
1120         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
1121     if (cert->pubKeyStored == 1)
1122         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
1123     if (cert->altNames)
1124         FreeAltNames(cert->altNames, cert->heap);
1125 }
1126
1127
1128 static int GetCertHeader(DecodedCert* cert)
1129 {
1130     int    ret = 0, version, len;
1131     byte   serialTmp[EXTERNAL_SERIAL_SIZE];
1132     mp_int mpi;
1133
1134     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1135         return ASN_PARSE_E;
1136
1137     cert->certBegin = cert->srcIdx;
1138
1139     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
1140         return ASN_PARSE_E;
1141     cert->sigIndex = len + cert->srcIdx;
1142
1143     if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
1144         return ASN_PARSE_E;
1145
1146     if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) 
1147         return ASN_PARSE_E;
1148
1149     len = mp_unsigned_bin_size(&mpi);
1150     if (len < (int)sizeof(serialTmp)) {
1151         if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) {
1152             if (len > EXTERNAL_SERIAL_SIZE)
1153                 len = EXTERNAL_SERIAL_SIZE;
1154             XMEMCPY(cert->serial, serialTmp, len);
1155             cert->serialSz = len;
1156         }
1157     }
1158     mp_clear(&mpi);
1159     return ret;
1160 }
1161
1162
1163 /* Store Rsa Key, may save later, Dsa could use in future */
1164 static int StoreRsaKey(DecodedCert* cert)
1165 {
1166     int    length;
1167     word32 read = cert->srcIdx;
1168
1169     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1170         return ASN_PARSE_E;
1171    
1172     read = cert->srcIdx - read;
1173     length += read;
1174
1175     while (read--)
1176        cert->srcIdx--;
1177
1178     cert->pubKeySize = length;
1179     cert->publicKey = cert->source + cert->srcIdx;
1180     cert->srcIdx += length;
1181
1182     return 0;
1183 }
1184
1185
1186 #ifdef HAVE_ECC
1187
1188     /* return 0 on sucess if the ECC curve oid sum is supported */
1189     static int CheckCurve(word32 oid)
1190     {
1191         if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid !=
1192                    ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1)
1193             return ALGO_ID_E; 
1194
1195         return 0;
1196     }
1197
1198 #endif /* HAVE_ECC */
1199
1200
1201 static int GetKey(DecodedCert* cert)
1202 {
1203     int length;
1204 #ifdef HAVE_NTRU
1205     int tmpIdx = cert->srcIdx;
1206 #endif
1207
1208     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1209         return ASN_PARSE_E;
1210     
1211     if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
1212         return ASN_PARSE_E;
1213
1214     if (cert->keyOID == RSAk) {
1215         byte b = cert->source[cert->srcIdx++];
1216         if (b != ASN_BIT_STRING)
1217             return ASN_BITSTR_E;
1218
1219         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1220             return ASN_PARSE_E;
1221         b = cert->source[cert->srcIdx++];
1222         if (b != 0x00)
1223             return ASN_EXPECT_0_E;
1224     }
1225     else if (cert->keyOID == DSAk )
1226         ;   /* do nothing */
1227 #ifdef HAVE_NTRU
1228     else if (cert->keyOID == NTRUk ) {
1229         const byte* key = &cert->source[tmpIdx];
1230         byte*       next = (byte*)key;
1231         word16      keyLen;
1232         byte        keyBlob[MAX_NTRU_KEY_SZ];
1233
1234         word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
1235                             &keyLen, NULL, &next);
1236
1237         if (rc != NTRU_OK)
1238             return ASN_NTRU_KEY_E;
1239         if (keyLen > sizeof(keyBlob))
1240             return ASN_NTRU_KEY_E;
1241
1242         rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, &keyLen,
1243                                                                 keyBlob, &next);
1244         if (rc != NTRU_OK)
1245             return ASN_NTRU_KEY_E;
1246
1247         if ( (next - key) < 0)
1248             return ASN_NTRU_KEY_E;
1249
1250         cert->srcIdx = tmpIdx + (next - key);
1251
1252         cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
1253                                           DYNAMIC_TYPE_PUBLIC_KEY);
1254         if (cert->publicKey == NULL)
1255             return MEMORY_E;
1256         XMEMCPY(cert->publicKey, keyBlob, keyLen);
1257         cert->pubKeyStored = 1;
1258         cert->pubKeySize   = keyLen;
1259     }
1260 #endif /* HAVE_NTRU */
1261 #ifdef HAVE_ECC
1262     else if (cert->keyOID == ECDSAk ) {
1263         word32 oid = 0;
1264         int    oidSz = 0;
1265         byte   b = cert->source[cert->srcIdx++];
1266     
1267         if (b != ASN_OBJECT_ID) 
1268             return ASN_OBJECT_ID_E;
1269
1270         if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
1271             return ASN_PARSE_E;
1272
1273         while(oidSz--)
1274             oid += cert->source[cert->srcIdx++];
1275         if (CheckCurve(oid) < 0)
1276             return ECC_CURVE_OID_E;
1277
1278         /* key header */
1279         b = cert->source[cert->srcIdx++];
1280         if (b != ASN_BIT_STRING)
1281             return ASN_BITSTR_E;
1282
1283         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1284             return ASN_PARSE_E;
1285         b = cert->source[cert->srcIdx++];
1286         if (b != 0x00)
1287             return ASN_EXPECT_0_E;
1288
1289         /* actual key, use length - 1 since ate preceding 0 */
1290         length -= 1;
1291
1292         cert->publicKey = (byte*) XMALLOC(length, cert->heap,
1293                                           DYNAMIC_TYPE_PUBLIC_KEY);
1294         if (cert->publicKey == NULL)
1295             return MEMORY_E;
1296         XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
1297         cert->pubKeyStored = 1;
1298         cert->pubKeySize   = length;
1299
1300         cert->srcIdx += length;
1301     }
1302 #endif /* HAVE_ECC */
1303     else
1304         return ASN_UNKNOWN_OID_E;
1305    
1306     if (cert->keyOID == RSAk) 
1307         return StoreRsaKey(cert);
1308     return 0;
1309 }
1310
1311
1312 /* process NAME, either issuer or subject */
1313 static int GetName(DecodedCert* cert, int nameType)
1314 {
1315     Sha    sha;
1316     int    length;  /* length of all distinguished names */
1317     int    dummy;
1318     char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
1319     word32 idx;
1320
1321     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
1322         CYASSL_MSG("Trying optional prefix...");
1323
1324         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1325             return ASN_PARSE_E;
1326
1327         cert->srcIdx += length;
1328         CYASSL_MSG("Got optional prefix");
1329     }
1330
1331     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
1332      * calculated over the entire DER encoding of the Name field, including
1333      * the tag and length. */
1334     idx = cert->srcIdx;
1335     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1336         return ASN_PARSE_E;
1337
1338     InitSha(&sha);
1339     ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx);
1340     if (nameType == ISSUER)
1341         ShaFinal(&sha, cert->issuerHash);
1342     else
1343         ShaFinal(&sha, cert->subjectHash);
1344
1345     length += cert->srcIdx;
1346     idx = 0;
1347
1348     while (cert->srcIdx < (word32)length) {
1349         byte   b;
1350         byte   joint[2];
1351         int    oidSz;
1352
1353         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
1354             (void)b;  /* empty body warning w/o messages enabled */
1355             CYASSL_MSG("Cert name lacks set header, trying sequence");
1356         }
1357
1358         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
1359             return ASN_PARSE_E;
1360
1361         b = cert->source[cert->srcIdx++];
1362         if (b != ASN_OBJECT_ID) 
1363             return ASN_OBJECT_ID_E;
1364
1365         if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
1366             return ASN_PARSE_E;
1367
1368         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
1369
1370         /* v1 name types */
1371         if (joint[0] == 0x55 && joint[1] == 0x04) {
1372             byte   id;
1373             byte   copy = FALSE;
1374             int    strLen;
1375
1376             cert->srcIdx += 2;
1377             id = cert->source[cert->srcIdx++]; 
1378             b  = cert->source[cert->srcIdx++];    /* strType */
1379
1380             if (GetLength(cert->source, &cert->srcIdx, &strLen,
1381                           cert->maxIdx) < 0)
1382                 return ASN_PARSE_E;
1383
1384             if (strLen > (int)(ASN_NAME_MAX - idx))
1385                 return ASN_PARSE_E; 
1386
1387             if (4  > (ASN_NAME_MAX - idx))  /* make sure room for biggest */
1388                 return ASN_PARSE_E;         /* pre fix header too "/CN=" */
1389
1390             if (id == ASN_COMMON_NAME) {
1391                 if (nameType == SUBJECT) {
1392                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
1393                     cert->subjectCNLen = strLen;
1394                 }
1395
1396                 XMEMCPY(&full[idx], "/CN=", 4);
1397                 idx += 4;
1398                 copy = TRUE;
1399             }
1400             else if (id == ASN_SUR_NAME) {
1401                 XMEMCPY(&full[idx], "/SN=", 4);
1402                 idx += 4;
1403                 copy = TRUE;
1404 #ifdef CYASSL_CERT_GEN
1405                 if (nameType == SUBJECT) {
1406                     cert->subjectSN = (char*)&cert->source[cert->srcIdx];
1407                     cert->subjectSNLen = strLen;
1408                 }
1409 #endif /* CYASSL_CERT_GEN */
1410             }
1411             else if (id == ASN_COUNTRY_NAME) {
1412                 XMEMCPY(&full[idx], "/C=", 3);
1413                 idx += 3;
1414                 copy = TRUE;
1415 #ifdef CYASSL_CERT_GEN
1416                 if (nameType == SUBJECT) {
1417                     cert->subjectC = (char*)&cert->source[cert->srcIdx];
1418                     cert->subjectCLen = strLen;
1419                 }
1420 #endif /* CYASSL_CERT_GEN */
1421             }
1422             else if (id == ASN_LOCALITY_NAME) {
1423                 XMEMCPY(&full[idx], "/L=", 3);
1424                 idx += 3;
1425                 copy = TRUE;
1426 #ifdef CYASSL_CERT_GEN
1427                 if (nameType == SUBJECT) {
1428                     cert->subjectL = (char*)&cert->source[cert->srcIdx];
1429                     cert->subjectLLen = strLen;
1430                 }
1431 #endif /* CYASSL_CERT_GEN */
1432             }
1433             else if (id == ASN_STATE_NAME) {
1434                 XMEMCPY(&full[idx], "/ST=", 4);
1435                 idx += 4;
1436                 copy = TRUE;
1437 #ifdef CYASSL_CERT_GEN
1438                 if (nameType == SUBJECT) {
1439                     cert->subjectST = (char*)&cert->source[cert->srcIdx];
1440                     cert->subjectSTLen = strLen;
1441                 }
1442 #endif /* CYASSL_CERT_GEN */
1443             }
1444             else if (id == ASN_ORG_NAME) {
1445                 XMEMCPY(&full[idx], "/O=", 3);
1446                 idx += 3;
1447                 copy = TRUE;
1448 #ifdef CYASSL_CERT_GEN
1449                 if (nameType == SUBJECT) {
1450                     cert->subjectO = (char*)&cert->source[cert->srcIdx];
1451                     cert->subjectOLen = strLen;
1452                 }
1453 #endif /* CYASSL_CERT_GEN */
1454             }
1455             else if (id == ASN_ORGUNIT_NAME) {
1456                 XMEMCPY(&full[idx], "/OU=", 4);
1457                 idx += 4;
1458                 copy = TRUE;
1459 #ifdef CYASSL_CERT_GEN
1460                 if (nameType == SUBJECT) {
1461                     cert->subjectOU = (char*)&cert->source[cert->srcIdx];
1462                     cert->subjectOULen = strLen;
1463                 }
1464 #endif /* CYASSL_CERT_GEN */
1465             }
1466
1467             if (copy) {
1468                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
1469                 idx += strLen;
1470             }
1471
1472             cert->srcIdx += strLen;
1473         }
1474         else {
1475             /* skip */
1476             byte email = FALSE;
1477             byte uid   = FALSE;
1478             int  adv;
1479
1480             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
1481                 email = TRUE;
1482
1483             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
1484                 uid = TRUE;
1485
1486             cert->srcIdx += oidSz + 1;
1487
1488             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
1489                 return ASN_PARSE_E;
1490
1491             if (adv > (int)(ASN_NAME_MAX - idx))
1492                 return ASN_PARSE_E; 
1493
1494             if (email) {
1495                 if (14 > (ASN_NAME_MAX - idx))
1496                     return ASN_PARSE_E; 
1497                 XMEMCPY(&full[idx], "/emailAddress=", 14);
1498                 idx += 14;
1499
1500 #ifdef CYASSL_CERT_GEN
1501                 if (nameType == SUBJECT) {
1502                     cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
1503                     cert->subjectEmailLen = adv;
1504                 }
1505 #endif /* CYASSL_CERT_GEN */
1506
1507                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
1508                 idx += adv;
1509             }
1510
1511             if (uid) {
1512                 if (5 > (ASN_NAME_MAX - idx))
1513                     return ASN_PARSE_E; 
1514                 XMEMCPY(&full[idx], "/UID=", 5);
1515                 idx += 5;
1516
1517                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
1518                 idx += adv;
1519             }
1520
1521             cert->srcIdx += adv;
1522         }
1523     }
1524     full[idx++] = 0;
1525
1526     return 0;
1527 }
1528
1529
1530 #ifndef NO_TIME_H
1531
1532 /* to the second */
1533 static int DateGreaterThan(const struct tm* a, const struct tm* b)
1534 {
1535     if (a->tm_year > b->tm_year)
1536         return 1;
1537
1538     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
1539         return 1;
1540     
1541     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
1542            a->tm_mday > b->tm_mday)
1543         return 1;
1544
1545     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
1546         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
1547         return 1;
1548
1549     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
1550         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
1551         a->tm_min > b->tm_min)
1552         return 1;
1553
1554     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
1555         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
1556         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
1557         return 1;
1558
1559     return 0; /* false */
1560 }
1561
1562
1563 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
1564 {
1565     return !DateGreaterThan(a,b);
1566 }
1567
1568
1569 /* like atoi but only use first byte */
1570 /* Make sure before and after dates are valid */
1571 int ValidateDate(const byte* date, byte format, int dateType)
1572 {
1573     time_t ltime;
1574     struct tm  certTime;
1575     struct tm* localTime;
1576     int    i = 0;
1577
1578     ltime = XTIME(0);
1579     XMEMSET(&certTime, 0, sizeof(certTime));
1580
1581     if (format == ASN_UTC_TIME) {
1582         if (btoi(date[0]) >= 5)
1583             certTime.tm_year = 1900;
1584         else
1585             certTime.tm_year = 2000;
1586     }
1587     else  { /* format == GENERALIZED_TIME */
1588         certTime.tm_year += btoi(date[i++]) * 1000;
1589         certTime.tm_year += btoi(date[i++]) * 100;
1590     }
1591
1592     GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
1593     GetTime(&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;    /* adjust */
1594     GetTime(&certTime.tm_mday, date, &i);
1595     GetTime(&certTime.tm_hour, date, &i); 
1596     GetTime(&certTime.tm_min,  date, &i); 
1597     GetTime(&certTime.tm_sec,  date, &i); 
1598
1599     if (date[i] != 'Z') {     /* only Zulu supported for this profile */
1600         CYASSL_MSG("Only Zulu time supported for this profile"); 
1601         return 0;
1602     }
1603
1604     localTime = XGMTIME(&ltime);
1605
1606     if (dateType == BEFORE) {
1607         if (DateLessThan(localTime, &certTime))
1608             return 0;
1609     }
1610     else
1611         if (DateGreaterThan(localTime, &certTime))
1612             return 0;
1613
1614     return 1;
1615 }
1616
1617 #endif /* NO_TIME_H */
1618
1619
1620 static int GetDate(DecodedCert* cert, int dateType)
1621 {
1622     int    length;
1623     byte   date[MAX_DATE_SIZE];
1624     byte   b;
1625
1626 #ifdef CYASSL_CERT_GEN
1627     word32 startIdx = 0;
1628     if (dateType == BEFORE)
1629         cert->beforeDate = &cert->source[cert->srcIdx];
1630     else
1631         cert->afterDate = &cert->source[cert->srcIdx];
1632     startIdx = cert->srcIdx;
1633 #endif
1634
1635     b = cert->source[cert->srcIdx++];
1636     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
1637         return ASN_TIME_E;
1638
1639     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1640         return ASN_PARSE_E;
1641
1642     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
1643         return ASN_DATE_SZ_E;
1644
1645     XMEMCPY(date, &cert->source[cert->srcIdx], length);
1646     cert->srcIdx += length;
1647
1648 #ifdef CYASSL_CERT_GEN
1649     if (dateType == BEFORE)
1650         cert->beforeDateLen = cert->srcIdx - startIdx;
1651     else
1652         cert->afterDateLen  = cert->srcIdx - startIdx;
1653 #endif
1654
1655     if (!XVALIDATE_DATE(date, b, dateType)) {
1656         if (dateType == BEFORE)
1657             return ASN_BEFORE_DATE_E;
1658         else
1659             return ASN_AFTER_DATE_E;
1660     }
1661
1662     return 0;
1663 }
1664
1665
1666 static int GetValidity(DecodedCert* cert, int verify)
1667 {
1668     int length;
1669     int badDate = 0;
1670
1671     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1672         return ASN_PARSE_E;
1673
1674     if (GetDate(cert, BEFORE) < 0 && verify)
1675         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
1676     
1677     if (GetDate(cert, AFTER) < 0 && verify)
1678         return ASN_AFTER_DATE_E;
1679    
1680     if (badDate != 0)
1681         return badDate;
1682
1683     return 0;
1684 }
1685
1686
1687 int DecodeToKey(DecodedCert* cert, int verify)
1688 {
1689     int badDate = 0;
1690     int ret;
1691
1692     if ( (ret = GetCertHeader(cert)) < 0)
1693         return ret;
1694
1695     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
1696                           cert->maxIdx)) < 0)
1697         return ret;
1698
1699     if ( (ret = GetName(cert, ISSUER)) < 0)
1700         return ret;
1701
1702     if ( (ret = GetValidity(cert, verify)) < 0)
1703         badDate = ret;
1704
1705     if ( (ret = GetName(cert, SUBJECT)) < 0)
1706         return ret;
1707
1708     if ( (ret = GetKey(cert)) < 0)
1709         return ret;
1710
1711     if (badDate != 0)
1712         return badDate;
1713
1714     return ret;
1715 }
1716
1717
1718 static int GetSignature(DecodedCert* cert)
1719 {
1720     int    length;
1721     byte   b = cert->source[cert->srcIdx++];
1722
1723     if (b != ASN_BIT_STRING)
1724         return ASN_BITSTR_E;
1725
1726     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
1727         return ASN_PARSE_E;
1728
1729     cert->sigLength = length;
1730
1731     b = cert->source[cert->srcIdx++];
1732     if (b != 0x00)
1733         return ASN_EXPECT_0_E;
1734
1735     cert->sigLength--;
1736     cert->signature = &cert->source[cert->srcIdx];
1737     cert->srcIdx += cert->sigLength;
1738
1739     return 0;
1740 }
1741
1742
1743 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
1744 {
1745     output[0] = ASN_OCTET_STRING;
1746     output[1] = (byte)digSz;
1747     XMEMCPY(&output[2], digest, digSz);
1748
1749     return digSz + 2;
1750
1751
1752
1753 static word32 BytePrecision(word32 value)
1754 {
1755     word32 i;
1756     for (i = sizeof(value); i; --i)
1757         if (value >> (i - 1) * 8)
1758             break;
1759
1760     return i;
1761 }
1762
1763
1764 static word32 SetLength(word32 length, byte* output)
1765 {
1766     word32 i = 0, j;
1767
1768     if (length < ASN_LONG_LENGTH)
1769         output[i++] = (byte)length;
1770     else {
1771         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
1772       
1773         for (j = BytePrecision(length); j; --j) {
1774             output[i] = (byte)(length >> (j - 1) * 8);
1775             i++;
1776         }
1777     }
1778
1779     return i;
1780 }
1781
1782
1783 static word32 SetSequence(word32 len, byte* output)
1784 {
1785     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
1786     return SetLength(len, output + 1) + 1;
1787 }
1788
1789
1790 static word32 SetAlgoID(int algoOID, byte* output, int type)
1791 {
1792     /* adding TAG_NULL and 0 to end */
1793     
1794     /* hashTypes */
1795     static const byte shaAlgoID[]    = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
1796                                          0x05, 0x00 };
1797     static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
1798                                          0x04, 0x02, 0x01, 0x05, 0x00 };
1799     static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
1800                                          0x04, 0x02, 0x02, 0x05, 0x00 };
1801     static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
1802                                          0x04, 0x02, 0x03, 0x05, 0x00 };
1803     static const byte md5AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
1804                                          0x02, 0x05, 0x05, 0x00  };
1805     static const byte md2AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
1806                                          0x02, 0x02, 0x05, 0x00};
1807     /* sigTypes */
1808     static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
1809                                            0x01, 0x01, 0x04, 0x05, 0x00};
1810     static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
1811                                            0x01, 0x01, 0x05, 0x05, 0x00};
1812     static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
1813                                             0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
1814     static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
1815                                             0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
1816     static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
1817                                             0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
1818     /* keyTypes */
1819     static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
1820                                       0x01, 0x01, 0x01, 0x05, 0x00};
1821     int    algoSz = 0;
1822     word32 idSz, seqSz;
1823     const  byte* algoName = 0;
1824     byte ID_Length[MAX_LENGTH_SZ];
1825     byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
1826
1827     if (type == hashType) {
1828         switch (algoOID) {
1829         case SHAh:
1830             algoSz = sizeof(shaAlgoID);
1831             algoName = shaAlgoID;
1832             break;
1833
1834         case SHA256h:
1835             algoSz = sizeof(sha256AlgoID);
1836             algoName = sha256AlgoID;
1837             break;
1838
1839         case SHA384h:
1840             algoSz = sizeof(sha384AlgoID);
1841             algoName = sha384AlgoID;
1842             break;
1843
1844         case SHA512h:
1845             algoSz = sizeof(sha512AlgoID);
1846             algoName = sha512AlgoID;
1847             break;
1848
1849         case MD2h:
1850             algoSz = sizeof(md2AlgoID);
1851             algoName = md2AlgoID;
1852             break;
1853
1854         case MD5h:
1855             algoSz = sizeof(md5AlgoID);
1856             algoName = md5AlgoID;
1857             break;
1858
1859         default:
1860             CYASSL_MSG("Unknown Hash Algo");
1861             return 0;  /* UNKOWN_HASH_E; */
1862         }
1863     }
1864     else if (type == sigType) {    /* sigType */
1865         switch (algoOID) {
1866         case CTC_MD5wRSA:
1867             algoSz = sizeof(md5wRSA_AlgoID);
1868             algoName = md5wRSA_AlgoID;
1869             break;
1870
1871         case CTC_SHAwRSA:
1872             algoSz = sizeof(shawRSA_AlgoID);
1873             algoName = shawRSA_AlgoID;
1874             break;
1875
1876         case CTC_SHA256wRSA:
1877             algoSz = sizeof(sha256wRSA_AlgoID);
1878             algoName = sha256wRSA_AlgoID;
1879             break;
1880
1881         case CTC_SHA384wRSA:
1882             algoSz = sizeof(sha384wRSA_AlgoID);
1883             algoName = sha384wRSA_AlgoID;
1884             break;
1885
1886         case CTC_SHA512wRSA:
1887             algoSz = sizeof(sha512wRSA_AlgoID);
1888             algoName = sha512wRSA_AlgoID;
1889             break;
1890
1891         default:
1892             CYASSL_MSG("Unknown Signature Algo");
1893             return 0;
1894         }
1895     }
1896     else if (type == keyType) {    /* keyType */
1897         switch (algoOID) {
1898         case RSAk:
1899             algoSz = sizeof(RSA_AlgoID);
1900             algoName = RSA_AlgoID;
1901             break;
1902
1903         default:
1904             CYASSL_MSG("Unknown Key Algo");
1905             return 0;
1906         }
1907     }
1908     else {
1909         CYASSL_MSG("Unknown Algo type");
1910         return 0;
1911     }
1912
1913     idSz  = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */
1914     seqSz = SetSequence(idSz + algoSz + 1, seqArray);
1915     seqArray[seqSz++] = ASN_OBJECT_ID;
1916
1917     XMEMCPY(output, seqArray, seqSz);
1918     XMEMCPY(output + seqSz, ID_Length, idSz);
1919     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
1920
1921     return seqSz + idSz + algoSz;
1922
1923 }
1924
1925
1926 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
1927 {
1928     byte digArray[MAX_ENCODED_DIG_SZ];
1929     byte algoArray[MAX_ALGO_SZ];
1930     byte seqArray[MAX_SEQ_SZ];
1931     word32 encDigSz, algoSz, seqSz; 
1932
1933     encDigSz = SetDigest(digest, digSz, digArray);
1934     algoSz   = SetAlgoID(hashOID, algoArray, hashType);
1935     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
1936
1937     XMEMCPY(out, seqArray, seqSz);
1938     XMEMCPY(out + seqSz, algoArray, algoSz);
1939     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
1940
1941     return encDigSz + algoSz + seqSz;
1942 }
1943                            
1944 #include <stdio.h>
1945 /* return true (1) for Confirmation */
1946 static int ConfirmSignature(const byte* buf, word32 bufSz,
1947     const byte* key, word32 keySz, word32 keyOID,
1948     const byte* sig, word32 sigSz, word32 sigOID,
1949     void* heap)
1950 {
1951 #ifdef CYASSL_SHA512
1952     byte digest[SHA512_DIGEST_SIZE]; /* max size */
1953 #elif !defined(NO_SHA256)
1954     byte digest[SHA256_DIGEST_SIZE]; /* max size */
1955 #else
1956     byte digest[SHA_DIGEST_SIZE];    /* max size */
1957 #endif
1958     int  typeH, digestSz, ret;
1959
1960     if (sigOID == CTC_MD5wRSA) {
1961         Md5 md5;
1962         InitMd5(&md5);
1963         Md5Update(&md5, buf, bufSz);
1964         Md5Final(&md5, digest);
1965         typeH    = MD5h;
1966         digestSz = MD5_DIGEST_SIZE;
1967     }
1968 #ifdef CYASSL_MD2
1969     else if (sigOID == CTC_MD2wRSA) {
1970         Md2 md2;
1971         InitMd2(&md2);
1972         Md2Update(&md2, buf, bufSz);
1973         Md2Final(&md2, digest);
1974         typeH    = MD2h;
1975         digestSz = MD2_DIGEST_SIZE;
1976     }
1977 #endif
1978     else if (sigOID == CTC_SHAwRSA ||
1979              sigOID == CTC_SHAwDSA ||
1980              sigOID == CTC_SHAwECDSA) {
1981         Sha sha;
1982         InitSha(&sha);
1983         ShaUpdate(&sha, buf, bufSz);
1984         ShaFinal(&sha, digest);
1985         typeH    = SHAh;
1986         digestSz = SHA_DIGEST_SIZE;
1987     }
1988 #ifndef NO_SHA256
1989     else if (sigOID == CTC_SHA256wRSA ||
1990              sigOID == CTC_SHA256wECDSA) {
1991         Sha256 sha256;
1992         InitSha256(&sha256);
1993         Sha256Update(&sha256, buf, bufSz);
1994         Sha256Final(&sha256, digest);
1995         typeH    = SHA256h;
1996         digestSz = SHA256_DIGEST_SIZE;
1997     }
1998 #endif
1999 #ifdef CYASSL_SHA512
2000     else if (sigOID == CTC_SHA512wRSA ||
2001              sigOID == CTC_SHA512wECDSA) {
2002         Sha512 sha512;
2003         InitSha512(&sha512);
2004         Sha512Update(&sha512, buf, bufSz);
2005         Sha512Final(&sha512, digest);
2006         typeH    = SHA512h;
2007         digestSz = SHA512_DIGEST_SIZE;
2008     }
2009 #endif
2010 #ifdef CYASSL_SHA384
2011     else if (sigOID == CTC_SHA384wRSA ||
2012              sigOID == CTC_SHA384wECDSA) {
2013         Sha384 sha384;
2014         InitSha384(&sha384);
2015         Sha384Update(&sha384, buf, bufSz);
2016         Sha384Final(&sha384, digest);
2017         typeH    = SHA384h;
2018         digestSz = SHA384_DIGEST_SIZE;
2019     }
2020 #endif
2021     else {
2022         CYASSL_MSG("Verify Signautre has unsupported type");
2023         return 0;
2024     }
2025
2026     if (keyOID == RSAk) {
2027         RsaKey pubKey;
2028         byte   encodedSig[MAX_ENCODED_SIG_SZ];
2029         byte   plain[MAX_ENCODED_SIG_SZ];
2030         word32 idx = 0;
2031         int    encodedSigSz, verifySz;
2032         byte*  out;
2033
2034         if (sigSz > MAX_ENCODED_SIG_SZ) {
2035             CYASSL_MSG("Verify Signautre is too big");
2036             return 0;
2037         }
2038             
2039         InitRsaKey(&pubKey, heap);
2040         if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) {
2041             CYASSL_MSG("ASN Key decode error RSA");
2042             ret = 0;
2043         }
2044         else {
2045             XMEMCPY(plain, sig, sigSz);
2046             if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out,
2047                                            &pubKey)) < 0) {
2048                 CYASSL_MSG("Rsa SSL verify error");
2049                 ret = 0;
2050             }
2051             else {
2052                 /* make sure we're right justified */
2053                 encodedSigSz =
2054                         EncodeSignature(encodedSig, digest, digestSz, typeH);
2055                 if (encodedSigSz != verifySz ||
2056                                 XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
2057                     CYASSL_MSG("Rsa SSL verify match encode error");
2058                     ret = 0;
2059                 }
2060                 else
2061                     ret = 1; /* match */
2062
2063 #ifdef CYASSL_DEBUG_ENCODING
2064                 {
2065                 int x;
2066                 printf("cyassl encodedSig:\n");
2067                 for (x = 0; x < encodedSigSz; x++) {
2068                     printf("%02x ", encodedSig[x]);
2069                     if ( (x % 16) == 15)
2070                         printf("\n");
2071                 }
2072                 printf("\n");
2073                 printf("actual digest:\n");
2074                 for (x = 0; x < verifySz; x++) {
2075                     printf("%02x ", out[x]);
2076                     if ( (x % 16) == 15)
2077                         printf("\n");
2078                 }
2079                 printf("\n");
2080                 }
2081 #endif /* CYASSL_DEBUG_ENCODING */
2082             }
2083         }
2084         FreeRsaKey(&pubKey);
2085         return ret;
2086     }
2087 #ifdef HAVE_ECC
2088     else if (keyOID == ECDSAk) {
2089         ecc_key pubKey;
2090         int     verify = 0;
2091         
2092         if (ecc_import_x963(key, keySz, &pubKey) < 0) {
2093             CYASSL_MSG("ASN Key import error ECC");
2094             return 0;
2095         }
2096     
2097         ret = ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, &pubKey);
2098         ecc_free(&pubKey);
2099         if (ret == 0 && verify == 1)
2100             return 1;  /* match */
2101
2102         CYASSL_MSG("ECC Verify didn't match");
2103         return 0;
2104     }
2105 #endif /* HAVE_ECC */
2106     else {
2107         CYASSL_MSG("Verify Key type unknown");
2108         return 0;
2109     }
2110 }
2111
2112
2113 static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
2114 {
2115     word32 idx = 0;
2116     int length = 0;
2117
2118     CYASSL_ENTER("DecodeAltNames");
2119
2120     if (GetSequence(input, &idx, &length, sz) < 0) {
2121         CYASSL_MSG("\tBad Sequence");
2122         return;
2123     }
2124
2125     while (length > 0) {
2126         DNS_entry* entry;
2127         int        strLen;
2128         byte       b = input[idx++];
2129
2130         length--;
2131
2132         if (b != (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
2133             CYASSL_MSG("\tNot DNS type");
2134             return;
2135         }
2136
2137         if (GetLength(input, &idx, &strLen, sz) < 0) {
2138             CYASSL_MSG("\tfail: str length");
2139             return;
2140         }
2141
2142         entry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
2143                                     DYNAMIC_TYPE_ALTNAME);
2144         if (entry == NULL) {
2145             CYASSL_MSG("\tOut of Memory");
2146             return;
2147         }
2148
2149         entry->name = (char*)XMALLOC(strLen + 1, cert->heap,
2150                                      DYNAMIC_TYPE_ALTNAME);
2151         if (entry->name == NULL) {
2152             CYASSL_MSG("\tOut of Memory");
2153             XFREE(entry, cert->heap, DYNAMIC_TYPE_ALTNAME);
2154             return;
2155         }
2156
2157         XMEMCPY(entry->name, &input[idx], strLen);
2158         entry->name[strLen] = '\0';
2159
2160         entry->next    = cert->altNames;
2161         cert->altNames = entry;
2162
2163         length -= strLen;
2164         idx    += strLen;
2165     }   
2166 }
2167
2168
2169 static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
2170 {
2171     word32 idx = 0;
2172     int length = 0;
2173
2174     CYASSL_ENTER("DecodeBasicCaConstraint");
2175     if (GetSequence(input, &idx, &length, sz) < 0) return;
2176
2177     if (length == 0) return;
2178     /* If the basic ca constraint is false, this extension may be named, but
2179      * left empty. So, if the length is 0, just return. */
2180
2181     if (input[idx++] != ASN_BOOLEAN)
2182     {
2183         CYASSL_MSG("\tfail: constraint not BOOLEAN");
2184         return;
2185     }
2186
2187     if (GetLength(input, &idx, &length, sz) < 0)
2188     {
2189         CYASSL_MSG("\tfail: length");
2190         return;
2191     }
2192
2193     if (input[idx])
2194         cert->isCA = 1;
2195 }
2196
2197
2198 #define CRLDP_FULL_NAME 0
2199     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
2200 #define GENERALNAME_URI 6
2201     /* From RFC3280 SS4.2.1.7, GeneralName */
2202
2203 static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
2204 {
2205     word32 idx = 0;
2206     int length = 0;
2207
2208     CYASSL_ENTER("DecodeCrlDist");
2209
2210     /* Unwrap the list of Distribution Points*/
2211     if (GetSequence(input, &idx, &length, sz) < 0) return;
2212
2213     /* Unwrap a single Distribution Point */
2214     if (GetSequence(input, &idx, &length, sz) < 0) return;
2215
2216     /* The Distribution Point has three explicit optional members
2217      *  First check for a DistributionPointName
2218      */
2219     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
2220     {
2221         idx++;
2222         if (GetLength(input, &idx, &length, sz) < 0) return;
2223
2224         if (input[idx] == 
2225                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
2226         {
2227             idx++;
2228             if (GetLength(input, &idx, &length, sz) < 0) return;
2229
2230             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
2231             {
2232                 idx++;
2233                 if (GetLength(input, &idx, &length, sz) < 0) return;
2234
2235                 cert->extCrlInfoSz = length;
2236                 cert->extCrlInfo = input + idx;
2237                 idx += length;
2238             }
2239             else
2240                 /* This isn't a URI, skip it. */
2241                 idx += length;
2242         }
2243         else
2244             /* This isn't a FULLNAME, skip it. */
2245             idx += length;
2246     }
2247
2248     /* Check for reasonFlags */
2249     if (idx < (word32)sz &&
2250         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
2251     {
2252         idx++;
2253         if (GetLength(input, &idx, &length, sz) < 0) return;
2254         idx += length;
2255     }
2256
2257     /* Check for cRLIssuer */
2258     if (idx < (word32)sz &&
2259         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
2260     {
2261         idx++;
2262         if (GetLength(input, &idx, &length, sz) < 0) return;
2263         idx += length;
2264     }
2265
2266     if (idx < (word32)sz)
2267     {
2268         CYASSL_MSG("\tThere are more CRL Distribution Point records, "
2269                    "but we only use the first one.");
2270     }
2271
2272     return;
2273 }
2274
2275
2276 static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
2277 /*
2278  *  Read the first of the Authority Information Access records. If there are
2279  *  any issues, return without saving the record.
2280  */
2281 {
2282     word32 idx = 0;
2283     int length = 0;
2284     word32 oid;
2285
2286     /* Unwrap the list of AIAs */
2287     if (GetSequence(input, &idx, &length, sz) < 0) return;
2288
2289     /* Unwrap a single AIA */
2290     if (GetSequence(input, &idx, &length, sz) < 0) return;
2291
2292     oid = 0;
2293     if (GetObjectId(input, &idx, &oid, sz) < 0) return;
2294
2295     /* Only supporting URIs right now. */
2296     if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
2297     {
2298         idx++;
2299         if (GetLength(input, &idx, &length, sz) < 0) return;
2300
2301         cert->extAuthInfoSz = length;
2302         cert->extAuthInfo = input + idx;
2303         idx += length;
2304     }
2305     else
2306     {
2307         /* Skip anything else. */
2308         idx++;
2309         if (GetLength(input, &idx, &length, sz) < 0) return;
2310         idx += length;
2311     }
2312
2313     if (idx < (word32)sz)
2314     {
2315         CYASSL_MSG("\tThere are more Authority Information Access records, "
2316                    "but we only use first one.");
2317     }
2318
2319     return;
2320 }
2321
2322
2323 static void DecodeCertExtensions(DecodedCert* cert)
2324 /*
2325  *  Processing the Certificate Extensions. This does not modify the current
2326  *  index. It is works starting with the recorded extensions pointer.
2327  */
2328 {
2329     word32 idx = 0;
2330     int sz = cert->extensionsSz;
2331     byte* input = cert->extensions;
2332     int length;
2333     word32 oid;
2334
2335     CYASSL_ENTER("DecodeCertExtensions");
2336
2337     if (input == NULL || sz == 0) return;
2338
2339     if (input[idx++] != ASN_EXTENSIONS) return;
2340
2341     if (GetLength(input, &idx, &length, sz) < 0) return;
2342
2343     if (GetSequence(input, &idx, &length, sz) < 0) return;
2344     
2345     while (idx < (word32)sz) {
2346         if (GetSequence(input, &idx, &length, sz) < 0) {
2347             CYASSL_MSG("\tfail: should be a SEQUENCE");
2348             return;
2349         }
2350
2351         oid = 0;
2352         if (GetObjectId(input, &idx, &oid, sz) < 0) {
2353             CYASSL_MSG("\tfail: OBJECT ID");
2354             return;
2355         }
2356
2357         /* check for critical flag */
2358         if (input[idx] == ASN_BOOLEAN) {
2359             CYASSL_MSG("\tfound optional critical flag, moving past");
2360             idx += (ASN_BOOL_SIZE + 1);
2361         }
2362
2363         /* process the extension based on the OID */
2364         if (input[idx++] != ASN_OCTET_STRING) {
2365             CYASSL_MSG("\tfail: should be an OCTET STRING");
2366             return;
2367         }
2368
2369         if (GetLength(input, &idx, &length, sz) < 0) {
2370             CYASSL_MSG("\tfail: extension data length");
2371             return;
2372         }
2373
2374         switch (oid) {
2375             case BASIC_CA_OID:
2376                 DecodeBasicCaConstraint(&input[idx], length, cert);
2377                 break;
2378
2379             case CRL_DIST_OID:
2380                 DecodeCrlDist(&input[idx], length, cert);
2381                 break;
2382
2383             case AUTH_INFO_OID:
2384                 DecodeAuthInfo(&input[idx], length, cert);
2385                 break;
2386
2387             case ALT_NAMES_OID:
2388                 DecodeAltNames(&input[idx], length, cert);
2389
2390             default:
2391                 CYASSL_MSG("\tExtension type not handled, skipping");
2392                 break;
2393         }
2394         idx += length;
2395     }
2396
2397     return;
2398 }
2399
2400
2401 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
2402 {
2403     int   ret;
2404     char* ptr;
2405
2406     ret = ParseCertRelative(cert, type, verify, cm);
2407     if (ret < 0)
2408         return ret;
2409
2410     if (cert->subjectCNLen > 0) {
2411         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
2412                               DYNAMIC_TYPE_SUBJECT_CN);
2413         if (ptr == NULL)
2414             return MEMORY_E;
2415         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
2416         ptr[cert->subjectCNLen] = '\0';
2417         cert->subjectCN = ptr;
2418         cert->subjectCNStored = 1;
2419     }
2420
2421     if (cert->keyOID == RSAk && cert->pubKeySize > 0) {
2422         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
2423                               DYNAMIC_TYPE_PUBLIC_KEY);
2424         if (ptr == NULL)
2425             return MEMORY_E;
2426         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
2427         cert->publicKey = (byte *)ptr;
2428         cert->pubKeyStored = 1;
2429     }
2430
2431     return ret;
2432 }
2433
2434
2435 /* from SSL proper, for locking can't do find here anymore */
2436 #ifdef __cplusplus
2437     extern "C" {
2438 #endif
2439     CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
2440 #ifdef __cplusplus
2441     } 
2442 #endif
2443
2444
2445 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
2446 {
2447     word32 confirmOID;
2448     int    ret;
2449     int    badDate = 0;
2450
2451     if ((ret = DecodeToKey(cert, verify)) < 0) {
2452         if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
2453             badDate = ret;
2454         else
2455             return ret;
2456     }
2457
2458     if (cert->srcIdx != cert->sigIndex) {
2459         if (cert->srcIdx < cert->sigIndex) {
2460             /* save extensions */
2461             cert->extensions    = &cert->source[cert->srcIdx];
2462             cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
2463             cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
2464         }
2465         DecodeCertExtensions(cert);
2466         /* advance past extensions */
2467         cert->srcIdx =  cert->sigIndex;
2468     }
2469
2470     if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
2471                          cert->maxIdx)) < 0)
2472         return ret;
2473
2474     if ((ret = GetSignature(cert)) < 0)
2475         return ret;
2476
2477     if (confirmOID != cert->signatureOID)
2478         return ASN_SIG_OID_E;
2479
2480     if (verify && type != CA_TYPE) {
2481         Signer* ca = GetCA(cm, cert->issuerHash);
2482         CYASSL_MSG("About to verify certificate signature");
2483  
2484         if (ca) {
2485 #ifdef HAVE_OCSP
2486             /* Need the ca's public key hash for OCSP */
2487             {
2488                 Sha sha;
2489                 InitSha(&sha);
2490                 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize);
2491                 ShaFinal(&sha, cert->issuerKeyHash);
2492             }
2493 #endif /* HAVE_OCSP */
2494             /* try to confirm/verify signature */
2495             if (!ConfirmSignature(cert->source + cert->certBegin,
2496                         cert->sigIndex - cert->certBegin,
2497                     ca->publicKey, ca->pubKeySize, ca->keyOID,
2498                     cert->signature, cert->sigLength, cert->signatureOID,
2499                     cert->heap)) {
2500                 CYASSL_MSG("Confirm signature failed");
2501                 return ASN_SIG_CONFIRM_E;
2502             }
2503         }
2504         else {
2505             /* no signer */
2506             CYASSL_MSG("No CA signer to verify with");
2507             return ASN_SIG_CONFIRM_E;
2508         }
2509     }
2510
2511     if (badDate != 0)
2512         return badDate;
2513
2514     return 0;
2515 }
2516
2517
2518 Signer* MakeSigner(void* heap)
2519 {
2520     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
2521                                        DYNAMIC_TYPE_SIGNER);
2522     if (signer) {
2523         signer->name      = 0;
2524         signer->publicKey = 0;
2525         signer->next      = 0;
2526     }
2527     (void)heap;
2528
2529     return signer;
2530 }
2531
2532
2533 void FreeSigners(Signer* signer, void* heap)
2534 {
2535     while (signer) {
2536         Signer* next = signer->next;
2537
2538         XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
2539         XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
2540         XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
2541
2542         signer = next;
2543     }
2544     (void)heap;
2545 }
2546
2547
2548 void CTaoCryptErrorString(int error, char* buffer)
2549 {
2550     const int max = MAX_ERROR_SZ;   /* shorthand */
2551
2552 #ifdef NO_ERROR_STRINGS
2553
2554     XSTRNCPY(buffer, "no support for error strings built in", max);
2555
2556 #else
2557
2558     switch (error) {
2559
2560     case OPEN_RAN_E :        
2561         XSTRNCPY(buffer, "opening random device error", max);
2562         break;
2563
2564     case READ_RAN_E :
2565         XSTRNCPY(buffer, "reading random device error", max);
2566         break;
2567
2568     case WINCRYPT_E :
2569         XSTRNCPY(buffer, "windows crypt init error", max);
2570         break;
2571
2572     case CRYPTGEN_E : 
2573         XSTRNCPY(buffer, "windows crypt generation error", max);
2574         break;
2575
2576     case RAN_BLOCK_E : 
2577         XSTRNCPY(buffer, "random device read would block error", max);
2578         break;
2579
2580     case MP_INIT_E :
2581         XSTRNCPY(buffer, "mp_init error state", max);
2582         break;
2583
2584     case MP_READ_E :
2585         XSTRNCPY(buffer, "mp_read error state", max);
2586         break;
2587
2588     case MP_EXPTMOD_E :
2589         XSTRNCPY(buffer, "mp_exptmod error state", max);
2590         break;
2591
2592     case MP_TO_E :
2593         XSTRNCPY(buffer, "mp_to_xxx error state, can't convert", max);
2594         break;
2595
2596     case MP_SUB_E :
2597         XSTRNCPY(buffer, "mp_sub error state, can't subtract", max);
2598         break;
2599
2600     case MP_ADD_E :
2601         XSTRNCPY(buffer, "mp_add error state, can't add", max);
2602         break;
2603
2604     case MP_MUL_E :
2605         XSTRNCPY(buffer, "mp_mul error state, can't multiply", max);
2606         break;
2607
2608     case MP_MULMOD_E :
2609         XSTRNCPY(buffer, "mp_mulmod error state, can't multiply mod", max);
2610         break;
2611
2612     case MP_MOD_E :
2613         XSTRNCPY(buffer, "mp_mod error state, can't mod", max);
2614         break;
2615
2616     case MP_INVMOD_E :
2617         XSTRNCPY(buffer, "mp_invmod error state, can't inv mod", max);
2618         break; 
2619         
2620     case MP_CMP_E :
2621         XSTRNCPY(buffer, "mp_cmp error state", max);
2622         break; 
2623         
2624     case MP_ZERO_E :
2625         XSTRNCPY(buffer, "mp zero result, not expected", max);
2626         break; 
2627         
2628     case MEMORY_E :
2629         XSTRNCPY(buffer, "out of memory error", max);
2630         break;
2631
2632     case RSA_WRONG_TYPE_E :
2633         XSTRNCPY(buffer, "RSA wrong block type for RSA function", max);
2634         break; 
2635
2636     case RSA_BUFFER_E :
2637         XSTRNCPY(buffer, "RSA buffer error, output too small or input too big",
2638                 max);
2639         break; 
2640
2641     case BUFFER_E :
2642         XSTRNCPY(buffer, "Buffer error, output too small or input too big",max);
2643         break; 
2644
2645     case ALGO_ID_E :
2646         XSTRNCPY(buffer, "Setting Cert AlogID error", max);
2647         break; 
2648
2649     case PUBLIC_KEY_E :
2650         XSTRNCPY(buffer, "Setting Cert Public Key error", max);
2651         break; 
2652
2653     case DATE_E :
2654         XSTRNCPY(buffer, "Setting Cert Date validity error", max);
2655         break; 
2656
2657     case SUBJECT_E :
2658         XSTRNCPY(buffer, "Setting Cert Subject name error", max);
2659         break; 
2660
2661     case ISSUER_E :
2662         XSTRNCPY(buffer, "Setting Cert Issuer name error", max);
2663         break; 
2664
2665     case CA_TRUE_E :
2666         XSTRNCPY(buffer, "Setting basic constraint CA true error", max);
2667         break; 
2668
2669     case EXTENSIONS_E :
2670         XSTRNCPY(buffer, "Setting extensions error", max);
2671         break; 
2672
2673     case ASN_PARSE_E :
2674         XSTRNCPY(buffer, "ASN parsing error, invalid input", max);
2675         break;
2676
2677     case ASN_VERSION_E :
2678         XSTRNCPY(buffer, "ASN version error, invalid number", max);
2679         break;
2680
2681     case ASN_GETINT_E :
2682         XSTRNCPY(buffer, "ASN get big int error, invalid data", max);
2683         break;
2684
2685     case ASN_RSA_KEY_E :
2686         XSTRNCPY(buffer, "ASN key init error, invalid input", max);
2687         break;
2688
2689     case ASN_OBJECT_ID_E :
2690         XSTRNCPY(buffer, "ASN object id error, invalid id", max);
2691         break;
2692
2693     case ASN_TAG_NULL_E :
2694         XSTRNCPY(buffer, "ASN tag error, not null", max);
2695         break;
2696
2697     case ASN_EXPECT_0_E :
2698         XSTRNCPY(buffer, "ASN expect error, not zero", max);
2699         break;
2700
2701     case ASN_BITSTR_E :
2702         XSTRNCPY(buffer, "ASN bit string error, wrong id", max);
2703         break;
2704
2705     case ASN_UNKNOWN_OID_E :
2706         XSTRNCPY(buffer, "ASN oid error, unknown sum id", max);
2707         break;
2708
2709     case ASN_DATE_SZ_E :
2710         XSTRNCPY(buffer, "ASN date error, bad size", max);
2711         break;
2712
2713     case ASN_BEFORE_DATE_E :
2714         XSTRNCPY(buffer, "ASN date error, current date before", max);
2715         break;
2716
2717     case ASN_AFTER_DATE_E :
2718         XSTRNCPY(buffer, "ASN date error, current date after", max);
2719         break;
2720
2721     case ASN_SIG_OID_E :
2722         XSTRNCPY(buffer, "ASN signature error, mismatched oid", max);
2723         break;
2724
2725     case ASN_TIME_E :
2726         XSTRNCPY(buffer, "ASN time error, unkown time type", max);
2727         break;
2728
2729     case ASN_INPUT_E :
2730         XSTRNCPY(buffer, "ASN input error, not enough data", max);
2731         break;
2732
2733     case ASN_SIG_CONFIRM_E :
2734         XSTRNCPY(buffer, "ASN sig error, confirm failure", max);
2735         break;
2736
2737     case ASN_SIG_HASH_E :
2738         XSTRNCPY(buffer, "ASN sig error, unsupported hash type", max);
2739         break;
2740
2741     case ASN_SIG_KEY_E :
2742         XSTRNCPY(buffer, "ASN sig error, unsupported key type", max);
2743         break;
2744
2745     case ASN_DH_KEY_E :
2746         XSTRNCPY(buffer, "ASN key init error, invalid input", max);
2747         break;
2748
2749     case ASN_NTRU_KEY_E :
2750         XSTRNCPY(buffer, "ASN NTRU key decode error, invalid input", max);
2751         break;
2752
2753     case ECC_BAD_ARG_E :
2754         XSTRNCPY(buffer, "ECC input argument wrong type, invalid input", max);
2755         break;
2756
2757     case ASN_ECC_KEY_E :
2758         XSTRNCPY(buffer, "ECC ASN1 bad key data, invalid input", max);
2759         break;
2760
2761     case ECC_CURVE_OID_E :
2762         XSTRNCPY(buffer, "ECC curve sum OID unsupported, invalid input", max);
2763         break;
2764
2765     case BAD_FUNC_ARG :
2766         XSTRNCPY(buffer, "Bad function argument", max);
2767         break;
2768
2769     case NOT_COMPILED_IN :
2770         XSTRNCPY(buffer, "Feature not compiled in", max);
2771         break;
2772
2773     case UNICODE_SIZE_E :
2774         XSTRNCPY(buffer, "Unicode password too big", max);
2775         break;
2776
2777     case NO_PASSWORD :
2778         XSTRNCPY(buffer, "No password provided by user", max);
2779         break;
2780
2781     case ALT_NAME_E :
2782         XSTRNCPY(buffer, "Alt Name problem, too big", max);
2783         break;
2784
2785     case AES_GCM_AUTH_E:
2786         XSTRNCPY(buffer, "AES-GCM Authentication check fail", max);
2787         break;
2788
2789     default:
2790         XSTRNCPY(buffer, "unknown error number", max);
2791
2792     }
2793
2794 #endif /* NO_ERROR_STRINGS */
2795
2796 }
2797
2798
2799 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
2800
2801 static int SetMyVersion(word32 version, byte* output, int header)
2802 {
2803     int i = 0;
2804
2805     if (header) {
2806         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
2807         output[i++] = ASN_BIT_STRING;
2808     }
2809     output[i++] = ASN_INTEGER;
2810     output[i++] = 0x01;
2811     output[i++] = (byte)version;
2812
2813     return i;
2814 }
2815
2816
2817 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
2818              int type)
2819 {
2820     char header[80];
2821     char footer[80];
2822
2823     int headerLen;
2824     int footerLen;
2825     int i;
2826     int err;
2827     int outLen;   /* return length or error */
2828
2829     if (type == CERT_TYPE) {
2830         XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header));
2831         XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer));
2832     } else {
2833         XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header));
2834         XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer));
2835     }
2836
2837     headerLen = XSTRLEN(header);
2838     footerLen = XSTRLEN(footer);
2839
2840     if (!der || !output)
2841         return BAD_FUNC_ARG;
2842
2843     /* don't even try if outSz too short */
2844     if (outSz < headerLen + footerLen + derSz)
2845         return BAD_FUNC_ARG;
2846
2847     /* header */
2848     XMEMCPY(output, header, headerLen);
2849     i = headerLen;
2850
2851     /* body */
2852     outLen = outSz;  /* input to Base64_Encode */
2853     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0)
2854         return err;
2855     i += outLen;
2856
2857     /* footer */
2858     if ( (i + footerLen) > (int)outSz)
2859         return BAD_FUNC_ARG;
2860     XMEMCPY(output + i, footer, footerLen);
2861
2862     return outLen + headerLen + footerLen;
2863 }
2864
2865
2866 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
2867
2868
2869 #ifdef CYASSL_KEY_GEN
2870
2871
2872 static mp_int* GetRsaInt(RsaKey* key, int idx)
2873 {
2874     if (idx == 0)
2875         return &key->n;
2876     if (idx == 1)
2877         return &key->e;
2878     if (idx == 2)
2879         return &key->d;
2880     if (idx == 3)
2881         return &key->p;
2882     if (idx == 4)
2883         return &key->q;
2884     if (idx == 5)
2885         return &key->dP;
2886     if (idx == 6)
2887         return &key->dQ;
2888     if (idx == 7)
2889         return &key->u;
2890
2891     return NULL;
2892 }
2893
2894
2895 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
2896    written */
2897 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
2898 {
2899     word32 seqSz, verSz, rawLen, intTotalLen = 0;
2900     word32 sizes[RSA_INTS];
2901     int    i, j, outLen;
2902
2903     byte seq[MAX_SEQ_SZ];
2904     byte ver[MAX_VERSION_SZ];
2905     byte tmps[RSA_INTS][MAX_RSA_INT_SZ];
2906
2907     if (!key || !output)
2908         return BAD_FUNC_ARG;
2909
2910     if (key->type != RSA_PRIVATE)
2911         return BAD_FUNC_ARG;
2912
2913     /* write all big ints from key to DER tmps */
2914     for (i = 0; i < RSA_INTS; i++) {
2915         mp_int* keyInt = GetRsaInt(key, i);
2916         rawLen = mp_unsigned_bin_size(keyInt);
2917
2918         tmps[i][0] = ASN_INTEGER;
2919         sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1;  /* int tag */
2920
2921         if ( (sizes[i] + rawLen) < sizeof(tmps[i])) {
2922             int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
2923             if (err == MP_OKAY) {
2924                 sizes[i] += rawLen;
2925                 intTotalLen += sizes[i];
2926             }
2927             else
2928                 return err;
2929         }
2930         else
2931             return ASN_INPUT_E; 
2932     }
2933
2934     /* make headers */
2935     verSz = SetMyVersion(0, ver, FALSE);
2936     seqSz = SetSequence(verSz + intTotalLen, seq);
2937
2938     outLen = seqSz + verSz + intTotalLen;
2939     if (outLen > (int)inLen)
2940         return BAD_FUNC_ARG;
2941
2942     /* write to output */
2943     XMEMCPY(output, seq, seqSz);
2944     j = seqSz;
2945     XMEMCPY(output + j, ver, verSz);
2946     j += verSz;
2947
2948     for (i = 0; i < RSA_INTS; i++) {
2949         XMEMCPY(output + j, tmps[i], sizes[i]);
2950         j += sizes[i];
2951     }
2952
2953     return outLen;
2954 }
2955
2956 #endif /* CYASSL_KEY_GEN */
2957
2958
2959 #ifdef CYASSL_CERT_GEN
2960
2961 /* Initialize and Set Certficate defaults:
2962    version    = 3 (0x2)
2963    serial     = 0
2964    sigType    = SHA_WITH_RSA
2965    issuer     = blank
2966    daysValid  = 500
2967    selfSigned = 1 (true) use subject as issuer
2968    subject    = blank
2969 */
2970 void InitCert(Cert* cert)
2971 {
2972     cert->version    = 2;   /* version 3 is hex 2 */
2973     cert->sigType    = CTC_SHAwRSA;
2974     cert->daysValid  = 500;
2975     cert->selfSigned = 1;
2976     cert->isCA       = 0;
2977     cert->bodySz     = 0;
2978 #ifdef CYASSL_ALT_NAMES
2979     cert->altNamesSz   = 0;
2980     cert->beforeDateSz = 0;
2981     cert->afterDateSz  = 0;
2982 #endif
2983     cert->keyType    = RSA_KEY;
2984     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
2985
2986     cert->issuer.country[0] = '\0';
2987     cert->issuer.state[0] = '\0';
2988     cert->issuer.locality[0] = '\0';
2989     cert->issuer.sur[0] = '\0';
2990     cert->issuer.org[0] = '\0';
2991     cert->issuer.unit[0] = '\0';
2992     cert->issuer.commonName[0] = '\0';
2993     cert->issuer.email[0] = '\0';
2994
2995     cert->subject.country[0] = '\0';
2996     cert->subject.state[0] = '\0';
2997     cert->subject.locality[0] = '\0';
2998     cert->subject.sur[0] = '\0';
2999     cert->subject.org[0] = '\0';
3000     cert->subject.unit[0] = '\0';
3001     cert->subject.commonName[0] = '\0';
3002     cert->subject.email[0] = '\0';
3003 }
3004
3005
3006 /* DER encoded x509 Certificate */
3007 typedef struct DerCert {
3008     byte size[MAX_LENGTH_SZ];          /* length encoded */
3009     byte version[MAX_VERSION_SZ];      /* version encoded */
3010     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
3011     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
3012     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
3013     byte subject[ASN_NAME_MAX];        /* subject encoded */
3014     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
3015     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
3016     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
3017     byte extensions[MAX_EXTENSIONS_SZ];  /* all extensions */
3018     int  sizeSz;                       /* encoded size length */
3019     int  versionSz;                    /* encoded version length */
3020     int  serialSz;                     /* encoded serial length */
3021     int  sigAlgoSz;                    /* enocded sig alog length */
3022     int  issuerSz;                     /* encoded issuer length */
3023     int  subjectSz;                    /* encoded subject length */
3024     int  validitySz;                   /* encoded validity length */
3025     int  publicKeySz;                  /* encoded public key length */
3026     int  caSz;                         /* encoded CA extension length */
3027     int  extensionsSz;                 /* encoded extensions total length */
3028     int  total;                        /* total encoded lengths */
3029 } DerCert;
3030
3031
3032 /* Write a set header to output */
3033 static word32 SetSet(word32 len, byte* output)
3034 {
3035     output[0] = ASN_SET | ASN_CONSTRUCTED;
3036     return SetLength(len, output + 1) + 1;
3037 }
3038
3039
3040 /* Write a serial number to output */
3041 static int SetSerial(const byte* serial, byte* output)
3042 {
3043     int length = 0;
3044
3045     output[length++] = ASN_INTEGER;
3046     length += SetLength(CTC_SERIAL_SIZE, &output[length]);
3047     XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
3048
3049     return length + CTC_SERIAL_SIZE;
3050 }
3051
3052
3053 /* Write a public RSA key to output */
3054 static int SetPublicKey(byte* output, RsaKey* key)
3055 {
3056     byte n[MAX_RSA_INT_SZ];
3057     byte e[MAX_RSA_E_SZ];
3058     byte algo[MAX_ALGO_SZ];
3059     byte seq[MAX_SEQ_SZ];
3060     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
3061     int  nSz;
3062     int  eSz;
3063     int  algoSz;
3064     int  seqSz;
3065     int  lenSz;
3066     int  idx;
3067     int  rawLen;
3068
3069     /* n */
3070     rawLen = mp_unsigned_bin_size(&key->n);
3071     n[0] = ASN_INTEGER;
3072     nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
3073
3074     if ( (nSz + rawLen) < (int)sizeof(n)) {
3075         int err = mp_to_unsigned_bin(&key->n, n + nSz);
3076         if (err == MP_OKAY)
3077             nSz += rawLen;
3078         else
3079             return MP_TO_E;
3080     }
3081     else
3082         return BUFFER_E;
3083
3084     /* e */
3085     rawLen = mp_unsigned_bin_size(&key->e);
3086     e[0] = ASN_INTEGER;
3087     eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
3088
3089     if ( (eSz + rawLen) < (int)sizeof(e)) {
3090         int err = mp_to_unsigned_bin(&key->e, e + eSz);
3091         if (err == MP_OKAY)
3092             eSz += rawLen;
3093         else
3094             return MP_TO_E;
3095     }
3096     else
3097         return BUFFER_E;
3098
3099     /* headers */
3100     algoSz = SetAlgoID(RSAk, algo, keyType);
3101     seqSz  = SetSequence(nSz + eSz, seq);
3102     lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
3103     len[lenSz++] = 0;   /* trailing 0 */
3104
3105     /* write */
3106     idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
3107         /* 1 is for ASN_BIT_STRING */
3108     /* algo */
3109     XMEMCPY(output + idx, algo, algoSz);
3110     idx += algoSz;
3111     /* bit string */
3112     output[idx++] = ASN_BIT_STRING;
3113     /* length */
3114     XMEMCPY(output + idx, len, lenSz);
3115     idx += lenSz;
3116     /* seq */
3117     XMEMCPY(output + idx, seq, seqSz);
3118     idx += seqSz;
3119     /* n */
3120     XMEMCPY(output + idx, n, nSz);
3121     idx += nSz;
3122     /* e */
3123     XMEMCPY(output + idx, e, eSz);
3124     idx += eSz;
3125
3126     return idx;
3127 }
3128
3129
3130 static INLINE byte itob(int number)
3131 {
3132     return (byte)number + 0x30;
3133 }
3134
3135
3136 /* write time to output, format */
3137 static void SetTime(struct tm* date, byte* output)
3138 {
3139     int i = 0;
3140
3141     output[i++] = itob((date->tm_year % 10000) / 1000);
3142     output[i++] = itob((date->tm_year % 1000)  /  100);
3143     output[i++] = itob((date->tm_year % 100)   /   10);
3144     output[i++] = itob( date->tm_year % 10);
3145
3146     output[i++] = itob(date->tm_mon / 10);
3147     output[i++] = itob(date->tm_mon % 10);
3148
3149     output[i++] = itob(date->tm_mday / 10);
3150     output[i++] = itob(date->tm_mday % 10);
3151
3152     output[i++] = itob(date->tm_hour / 10);
3153     output[i++] = itob(date->tm_hour % 10);
3154
3155     output[i++] = itob(date->tm_min / 10);
3156     output[i++] = itob(date->tm_min % 10);
3157
3158     output[i++] = itob(date->tm_sec / 10);
3159     output[i++] = itob(date->tm_sec % 10);
3160     
3161     output[i] = 'Z';  /* Zulu profile */
3162 }
3163
3164
3165 #ifdef CYASSL_ALT_NAMES
3166
3167 /* Copy Dates from cert, return bytes written */
3168 static int CopyValidity(byte* output, Cert* cert)
3169 {
3170     int seqSz;
3171
3172     CYASSL_ENTER("CopyValidity");
3173
3174     /* headers and output */
3175     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
3176     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
3177     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
3178                                                  cert->afterDateSz);
3179     return seqSz + cert->beforeDateSz + cert->afterDateSz;
3180 }
3181
3182 #endif
3183
3184
3185 /* Set Date validity from now until now + daysValid */
3186 static int SetValidity(byte* output, int daysValid)
3187 {
3188     byte before[MAX_DATE_SIZE];
3189     byte  after[MAX_DATE_SIZE];
3190
3191     int beforeSz;
3192     int afterSz;
3193     int seqSz;
3194
3195     time_t     ticks;
3196     struct tm* now;
3197     struct tm  local;
3198
3199     ticks = XTIME(0);
3200     now   = XGMTIME(&ticks);
3201
3202     /* before now */
3203     local = *now;
3204     before[0] = ASN_GENERALIZED_TIME;
3205     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
3206
3207     /* subtract 1 day for more compliance */
3208     local.tm_mday -= 1;
3209     mktime(&local);
3210
3211     /* adjust */
3212     local.tm_year += 1900;
3213     local.tm_mon  +=    1;
3214
3215     SetTime(&local, before + beforeSz);
3216     beforeSz += ASN_GEN_TIME_SZ;
3217     
3218     /* after now + daysValid */
3219     local = *now;
3220     after[0] = ASN_GENERALIZED_TIME;
3221     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
3222
3223     /* add daysValid */
3224     local.tm_mday += daysValid;
3225     mktime(&local);
3226
3227     /* adjust */
3228     local.tm_year += 1900;
3229     local.tm_mon  +=    1;
3230
3231     SetTime(&local, after + afterSz);
3232     afterSz += ASN_GEN_TIME_SZ;
3233
3234     /* headers and output */
3235     seqSz = SetSequence(beforeSz + afterSz, output);
3236     XMEMCPY(output + seqSz, before, beforeSz);
3237     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
3238
3239     return seqSz + beforeSz + afterSz;
3240 }
3241
3242
3243 /* ASN Encoded Name field */
3244 typedef struct EncodedName {
3245     int  nameLen;                /* actual string value length */
3246     int  totalLen;               /* total encoded length */
3247     int  type;                   /* type of name */
3248     int  used;                   /* are we actually using this one */
3249     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
3250 } EncodedName;
3251
3252
3253 /* Get Which Name from index */
3254 static const char* GetOneName(CertName* name, int idx)
3255 {
3256     switch (idx) {
3257     case 0:
3258        return name->country;
3259        break;
3260     case 1:
3261        return name->state;
3262        break;
3263     case 2:
3264        return name->locality;
3265        break;
3266     case 3:
3267        return name->sur;
3268        break;
3269     case 4:
3270        return name->org;
3271        break;
3272     case 5:
3273        return name->unit;
3274        break;
3275     case 6:
3276        return name->commonName;
3277        break;
3278     case 7:
3279        return name->email;
3280        break;
3281     default:
3282        return 0;
3283     }
3284 }
3285
3286
3287 /* Get ASN Name from index */
3288 static byte GetNameId(int idx)
3289 {
3290     switch (idx) {
3291     case 0:
3292        return ASN_COUNTRY_NAME;
3293        break;
3294     case 1:
3295        return ASN_STATE_NAME;
3296        break;
3297     case 2:
3298        return ASN_LOCALITY_NAME;
3299        break;
3300     case 3:
3301        return ASN_SUR_NAME;
3302        break;
3303     case 4:
3304        return ASN_ORG_NAME;
3305        break;
3306     case 5:
3307        return ASN_ORGUNIT_NAME;
3308        break;
3309     case 6:
3310        return ASN_COMMON_NAME;
3311        break;
3312     case 7:
3313        /* email uses different id type */
3314        return 0;
3315        break;
3316     default:
3317        return 0;
3318     }
3319 }
3320
3321
3322 /* encode all extensions, return total bytes written */
3323 static int SetExtensions(byte* output, const byte* ext, int extSz)
3324 {
3325     byte sequence[MAX_SEQ_SZ];
3326     byte len[MAX_LENGTH_SZ];
3327
3328     int sz = 0;
3329     int seqSz = SetSequence(extSz, sequence);
3330     int lenSz = SetLength(seqSz + extSz, len);
3331
3332     output[0] = ASN_EXTENSIONS; /* extensions id */
3333     sz++;
3334     XMEMCPY(&output[sz], len, lenSz);  /* length */
3335     sz += lenSz; 
3336     XMEMCPY(&output[sz], sequence, seqSz);  /* sequence */
3337     sz += seqSz;
3338     XMEMCPY(&output[sz], ext, extSz);  /* extensions */
3339     sz += extSz;
3340
3341     return sz;
3342 }
3343
3344
3345 /* encode CA basic constraint true, return total bytes written */
3346 static int SetCa(byte* output)
3347 {
3348     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
3349                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
3350     
3351     XMEMCPY(output, ca, sizeof(ca));
3352
3353     return (int)sizeof(ca);
3354 }
3355
3356
3357 /* encode CertName into output, return total bytes written */
3358 static int SetName(byte* output, CertName* name)
3359 {
3360     int         totalBytes = 0, i, idx;
3361     EncodedName names[NAME_ENTRIES];
3362
3363     for (i = 0; i < NAME_ENTRIES; i++) {
3364         const char* nameStr = GetOneName(name, i);
3365         if (nameStr) {
3366             /* bottom up */
3367             byte firstLen[MAX_LENGTH_SZ];
3368             byte secondLen[MAX_LENGTH_SZ];
3369             byte sequence[MAX_SEQ_SZ];
3370             byte set[MAX_SET_SZ];
3371
3372             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
3373             int strLen  = XSTRLEN(nameStr);
3374             int thisLen = strLen;
3375             int firstSz, secondSz, seqSz, setSz;
3376
3377             if (strLen == 0) { /* no user data for this item */
3378                 names[i].used = 0;
3379                 continue;
3380             }
3381
3382             secondSz = SetLength(strLen, secondLen);
3383             thisLen += secondSz;
3384             if (email) {
3385                 thisLen += EMAIL_JOINT_LEN;
3386                 thisLen ++;                               /* id type */
3387                 firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
3388             }
3389             else {
3390                 thisLen++;                                 /* str type */
3391                 thisLen++;                                 /* id  type */
3392                 thisLen += JOINT_LEN;    
3393                 firstSz = SetLength(JOINT_LEN + 1, firstLen);
3394             }
3395             thisLen += firstSz;
3396             thisLen++;                                /* object id */
3397
3398             seqSz = SetSequence(thisLen, sequence);
3399             thisLen += seqSz;
3400             setSz = SetSet(thisLen, set);
3401             thisLen += setSz;
3402
3403             if (thisLen > (int)sizeof(names[i].encoded))
3404                 return BUFFER_E;
3405
3406             /* store it */
3407             idx = 0;
3408             /* set */
3409             XMEMCPY(names[i].encoded, set, setSz);
3410             idx += setSz;
3411             /* seq */
3412             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
3413             idx += seqSz;
3414             /* asn object id */
3415             names[i].encoded[idx++] = ASN_OBJECT_ID;
3416             /* first length */
3417             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
3418             idx += firstSz;
3419             if (email) {
3420                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
3421                                            0x01, 0x09, 0x01, 0x16 };
3422                 /* email joint id */
3423                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
3424                 idx += sizeof(EMAIL_OID);
3425             }
3426             else {
3427                 /* joint id */
3428                 names[i].encoded[idx++] = 0x55;
3429                 names[i].encoded[idx++] = 0x04;
3430                 /* id type */
3431                 names[i].encoded[idx++] = GetNameId(i);
3432                 /* str type */
3433                 names[i].encoded[idx++] = 0x13;
3434             }
3435             /* second length */
3436             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
3437             idx += secondSz;
3438             /* str value */
3439             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
3440             idx += strLen;
3441
3442             totalBytes += idx;
3443             names[i].totalLen = idx;
3444             names[i].used = 1;
3445         }
3446         else
3447             names[i].used = 0;
3448     }
3449
3450     /* header */
3451     idx = SetSequence(totalBytes, output);
3452     totalBytes += idx;
3453     if (totalBytes > ASN_NAME_MAX)
3454         return BUFFER_E;
3455
3456     for (i = 0; i < NAME_ENTRIES; i++) {
3457         if (names[i].used) {
3458             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
3459             idx += names[i].totalLen;
3460         }
3461     }
3462     return totalBytes;
3463 }
3464
3465
3466 /* encode info from cert into DER enocder format */
3467 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng,
3468                       const byte* ntruKey, word16 ntruSz)
3469 {
3470     (void)ntruKey;
3471     (void)ntruSz;
3472     /* version */
3473     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
3474
3475     /* serial number */
3476     RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
3477     cert->serial[0] = 0x01;   /* ensure positive */
3478     der->serialSz  = SetSerial(cert->serial, der->serial);
3479
3480     /* signature algo */
3481     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType);
3482     if (der->sigAlgoSz == 0)
3483         return ALGO_ID_E;
3484
3485     /* public key */
3486     if (cert->keyType == RSA_KEY) {
3487         der->publicKeySz = SetPublicKey(der->publicKey, rsaKey);
3488         if (der->publicKeySz == 0)
3489             return PUBLIC_KEY_E;
3490     }
3491     else {
3492 #ifdef HAVE_NTRU
3493         word32 rc;
3494         word16 encodedSz;
3495
3496         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
3497                                               ntruKey, &encodedSz, NULL);
3498         if (rc != NTRU_OK)
3499             return PUBLIC_KEY_E;
3500         if (encodedSz > MAX_PUBLIC_KEY_SZ)
3501             return PUBLIC_KEY_E;
3502
3503         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
3504                               ntruKey, &encodedSz, der->publicKey);
3505         if (rc != NTRU_OK)
3506             return PUBLIC_KEY_E;
3507
3508         der->publicKeySz = encodedSz;
3509 #endif
3510     }
3511
3512     der->validitySz = 0;
3513 #ifdef CYASSL_ALT_NAMES
3514     /* date validity copy ? */
3515     if (cert->beforeDateSz && cert->afterDateSz) {
3516         der->validitySz = CopyValidity(der->validity, cert);
3517         if (der->validitySz == 0)
3518             return DATE_E;
3519     }
3520 #endif
3521
3522     /* date validity */
3523     if (der->validitySz == 0) {
3524         der->validitySz = SetValidity(der->validity, cert->daysValid);
3525         if (der->validitySz == 0)
3526             return DATE_E;
3527     }
3528
3529     /* subject name */
3530     der->subjectSz = SetName(der->subject, &cert->subject);
3531     if (der->subjectSz == 0)
3532         return SUBJECT_E;
3533
3534     /* issuer name */
3535     der->issuerSz = SetName(der->issuer, cert->selfSigned ?
3536              &cert->subject : &cert->issuer);
3537     if (der->issuerSz == 0)
3538         return ISSUER_E;
3539
3540     /* CA */
3541     if (cert->isCA) {
3542         der->caSz = SetCa(der->ca);
3543         if (der->caSz == 0)
3544             return CA_TRUE_E;
3545     }
3546     else
3547         der->caSz = 0;
3548
3549     /* extensions, just CA now */
3550     if (cert->isCA) {
3551         der->extensionsSz = SetExtensions(der->extensions, der->ca, der->caSz);
3552         if (der->extensionsSz == 0)
3553             return EXTENSIONS_E;
3554     }
3555     else
3556         der->extensionsSz = 0;
3557
3558 #ifdef CYASSL_ALT_NAMES
3559     if (der->extensionsSz == 0 && cert->altNamesSz) {
3560         der->extensionsSz = SetExtensions(der->extensions, cert->altNames,
3561                                           cert->altNamesSz);
3562         if (der->extensionsSz == 0)
3563             return EXTENSIONS_E;
3564     }
3565 #endif
3566
3567     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
3568         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
3569         der->extensionsSz;
3570
3571     return 0;
3572 }
3573
3574
3575 /* write DER encoded cert to buffer, size already checked */
3576 static int WriteCertBody(DerCert* der, byte* buffer)
3577 {
3578     int idx;
3579
3580     /* signed part header */
3581     idx = SetSequence(der->total, buffer);
3582     /* version */
3583     XMEMCPY(buffer + idx, der->version, der->versionSz);
3584     idx += der->versionSz;
3585     /* serial */
3586     XMEMCPY(buffer + idx, der->serial, der->serialSz);
3587     idx += der->serialSz;
3588     /* sig algo */
3589     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
3590     idx += der->sigAlgoSz;
3591     /* issuer */
3592     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
3593     idx += der->issuerSz;
3594     /* validity */
3595     XMEMCPY(buffer + idx, der->validity, der->validitySz);
3596     idx += der->validitySz;
3597     /* subject */
3598     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
3599     idx += der->subjectSz;
3600     /* public key */
3601     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
3602     idx += der->publicKeySz;
3603     if (der->extensionsSz) {
3604         /* extensions */
3605         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
3606                                                    sizeof(der->extensions)));
3607         idx += der->extensionsSz;
3608     }
3609
3610     return idx;
3611 }
3612
3613
3614 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
3615 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
3616                          RsaKey* key, RNG* rng, int sigAlgoType)
3617 {
3618     byte    digest[SHA256_DIGEST_SIZE];     /* max size */
3619     byte    encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
3620     int     encSigSz, digestSz, typeH;
3621
3622     if (sigAlgoType == CTC_MD5wRSA) {
3623         Md5     md5;
3624         InitMd5(&md5);
3625         Md5Update(&md5, buffer, sz);
3626         Md5Final(&md5, digest);
3627         digestSz = MD5_DIGEST_SIZE;
3628         typeH    = MD5h;
3629     }
3630     else if (sigAlgoType == CTC_SHAwRSA) {
3631         Sha     sha;
3632         InitSha(&sha);
3633         ShaUpdate(&sha, buffer, sz);
3634         ShaFinal(&sha, digest);
3635         digestSz = SHA_DIGEST_SIZE;
3636         typeH    = SHAh;
3637     }
3638     else if (sigAlgoType == CTC_SHA256wRSA) {
3639         Sha256     sha256;
3640         InitSha256(&sha256);
3641         Sha256Update(&sha256, buffer, sz);
3642         Sha256Final(&sha256, digest);
3643         digestSz = SHA256_DIGEST_SIZE;
3644         typeH    = SHA256h;
3645     }
3646     else
3647         return ALGO_ID_E;
3648
3649     /* signature */
3650     encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
3651     return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng);
3652 }
3653
3654
3655 /* add signature to end of buffer, size of buffer assumed checked, return
3656    new length */
3657 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
3658                         int sigAlgoType)
3659 {
3660     byte seq[MAX_SEQ_SZ];
3661     int  idx = bodySz, seqSz;
3662
3663     /* algo */
3664     idx += SetAlgoID(sigAlgoType, buffer + idx, sigType);
3665     /* bit string */
3666     buffer[idx++] = ASN_BIT_STRING;
3667     /* length */
3668     idx += SetLength(sigSz + 1, buffer + idx);
3669     buffer[idx++] = 0;   /* trailing 0 */
3670     /* signature */
3671     XMEMCPY(buffer + idx, sig, sigSz);
3672     idx += sigSz;
3673
3674     /* make room for overall header */
3675     seqSz = SetSequence(idx, seq);
3676     XMEMMOVE(buffer + seqSz, buffer, idx);
3677     XMEMCPY(buffer, seq, seqSz);
3678
3679     return idx + seqSz;
3680 }
3681
3682
3683 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
3684 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
3685                    RsaKey* rsaKey, RNG* rng, const byte* ntruKey, word16 ntruSz)
3686 {
3687     DerCert der;
3688     int     ret;
3689
3690     cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY;
3691     ret = EncodeCert(cert, &der, rsaKey, rng, ntruKey, ntruSz);
3692     if (ret != 0)
3693         return ret;
3694
3695     if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
3696         return BUFFER_E;
3697
3698     return cert->bodySz = WriteCertBody(&der, derBuffer);
3699 }
3700
3701
3702 /* Make an x509 Certificate v3 RSA from cert input, write to buffer */
3703 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,RNG* rng)
3704 {
3705     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, rng, NULL, 0);
3706 }
3707
3708
3709 #ifdef HAVE_NTRU
3710
3711 int  MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
3712                   const byte* ntruKey, word16 keySz, RNG* rng)
3713 {
3714     return MakeAnyCert(cert, derBuffer, derSz, NULL, rng, ntruKey, keySz);
3715 }
3716
3717 #endif /* HAVE_NTRU */
3718
3719
3720 int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
3721 {
3722     byte    sig[MAX_ENCODED_SIG_SZ];
3723     int     sigSz;
3724     int     bodySz = cert->bodySz;
3725
3726     if (bodySz < 0)
3727         return bodySz;
3728
3729     sigSz  = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng,
3730                            cert->sigType);
3731     if (sigSz < 0)
3732         return sigSz; 
3733
3734     if (bodySz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
3735         return BUFFER_E; 
3736
3737     return AddSignature(buffer, bodySz, sig, sigSz, cert->sigType);
3738 }
3739
3740
3741 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
3742 {
3743     int ret = MakeCert(cert, buffer, buffSz, key, rng);
3744
3745     if (ret < 0)
3746         return ret;
3747
3748     return SignCert(cert, buffer, buffSz, key, rng);
3749 }
3750
3751
3752 #ifdef CYASSL_ALT_NAMES 
3753
3754 /* Set Alt Names from der cert, return 0 on success */
3755 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
3756 {
3757     DecodedCert decoded;
3758     int         ret;
3759
3760     if (derSz < 0)
3761         return derSz;
3762
3763     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
3764     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
3765
3766     if (ret < 0) {
3767         FreeDecodedCert(&decoded);
3768         return ret;
3769     }
3770
3771     if (decoded.extensions) {
3772         byte   b;
3773         int    length;
3774         word32 maxExtensionsIdx;
3775
3776         decoded.srcIdx = decoded.extensionsIdx;
3777         b = decoded.source[decoded.srcIdx++];
3778         if (b != ASN_EXTENSIONS) {
3779             FreeDecodedCert(&decoded);
3780             return ASN_PARSE_E;
3781         }
3782
3783         if (GetLength(decoded.source, &decoded.srcIdx, &length,
3784                       decoded.maxIdx) < 0) {
3785             FreeDecodedCert(&decoded);
3786             return ASN_PARSE_E;
3787         }
3788
3789         if (GetSequence(decoded.source, &decoded.srcIdx, &length,
3790                         decoded.maxIdx) < 0) {
3791             FreeDecodedCert(&decoded);
3792             return ASN_PARSE_E;
3793         }
3794
3795         maxExtensionsIdx = decoded.srcIdx + length;
3796
3797         while (decoded.srcIdx < maxExtensionsIdx) {
3798             word32 oid;
3799             word32 startIdx = decoded.srcIdx;
3800             word32 tmpIdx;
3801
3802             if (GetSequence(decoded.source, &decoded.srcIdx, &length,
3803                         decoded.maxIdx) < 0) {
3804                 FreeDecodedCert(&decoded);
3805                 return ASN_PARSE_E;
3806             }
3807
3808             tmpIdx = decoded.srcIdx;
3809             decoded.srcIdx = startIdx;
3810
3811             if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid,
3812                           decoded.maxIdx) < 0) {
3813                 FreeDecodedCert(&decoded);
3814                 return ASN_PARSE_E;
3815             }
3816
3817             if (oid == ALT_NAMES_OID) {
3818                 cert->altNamesSz = length + (tmpIdx - startIdx);
3819
3820                 if (cert->altNamesSz < (int)sizeof(cert->altNames))
3821                     XMEMCPY(cert->altNames, &decoded.source[startIdx],
3822                         cert->altNamesSz);
3823                 else {
3824                     cert->altNamesSz = 0;
3825                     CYASSL_MSG("AltNames extensions too big");
3826                     FreeDecodedCert(&decoded);
3827                     return ALT_NAME_E;
3828                 }
3829             }
3830             decoded.srcIdx = tmpIdx + length;
3831         }
3832     }
3833     FreeDecodedCert(&decoded);
3834
3835     return 0;
3836 }
3837
3838
3839 /* Set Dates from der cert, return 0 on success */
3840 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
3841 {
3842     DecodedCert decoded;
3843     int         ret;
3844
3845     CYASSL_ENTER("SetDatesFromCert");
3846     if (derSz < 0)
3847         return derSz;
3848
3849     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
3850     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
3851
3852     if (ret < 0) {
3853         CYASSL_MSG("ParseCertRelative error");
3854         FreeDecodedCert(&decoded);
3855         return ret;
3856     }
3857
3858     if (decoded.beforeDate == NULL || decoded.afterDate == NULL) {
3859         CYASSL_MSG("Couldn't extract dates");
3860         FreeDecodedCert(&decoded);
3861         return -1;
3862     }
3863
3864     if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen >
3865                                                  MAX_DATE_SIZE) {
3866         CYASSL_MSG("Bad date size");
3867         FreeDecodedCert(&decoded);
3868         return -1;
3869     }
3870
3871     XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen);
3872     XMEMCPY(cert->afterDate,  decoded.afterDate,  decoded.afterDateLen);
3873
3874     cert->beforeDateSz = decoded.beforeDateLen;
3875     cert->afterDateSz  = decoded.afterDateLen;
3876
3877     return 0;
3878 }
3879
3880
3881 #endif /* CYASSL_ALT_NAMES */
3882
3883
3884 /* Set cn name from der buffer, return 0 on success */
3885 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
3886 {
3887     DecodedCert decoded;
3888     int         ret;
3889     int         sz;
3890
3891     if (derSz < 0)
3892         return derSz;
3893
3894     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
3895     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
3896
3897     if (ret < 0)
3898         return ret;
3899
3900     if (decoded.subjectCN) {
3901         sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen :
3902                                                   CTC_NAME_SIZE - 1;
3903         strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE);
3904         cn->commonName[sz] = 0;
3905     }
3906     if (decoded.subjectC) {
3907         sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen :
3908                                                  CTC_NAME_SIZE - 1;
3909         strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE);
3910         cn->country[sz] = 0;
3911     }
3912     if (decoded.subjectST) {
3913         sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen :
3914                                                   CTC_NAME_SIZE - 1;
3915         strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE);
3916         cn->state[sz] = 0;
3917     }
3918     if (decoded.subjectL) {
3919         sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen :
3920                                                  CTC_NAME_SIZE - 1;
3921         strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE);
3922         cn->locality[sz] = 0;
3923     }
3924     if (decoded.subjectO) {
3925         sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen :
3926                                                  CTC_NAME_SIZE - 1;
3927         strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE);
3928         cn->org[sz] = 0;
3929     }
3930     if (decoded.subjectOU) {
3931         sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen :
3932                                                   CTC_NAME_SIZE - 1;
3933         strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE);
3934         cn->unit[sz] = 0;
3935     }
3936     if (decoded.subjectSN) {
3937         sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen :
3938                                                   CTC_NAME_SIZE - 1;
3939         strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE);
3940         cn->sur[sz] = 0;
3941     }
3942     if (decoded.subjectEmail) {
3943         sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ?
3944                               decoded.subjectEmailLen : CTC_NAME_SIZE - 1;
3945         strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE);
3946         cn->email[sz] = 0;
3947     }
3948
3949     FreeDecodedCert(&decoded);
3950
3951     return 0;
3952 }
3953
3954
3955 #ifndef NO_FILESYSTEM
3956
3957 /* forward from CyaSSL */
3958 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
3959
3960 /* Set cert issuer from issuerFile in PEM */
3961 int SetIssuer(Cert* cert, const char* issuerFile)
3962 {
3963     byte        der[8192];
3964     int         derSz = CyaSSL_PemCertToDer(issuerFile, der, sizeof(der));
3965
3966     cert->selfSigned = 0;
3967     return SetNameFromCert(&cert->issuer, der, derSz);
3968 }
3969
3970
3971 /* Set cert subject from subjectFile in PEM */
3972 int SetSubject(Cert* cert, const char* subjectFile)
3973 {
3974     byte        der[8192];
3975     int         derSz = CyaSSL_PemCertToDer(subjectFile, der, sizeof(der));
3976
3977     return SetNameFromCert(&cert->subject, der, derSz);
3978 }
3979
3980
3981 #ifdef CYASSL_ALT_NAMES
3982
3983 /* Set atl names from file in PEM */
3984 int SetAltNames(Cert* cert, const char* file)
3985 {
3986     byte        der[8192];
3987     int         derSz = CyaSSL_PemCertToDer(file, der, sizeof(der));
3988
3989     return SetAltNamesFromCert(cert, der, derSz);
3990 }
3991
3992 #endif /* CYASSL_ALT_NAMES */
3993
3994 #endif /* NO_FILESYSTEM */
3995
3996 /* Set cert issuer from DER buffer */
3997 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
3998 {
3999     cert->selfSigned = 0;
4000     return SetNameFromCert(&cert->issuer, der, derSz);
4001 }
4002
4003
4004 /* Set cert subject from DER buffer */
4005 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
4006 {
4007     return SetNameFromCert(&cert->subject, der, derSz);
4008 }
4009
4010
4011 #ifdef CYASSL_ALT_NAMES
4012
4013 /* Set cert alt names from DER buffer */
4014 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
4015 {
4016     return SetAltNamesFromCert(cert, der, derSz);
4017 }
4018
4019 /* Set cert dates from DER buffer */
4020 int SetDatesBuffer(Cert* cert, const byte* der, int derSz)
4021 {
4022     return SetDatesFromCert(cert, der, derSz);
4023 }
4024
4025 #endif /* CYASSL_ALT_NAMES */
4026
4027 #endif /* CYASSL_CERT_GEN */
4028
4029
4030 #ifdef HAVE_ECC
4031
4032 /* Der Encode r & s ints into out, outLen is (in/out) size */
4033 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
4034 {
4035     word32 idx = 0;
4036     word32 rSz;                           /* encoding size */
4037     word32 sSz;
4038     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
4039
4040     int rLen = mp_unsigned_bin_size(r);   /* big int size */
4041     int sLen = mp_unsigned_bin_size(s);
4042     int err;
4043
4044     if (*outLen < (rLen + sLen + headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
4045         return BAD_FUNC_ARG;
4046
4047     idx = SetSequence(rLen + sLen + headerSz, out);
4048
4049     /* store r */
4050     out[idx++] = ASN_INTEGER;
4051     rSz = SetLength(rLen, &out[idx]);
4052     idx += rSz;
4053     err = mp_to_unsigned_bin(r, &out[idx]);
4054     if (err != MP_OKAY) return err;
4055     idx += rLen;
4056
4057     /* store s */
4058     out[idx++] = ASN_INTEGER;
4059     sSz = SetLength(sLen, &out[idx]);
4060     idx += sSz;
4061     err = mp_to_unsigned_bin(s, &out[idx]);
4062     if (err != MP_OKAY) return err;
4063     idx += sLen;
4064
4065     *outLen = idx;
4066
4067     return 0;
4068 }
4069
4070
4071 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */
4072 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
4073 {
4074     word32 idx = 0;
4075     int    len = 0;
4076
4077     if (GetSequence(sig, &idx, &len, sigLen) < 0)
4078         return ASN_ECC_KEY_E;
4079
4080     if ((word32)len > (sigLen - idx))
4081         return ASN_ECC_KEY_E;
4082
4083     if (GetInt(r, sig, &idx, sigLen) < 0)
4084         return ASN_ECC_KEY_E;
4085
4086     if (GetInt(s, sig, &idx, sigLen) < 0)
4087         return ASN_ECC_KEY_E;
4088
4089     return 0;
4090 }
4091
4092
4093 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
4094                         word32 inSz)
4095 {
4096     word32 oid = 0;
4097     int    version, length;
4098     int    privSz, pubSz;
4099     byte   b;
4100     byte   priv[ECC_MAXSIZE];
4101     byte   pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */
4102
4103     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
4104         return ASN_PARSE_E;
4105
4106     if (GetMyVersion(input, inOutIdx, &version) < 0)
4107         return ASN_PARSE_E;
4108
4109     b = input[*inOutIdx];
4110     *inOutIdx += 1;
4111
4112     /* priv type */
4113     if (b != 4 && b != 6 && b != 7) 
4114         return ASN_PARSE_E;
4115
4116     if (GetLength(input, inOutIdx, &length, inSz) < 0)
4117         return ASN_PARSE_E;
4118
4119     /* priv key */
4120     privSz = length;
4121     XMEMCPY(priv, &input[*inOutIdx], privSz);
4122     *inOutIdx += length;
4123
4124     /* prefix 0, may have */
4125     b = input[*inOutIdx];
4126     if (b == ECC_PREFIX_0) {
4127         *inOutIdx += 1;
4128
4129         if (GetLength(input, inOutIdx, &length, inSz) < 0)
4130             return ASN_PARSE_E;
4131
4132         /* object id */
4133         b = input[*inOutIdx];
4134         *inOutIdx += 1;
4135     
4136         if (b != ASN_OBJECT_ID) 
4137             return ASN_OBJECT_ID_E;
4138
4139         if (GetLength(input, inOutIdx, &length, inSz) < 0)
4140             return ASN_PARSE_E;
4141
4142         while(length--) {
4143             oid += input[*inOutIdx];
4144             *inOutIdx += 1;
4145         }
4146         if (CheckCurve(oid) < 0)
4147             return ECC_CURVE_OID_E;
4148     }
4149     
4150     /* prefix 1 */
4151     b = input[*inOutIdx];
4152     *inOutIdx += 1;
4153     if (b != ECC_PREFIX_1)
4154         return ASN_ECC_KEY_E;
4155
4156     if (GetLength(input, inOutIdx, &length, inSz) < 0)
4157         return ASN_PARSE_E;
4158
4159     /* key header */
4160     b = input[*inOutIdx];
4161     *inOutIdx += 1;
4162     if (b != ASN_BIT_STRING)
4163         return ASN_BITSTR_E;
4164
4165     if (GetLength(input, inOutIdx, &length, inSz) < 0)
4166         return ASN_PARSE_E;
4167     b = input[*inOutIdx];
4168     *inOutIdx += 1;
4169     if (b != 0x00)
4170         return ASN_EXPECT_0_E;
4171
4172     pubSz = length - 1;  /* null prefix */
4173     XMEMCPY(pub, &input[*inOutIdx], pubSz);
4174
4175     *inOutIdx += length;
4176     
4177     return ecc_import_private_key(priv, privSz, pub, pubSz, key);
4178 }
4179
4180 #endif  /* HAVE_ECC */
4181
4182
4183 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
4184
4185 /* Get raw Date only, no processing, 0 on success */
4186 static int GetBasicDate(const byte* source, word32* idx, byte* date,
4187                         byte* format, int maxIdx)
4188 {
4189     int    length;
4190
4191     CYASSL_ENTER("GetBasicDate");
4192
4193     *format = source[*idx];
4194     *idx += 1;
4195     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
4196         return ASN_TIME_E;
4197
4198     if (GetLength(source, idx, &length, maxIdx) < 0)
4199         return ASN_PARSE_E;
4200
4201     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
4202         return ASN_DATE_SZ_E;
4203
4204     XMEMCPY(date, &source[*idx], length);
4205     *idx += length;
4206
4207     return 0;
4208 }
4209
4210 #endif
4211
4212
4213 #ifdef HAVE_OCSP
4214
4215 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
4216 {
4217     word32 idx = *inOutIdx;
4218     word32 len;
4219
4220     CYASSL_ENTER("GetEnumerated");
4221
4222     *value = 0;
4223
4224     if (input[idx++] != ASN_ENUMERATED)
4225         return ASN_PARSE_E;
4226
4227     len = input[idx++];
4228     if (len > 4)
4229         return ASN_PARSE_E;
4230
4231     while (len--) {
4232         *value  = *value << 8 | input[idx++];
4233     }
4234
4235     *inOutIdx = idx;
4236
4237     return *value;
4238 }
4239
4240
4241 static int DecodeSingleResponse(byte* source,
4242                             word32* ioIndex, OcspResponse* resp, word32 size)
4243 {
4244     word32 index = *ioIndex, prevIndex, oid;
4245     int length, wrapperSz;
4246     CertStatus* cs = resp->status;
4247
4248     CYASSL_ENTER("DecodeSingleResponse");
4249
4250     /* Outer wrapper of the SEQUENCE OF Single Responses. */
4251     if (GetSequence(source, &index, &wrapperSz, size) < 0)
4252         return ASN_PARSE_E;
4253
4254     prevIndex = index;
4255
4256     /* When making a request, we only request one status on one certificate
4257      * at a time. There should only be one SingleResponse */
4258
4259     /* Wrapper around the Single Response */
4260     if (GetSequence(source, &index, &length, size) < 0)
4261         return ASN_PARSE_E;
4262
4263     /* Wrapper around the CertID */
4264     if (GetSequence(source, &index, &length, size) < 0)
4265         return ASN_PARSE_E;
4266     /* Skip the hash algorithm */
4267     if (GetAlgoId(source, &index, &oid, size) < 0)
4268         return ASN_PARSE_E;
4269     /* Save reference to the hash of CN */
4270     if (source[index++] != ASN_OCTET_STRING)
4271         return ASN_PARSE_E;
4272     if (GetLength(source, &index, &length, size) < 0)
4273         return ASN_PARSE_E;
4274     resp->issuerHash = source + index;
4275     index += length;
4276     /* Save reference to the hash of the issuer public key */
4277     if (source[index++] != ASN_OCTET_STRING)
4278         return ASN_PARSE_E;
4279     if (GetLength(source, &index, &length, size) < 0)
4280         return ASN_PARSE_E;
4281     resp->issuerKeyHash = source + index;
4282     index += length;
4283
4284     /* Read the serial number, it is handled as a string, not as a 
4285      * proper number. Just XMEMCPY the data over, rather than load it
4286      * as an mp_int. */
4287     if (source[index++] != ASN_INTEGER)
4288         return ASN_PARSE_E;
4289     if (GetLength(source, &index, &length, size) < 0)
4290         return ASN_PARSE_E;
4291     if (length <= EXTERNAL_SERIAL_SIZE)
4292     {
4293         if (source[index] == 0)
4294         {
4295             index++;
4296             length--;
4297         }
4298         XMEMCPY(cs->serial, source + index, length);
4299         cs->serialSz = length;
4300     }
4301     else
4302     {
4303         return ASN_GETINT_E;
4304     }
4305     index += length;
4306
4307     /* CertStatus */
4308     switch (source[index++])
4309     {
4310         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
4311             cs->status = CERT_GOOD;
4312             index++;
4313             break;
4314         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
4315             cs->status = CERT_REVOKED;
4316             GetLength(source, &index, &length, size);
4317             index += length;
4318             break;
4319         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
4320             cs->status = CERT_UNKNOWN;
4321             index++;
4322             break;
4323         default:
4324             return ASN_PARSE_E;
4325     }
4326
4327     if (GetBasicDate(source, &index, cs->thisDate,
4328                                                 &cs->thisDateFormat, size) < 0)
4329         return ASN_PARSE_E;
4330     if (!ValidateDate(cs->thisDate, cs->thisDateFormat, BEFORE))
4331         return ASN_BEFORE_DATE_E;
4332     
4333     /* The following items are optional. Only check for them if there is more
4334      * unprocessed data in the singleResponse wrapper. */
4335     
4336     if ((index - prevIndex < wrapperSz) &&
4337         (source[index] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
4338     {
4339         index++;
4340         if (GetLength(source, &index, &length, size) < 0)
4341             return ASN_PARSE_E;
4342         if (GetBasicDate(source, &index, cs->nextDate,
4343                                                 &cs->nextDateFormat, size) < 0)
4344             return ASN_PARSE_E;
4345     }
4346     if ((index - prevIndex < wrapperSz) &&
4347         (source[index] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
4348     {
4349         index++;
4350         if (GetLength(source, &index, &length, size) < 0)
4351             return ASN_PARSE_E;
4352         index += length;
4353     }
4354
4355     *ioIndex = index;
4356
4357     return 0;
4358 }
4359
4360 static int DecodeOcspRespExtensions(byte* source,
4361                             word32* ioIndex, OcspResponse* resp, word32 sz)
4362 {
4363     word32 idx = *ioIndex;
4364     int length;
4365     int ext_bound; /* boundary index for the sequence of extensions */
4366     word32 oid;
4367
4368     CYASSL_ENTER("DecodeOcspRespExtensions");
4369
4370     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
4371         return ASN_PARSE_E;
4372
4373     if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
4374
4375     if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
4376    
4377     ext_bound = idx + length;
4378
4379     while (idx < (word32)ext_bound) {
4380         if (GetSequence(source, &idx, &length, sz) < 0) {
4381             CYASSL_MSG("\tfail: should be a SEQUENCE");
4382             return ASN_PARSE_E;
4383         }
4384
4385         oid = 0;
4386         if (GetObjectId(source, &idx, &oid, sz) < 0) {
4387             CYASSL_MSG("\tfail: OBJECT ID");
4388             return ASN_PARSE_E;
4389         }
4390
4391         /* check for critical flag */
4392         if (source[idx] == ASN_BOOLEAN) {
4393             CYASSL_MSG("\tfound optional critical flag, moving past");
4394             idx += (ASN_BOOL_SIZE + 1);
4395         }
4396
4397         /* process the extension based on the OID */
4398         if (source[idx++] != ASN_OCTET_STRING) {
4399             CYASSL_MSG("\tfail: should be an OCTET STRING");
4400             return ASN_PARSE_E;
4401         }
4402
4403         if (GetLength(source, &idx, &length, sz) < 0) {
4404             CYASSL_MSG("\tfail: extension data length");
4405             return ASN_PARSE_E;
4406         }
4407
4408         if (oid == OCSP_NONCE_OID) {
4409             resp->nonce = source + idx;
4410             resp->nonceSz = length;
4411         }
4412
4413         idx += length;
4414     }
4415
4416     *ioIndex = idx;
4417     return 0;
4418 }
4419
4420
4421 static int DecodeResponseData(byte* source,
4422                             word32* ioIndex, OcspResponse* resp, word32 size)
4423 {
4424     word32 idx = *ioIndex, prev_idx;
4425     int length;
4426     int version;
4427     word32 responderId = 0;
4428
4429     CYASSL_ENTER("DecodeResponseData");
4430
4431     resp->response = source + idx;
4432     prev_idx = idx;
4433     if (GetSequence(source, &idx, &length, size) < 0)
4434         return ASN_PARSE_E;
4435     resp->responseSz = length + idx - prev_idx;
4436
4437     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
4438      * item isn't an EXPLICIT[0], then set version to zero and move
4439      * onto the next item.
4440      */
4441     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
4442     {    
4443         idx += 2; /* Eat the value and length */
4444         if (GetMyVersion(source, &idx, &version) < 0)
4445             return ASN_PARSE_E;
4446     } else
4447         version = 0;
4448
4449     responderId = source[idx++];
4450     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
4451         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
4452     {
4453         if (GetLength(source, &idx, &length, size) < 0)
4454             return ASN_PARSE_E;
4455         idx += length;
4456     }
4457     else
4458         return ASN_PARSE_E;
4459     
4460     /* save pointer to the producedAt time */
4461     if (GetBasicDate(source, &idx, resp->producedDate,
4462                                         &resp->producedDateFormat, size) < 0)
4463         return ASN_PARSE_E;
4464     if (!ValidateDate(resp->producedDate, resp->producedDateFormat, BEFORE))
4465         return ASN_BEFORE_DATE_E;
4466     idx += length;
4467
4468     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
4469         return ASN_PARSE_E;
4470
4471     if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
4472         return ASN_PARSE_E;
4473
4474     *ioIndex = idx;
4475     return 0;
4476 }
4477
4478
4479 static int DecodeCerts(byte* source,
4480                             word32* ioIndex, OcspResponse* resp, word32 size)
4481 {
4482     word32 idx = *ioIndex;
4483
4484     CYASSL_ENTER("DecodeCerts");
4485
4486     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
4487     {
4488         int length;
4489
4490         if (GetLength(source, &idx, &length, size) < 0)
4491             return ASN_PARSE_E;
4492
4493         if (GetSequence(source, &idx, &length, size) < 0)
4494             return ASN_PARSE_E;
4495
4496         resp->cert = source + idx;
4497         resp->certSz = length;
4498
4499         idx += length;
4500     }
4501     *ioIndex = idx;
4502     return 0;
4503 }
4504
4505 static int DecodeBasicOcspResponse(byte* source,
4506                             word32* ioIndex, OcspResponse* resp, word32 size)
4507 {
4508     int length;
4509     word32 idx = *ioIndex;
4510     word32 end_index;
4511
4512     CYASSL_ENTER("DecodeBasicOcspResponse");
4513
4514     if (GetSequence(source, &idx, &length, size) < 0)
4515         return ASN_PARSE_E;
4516
4517     if (idx + length > size)
4518         return ASN_INPUT_E;
4519     end_index = idx + length;
4520
4521     if (DecodeResponseData(source, &idx, resp, size) < 0)
4522         return ASN_PARSE_E;
4523     
4524     /* Get the signature algorithm */
4525     if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
4526         return ASN_PARSE_E;
4527
4528     /* Obtain pointer to the start of the signature, and save the size */
4529     if (source[idx++] == ASN_BIT_STRING)
4530     {
4531         int sigLength = 0;
4532         if (GetLength(source, &idx, &sigLength, size) < 0)
4533             return ASN_PARSE_E;
4534         resp->sigSz = sigLength;
4535         resp->sig = source + idx;
4536         idx += sigLength;
4537     }
4538
4539     /*
4540      * Check the length of the BasicOcspResponse against the current index to
4541      * see if there are certificates, they are optional.
4542      */
4543     if (idx < end_index)
4544     {
4545         DecodedCert cert;
4546         int ret;
4547
4548         if (DecodeCerts(source, &idx, resp, size) < 0)
4549             return ASN_PARSE_E;
4550
4551         InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
4552         ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
4553         if (ret < 0)
4554             return ret;
4555
4556         ret = ConfirmSignature(resp->response, resp->responseSz,
4557                             cert.publicKey, cert.pubKeySize, cert.keyOID,
4558                             resp->sig, resp->sigSz, resp->sigOID, NULL);
4559         FreeDecodedCert(&cert);
4560
4561         if (ret == 0)
4562         {
4563             CYASSL_MSG("\tConfirm signature failed");
4564             return ASN_SIG_CONFIRM_E;
4565         }
4566     }
4567
4568     *ioIndex = idx;
4569     return 0;
4570 }
4571
4572
4573 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
4574                                                     byte* source, word32 inSz)
4575 {
4576     CYASSL_ENTER("InitOcspResponse");
4577
4578     resp->responseStatus = -1;
4579     resp->response = NULL;
4580     resp->responseSz = 0;
4581     resp->producedDateFormat = 0;
4582     resp->issuerHash = NULL;
4583     resp->issuerKeyHash = NULL;
4584     resp->sig = NULL;
4585     resp->sigSz = 0;
4586     resp->sigOID = 0;
4587     resp->status = status;
4588     resp->nonce = NULL;
4589     resp->nonceSz = 0;
4590     resp->source = source;
4591     resp->maxIdx = inSz;
4592 }
4593
4594
4595 int OcspResponseDecode(OcspResponse* resp)
4596 {
4597     int length = 0;
4598     word32 idx = 0;
4599     byte* source = resp->source;
4600     word32 size = resp->maxIdx;
4601     word32 oid;
4602
4603     CYASSL_ENTER("OcspResponseDecode");
4604
4605     /* peel the outer SEQUENCE wrapper */
4606     if (GetSequence(source, &idx, &length, size) < 0)
4607         return ASN_PARSE_E;
4608     
4609     /* First get the responseStatus, an ENUMERATED */
4610     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
4611         return ASN_PARSE_E;
4612
4613     if (resp->responseStatus != OCSP_SUCCESSFUL)
4614         return 0;
4615
4616     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
4617     if (idx >= size)
4618         return ASN_INPUT_E;
4619     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
4620         return ASN_PARSE_E;
4621     if (GetLength(source, &idx, &length, size) < 0)
4622         return ASN_PARSE_E;
4623
4624     /* Get the responseBytes SEQUENCE */
4625     if (GetSequence(source, &idx, &length, size) < 0)
4626         return ASN_PARSE_E;
4627
4628     /* Check ObjectID for the resposeBytes */
4629     if (GetObjectId(source, &idx, &oid, size) < 0)
4630         return ASN_PARSE_E;
4631     if (oid != OCSP_BASIC_OID)
4632         return ASN_PARSE_E;
4633     if (source[idx++] != ASN_OCTET_STRING)
4634         return ASN_PARSE_E;
4635
4636     if (GetLength(source, &idx, &length, size) < 0)
4637         return ASN_PARSE_E;
4638
4639     if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
4640         return ASN_PARSE_E;
4641     
4642     return 0;
4643 }
4644
4645
4646 static int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
4647 {
4648     int result = 0;
4649
4650     CYASSL_ENTER("SetSerialNumber");
4651
4652     if (snSz <= EXTERNAL_SERIAL_SIZE) {
4653         output[0] = ASN_INTEGER;
4654         output[1] = snSz + 1;
4655         output[2] = 0;
4656         XMEMCPY(&output[3], sn, snSz);
4657         result = snSz + 3;
4658     }
4659     return result;
4660 }
4661
4662
4663 static word32 SetOcspReqExtensions(word32 extSz, byte* output,
4664                                             const byte* nonce, word32 nonceSz)
4665 {
4666     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
4667                                        0x30, 0x01, 0x02 };
4668     byte seqArray[5][MAX_SEQ_SZ];
4669     word32 seqSz[5], totalSz;
4670
4671     CYASSL_ENTER("SetOcspReqExtensions");
4672
4673     if (nonce == NULL || nonceSz == 0) return 0;
4674     
4675     seqArray[0][0] = ASN_OCTET_STRING;
4676     seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
4677
4678     seqArray[1][0] = ASN_OBJECT_ID;
4679     seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
4680
4681     totalSz = seqSz[0] + seqSz[1] + nonceSz + sizeof(NonceObjId);
4682
4683     seqSz[2] = SetSequence(totalSz, seqArray[2]);
4684     totalSz += seqSz[2];
4685
4686     seqSz[3] = SetSequence(totalSz, seqArray[3]);
4687     totalSz += seqSz[3];
4688
4689     seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
4690     seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
4691     totalSz += seqSz[4];
4692
4693     if (totalSz < extSz)
4694     {
4695         totalSz = 0;
4696         XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
4697         totalSz += seqSz[4];
4698         XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
4699         totalSz += seqSz[3];
4700         XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
4701         totalSz += seqSz[2];
4702         XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
4703         totalSz += seqSz[1];
4704         XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
4705         totalSz += sizeof(NonceObjId);
4706         XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
4707         totalSz += seqSz[0];
4708         XMEMCPY(output + totalSz, nonce, nonceSz);
4709         totalSz += nonceSz;
4710     }
4711
4712     return totalSz;
4713 }
4714
4715
4716 int EncodeOcspRequest(OcspRequest* req)
4717 {
4718     byte seqArray[5][MAX_SEQ_SZ];
4719     /* The ASN.1 of the OCSP Request is an onion of sequences */
4720     byte algoArray[MAX_ALGO_SZ];
4721     byte issuerArray[MAX_ENCODED_DIG_SZ];
4722     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
4723     byte snArray[MAX_SN_SZ];
4724     byte extArray[MAX_OCSP_EXT_SZ];
4725     byte* output = req->dest;
4726     word32 outputSz = req->destSz;
4727     RNG rng;
4728     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
4729     int i;
4730
4731     CYASSL_ENTER("EncodeOcspRequest");
4732
4733     algoSz = SetAlgoID(SHAh, algoArray, hashType);
4734
4735     req->issuerHash = req->cert->issuerHash;
4736     issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray);
4737     
4738     req->issuerKeyHash = req->cert->issuerKeyHash;
4739     issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray);
4740
4741     req->serial = req->cert->serial;
4742     req->serialSz = req->cert->serialSz;
4743     snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
4744
4745     if (InitRng(&rng) != 0) {
4746         CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
4747         extSz = 0;
4748     } else {
4749         req->nonceSz = MAX_OCSP_NONCE_SZ;
4750         RNG_GenerateBlock(&rng, req->nonce, req->nonceSz);
4751         extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
4752                                                     req->nonce, req->nonceSz);
4753     }
4754
4755     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
4756
4757     for (i = 4; i >= 0; i--) {
4758         seqSz[i] = SetSequence(totalSz, seqArray[i]);
4759         totalSz += seqSz[i];
4760         if (i == 2) totalSz += extSz;
4761     }
4762     totalSz = 0;
4763     for (i = 0; i < 5; i++) {
4764         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
4765         totalSz += seqSz[i];
4766     }
4767     XMEMCPY(output + totalSz, algoArray, algoSz);
4768     totalSz += algoSz;
4769     XMEMCPY(output + totalSz, issuerArray, issuerSz);
4770     totalSz += issuerSz;
4771     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
4772     totalSz += issuerKeySz;
4773     XMEMCPY(output + totalSz, snArray, snSz);
4774     totalSz += snSz;
4775     if (extSz != 0) {
4776         XMEMCPY(output + totalSz, extArray, extSz);
4777         totalSz += extSz;
4778     }
4779
4780     return totalSz;
4781 }
4782
4783
4784 void InitOcspRequest(OcspRequest* req, DecodedCert* cert,
4785                                                     byte* dest, word32 destSz)
4786 {
4787     CYASSL_ENTER("InitOcspRequest");
4788
4789     req->cert = cert;
4790     req->nonceSz = 0;
4791     req->issuerHash = NULL;
4792     req->issuerKeyHash = NULL;
4793     req->serial = NULL;
4794     req->dest = dest;
4795     req->destSz = destSz;
4796 }
4797
4798
4799 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
4800 {
4801     int cmp;
4802
4803     CYASSL_ENTER("CompareOcspReqResp");
4804
4805     if (req == NULL)
4806     {
4807         CYASSL_MSG("\tReq missing");
4808         return -1;
4809     }
4810
4811     if (resp == NULL)
4812     {
4813         CYASSL_MSG("\tResp missing");
4814         return 1;
4815     }
4816
4817     cmp = req->nonceSz - resp->nonceSz;
4818     if (cmp != 0)
4819     {
4820         CYASSL_MSG("\tnonceSz mismatch");
4821         return cmp;
4822     }
4823
4824     cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
4825     if (cmp != 0)
4826     {
4827         CYASSL_MSG("\tnonce mismatch");
4828         return cmp;
4829     }
4830
4831     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE);
4832     if (cmp != 0)
4833     {
4834         CYASSL_MSG("\tissuerHash mismatch");
4835         return cmp;
4836     }
4837
4838     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE);
4839     if (cmp != 0)
4840     {
4841         CYASSL_MSG("\tissuerKeyHash mismatch");
4842         return cmp;
4843     }
4844
4845     cmp = req->serialSz - resp->status->serialSz;
4846     if (cmp != 0)
4847     {
4848         CYASSL_MSG("\tserialSz mismatch");
4849         return cmp;
4850     }
4851
4852     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
4853     if (cmp != 0)
4854     {
4855         CYASSL_MSG("\tserial mismatch");
4856         return cmp;
4857     }
4858
4859     return 0;
4860 }
4861
4862 #endif
4863
4864
4865 #ifdef HAVE_CRL
4866
4867 /* initialize decoded CRL */
4868 void InitDecodedCRL(DecodedCRL* dcrl)
4869 {
4870     CYASSL_MSG("InitDecodedCRL");
4871
4872     dcrl->certBegin    = 0;
4873     dcrl->sigIndex     = 0;
4874     dcrl->sigLength    = 0;
4875     dcrl->signatureOID = 0;
4876     dcrl->certs        = NULL;
4877     dcrl->totalCerts   = 0;
4878 }
4879
4880
4881 /* free decoded CRL resources */
4882 void FreeDecodedCRL(DecodedCRL* dcrl)
4883 {
4884     RevokedCert* tmp = dcrl->certs;
4885
4886     CYASSL_MSG("FreeDecodedCRL");
4887
4888     while(tmp) {
4889         RevokedCert* next = tmp->next;
4890         XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
4891         tmp = next;
4892     }
4893 }
4894
4895
4896 /* store SHA1 hash of NAME */
4897 static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
4898 {
4899     Sha    sha;
4900     int    length;  /* length of all distinguished names */
4901     word32 dummy;
4902
4903     CYASSL_ENTER("GetNameHash");
4904
4905     if (source[*idx] == ASN_OBJECT_ID) {
4906         CYASSL_MSG("Trying optional prefix...");
4907
4908         if (GetLength(source, idx, &length, maxIdx) < 0)
4909             return ASN_PARSE_E;
4910
4911         *idx += length;
4912         CYASSL_MSG("Got optional prefix");
4913     }
4914
4915     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
4916      * calculated over the entire DER encoding of the Name field, including
4917      * the tag and length. */
4918     dummy = *idx;
4919     if (GetSequence(source, idx, &length, maxIdx) < 0)
4920         return ASN_PARSE_E;
4921
4922     InitSha(&sha);
4923     ShaUpdate(&sha, source + dummy, length + *idx - dummy);
4924     ShaFinal(&sha, hash);
4925
4926     *idx += length;
4927
4928     return 0;
4929 }
4930
4931
4932 /* Get Revoked Cert list, 0 on success */
4933 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
4934                       int maxIdx)
4935 {
4936     int    len;
4937     word32 end;
4938     byte   b;
4939     RevokedCert* rc;
4940
4941     CYASSL_ENTER("GetRevoked");
4942
4943     if (GetSequence(buff, idx, &len, maxIdx) < 0)
4944         return ASN_PARSE_E;
4945
4946     end = *idx + len;
4947
4948     /* get serial number */
4949     b = buff[*idx];
4950     *idx += 1;
4951
4952     if (b != ASN_INTEGER) {
4953         CYASSL_MSG("Expecting Integer");
4954         return ASN_PARSE_E;
4955     }
4956
4957     if (GetLength(buff, idx, &len, maxIdx) < 0)
4958         return ASN_PARSE_E;
4959
4960     if (len > EXTERNAL_SERIAL_SIZE) {
4961         CYASSL_MSG("Serial Size too big");
4962         return ASN_PARSE_E;
4963     }
4964
4965     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
4966     if (rc == NULL) {
4967         CYASSL_MSG("Alloc Revoked Cert failed");
4968         return MEMORY_E;
4969     }
4970
4971     XMEMCPY(rc->serialNumber, &buff[*idx], len);
4972     rc->serialSz = len;
4973
4974     /* add to list */
4975     rc->next = dcrl->certs;
4976     dcrl->certs = rc;
4977     dcrl->totalCerts++;
4978
4979     *idx += len;
4980
4981     /* get date */
4982     b = buff[*idx];
4983     *idx += 1;
4984
4985     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
4986         CYASSL_MSG("Expecting Date");
4987         return ASN_PARSE_E;
4988     }
4989
4990     if (GetLength(buff, idx, &len, maxIdx) < 0)
4991         return ASN_PARSE_E;
4992
4993     /* skip for now */
4994     *idx += len;
4995
4996     if (*idx != end)  /* skip extensions */
4997         *idx = end;
4998
4999     return 0;
5000 }
5001
5002
5003 /* Get CRL Signature, 0 on success */
5004 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
5005                             int maxIdx)
5006 {
5007     int    length;
5008     byte   b;
5009
5010     CYASSL_ENTER("GetCRL_Signature");
5011
5012     b = source[*idx];
5013     *idx += 1;
5014     if (b != ASN_BIT_STRING)
5015         return ASN_BITSTR_E;
5016
5017     if (GetLength(source, idx, &length, maxIdx) < 0)
5018         return ASN_PARSE_E;
5019
5020     dcrl->sigLength = length;
5021
5022     b = source[*idx];
5023     *idx += 1;
5024     if (b != 0x00)
5025         return ASN_EXPECT_0_E;
5026
5027     dcrl->sigLength--;
5028     dcrl->signature = (byte*)&source[*idx];
5029
5030     *idx += dcrl->sigLength;
5031
5032     return 0;
5033 }
5034
5035
5036 /* prase crl buffer into decoded state, 0 on success */
5037 int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz, void* cm)
5038 {
5039     int     version, len;
5040     word32  oid, idx = 0;
5041     Md5     md5;
5042     Signer* ca;
5043
5044     CYASSL_MSG("ParseCRL");
5045
5046     /* raw crl hash */
5047     InitMd5(&md5);
5048     Md5Update(&md5, buff, sz);
5049     Md5Final(&md5, dcrl->crlHash);
5050
5051     if (GetSequence(buff, &idx, &len, sz) < 0)
5052         return ASN_PARSE_E;
5053
5054     dcrl->certBegin = idx;
5055
5056     if (GetSequence(buff, &idx, &len, sz) < 0)
5057         return ASN_PARSE_E;
5058     dcrl->sigIndex = len + idx;
5059
5060     /* may have version */
5061     if (buff[idx] == ASN_INTEGER) {
5062         if (GetMyVersion(buff, &idx, &version) < 0)
5063             return ASN_PARSE_E;
5064     }
5065
5066     if (GetAlgoId(buff, &idx, &oid, sz) < 0)
5067         return ASN_PARSE_E;
5068
5069     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
5070         return ASN_PARSE_E;
5071
5072     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
5073         return ASN_PARSE_E;
5074
5075     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
5076         return ASN_PARSE_E;
5077
5078     if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
5079         CYASSL_MSG("CRL after date is no longer valid");
5080         return ASN_AFTER_DATE_E;
5081     }
5082
5083     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
5084         if (GetSequence(buff, &idx, &len, sz) < 0)
5085             return ASN_PARSE_E;
5086
5087         len += idx;
5088
5089         while (idx < (word32)len) {
5090             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
5091                 return ASN_PARSE_E;
5092         }
5093     }
5094
5095     if (idx != dcrl->sigIndex)
5096         idx = dcrl->sigIndex;   /* skip extensions */
5097
5098     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
5099         return ASN_PARSE_E;
5100
5101     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
5102         return ASN_PARSE_E;
5103
5104     ca = GetCA(cm, dcrl->issuerHash);
5105     CYASSL_MSG("About to verify CRL signature");
5106
5107     if (ca) {
5108         CYASSL_MSG("Found CRL issuer CA");
5109         /* try to confirm/verify signature */
5110         if (!ConfirmSignature(buff + dcrl->certBegin,
5111                 dcrl->sigIndex - dcrl->certBegin,
5112                 ca->publicKey, ca->pubKeySize, ca->keyOID,
5113                 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
5114             CYASSL_MSG("CRL Confirm signature failed");
5115             return ASN_SIG_CONFIRM_E;
5116         }
5117     }
5118     else {
5119         CYASSL_MSG("Did NOT find CRL issuer CA");
5120         return ASN_SIG_CONFIRM_E;
5121     }
5122
5123     return 0;
5124 }
5125
5126 #endif /* HAVE_CRL */