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