This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers asn.c Source File

asn.c

00001 /* asn.c
00002  *
00003  * Copyright (C) 2006-2013 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifndef NO_ASN
00029 
00030 #ifdef HAVE_RTP_SYS
00031     #include "os.h"           /* dc_rtc_api needs    */
00032     #include "dc_rtc_api.h"   /* to get current time */
00033 #endif
00034 
00035 #include <cyassl/ctaocrypt/integer.h>
00036 #include <cyassl/ctaocrypt/asn.h>
00037 #include <cyassl/ctaocrypt/coding.h>
00038 #include <cyassl/ctaocrypt/sha.h>
00039 #include <cyassl/ctaocrypt/md5.h>
00040 #include <cyassl/ctaocrypt/md2.h>
00041 #include <cyassl/ctaocrypt/ctaoerror2.h>
00042 #include <cyassl/ctaocrypt/pwdbased.h>
00043 #include <cyassl/ctaocrypt/des3.h>
00044 #include <cyassl/ctaocrypt/sha256.h>
00045 #include <cyassl/ctaocrypt/sha512.h>
00046 #include <cyassl/ctaocrypt/logging.h>
00047 
00048 #include <cyassl/ctaocrypt/random.h>
00049 
00050 
00051 #ifndef NO_RC4
00052     #include <cyassl/ctaocrypt/arc4.h>
00053 #endif
00054 
00055 #ifdef HAVE_NTRU
00056     #include "crypto_ntru.h"
00057 #endif
00058 
00059 #ifdef HAVE_ECC
00060     #include <cyassl/ctaocrypt/ecc.h>
00061 #endif
00062 
00063 #ifdef CYASSL_DEBUG_ENCODING
00064     #ifdef FREESCALE_MQX
00065         #include <fio.h>
00066     #else
00067         #include <stdio.h>
00068     #endif
00069 #endif
00070 
00071 #ifdef _MSC_VER
00072     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
00073     #pragma warning(disable: 4996)
00074 #endif
00075 
00076 
00077 #ifndef TRUE
00078     #define TRUE  1
00079 #endif
00080 #ifndef FALSE
00081     #define FALSE 0
00082 #endif
00083 
00084 
00085 #ifdef HAVE_RTP_SYS 
00086     /* uses parital <time.h> structures */
00087     #define XTIME(tl)  (0)
00088     #define XGMTIME(c) my_gmtime((c))
00089     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00090 #elif defined(MICRIUM)
00091     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
00092         #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t))
00093     #else
00094         #define XVALIDATE_DATE(d, f, t) (0)
00095     #endif
00096     #define NO_TIME_H
00097     /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
00098 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
00099     #include <time.h>
00100     #define XTIME(t1) pic32_time((t1))
00101     #define XGMTIME(c) gmtime((c))
00102     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00103 #elif defined(CYASSL_MDK_ARM)
00104     #include <rtl.h>
00105     #undef RNG
00106     #include "cyassl_MDK_ARM.h"
00107     #undef RNG
00108     #define RNG CyaSSL_RNG /*for avoiding name conflict in "stm32f2xx.h" */
00109     #define XTIME(tl)  (0)
00110     #define XGMTIME(c) Cyassl_MDK_gmtime((c))
00111     #define XVALIDATE_DATE(d, f, t)  ValidateDate((d), (f), (t))
00112 #elif defined(USER_TIME)
00113     /* user time, and gmtime compatible functions, there is a gmtime 
00114        implementation here that WINCE uses, so really just need some ticks
00115        since the EPOCH 
00116     */
00117 
00118     struct tm {
00119     int tm_sec;     /* seconds after the minute [0-60] */
00120     int tm_min;     /* minutes after the hour [0-59] */
00121     int tm_hour;    /* hours since midnight [0-23] */
00122     int tm_mday;    /* day of the month [1-31] */
00123     int tm_mon;     /* months since January [0-11] */
00124     int tm_year;    /* years since 1900 */
00125     int tm_wday;    /* days since Sunday [0-6] */
00126     int tm_yday;    /* days since January 1 [0-365] */
00127     int tm_isdst;   /* Daylight Savings Time flag */
00128     long    tm_gmtoff;  /* offset from CUT in seconds */
00129     char    *tm_zone;   /* timezone abbreviation */
00130     };
00131     typedef long time_t;
00132 
00133     /* forward declaration */
00134     struct tm* gmtime(const time_t* timer);
00135     extern time_t XTIME(time_t * timer);
00136 
00137     #define XGMTIME(c) gmtime((c))
00138     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00139 
00140     #ifdef STACK_TRAP
00141         /* for stack trap tracking, don't call os gmtime on OS X/linux,
00142            uses a lot of stack spce */
00143         extern time_t time(time_t * timer);
00144         #define XTIME(tl)  time((tl))
00145     #endif /* STACK_TRAP */
00146 #else
00147     /* default */
00148     /* uses complete <time.h> facility */
00149     #include <time.h>
00150     #define XTIME(tl)  time((tl))
00151     #define XGMTIME(c) gmtime((c))
00152     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00153 #endif
00154 
00155 
00156 #ifdef _WIN32_WCE
00157 /* no time() or gmtime() even though in time.h header?? */
00158 
00159 #include <windows.h>
00160 
00161 
00162 time_t time(time_t* timer)
00163 {
00164     SYSTEMTIME     sysTime;
00165     FILETIME       fTime;
00166     ULARGE_INTEGER intTime;
00167     time_t         localTime;
00168 
00169     if (timer == NULL)
00170         timer = &localTime;
00171 
00172     GetSystemTime(&sysTime);
00173     SystemTimeToFileTime(&sysTime, &fTime);
00174     
00175     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
00176     /* subtract EPOCH */
00177     intTime.QuadPart -= 0x19db1ded53e8000;
00178     /* to secs */
00179     intTime.QuadPart /= 10000000;
00180     *timer = (time_t)intTime.QuadPart;
00181 
00182     return *timer;
00183 }
00184 
00185 #endif /*  _WIN32_WCE */
00186 #if defined( _WIN32_WCE ) || defined( USER_TIME )
00187 
00188 struct tm* gmtime(const time_t* timer)
00189 {
00190     #define YEAR0          1900
00191     #define EPOCH_YEAR     1970
00192     #define SECS_DAY       (24L * 60L * 60L)
00193     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
00194     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
00195 
00196     static const int _ytab[2][12] =
00197     {
00198         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
00199         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
00200     };
00201 
00202     static struct tm st_time;
00203     struct tm* ret = &st_time;
00204     time_t secs = *timer;
00205     unsigned long dayclock, dayno;
00206     int year = EPOCH_YEAR;
00207 
00208     dayclock = (unsigned long)secs % SECS_DAY;
00209     dayno    = (unsigned long)secs / SECS_DAY;
00210 
00211     ret->tm_sec  = (int) dayclock % 60;
00212     ret->tm_min  = (int)(dayclock % 3600) / 60;
00213     ret->tm_hour = (int) dayclock / 3600;
00214     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
00215 
00216     while(dayno >= (unsigned long)YEARSIZE(year)) {
00217         dayno -= YEARSIZE(year);
00218         year++;
00219     }
00220 
00221     ret->tm_year = year - YEAR0;
00222     ret->tm_yday = (int)dayno;
00223     ret->tm_mon  = 0;
00224 
00225     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
00226         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
00227         ret->tm_mon++;
00228     }
00229 
00230     ret->tm_mday  = (int)++dayno;
00231     ret->tm_isdst = 0;
00232 
00233     return ret;
00234 }
00235 
00236 #endif /* _WIN32_WCE  || USER_TIME */
00237 
00238 
00239 #ifdef HAVE_RTP_SYS  
00240 
00241 #define YEAR0          1900
00242 
00243 struct tm* my_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
00244 {
00245     static struct tm st_time;
00246     struct tm* ret = &st_time;
00247 
00248     DC_RTC_CALENDAR cal;
00249     dc_rtc_time_get(&cal, TRUE);
00250 
00251     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
00252     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
00253     ret->tm_mday  = cal.day;
00254     ret->tm_hour  = cal.hour;
00255     ret->tm_min   = cal.minute;
00256     ret->tm_sec   = cal.second;
00257 
00258     return ret;
00259 }
00260 
00261 #endif /* HAVE_RTP_SYS */
00262 
00263 
00264 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
00265 
00266 /*
00267  * time() is just a stub in Microchip libraries. We need our own
00268  * implementation. Use SNTP client to get seconds since epoch.
00269  */
00270 time_t pic32_time(time_t* timer)
00271 {
00272 #ifdef MICROCHIP_TCPIP_V5
00273     DWORD sec = 0;
00274 #else
00275     uint32_t sec = 0;
00276 #endif
00277     time_t localTime;
00278 
00279     if (timer == NULL)
00280         timer = &localTime;
00281 
00282     sec = SNTPGetUTCSeconds();
00283     *timer = (time_t) sec;
00284 
00285     return *timer;
00286 }
00287 
00288 #endif /* MICROCHIP_TCPIP */
00289 
00290 
00291 static INLINE word32 btoi(byte b)
00292 {
00293     return b - 0x30;
00294 }
00295 
00296 
00297 /* two byte date/time, add to value */
00298 static INLINE void GetTime(int* value, const byte* date, int* idx)
00299 {
00300     int i = *idx;
00301 
00302     *value += btoi(date[i++]) * 10;
00303     *value += btoi(date[i++]);
00304 
00305     *idx = i;
00306 }
00307 
00308 
00309 #if defined(MICRIUM)
00310 
00311 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
00312                                          CPU_INT08U dateType)
00313 {
00314     CPU_BOOLEAN  rtn_code;
00315     CPU_INT32S   i;
00316     CPU_INT32S   val;    
00317     CPU_INT16U   year;
00318     CPU_INT08U   month;
00319     CPU_INT16U   day;
00320     CPU_INT08U   hour;
00321     CPU_INT08U   min;
00322     CPU_INT08U   sec;
00323 
00324     i    = 0;
00325     year = 0u;
00326 
00327     if (format == ASN_UTC_TIME) {
00328         if (btoi(date[0]) >= 5)
00329             year = 1900;
00330         else
00331             year = 2000;
00332     }
00333     else  { /* format == GENERALIZED_TIME */
00334         year += btoi(date[i++]) * 1000;
00335         year += btoi(date[i++]) * 100;
00336     }    
00337 
00338     val = year;
00339     GetTime(&val, date, &i);
00340     year = (CPU_INT16U)val;
00341 
00342     val = 0;
00343     GetTime(&val, date, &i);   
00344     month = (CPU_INT08U)val;   
00345 
00346     val = 0;
00347     GetTime(&val, date, &i);  
00348     day = (CPU_INT16U)val;
00349 
00350     val = 0;
00351     GetTime(&val, date, &i);  
00352     hour = (CPU_INT08U)val;
00353 
00354     val = 0;
00355     GetTime(&val, date, &i);  
00356     min = (CPU_INT08U)val;
00357 
00358     val = 0;
00359     GetTime(&val, date, &i);  
00360     sec = (CPU_INT08U)val;
00361 
00362     return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); 
00363 }
00364 
00365 #endif /* MICRIUM */
00366 
00367 
00368 static int GetLength(const byte* input, word32* inOutIdx, int* len,
00369                      word32 maxIdx)
00370 {
00371     int     length = 0;
00372     word32  i = *inOutIdx;
00373     byte    b;
00374 
00375     if ( (i+1) > maxIdx) {   /* for first read */
00376         CYASSL_MSG("GetLength bad index on input");
00377         return BUFFER_E;
00378     }
00379 
00380     b = input[i++];
00381     if (b >= ASN_LONG_LENGTH) {        
00382         word32 bytes = b & 0x7F;
00383 
00384         if ( (i+bytes) > maxIdx) {   /* for reading bytes */
00385             CYASSL_MSG("GetLength bad long length");
00386             return BUFFER_E;
00387         }
00388 
00389         while (bytes--) {
00390             b = input[i++];
00391             length = (length << 8) | b;
00392         }
00393     }
00394     else
00395         length = b;
00396     
00397     if ( (i+length) > maxIdx) {   /* for user of length */
00398         CYASSL_MSG("GetLength value exceeds buffer length");
00399         return BUFFER_E;
00400     }
00401 
00402     *inOutIdx = i;
00403     *len      = length;
00404 
00405     return length;
00406 }
00407 
00408 
00409 static int GetSequence(const byte* input, word32* inOutIdx, int* len,
00410                        word32 maxIdx)
00411 {
00412     int    length = -1;
00413     word32 idx    = *inOutIdx;
00414 
00415     if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
00416             GetLength(input, &idx, &length, maxIdx) < 0)
00417         return ASN_PARSE_E;
00418 
00419     *len      = length;
00420     *inOutIdx = idx;
00421 
00422     return length;
00423 }
00424 
00425 
00426 static int GetSet(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
00427 {
00428     int    length = -1;
00429     word32 idx    = *inOutIdx;
00430 
00431     if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
00432             GetLength(input, &idx, &length, maxIdx) < 0)
00433         return ASN_PARSE_E;
00434 
00435     *len      = length;
00436     *inOutIdx = idx;
00437 
00438     return length;
00439 }
00440 
00441 
00442 /* winodws header clash for WinCE using GetVersion */
00443 static int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
00444 {
00445     word32 idx = *inOutIdx;
00446 
00447     CYASSL_ENTER("GetMyVersion");
00448 
00449     if (input[idx++] != ASN_INTEGER)
00450         return ASN_PARSE_E;
00451 
00452     if (input[idx++] != 0x01)
00453         return ASN_VERSION_E;
00454 
00455     *version  = input[idx++];
00456     *inOutIdx = idx;
00457 
00458     return *version;
00459 }
00460 
00461 
00462 #ifndef NO_PWDBASED
00463 /* Get small count integer, 32 bits or less */
00464 static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
00465 {
00466     word32 idx = *inOutIdx;
00467     word32 len;
00468 
00469     *number = 0;
00470 
00471     if (input[idx++] != ASN_INTEGER)
00472         return ASN_PARSE_E;
00473 
00474     len = input[idx++];
00475     if (len > 4)
00476         return ASN_PARSE_E;
00477 
00478     while (len--) {
00479         *number  = *number << 8 | input[idx++];
00480     }
00481 
00482     *inOutIdx = idx;
00483 
00484     return *number;
00485 }
00486 #endif /* !NO_PWDBASED */
00487 
00488 
00489 /* May not have one, not an error */
00490 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
00491 {
00492     word32 idx = *inOutIdx;
00493 
00494     CYASSL_ENTER("GetExplicitVersion");
00495     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
00496         *inOutIdx = ++idx;  /* eat header */
00497         return GetMyVersion(input, inOutIdx, version);
00498     }
00499 
00500     /* go back as is */
00501     *version = 0;
00502 
00503     return 0;
00504 }
00505 
00506 
00507 static int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
00508                   word32 maxIdx)
00509 {
00510     word32 i = *inOutIdx;
00511     byte   b = input[i++];
00512     int    length;
00513 
00514     if (b != ASN_INTEGER)
00515         return ASN_PARSE_E;
00516 
00517     if (GetLength(input, &i, &length, maxIdx) < 0)
00518         return ASN_PARSE_E;
00519 
00520     if ( (b = input[i++]) == 0x00)
00521         length--;
00522     else
00523         i--;
00524 
00525     if (mp_init(mpi) != MP_OKAY)
00526         return MP_INIT_E;
00527 
00528     if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
00529         mp_clear(mpi);
00530         return ASN_GETINT_E;
00531     }
00532 
00533     *inOutIdx = i + length;
00534     return 0;
00535 }
00536 
00537 
00538 static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
00539                      word32 maxIdx)
00540 {
00541     int    length;
00542     word32 i = *inOutIdx;
00543     byte   b;
00544     *oid = 0;
00545     
00546     b = input[i++];
00547     if (b != ASN_OBJECT_ID) 
00548         return ASN_OBJECT_ID_E;
00549     
00550     if (GetLength(input, &i, &length, maxIdx) < 0)
00551         return ASN_PARSE_E;
00552     
00553     while(length--)
00554         *oid += input[i++];
00555     /* just sum it up for now */
00556     
00557     *inOutIdx = i;
00558     
00559     return 0;
00560 }
00561 
00562 
00563 static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
00564                      word32 maxIdx)
00565 {
00566     int    length;
00567     word32 i = *inOutIdx;
00568     byte   b;
00569     *oid = 0;
00570    
00571     CYASSL_ENTER("GetAlgoId");
00572 
00573     if (GetSequence(input, &i, &length, maxIdx) < 0)
00574         return ASN_PARSE_E;
00575     
00576     b = input[i++];
00577     if (b != ASN_OBJECT_ID) 
00578         return ASN_OBJECT_ID_E;
00579     
00580     if (GetLength(input, &i, &length, maxIdx) < 0)
00581         return ASN_PARSE_E;
00582     
00583     while(length--) {
00584         /* odd HC08 compiler behavior here when input[i++] */
00585         *oid += input[i];
00586         i++;
00587     }
00588     /* just sum it up for now */
00589     
00590     /* could have NULL tag and 0 terminator, but may not */
00591     b = input[i++];
00592     
00593     if (b == ASN_TAG_NULL) {
00594         b = input[i++];
00595         if (b != 0) 
00596             return ASN_EXPECT_0_E;
00597     }
00598     else
00599     /* go back, didn't have it */
00600         i--;
00601     
00602     *inOutIdx = i;
00603     
00604     return 0;
00605 }
00606 
00607 #ifndef NO_RSA
00608 
00609 
00610 #ifdef HAVE_CAVIUM
00611 
00612 static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input,
00613                         word32* inOutIdx, word32 maxIdx, void* heap)
00614 {
00615     word32 i = *inOutIdx;
00616     byte   b = input[i++];
00617     int    length;
00618 
00619     if (b != ASN_INTEGER)
00620         return ASN_PARSE_E;
00621 
00622     if (GetLength(input, &i, &length, maxIdx) < 0)
00623         return ASN_PARSE_E;
00624 
00625     if ( (b = input[i++]) == 0x00)
00626         length--;
00627     else
00628         i--;
00629 
00630     *buffSz = (word16)length;
00631     *buff   = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA);
00632     if (*buff == NULL)
00633         return MEMORY_E;
00634 
00635     XMEMCPY(*buff, input + i, *buffSz);
00636 
00637     *inOutIdx = i + length;
00638     return 0;
00639 }
00640 
00641 static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
00642                                      RsaKey* key, word32 inSz)
00643 {
00644     int   version, length;
00645     void* h = key->heap;
00646 
00647     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
00648         return ASN_PARSE_E;
00649 
00650     if (GetMyVersion(input, inOutIdx, &version) < 0)
00651         return ASN_PARSE_E;
00652 
00653     key->type = RSA_PRIVATE;
00654 
00655     if (GetCaviumInt(&key->c_n,  &key->c_nSz,   input, inOutIdx, inSz, h) < 0 ||
00656         GetCaviumInt(&key->c_e,  &key->c_eSz,   input, inOutIdx, inSz, h) < 0 ||
00657         GetCaviumInt(&key->c_d,  &key->c_dSz,   input, inOutIdx, inSz, h) < 0 ||
00658         GetCaviumInt(&key->c_p,  &key->c_pSz,   input, inOutIdx, inSz, h) < 0 ||
00659         GetCaviumInt(&key->c_q,  &key->c_qSz,   input, inOutIdx, inSz, h) < 0 ||
00660         GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 ||
00661         GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 ||
00662         GetCaviumInt(&key->c_u,  &key->c_uSz,   input, inOutIdx, inSz, h) < 0 )
00663             return ASN_RSA_KEY_E;
00664 
00665     return 0;
00666 }
00667 
00668 
00669 #endif /* HAVE_CAVIUM */
00670 
00671 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
00672                         word32 inSz)
00673 {
00674     int    version, length;
00675 
00676 #ifdef HAVE_CAVIUM
00677     if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
00678         return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz);
00679 #endif
00680 
00681     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
00682         return ASN_PARSE_E;
00683 
00684     if (GetMyVersion(input, inOutIdx, &version) < 0)
00685         return ASN_PARSE_E;
00686 
00687     key->type = RSA_PRIVATE;
00688 
00689     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
00690         GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
00691         GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
00692         GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
00693         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
00694         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
00695         GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
00696         GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
00697 
00698     return 0;
00699 }
00700 
00701 #endif /* NO_RSA */
00702 
00703 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
00704 int ToTraditional(byte* input, word32 sz)
00705 {
00706     word32 inOutIdx = 0, oid;
00707     int    version, length;
00708 
00709     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
00710         return ASN_PARSE_E;
00711 
00712     if (GetMyVersion(input, &inOutIdx, &version) < 0)
00713         return ASN_PARSE_E;
00714     
00715     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
00716         return ASN_PARSE_E;
00717 
00718     if (input[inOutIdx] == ASN_OBJECT_ID) {
00719         /* pkcs8 ecc uses slightly different format */
00720         inOutIdx++;  /* past id */
00721         if (GetLength(input, &inOutIdx, &length, sz) < 0)
00722             return ASN_PARSE_E;
00723         inOutIdx += length;  /* over sub id, key input will verify */
00724     }
00725     
00726     if (input[inOutIdx++] != ASN_OCTET_STRING)
00727         return ASN_PARSE_E;
00728     
00729     if (GetLength(input, &inOutIdx, &length, sz) < 0)
00730         return ASN_PARSE_E;
00731     
00732     XMEMMOVE(input, input + inOutIdx, length);
00733 
00734     return 0;
00735 }
00736 
00737 
00738 #ifndef NO_PWDBASED
00739 
00740 /* Check To see if PKCS version algo is supported, set id if it is return 0
00741    < 0 on error */
00742 static int CheckAlgo(int first, int second, int* id, int* version)
00743 {
00744     *id      = ALGO_ID_E;
00745     *version = PKCS5;   /* default */
00746 
00747     if (first == 1) {
00748         switch (second) {
00749         case 1:
00750             *id = PBE_SHA1_RC4_128;
00751             *version = PKCS12;
00752             return 0;
00753         case 3:
00754             *id = PBE_SHA1_DES3;
00755             *version = PKCS12;
00756             return 0;
00757         default:
00758             return ALGO_ID_E;
00759         }
00760     }
00761 
00762     if (first != PKCS5)
00763         return ASN_INPUT_E;  /* VERSION ERROR */
00764 
00765     if (second == PBES2) {
00766         *version = PKCS5v2;
00767         return 0;
00768     }
00769 
00770     switch (second) {
00771     case 3:                   /* see RFC 2898 for ids */
00772         *id = PBE_MD5_DES;
00773         return 0;
00774     case 10:
00775         *id = PBE_SHA1_DES;
00776         return 0;
00777     default:
00778         return ALGO_ID_E;
00779 
00780     }
00781 }
00782 
00783 
00784 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
00785    < 0 on error */
00786 static int CheckAlgoV2(int oid, int* id)
00787 {
00788     switch (oid) {
00789     case 69:
00790         *id = PBE_SHA1_DES;
00791         return 0;
00792     case 652:
00793         *id = PBE_SHA1_DES3;
00794         return 0;
00795     default:
00796         return ALGO_ID_E;
00797 
00798     }
00799 }
00800 
00801 
00802 /* Decrypt intput in place from parameters based on id */
00803 static int DecryptKey(const char* password, int passwordSz, byte* salt,
00804                       int saltSz, int iterations, int id, byte* input,
00805                       int length, int version, byte* cbcIv)
00806 {
00807     byte   key[MAX_KEY_SIZE];
00808     int    typeH;
00809     int    derivedLen;
00810     int    decryptionType;
00811     int    ret = 0; 
00812 
00813     switch (id) {
00814         case PBE_MD5_DES:
00815             typeH = MD5;
00816             derivedLen = 16;           /* may need iv for v1.5 */
00817             decryptionType = DES_TYPE;
00818             break;
00819 
00820         case PBE_SHA1_DES:
00821             typeH = SHA;
00822             derivedLen = 16;           /* may need iv for v1.5 */
00823             decryptionType = DES_TYPE;
00824             break;
00825 
00826         case PBE_SHA1_DES3:
00827             typeH = SHA;
00828             derivedLen = 32;           /* may need iv for v1.5 */
00829             decryptionType = DES3_TYPE;
00830             break;
00831 
00832         case PBE_SHA1_RC4_128:
00833             typeH = SHA;
00834             derivedLen = 16;
00835             decryptionType = RC4_TYPE;
00836             break;
00837 
00838         default:
00839             return ALGO_ID_E;
00840     }
00841 
00842     if (version == PKCS5v2)
00843         ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations,
00844                derivedLen, typeH);
00845     else if (version == PKCS5)
00846         ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
00847                derivedLen, typeH);
00848     else if (version == PKCS12) {
00849         int  i, idx = 0;
00850         byte unicodePasswd[MAX_UNICODE_SZ];
00851 
00852         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd))
00853             return UNICODE_SIZE_E; 
00854 
00855         for (i = 0; i < passwordSz; i++) {
00856             unicodePasswd[idx++] = 0x00;
00857             unicodePasswd[idx++] = (byte)password[i];
00858         }
00859         /* add trailing NULL */
00860         unicodePasswd[idx++] = 0x00;
00861         unicodePasswd[idx++] = 0x00;
00862 
00863         ret =  PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
00864                             iterations, derivedLen, typeH, 1);
00865         if (decryptionType != RC4_TYPE)
00866             ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
00867                                 iterations, 8, typeH, 2);
00868     }
00869     else
00870         return ALGO_ID_E;
00871 
00872     if (ret != 0)
00873         return ret;
00874 
00875     switch (decryptionType) {
00876 #ifndef NO_DES3
00877         case DES_TYPE:
00878         {
00879             Des    dec;
00880             byte*  desIv = key + 8;
00881 
00882             if (version == PKCS5v2 || version == PKCS12)
00883                 desIv = cbcIv;
00884             Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
00885             Des_CbcDecrypt(&dec, input, input, length);
00886             break;
00887         }
00888 
00889         case DES3_TYPE:
00890         {
00891             Des3   dec;
00892             byte*  desIv = key + 24;
00893 
00894             if (version == PKCS5v2 || version == PKCS12)
00895                 desIv = cbcIv;
00896             Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
00897             Des3_CbcDecrypt(&dec, input, input, length);
00898             break;
00899         }
00900 #endif
00901 #ifndef NO_RC4
00902         case RC4_TYPE:
00903         {
00904             Arc4    dec;
00905 
00906             Arc4SetKey(&dec, key, derivedLen);
00907             Arc4Process(&dec, input, input, length);
00908             break;
00909         }
00910 #endif
00911 
00912         default:
00913             return ALGO_ID_E; 
00914     }
00915 
00916     return 0;
00917 }
00918 
00919 
00920 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
00921    of input */
00922 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
00923 {
00924     word32 inOutIdx = 0, oid;
00925     int    first, second, length, version, saltSz, id;
00926     int    iterations = 0;
00927     byte   salt[MAX_SALT_SIZE];
00928     byte   cbcIv[MAX_IV_SIZE];
00929     
00930     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
00931         return ASN_PARSE_E;
00932 
00933     if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
00934         return ASN_PARSE_E;
00935     
00936     first  = input[inOutIdx - 2];   /* PKCS version alwyas 2nd to last byte */
00937     second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
00938 
00939     if (CheckAlgo(first, second, &id, &version) < 0)
00940         return ASN_INPUT_E;  /* Algo ID error */
00941 
00942     if (version == PKCS5v2) {
00943 
00944         if (GetSequence(input, &inOutIdx, &length, sz) < 0)
00945             return ASN_PARSE_E;
00946 
00947         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
00948             return ASN_PARSE_E;
00949 
00950         if (oid != PBKDF2_OID)
00951             return ASN_PARSE_E;
00952     }
00953 
00954     if (GetSequence(input, &inOutIdx, &length, sz) < 0)
00955         return ASN_PARSE_E;
00956 
00957     if (input[inOutIdx++] != ASN_OCTET_STRING)
00958         return ASN_PARSE_E;
00959     
00960     if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
00961         return ASN_PARSE_E;
00962 
00963     if (saltSz > MAX_SALT_SIZE)
00964         return ASN_PARSE_E;
00965      
00966     XMEMCPY(salt, &input[inOutIdx], saltSz);
00967     inOutIdx += saltSz;
00968 
00969     if (GetShortInt(input, &inOutIdx, &iterations) < 0)
00970         return ASN_PARSE_E;
00971 
00972     if (version == PKCS5v2) {
00973         /* get encryption algo */
00974         if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
00975             return ASN_PARSE_E;
00976 
00977         if (CheckAlgoV2(oid, &id) < 0)
00978             return ASN_PARSE_E;  /* PKCS v2 algo id error */
00979 
00980         if (input[inOutIdx++] != ASN_OCTET_STRING)
00981             return ASN_PARSE_E;
00982     
00983         if (GetLength(input, &inOutIdx, &length, sz) < 0)
00984             return ASN_PARSE_E;
00985 
00986         XMEMCPY(cbcIv, &input[inOutIdx], length);
00987         inOutIdx += length;
00988     }
00989 
00990     if (input[inOutIdx++] != ASN_OCTET_STRING)
00991         return ASN_PARSE_E;
00992     
00993     if (GetLength(input, &inOutIdx, &length, sz) < 0)
00994         return ASN_PARSE_E;
00995 
00996     if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
00997                    input + inOutIdx, length, version, cbcIv) < 0)
00998         return ASN_INPUT_E;  /* decrypt failure */
00999 
01000     XMEMMOVE(input, input + inOutIdx, length);
01001     return ToTraditional(input, length);
01002 }
01003 
01004 #endif /* NO_PWDBASED */
01005 
01006 #ifndef NO_RSA
01007 
01008 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
01009                        word32 inSz)
01010 {
01011     int    length;
01012 
01013     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01014         return ASN_PARSE_E;
01015 
01016     key->type = RSA_PUBLIC;
01017 
01018 #ifdef OPENSSL_EXTRA
01019     {
01020     byte b = input[*inOutIdx];
01021     if (b != ASN_INTEGER) {
01022         /* not from decoded cert, will have algo id, skip past */
01023         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01024             return ASN_PARSE_E;
01025         
01026         b = input[(*inOutIdx)++];
01027         if (b != ASN_OBJECT_ID) 
01028             return ASN_OBJECT_ID_E;
01029         
01030         if (GetLength(input, inOutIdx, &length, inSz) < 0)
01031             return ASN_PARSE_E;
01032         
01033         *inOutIdx += length;   /* skip past */
01034         
01035         /* could have NULL tag and 0 terminator, but may not */
01036         b = input[(*inOutIdx)++];
01037         
01038         if (b == ASN_TAG_NULL) {
01039             b = input[(*inOutIdx)++];
01040             if (b != 0) 
01041                 return ASN_EXPECT_0_E;
01042         }
01043         else
01044         /* go back, didn't have it */
01045             (*inOutIdx)--;
01046         
01047         /* should have bit tag length and seq next */
01048         b = input[(*inOutIdx)++];
01049         if (b != ASN_BIT_STRING)
01050             return ASN_BITSTR_E;
01051         
01052         if (GetLength(input, inOutIdx, &length, inSz) < 0)
01053             return ASN_PARSE_E;
01054         
01055         /* could have 0 */
01056         b = input[(*inOutIdx)++];
01057         if (b != 0)
01058             (*inOutIdx)--;
01059         
01060         if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01061             return ASN_PARSE_E;
01062     }  /* end if */
01063     }  /* openssl var block */
01064 #endif /* OPENSSL_EXTRA */
01065 
01066     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
01067         GetInt(&key->e,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
01068 
01069     return 0;
01070 }
01071 
01072 #endif
01073 
01074 #ifndef NO_DH
01075 
01076 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
01077 {
01078     int    length;
01079 
01080     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01081         return ASN_PARSE_E;
01082 
01083     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
01084         GetInt(&key->g,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
01085 
01086     return 0;
01087 }
01088 
01089 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
01090 {
01091     /* may have leading 0 */
01092     if (p[0] == 0) {
01093         pSz--; p++;
01094     }
01095 
01096     if (g[0] == 0) {
01097         gSz--; g++;
01098     }
01099 
01100     if (mp_init(&key->p) != MP_OKAY)
01101         return MP_INIT_E;
01102     if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
01103         mp_clear(&key->p);
01104         return ASN_DH_KEY_E;
01105     }
01106 
01107     if (mp_init(&key->g) != MP_OKAY) {
01108         mp_clear(&key->p);
01109         return MP_INIT_E;
01110     }
01111     if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
01112         mp_clear(&key->g);
01113         mp_clear(&key->p);
01114         return ASN_DH_KEY_E;
01115     }
01116 
01117     return 0;
01118 }
01119 
01120 
01121 #ifdef OPENSSL_EXTRA
01122 
01123 int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
01124                  byte* g, word32* gInOutSz)
01125 {
01126     word32 i = 0;
01127     byte   b;
01128     int    length;
01129 
01130     if (GetSequence(input, &i, &length, inSz) < 0)
01131         return ASN_PARSE_E;
01132 
01133     b = input[i++];
01134     if (b != ASN_INTEGER)
01135         return ASN_PARSE_E;
01136 
01137     if (GetLength(input, &i, &length, inSz) < 0)
01138         return ASN_PARSE_E;
01139 
01140     if ( (b = input[i++]) == 0x00)
01141         length--;
01142     else
01143         i--;
01144 
01145     if (length <= (int)*pInOutSz) {
01146         XMEMCPY(p, &input[i], length);
01147         *pInOutSz = length;
01148     }
01149     else
01150         return BUFFER_E;
01151 
01152     i += length;
01153 
01154     b = input[i++];
01155     if (b != ASN_INTEGER)
01156         return ASN_PARSE_E;
01157 
01158     if (GetLength(input, &i, &length, inSz) < 0)
01159         return ASN_PARSE_E;
01160 
01161     if (length <= (int)*gInOutSz) {
01162         XMEMCPY(g, &input[i], length);
01163         *gInOutSz = length;
01164     }
01165     else
01166         return BUFFER_E;
01167 
01168     return 0;
01169 }
01170 
01171 #endif /* OPENSSL_EXTRA */
01172 #endif /* NO_DH */
01173 
01174 
01175 #ifndef NO_DSA
01176 
01177 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
01178                         word32 inSz)
01179 {
01180     int    length;
01181 
01182     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01183         return ASN_PARSE_E;
01184 
01185     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
01186         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
01187         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
01188         GetInt(&key->y,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
01189 
01190     key->type = DSA_PUBLIC;
01191     return 0;
01192 }
01193 
01194 
01195 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
01196                         word32 inSz)
01197 {
01198     int    length, version;
01199 
01200     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
01201         return ASN_PARSE_E;
01202 
01203     if (GetMyVersion(input, inOutIdx, &version) < 0)
01204         return ASN_PARSE_E;
01205 
01206     if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
01207         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
01208         GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
01209         GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
01210         GetInt(&key->x,  input, inOutIdx, inSz) < 0 )  return ASN_DH_KEY_E;
01211 
01212     key->type = DSA_PRIVATE;
01213     return 0;
01214 }
01215 
01216 #endif /* NO_DSA */
01217 
01218 
01219 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
01220 {
01221     cert->publicKey       = 0;
01222     cert->pubKeyStored    = 0;
01223     cert->signature       = 0;
01224     cert->subjectCN       = 0;
01225     cert->subjectCNLen    = 0;
01226     cert->subjectCNStored = 0;
01227     cert->altNames        = NULL;
01228     cert->issuer[0]       = '\0';
01229     cert->subject[0]      = '\0';
01230     cert->source          = source;  /* don't own */
01231     cert->srcIdx          = 0;
01232     cert->maxIdx          = inSz;    /* can't go over this index */
01233     cert->heap            = heap;
01234     XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
01235     cert->serialSz        = 0;
01236     cert->extensions      = 0;
01237     cert->extensionsSz    = 0;
01238     cert->extensionsIdx   = 0;
01239     cert->extAuthInfo     = NULL;
01240     cert->extAuthInfoSz   = 0;
01241     cert->extCrlInfo      = NULL;
01242     cert->extCrlInfoSz    = 0;
01243     XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE);
01244     cert->extSubjKeyIdSet = 0;
01245     XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE);
01246     cert->extAuthKeyIdSet = 0;
01247     cert->isCA            = 0;
01248 #ifdef CYASSL_CERT_GEN
01249     cert->subjectSN       = 0;
01250     cert->subjectSNLen    = 0;
01251     cert->subjectC        = 0;
01252     cert->subjectCLen     = 0;
01253     cert->subjectL        = 0;
01254     cert->subjectLLen     = 0;
01255     cert->subjectST       = 0;
01256     cert->subjectSTLen    = 0;
01257     cert->subjectO        = 0;
01258     cert->subjectOLen     = 0;
01259     cert->subjectOU       = 0;
01260     cert->subjectOULen    = 0;
01261     cert->subjectEmail    = 0;
01262     cert->subjectEmailLen = 0;
01263     cert->beforeDate      = 0;
01264     cert->beforeDateLen   = 0;
01265     cert->afterDate       = 0;
01266     cert->afterDateLen    = 0;
01267 #endif /* CYASSL_CERT_GEN */
01268 }
01269 
01270 
01271 void FreeAltNames(DNS_entry* altNames, void* heap)
01272 {
01273     (void)heap;
01274 
01275     while (altNames) {
01276         DNS_entry* tmp = altNames->next;
01277 
01278         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
01279         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
01280         altNames = tmp;
01281     }
01282 }
01283 
01284 
01285 void FreeDecodedCert(DecodedCert* cert)
01286 {
01287     if (cert->subjectCNStored == 1)
01288         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
01289     if (cert->pubKeyStored == 1)
01290         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01291     if (cert->altNames)
01292         FreeAltNames(cert->altNames, cert->heap);
01293 }
01294 
01295 
01296 static int GetCertHeader(DecodedCert* cert)
01297 {
01298     int    ret = 0, version, len;
01299     byte   serialTmp[EXTERNAL_SERIAL_SIZE];
01300     mp_int mpi;
01301 
01302     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
01303         return ASN_PARSE_E;
01304 
01305     cert->certBegin = cert->srcIdx;
01306 
01307     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
01308         return ASN_PARSE_E;
01309     cert->sigIndex = len + cert->srcIdx;
01310 
01311     if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
01312         return ASN_PARSE_E;
01313 
01314     if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) 
01315         return ASN_PARSE_E;
01316 
01317     len = mp_unsigned_bin_size(&mpi);
01318     if (len < (int)sizeof(serialTmp)) {
01319         if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) {
01320             if (len > EXTERNAL_SERIAL_SIZE)
01321                 len = EXTERNAL_SERIAL_SIZE;
01322             XMEMCPY(cert->serial, serialTmp, len);
01323             cert->serialSz = len;
01324         }
01325     }
01326     mp_clear(&mpi);
01327     return ret;
01328 }
01329 
01330 #if !defined(NO_RSA)
01331 /* Store Rsa Key, may save later, Dsa could use in future */
01332 static int StoreRsaKey(DecodedCert* cert)
01333 {
01334     int    length;
01335     word32 read = cert->srcIdx;
01336 
01337     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01338         return ASN_PARSE_E;
01339    
01340     read = cert->srcIdx - read;
01341     length += read;
01342 
01343     while (read--)
01344        cert->srcIdx--;
01345 
01346     cert->pubKeySize = length;
01347     cert->publicKey = cert->source + cert->srcIdx;
01348     cert->srcIdx += length;
01349 
01350     return 0;
01351 }
01352 #endif
01353 
01354 
01355 #ifdef HAVE_ECC
01356 
01357     /* return 0 on sucess if the ECC curve oid sum is supported */
01358     static int CheckCurve(word32 oid)
01359     {
01360         if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid !=
01361                    ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1)
01362             return ALGO_ID_E; 
01363 
01364         return 0;
01365     }
01366 
01367 #endif /* HAVE_ECC */
01368 
01369 
01370 static int GetKey(DecodedCert* cert)
01371 {
01372     int length;
01373 #ifdef HAVE_NTRU
01374     int tmpIdx = cert->srcIdx;
01375 #endif
01376 
01377     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01378         return ASN_PARSE_E;
01379     
01380     if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
01381         return ASN_PARSE_E;
01382 
01383     switch (cert->keyOID) {
01384         case DSAk:
01385             /* do nothing */
01386         break;
01387    #ifndef NO_RSA
01388         case RSAk:
01389         {
01390             byte b = cert->source[cert->srcIdx++];
01391             if (b != ASN_BIT_STRING)
01392                 return ASN_BITSTR_E;
01393 
01394             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
01395                 return ASN_PARSE_E;
01396             b = cert->source[cert->srcIdx++];
01397             if (b != 0x00)
01398                 return ASN_EXPECT_0_E;
01399     
01400             return StoreRsaKey(cert);
01401         }
01402 
01403     #endif /* NO_RSA */
01404     #ifdef HAVE_NTRU
01405         case NTRUk:
01406         {
01407             const byte* key = &cert->source[tmpIdx];
01408             byte*       next = (byte*)key;
01409             word16      keyLen;
01410             byte        keyBlob[MAX_NTRU_KEY_SZ];
01411 
01412             word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
01413                                 &keyLen, NULL, &next);
01414 
01415             if (rc != NTRU_OK)
01416                 return ASN_NTRU_KEY_E;
01417             if (keyLen > sizeof(keyBlob))
01418                 return ASN_NTRU_KEY_E;
01419 
01420             rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen,
01421                                                                 keyBlob, &next);
01422             if (rc != NTRU_OK)
01423                 return ASN_NTRU_KEY_E;
01424 
01425             if ( (next - key) < 0)
01426                 return ASN_NTRU_KEY_E;
01427 
01428             cert->srcIdx = tmpIdx + (int)(next - key);
01429 
01430             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
01431                                               DYNAMIC_TYPE_PUBLIC_KEY);
01432             if (cert->publicKey == NULL)
01433                 return MEMORY_E;
01434             XMEMCPY(cert->publicKey, keyBlob, keyLen);
01435             cert->pubKeyStored = 1;
01436             cert->pubKeySize   = keyLen;
01437         }
01438         break;
01439     #endif /* HAVE_NTRU */
01440     #ifdef HAVE_ECC
01441         case ECDSAk:
01442         {
01443             word32 oid = 0;
01444             int    oidSz = 0;
01445             byte   b = cert->source[cert->srcIdx++];
01446         
01447             if (b != ASN_OBJECT_ID) 
01448                 return ASN_OBJECT_ID_E;
01449 
01450             if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0)
01451                 return ASN_PARSE_E;
01452 
01453             while(oidSz--)
01454                 oid += cert->source[cert->srcIdx++];
01455             if (CheckCurve(oid) < 0)
01456                 return ECC_CURVE_OID_E;
01457 
01458             /* key header */
01459             b = cert->source[cert->srcIdx++];
01460             if (b != ASN_BIT_STRING)
01461                 return ASN_BITSTR_E;
01462 
01463             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
01464                 return ASN_PARSE_E;
01465             b = cert->source[cert->srcIdx++];
01466             if (b != 0x00)
01467                 return ASN_EXPECT_0_E;
01468 
01469             /* actual key, use length - 1 since ate preceding 0 */
01470             length -= 1;
01471 
01472             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
01473                                               DYNAMIC_TYPE_PUBLIC_KEY);
01474             if (cert->publicKey == NULL)
01475                 return MEMORY_E;
01476             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
01477             cert->pubKeyStored = 1;
01478             cert->pubKeySize   = length;
01479 
01480             cert->srcIdx += length;
01481         }
01482         break;
01483     #endif /* HAVE_ECC */
01484         default:
01485             return ASN_UNKNOWN_OID_E;
01486     }
01487    
01488     return 0;
01489 }
01490 
01491 
01492 /* process NAME, either issuer or subject */
01493 static int GetName(DecodedCert* cert, int nameType)
01494 {
01495     Sha    sha;     /* MUST have SHA-1 hash for cert names */
01496     int    length;  /* length of all distinguished names */
01497     int    dummy;
01498     char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
01499     word32 idx;
01500 
01501     CYASSL_MSG("Getting Cert Name");
01502 
01503     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
01504         CYASSL_MSG("Trying optional prefix...");
01505 
01506         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01507             return ASN_PARSE_E;
01508 
01509         cert->srcIdx += length;
01510         CYASSL_MSG("Got optional prefix");
01511     }
01512 
01513     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
01514      * calculated over the entire DER encoding of the Name field, including
01515      * the tag and length. */
01516     idx = cert->srcIdx;
01517     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01518         return ASN_PARSE_E;
01519 
01520     InitSha(&sha);
01521     ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx);
01522     if (nameType == ISSUER)
01523         ShaFinal(&sha, cert->issuerHash);
01524     else
01525         ShaFinal(&sha, cert->subjectHash);
01526 
01527     length += cert->srcIdx;
01528     idx = 0;
01529 
01530     while (cert->srcIdx < (word32)length) {
01531         byte   b;
01532         byte   joint[2];
01533         byte   tooBig = FALSE;
01534         int    oidSz;
01535 
01536         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
01537             CYASSL_MSG("Cert name lacks set header, trying sequence");
01538         }
01539 
01540         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
01541             return ASN_PARSE_E;
01542 
01543         b = cert->source[cert->srcIdx++];
01544         if (b != ASN_OBJECT_ID) 
01545             return ASN_OBJECT_ID_E;
01546 
01547         if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
01548             return ASN_PARSE_E;
01549 
01550         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
01551 
01552         /* v1 name types */
01553         if (joint[0] == 0x55 && joint[1] == 0x04) {
01554             byte   id;
01555             byte   copy = FALSE;
01556             int    strLen;
01557 
01558             cert->srcIdx += 2;
01559             id = cert->source[cert->srcIdx++]; 
01560             b  = cert->source[cert->srcIdx++];    /* strType */
01561             (void)b;                              /* may want to validate? */
01562 
01563             if (GetLength(cert->source, &cert->srcIdx, &strLen,
01564                           cert->maxIdx) < 0)
01565                 return ASN_PARSE_E;
01566 
01567             if ( (strLen + 4) > (int)(ASN_NAME_MAX - idx)) {
01568                 /* include biggest pre fix header too 4 = "/CN=" */
01569                 CYASSL_MSG("ASN Name too big, skipping");
01570                 tooBig = TRUE;
01571             }
01572 
01573             if (id == ASN_COMMON_NAME) {
01574                 if (nameType == SUBJECT) {
01575                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
01576                     cert->subjectCNLen = strLen;
01577                 }
01578 
01579                 if (!tooBig) {
01580                     XMEMCPY(&full[idx], "/CN=", 4);
01581                     idx += 4;
01582                     copy = TRUE;
01583                 }
01584             }
01585             else if (id == ASN_SUR_NAME) {
01586                 if (!tooBig) {
01587                     XMEMCPY(&full[idx], "/SN=", 4);
01588                     idx += 4;
01589                     copy = TRUE;
01590                 }
01591 #ifdef CYASSL_CERT_GEN
01592                 if (nameType == SUBJECT) {
01593                     cert->subjectSN = (char*)&cert->source[cert->srcIdx];
01594                     cert->subjectSNLen = strLen;
01595                 }
01596 #endif /* CYASSL_CERT_GEN */
01597             }
01598             else if (id == ASN_COUNTRY_NAME) {
01599                 if (!tooBig) {
01600                     XMEMCPY(&full[idx], "/C=", 3);
01601                     idx += 3;
01602                     copy = TRUE;
01603                 }
01604 #ifdef CYASSL_CERT_GEN
01605                 if (nameType == SUBJECT) {
01606                     cert->subjectC = (char*)&cert->source[cert->srcIdx];
01607                     cert->subjectCLen = strLen;
01608                 }
01609 #endif /* CYASSL_CERT_GEN */
01610             }
01611             else if (id == ASN_LOCALITY_NAME) {
01612                 if (!tooBig) {
01613                     XMEMCPY(&full[idx], "/L=", 3);
01614                     idx += 3;
01615                     copy = TRUE;
01616                 }
01617 #ifdef CYASSL_CERT_GEN
01618                 if (nameType == SUBJECT) {
01619                     cert->subjectL = (char*)&cert->source[cert->srcIdx];
01620                     cert->subjectLLen = strLen;
01621                 }
01622 #endif /* CYASSL_CERT_GEN */
01623             }
01624             else if (id == ASN_STATE_NAME) {
01625                 if (!tooBig) {
01626                     XMEMCPY(&full[idx], "/ST=", 4);
01627                     idx += 4;
01628                     copy = TRUE;
01629                 }
01630 #ifdef CYASSL_CERT_GEN
01631                 if (nameType == SUBJECT) {
01632                     cert->subjectST = (char*)&cert->source[cert->srcIdx];
01633                     cert->subjectSTLen = strLen;
01634                 }
01635 #endif /* CYASSL_CERT_GEN */
01636             }
01637             else if (id == ASN_ORG_NAME) {
01638                 if (!tooBig) {
01639                     XMEMCPY(&full[idx], "/O=", 3);
01640                     idx += 3;
01641                     copy = TRUE;
01642                 }
01643 #ifdef CYASSL_CERT_GEN
01644                 if (nameType == SUBJECT) {
01645                     cert->subjectO = (char*)&cert->source[cert->srcIdx];
01646                     cert->subjectOLen = strLen;
01647                 }
01648 #endif /* CYASSL_CERT_GEN */
01649             }
01650             else if (id == ASN_ORGUNIT_NAME) {
01651                 if (!tooBig) {
01652                     XMEMCPY(&full[idx], "/OU=", 4);
01653                     idx += 4;
01654                     copy = TRUE;
01655                 }
01656 #ifdef CYASSL_CERT_GEN
01657                 if (nameType == SUBJECT) {
01658                     cert->subjectOU = (char*)&cert->source[cert->srcIdx];
01659                     cert->subjectOULen = strLen;
01660                 }
01661 #endif /* CYASSL_CERT_GEN */
01662             }
01663 
01664             if (copy && !tooBig) {
01665                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
01666                 idx += strLen;
01667             }
01668 
01669             cert->srcIdx += strLen;
01670         }
01671         else {
01672             /* skip */
01673             byte email = FALSE;
01674             byte uid   = FALSE;
01675             int  adv;
01676 
01677             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
01678                 email = TRUE;
01679 
01680             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
01681                 uid = TRUE;
01682 
01683             cert->srcIdx += oidSz + 1;
01684 
01685             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
01686                 return ASN_PARSE_E;
01687 
01688             if (adv > (int)(ASN_NAME_MAX - idx)) {
01689                 CYASSL_MSG("ASN name too big, skipping");
01690                 tooBig = TRUE;
01691             }
01692 
01693             if (email) {
01694                 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
01695                     CYASSL_MSG("ASN name too big, skipping");
01696                     tooBig = TRUE;
01697                 }
01698                 if (!tooBig) {
01699                     XMEMCPY(&full[idx], "/emailAddress=", 14);
01700                     idx += 14;
01701                 }
01702 
01703 #ifdef CYASSL_CERT_GEN
01704                 if (nameType == SUBJECT) {
01705                     cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
01706                     cert->subjectEmailLen = adv;
01707                 }
01708 #endif /* CYASSL_CERT_GEN */
01709 
01710                 if (!tooBig) {
01711                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
01712                     idx += adv;
01713                 }
01714             }
01715 
01716             if (uid) {
01717                 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
01718                     CYASSL_MSG("ASN name too big, skipping");
01719                     tooBig = TRUE;
01720                 }
01721                 if (!tooBig) {
01722                     XMEMCPY(&full[idx], "/UID=", 5);
01723                     idx += 5;
01724 
01725                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
01726                     idx += adv;
01727                 }
01728             }
01729 
01730             cert->srcIdx += adv;
01731         }
01732     }
01733     full[idx++] = 0;
01734 
01735     return 0;
01736 }
01737 
01738 
01739 #ifndef NO_TIME_H
01740 
01741 /* to the second */
01742 static int DateGreaterThan(const struct tm* a, const struct tm* b)
01743 {
01744     if (a->tm_year > b->tm_year)
01745         return 1;
01746 
01747     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
01748         return 1;
01749     
01750     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01751            a->tm_mday > b->tm_mday)
01752         return 1;
01753 
01754     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01755         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
01756         return 1;
01757 
01758     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01759         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
01760         a->tm_min > b->tm_min)
01761         return 1;
01762 
01763     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01764         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
01765         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
01766         return 1;
01767 
01768     return 0; /* false */
01769 }
01770 
01771 
01772 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
01773 {
01774     return !DateGreaterThan(a,b);
01775 }
01776 
01777 
01778 /* like atoi but only use first byte */
01779 /* Make sure before and after dates are valid */
01780 int ValidateDate(const byte* date, byte format, int dateType)
01781 {
01782     time_t ltime;
01783     struct tm  certTime;
01784     struct tm* localTime;
01785     int    i = 0;
01786 
01787     ltime = XTIME(0);
01788     
01789     XMEMSET(&certTime, 0, sizeof(certTime));
01790 
01791     if (format == ASN_UTC_TIME) {
01792         if (btoi(date[0]) >= 5)
01793             certTime.tm_year = 1900;
01794         else
01795             certTime.tm_year = 2000;
01796     }
01797     else  { /* format == GENERALIZED_TIME */
01798         certTime.tm_year += btoi(date[i++]) * 1000;
01799         certTime.tm_year += btoi(date[i++]) * 100;
01800     }
01801 
01802     GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
01803     GetTime(&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;    /* adjust */
01804     GetTime(&certTime.tm_mday, date, &i);
01805     GetTime(&certTime.tm_hour, date, &i); 
01806     GetTime(&certTime.tm_min,  date, &i); 
01807     GetTime(&certTime.tm_sec,  date, &i); 
01808         
01809         if (date[i] != 'Z') {     /* only Zulu supported for this profile */
01810         CYASSL_MSG("Only Zulu time supported for this profile"); 
01811         return 0;
01812     }
01813 
01814     //localTime = XGMTIME(&ltime);
01815     // XXX gmtime seems to be broken on mbed, need to find out why
01816     localTime = localtime(&ltime);
01817     
01818     if (dateType == BEFORE) {
01819         if (DateLessThan(localTime, &certTime))
01820             return 0;
01821     }
01822     else
01823         if (DateGreaterThan(localTime, &certTime))
01824             return 0;
01825 
01826     return 1;
01827 }
01828 
01829 #endif /* NO_TIME_H */
01830 
01831 
01832 static int GetDate(DecodedCert* cert, int dateType)
01833 {
01834     int    length;
01835     byte   date[MAX_DATE_SIZE];
01836     byte   b;
01837 
01838 #ifdef CYASSL_CERT_GEN
01839     word32 startIdx = 0;
01840     if (dateType == BEFORE)
01841         cert->beforeDate = &cert->source[cert->srcIdx];
01842     else
01843         cert->afterDate = &cert->source[cert->srcIdx];
01844     startIdx = cert->srcIdx;
01845 #endif
01846 
01847     b = cert->source[cert->srcIdx++];
01848     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
01849         return ASN_TIME_E;
01850 
01851     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01852         return ASN_PARSE_E;
01853 
01854     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
01855         return ASN_DATE_SZ_E;
01856 
01857     XMEMCPY(date, &cert->source[cert->srcIdx], length);
01858     cert->srcIdx += length;
01859 
01860 #ifdef CYASSL_CERT_GEN
01861     if (dateType == BEFORE)
01862         cert->beforeDateLen = cert->srcIdx - startIdx;
01863     else
01864         cert->afterDateLen  = cert->srcIdx - startIdx;
01865 #endif
01866 
01867     if (!XVALIDATE_DATE(date, b, dateType)) {
01868         if (dateType == BEFORE)
01869             return ASN_BEFORE_DATE_E;
01870         else
01871             return ASN_AFTER_DATE_E;
01872     }
01873 
01874     return 0;
01875 }
01876 
01877 
01878 static int GetValidity(DecodedCert* cert, int verify)
01879 {
01880     int length;
01881     int badDate = 0;
01882 
01883     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01884         return ASN_PARSE_E;
01885 
01886     if (GetDate(cert, BEFORE) < 0 && verify)
01887         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
01888     
01889     if (GetDate(cert, AFTER) < 0 && verify)
01890         return ASN_AFTER_DATE_E;
01891    
01892     if (badDate != 0)
01893         return badDate;
01894 
01895     return 0;
01896 }
01897 
01898 
01899 int DecodeToKey(DecodedCert* cert, int verify)
01900 {
01901     int badDate = 0;
01902     int ret;
01903 
01904     if ( (ret = GetCertHeader(cert)) < 0)
01905         return ret;
01906 
01907     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
01908                           cert->maxIdx)) < 0)
01909         return ret;
01910 
01911     if ( (ret = GetName(cert, ISSUER)) < 0)
01912         return ret;
01913 
01914     if ( (ret = GetValidity(cert, verify)) < 0)
01915         badDate = ret;
01916 
01917     if ( (ret = GetName(cert, SUBJECT)) < 0)
01918         return ret;
01919 
01920     if ( (ret = GetKey(cert)) < 0)
01921         return ret;
01922 
01923     if (badDate != 0)
01924         return badDate;
01925 
01926     return ret;
01927 }
01928 
01929 
01930 static int GetSignature(DecodedCert* cert)
01931 {
01932     int    length;
01933     byte   b = cert->source[cert->srcIdx++];
01934 
01935     if (b != ASN_BIT_STRING)
01936         return ASN_BITSTR_E;
01937 
01938     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01939         return ASN_PARSE_E;
01940 
01941     cert->sigLength = length;
01942 
01943     b = cert->source[cert->srcIdx++];
01944     if (b != 0x00)
01945         return ASN_EXPECT_0_E;
01946 
01947     cert->sigLength--;
01948     cert->signature = &cert->source[cert->srcIdx];
01949     cert->srcIdx += cert->sigLength;
01950 
01951     return 0;
01952 }
01953 
01954 
01955 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
01956 {
01957     output[0] = ASN_OCTET_STRING;
01958     output[1] = (byte)digSz;
01959     XMEMCPY(&output[2], digest, digSz);
01960 
01961     return digSz + 2;
01962 } 
01963 
01964 
01965 static word32 BytePrecision(word32 value)
01966 {
01967     word32 i;
01968     for (i = sizeof(value); i; --i)
01969         if (value >> ((i - 1) * CYASSL_BIT_SIZE))
01970             break;
01971 
01972     return i;
01973 }
01974 
01975 
01976 static word32 SetLength(word32 length, byte* output)
01977 {
01978     word32 i = 0, j;
01979 
01980     if (length < ASN_LONG_LENGTH)
01981         output[i++] = (byte)length;
01982     else {
01983         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
01984       
01985         for (j = BytePrecision(length); j; --j) {
01986             output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE));
01987             i++;
01988         }
01989     }
01990 
01991     return i;
01992 }
01993 
01994 
01995 static word32 SetSequence(word32 len, byte* output)
01996 {
01997     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
01998     return SetLength(len, output + 1) + 1;
01999 }
02000 
02001 
02002 static word32 SetAlgoID(int algoOID, byte* output, int type)
02003 {
02004     /* adding TAG_NULL and 0 to end */
02005     
02006     /* hashTypes */
02007     static const byte shaAlgoID[]    = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
02008                                          0x05, 0x00 };
02009     static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02010                                          0x04, 0x02, 0x01, 0x05, 0x00 };
02011     static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02012                                          0x04, 0x02, 0x02, 0x05, 0x00 };
02013     static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02014                                          0x04, 0x02, 0x03, 0x05, 0x00 };
02015     static const byte md5AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02016                                          0x02, 0x05, 0x05, 0x00  };
02017     static const byte md2AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02018                                          0x02, 0x02, 0x05, 0x00};
02019 
02020     /* sigTypes */
02021     #ifndef NO_RSA
02022         static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02023                                             0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
02024         static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02025                                             0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
02026         static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02027                                             0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
02028         static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
02029                                             0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
02030         static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
02031                                             0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
02032     #endif /* NO_RSA */
02033  
02034     /* keyTypes */
02035     #ifndef NO_RSA
02036         static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02037                                             0x01, 0x01, 0x01, 0x05, 0x00};
02038     #endif /* NO_RSA */
02039 
02040     int    algoSz = 0;
02041     word32 idSz, seqSz;
02042     const  byte* algoName = 0;
02043     byte ID_Length[MAX_LENGTH_SZ];
02044     byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
02045 
02046     if (type == hashType) {
02047         switch (algoOID) {
02048         case SHAh:
02049             algoSz = sizeof(shaAlgoID);
02050             algoName = shaAlgoID;
02051             break;
02052 
02053         case SHA256h:
02054             algoSz = sizeof(sha256AlgoID);
02055             algoName = sha256AlgoID;
02056             break;
02057 
02058         case SHA384h:
02059             algoSz = sizeof(sha384AlgoID);
02060             algoName = sha384AlgoID;
02061             break;
02062 
02063         case SHA512h:
02064             algoSz = sizeof(sha512AlgoID);
02065             algoName = sha512AlgoID;
02066             break;
02067 
02068         case MD2h:
02069             algoSz = sizeof(md2AlgoID);
02070             algoName = md2AlgoID;
02071             break;
02072 
02073         case MD5h:
02074             algoSz = sizeof(md5AlgoID);
02075             algoName = md5AlgoID;
02076             break;
02077 
02078         default:
02079             CYASSL_MSG("Unknown Hash Algo");
02080             return 0;  /* UNKOWN_HASH_E; */
02081         }
02082     }
02083     else if (type == sigType) {    /* sigType */
02084         switch (algoOID) {
02085         #ifndef NO_RSA
02086             case CTC_MD5wRSA:
02087                 algoSz = sizeof(md5wRSA_AlgoID);
02088                 algoName = md5wRSA_AlgoID;
02089                 break;
02090 
02091             case CTC_SHAwRSA:
02092                 algoSz = sizeof(shawRSA_AlgoID);
02093                 algoName = shawRSA_AlgoID;
02094                 break;
02095 
02096             case CTC_SHA256wRSA:
02097                 algoSz = sizeof(sha256wRSA_AlgoID);
02098                 algoName = sha256wRSA_AlgoID;
02099                 break;
02100 
02101             case CTC_SHA384wRSA:
02102                 algoSz = sizeof(sha384wRSA_AlgoID);
02103                 algoName = sha384wRSA_AlgoID;
02104                 break;
02105 
02106             case CTC_SHA512wRSA:
02107                 algoSz = sizeof(sha512wRSA_AlgoID);
02108                 algoName = sha512wRSA_AlgoID;
02109                 break;
02110         #endif /* NO_RSA */
02111         default:
02112             CYASSL_MSG("Unknown Signature Algo");
02113             return 0;
02114         }
02115     }
02116     else if (type == keyType) {    /* keyType */
02117         switch (algoOID) {
02118         #ifndef NO_RSA
02119             case RSAk:
02120                 algoSz = sizeof(RSA_AlgoID);
02121                 algoName = RSA_AlgoID;
02122                 break;
02123         #endif /* NO_RSA */
02124         default:
02125             CYASSL_MSG("Unknown Key Algo");
02126             return 0;
02127         }
02128     }
02129     else {
02130         CYASSL_MSG("Unknown Algo type");
02131         return 0;
02132     }
02133 
02134     idSz  = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */
02135     seqSz = SetSequence(idSz + algoSz + 1, seqArray);
02136     seqArray[seqSz++] = ASN_OBJECT_ID;
02137 
02138     XMEMCPY(output, seqArray, seqSz);
02139     XMEMCPY(output + seqSz, ID_Length, idSz);
02140     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
02141 
02142     return seqSz + idSz + algoSz;
02143 
02144 }
02145 
02146 
02147 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
02148 {
02149     byte digArray[MAX_ENCODED_DIG_SZ];
02150     byte algoArray[MAX_ALGO_SZ];
02151     byte seqArray[MAX_SEQ_SZ];
02152     word32 encDigSz, algoSz, seqSz; 
02153 
02154     encDigSz = SetDigest(digest, digSz, digArray);
02155     algoSz   = SetAlgoID(hashOID, algoArray, hashType);
02156     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
02157 
02158     XMEMCPY(out, seqArray, seqSz);
02159     XMEMCPY(out + seqSz, algoArray, algoSz);
02160     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
02161 
02162     return encDigSz + algoSz + seqSz;
02163 }
02164 
02165 
02166 /* return true (1) for Confirmation */
02167 static int ConfirmSignature(const byte* buf, word32 bufSz,
02168     const byte* key, word32 keySz, word32 keyOID,
02169     const byte* sig, word32 sigSz, word32 sigOID,
02170     void* heap)
02171 {
02172 #ifdef CYASSL_SHA512
02173     byte digest[SHA512_DIGEST_SIZE]; /* max size */
02174 #elif !defined(NO_SHA256)
02175     byte digest[SHA256_DIGEST_SIZE]; /* max size */
02176 #else
02177     byte digest[SHA_DIGEST_SIZE];    /* max size */
02178 #endif
02179     int  typeH, digestSz, ret = 0;
02180 
02181     (void)key;
02182     (void)keySz;
02183     (void)sig;
02184     (void)sigSz;
02185     (void)heap;
02186     (void)ret;
02187 
02188     switch (sigOID) {
02189 #ifndef NO_MD5
02190         case CTC_MD5wRSA:
02191         {
02192             Md5 md5;
02193             InitMd5(&md5);
02194             Md5Update(&md5, buf, bufSz);
02195             Md5Final(&md5, digest);
02196             typeH    = MD5h;
02197             digestSz = MD5_DIGEST_SIZE;
02198         }
02199         break;
02200 #endif
02201     #if defined(CYASSL_MD2)
02202         case CTC_MD2wRSA:
02203         {
02204             Md2 md2;
02205             InitMd2(&md2);
02206             Md2Update(&md2, buf, bufSz);
02207             Md2Final(&md2, digest);
02208             typeH    = MD2h;
02209             digestSz = MD2_DIGEST_SIZE;
02210         }
02211         break;
02212     #endif
02213 #ifndef NO_SHA
02214         case CTC_SHAwRSA:
02215         case CTC_SHAwDSA:
02216         case CTC_SHAwECDSA:
02217         {
02218             Sha sha;
02219             InitSha(&sha);
02220             ShaUpdate(&sha, buf, bufSz);
02221             ShaFinal(&sha, digest);
02222             typeH    = SHAh;
02223             digestSz = SHA_DIGEST_SIZE;
02224         }
02225         break;
02226 #endif
02227     #ifndef NO_SHA256
02228         case CTC_SHA256wRSA:
02229         case CTC_SHA256wECDSA:
02230         {
02231             Sha256 sha256;
02232             InitSha256(&sha256);
02233             Sha256Update(&sha256, buf, bufSz);
02234             Sha256Final(&sha256, digest);
02235             typeH    = SHA256h;
02236             digestSz = SHA256_DIGEST_SIZE;
02237         }
02238         break;
02239     #endif
02240     #ifdef CYASSL_SHA512
02241         case CTC_SHA512wRSA:
02242         case CTC_SHA512wECDSA:
02243         {
02244             Sha512 sha512;
02245             InitSha512(&sha512);
02246             Sha512Update(&sha512, buf, bufSz);
02247             Sha512Final(&sha512, digest);
02248             typeH    = SHA512h;
02249             digestSz = SHA512_DIGEST_SIZE;
02250         }
02251         break;
02252     #endif
02253     #ifdef CYASSL_SHA384
02254         case CTC_SHA384wRSA:
02255         case CTC_SHA384wECDSA:
02256         {
02257             Sha384 sha384;
02258             InitSha384(&sha384);
02259             Sha384Update(&sha384, buf, bufSz);
02260             Sha384Final(&sha384, digest);
02261             typeH    = SHA384h;
02262             digestSz = SHA384_DIGEST_SIZE;
02263         }
02264         break;
02265     #endif
02266         default:
02267             CYASSL_MSG("Verify Signautre has unsupported type");
02268             return 0;
02269     }
02270 
02271     switch (keyOID) {
02272     #ifndef NO_RSA
02273         case RSAk:
02274         {
02275             RsaKey pubKey;
02276             byte   encodedSig[MAX_ENCODED_SIG_SZ];
02277             byte   plain[MAX_ENCODED_SIG_SZ];
02278             word32 idx = 0;
02279             int    encodedSigSz, verifySz;
02280             byte*  out;
02281 
02282             if (sigSz > MAX_ENCODED_SIG_SZ) {
02283                 CYASSL_MSG("Verify Signautre is too big");
02284                 return 0;
02285             }
02286                 
02287             InitRsaKey(&pubKey, heap);
02288             if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) {
02289                 CYASSL_MSG("ASN Key decode error RSA");
02290                 ret = 0;
02291             }
02292             else {
02293                 XMEMCPY(plain, sig, sigSz);
02294                 if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out,
02295                                                &pubKey)) < 0) {
02296                     CYASSL_MSG("Rsa SSL verify error");
02297                     ret = 0;
02298                 }
02299                 else {
02300                     /* make sure we're right justified */
02301                     encodedSigSz =
02302                         EncodeSignature(encodedSig, digest, digestSz, typeH);
02303                     if (encodedSigSz != verifySz ||
02304                                 XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
02305                         CYASSL_MSG("Rsa SSL verify match encode error");
02306                         ret = 0;
02307                     }
02308                     else
02309                         ret = 1; /* match */
02310 
02311                     #ifdef CYASSL_DEBUG_ENCODING
02312                     {
02313                     int x;
02314                     printf("cyassl encodedSig:\n");
02315                     for (x = 0; x < encodedSigSz; x++) {
02316                         printf("%02x ", encodedSig[x]);
02317                         if ( (x % 16) == 15)
02318                             printf("\n");
02319                     }
02320                     printf("\n");
02321                     printf("actual digest:\n");
02322                     for (x = 0; x < verifySz; x++) {
02323                         printf("%02x ", out[x]);
02324                         if ( (x % 16) == 15)
02325                             printf("\n");
02326                     }
02327                     printf("\n");
02328                     }
02329                     #endif /* CYASSL_DEBUG_ENCODING */
02330                 }
02331             }
02332             FreeRsaKey(&pubKey);
02333             return ret;
02334         }
02335 
02336     #endif /* NO_RSA */
02337     #ifdef HAVE_ECC
02338         case ECDSAk:
02339         {
02340             ecc_key pubKey;
02341             int     verify = 0;
02342             
02343             if (ecc_import_x963(key, keySz, &pubKey) < 0) {
02344                 CYASSL_MSG("ASN Key import error ECC");
02345                 return 0;
02346             }
02347         
02348             ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey);
02349             ecc_free(&pubKey);
02350             if (ret == 0 && verify == 1)
02351                 return 1;  /* match */
02352 
02353             CYASSL_MSG("ECC Verify didn't match");
02354             return 0;
02355         }
02356     #endif /* HAVE_ECC */
02357         default:
02358             CYASSL_MSG("Verify Key type unknown");
02359             return 0;
02360     }
02361 }
02362 
02363 
02364 static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
02365 {
02366     word32 idx = 0;
02367     int length = 0;
02368 
02369     CYASSL_ENTER("DecodeAltNames");
02370 
02371     if (GetSequence(input, &idx, &length, sz) < 0) {
02372         CYASSL_MSG("\tBad Sequence");
02373         return;
02374     }
02375 
02376     while (length > 0) {
02377         DNS_entry* entry;
02378         int        strLen;
02379         byte       b = input[idx++];
02380 
02381         length--;
02382 
02383         if (b != (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
02384             CYASSL_MSG("\tNot DNS type");
02385             return;
02386         }
02387 
02388         if (GetLength(input, &idx, &strLen, sz) < 0) {
02389             CYASSL_MSG("\tfail: str length");
02390             return;
02391         }
02392 
02393         entry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
02394                                     DYNAMIC_TYPE_ALTNAME);
02395         if (entry == NULL) {
02396             CYASSL_MSG("\tOut of Memory");
02397             return;
02398         }
02399 
02400         entry->name = (char*)XMALLOC(strLen + 1, cert->heap,
02401                                      DYNAMIC_TYPE_ALTNAME);
02402         if (entry->name == NULL) {
02403             CYASSL_MSG("\tOut of Memory");
02404             XFREE(entry, cert->heap, DYNAMIC_TYPE_ALTNAME);
02405             return;
02406         }
02407 
02408         XMEMCPY(entry->name, &input[idx], strLen);
02409         entry->name[strLen] = '\0';
02410 
02411         entry->next    = cert->altNames;
02412         cert->altNames = entry;
02413 
02414         length -= strLen;
02415         idx    += strLen;
02416     }   
02417 }
02418 
02419 
02420 static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
02421 {
02422     word32 idx = 0;
02423     int length = 0;
02424 
02425     CYASSL_ENTER("DecodeBasicCaConstraint");
02426     if (GetSequence(input, &idx, &length, sz) < 0) return;
02427 
02428     if (length == 0) return;
02429     /* If the basic ca constraint is false, this extension may be named, but
02430      * left empty. So, if the length is 0, just return. */
02431 
02432     if (input[idx++] != ASN_BOOLEAN)
02433     {
02434         CYASSL_MSG("\tfail: constraint not BOOLEAN");
02435         return;
02436     }
02437 
02438     if (GetLength(input, &idx, &length, sz) < 0)
02439     {
02440         CYASSL_MSG("\tfail: length");
02441         return;
02442     }
02443 
02444     if (input[idx])
02445         cert->isCA = 1;
02446 }
02447 
02448 
02449 #define CRLDP_FULL_NAME 0
02450     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
02451 #define GENERALNAME_URI 6
02452     /* From RFC3280 SS4.2.1.7, GeneralName */
02453 
02454 static void DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
02455 {
02456     word32 idx = 0;
02457     int length = 0;
02458 
02459     CYASSL_ENTER("DecodeCrlDist");
02460 
02461     /* Unwrap the list of Distribution Points*/
02462     if (GetSequence(input, &idx, &length, sz) < 0) return;
02463 
02464     /* Unwrap a single Distribution Point */
02465     if (GetSequence(input, &idx, &length, sz) < 0) return;
02466 
02467     /* The Distribution Point has three explicit optional members
02468      *  First check for a DistributionPointName
02469      */
02470     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
02471     {
02472         idx++;
02473         if (GetLength(input, &idx, &length, sz) < 0) return;
02474 
02475         if (input[idx] == 
02476                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
02477         {
02478             idx++;
02479             if (GetLength(input, &idx, &length, sz) < 0) return;
02480 
02481             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
02482             {
02483                 idx++;
02484                 if (GetLength(input, &idx, &length, sz) < 0) return;
02485 
02486                 cert->extCrlInfoSz = length;
02487                 cert->extCrlInfo = input + idx;
02488                 idx += length;
02489             }
02490             else
02491                 /* This isn't a URI, skip it. */
02492                 idx += length;
02493         }
02494         else
02495             /* This isn't a FULLNAME, skip it. */
02496             idx += length;
02497     }
02498 
02499     /* Check for reasonFlags */
02500     if (idx < (word32)sz &&
02501         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
02502     {
02503         idx++;
02504         if (GetLength(input, &idx, &length, sz) < 0) return;
02505         idx += length;
02506     }
02507 
02508     /* Check for cRLIssuer */
02509     if (idx < (word32)sz &&
02510         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
02511     {
02512         idx++;
02513         if (GetLength(input, &idx, &length, sz) < 0) return;
02514         idx += length;
02515     }
02516 
02517     if (idx < (word32)sz)
02518     {
02519         CYASSL_MSG("\tThere are more CRL Distribution Point records, "
02520                    "but we only use the first one.");
02521     }
02522 
02523     return;
02524 }
02525 
02526 
02527 static void DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
02528 /*
02529  *  Read the first of the Authority Information Access records. If there are
02530  *  any issues, return without saving the record.
02531  */
02532 {
02533     word32 idx = 0;
02534     int length = 0;
02535     word32 oid;
02536 
02537     /* Unwrap the list of AIAs */
02538     if (GetSequence(input, &idx, &length, sz) < 0) return;
02539 
02540     /* Unwrap a single AIA */
02541     if (GetSequence(input, &idx, &length, sz) < 0) return;
02542 
02543     oid = 0;
02544     if (GetObjectId(input, &idx, &oid, sz) < 0) return;
02545 
02546     /* Only supporting URIs right now. */
02547     if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
02548     {
02549         idx++;
02550         if (GetLength(input, &idx, &length, sz) < 0) return;
02551 
02552         cert->extAuthInfoSz = length;
02553         cert->extAuthInfo = input + idx;
02554         idx += length;
02555     }
02556     else
02557     {
02558         /* Skip anything else. */
02559         idx++;
02560         if (GetLength(input, &idx, &length, sz) < 0) return;
02561         idx += length;
02562     }
02563 
02564     if (idx < (word32)sz)
02565     {
02566         CYASSL_MSG("\tThere are more Authority Information Access records, "
02567                    "but we only use first one.");
02568     }
02569 
02570     return;
02571 }
02572 
02573 
02574 static void DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
02575 {
02576     word32 idx = 0;
02577     int length = 0;
02578 
02579     CYASSL_ENTER("DecodeAuthKeyId");
02580 
02581     if (GetSequence(input, &idx, &length, sz) < 0) {
02582         CYASSL_MSG("\tfail: should be a SEQUENCE\n");
02583         return;
02584     }
02585 
02586     if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
02587         CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n");
02588     }
02589 
02590     if (GetLength(input, &idx, &length, sz) < 0) {
02591         CYASSL_MSG("\tfail: extension data length");
02592         return;
02593     }
02594 
02595     if (length == SHA_SIZE) {
02596         XMEMCPY(cert->extAuthKeyId, input + idx, length);
02597     }
02598     else {
02599         Sha sha;
02600         InitSha(&sha);
02601         ShaUpdate(&sha, input + idx, length);
02602         ShaFinal(&sha, cert->extAuthKeyId);
02603     }
02604     cert->extAuthKeyIdSet = 1;
02605 
02606     return;
02607 }
02608 
02609 
02610 static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
02611 {
02612     word32 idx = 0;
02613     int length = 0;
02614 
02615     CYASSL_ENTER("DecodeSubjKeyId");
02616 
02617     if (input[idx++] != ASN_OCTET_STRING) {
02618         CYASSL_MSG("\tfail: should be an OCTET STRING");
02619         return;
02620     }
02621 
02622     if (GetLength(input, &idx, &length, sz) < 0) {
02623         CYASSL_MSG("\tfail: extension data length");
02624         return;
02625     }
02626 
02627     if (length == SIGNER_DIGEST_SIZE) {
02628         XMEMCPY(cert->extSubjKeyId, input + idx, length);
02629     }
02630     else {
02631         Sha sha;
02632         InitSha(&sha);
02633         ShaUpdate(&sha, input + idx, length);
02634         ShaFinal(&sha, cert->extSubjKeyId);
02635     }
02636     cert->extSubjKeyIdSet = 1;
02637 
02638     return;
02639 }
02640 
02641 
02642 static void DecodeCertExtensions(DecodedCert* cert)
02643 /*
02644  *  Processing the Certificate Extensions. This does not modify the current
02645  *  index. It is works starting with the recorded extensions pointer.
02646  */
02647 {
02648     word32 idx = 0;
02649     int sz = cert->extensionsSz;
02650     byte* input = cert->extensions;
02651     int length;
02652     word32 oid;
02653 
02654     CYASSL_ENTER("DecodeCertExtensions");
02655 
02656     if (input == NULL || sz == 0) return;
02657 
02658     if (input[idx++] != ASN_EXTENSIONS) return;
02659 
02660     if (GetLength(input, &idx, &length, sz) < 0) return;
02661 
02662     if (GetSequence(input, &idx, &length, sz) < 0) return;
02663     
02664     while (idx < (word32)sz) {
02665         if (GetSequence(input, &idx, &length, sz) < 0) {
02666             CYASSL_MSG("\tfail: should be a SEQUENCE");
02667             return;
02668         }
02669 
02670         oid = 0;
02671         if (GetObjectId(input, &idx, &oid, sz) < 0) {
02672             CYASSL_MSG("\tfail: OBJECT ID");
02673             return;
02674         }
02675 
02676         /* check for critical flag */
02677         if (input[idx] == ASN_BOOLEAN) {
02678             CYASSL_MSG("\tfound optional critical flag, moving past");
02679             idx += (ASN_BOOL_SIZE + 1);
02680         }
02681 
02682         /* process the extension based on the OID */
02683         if (input[idx++] != ASN_OCTET_STRING) {
02684             CYASSL_MSG("\tfail: should be an OCTET STRING");
02685             return;
02686         }
02687 
02688         if (GetLength(input, &idx, &length, sz) < 0) {
02689             CYASSL_MSG("\tfail: extension data length");
02690             return;
02691         }
02692 
02693         switch (oid) {
02694             case BASIC_CA_OID:
02695                 DecodeBasicCaConstraint(&input[idx], length, cert);
02696                 break;
02697 
02698             case CRL_DIST_OID:
02699                 DecodeCrlDist(&input[idx], length, cert);
02700                 break;
02701 
02702             case AUTH_INFO_OID:
02703                 DecodeAuthInfo(&input[idx], length, cert);
02704                 break;
02705 
02706             case ALT_NAMES_OID:
02707                 DecodeAltNames(&input[idx], length, cert);
02708 
02709             case AUTH_KEY_OID:
02710                 DecodeAuthKeyId(&input[idx], length, cert);
02711                 break;
02712 
02713             case SUBJ_KEY_OID:
02714                 DecodeSubjKeyId(&input[idx], length, cert);
02715                 break;
02716 
02717             default:
02718                 CYASSL_MSG("\tExtension type not handled, skipping");
02719                 break;
02720         }
02721         idx += length;
02722     }
02723 
02724     return;
02725 }
02726 
02727 
02728 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
02729 {
02730     int   ret;
02731     char* ptr;
02732 
02733     ret = ParseCertRelative(cert, type, verify, cm);
02734     if (ret < 0)
02735         return ret;
02736 
02737     if (cert->subjectCNLen > 0) {
02738         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
02739                               DYNAMIC_TYPE_SUBJECT_CN);
02740         if (ptr == NULL)
02741             return MEMORY_E;
02742         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
02743         ptr[cert->subjectCNLen] = '\0';
02744         cert->subjectCN = ptr;
02745         cert->subjectCNStored = 1;
02746     }
02747 
02748     if (cert->keyOID == RSAk && cert->pubKeySize > 0) {
02749         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
02750                               DYNAMIC_TYPE_PUBLIC_KEY);
02751         if (ptr == NULL)
02752             return MEMORY_E;
02753         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
02754         cert->publicKey = (byte *)ptr;
02755         cert->pubKeyStored = 1;
02756     }
02757 
02758     return ret;
02759 }
02760 
02761 
02762 /* from SSL proper, for locking can't do find here anymore */
02763 #ifdef __cplusplus
02764     extern "C" {
02765 #endif
02766     CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
02767     #ifndef NO_SKID
02768         CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
02769     #endif
02770 #ifdef __cplusplus
02771     } 
02772 #endif
02773 
02774 
02775 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
02776 {
02777     word32 confirmOID;
02778     int    ret;
02779     int    badDate = 0;
02780 
02781     if ((ret = DecodeToKey(cert, verify)) < 0) {
02782         if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
02783             badDate = ret;
02784         else
02785             return ret;
02786     }
02787 
02788     if (cert->srcIdx != cert->sigIndex) {
02789         if (cert->srcIdx < cert->sigIndex) {
02790             /* save extensions */
02791             cert->extensions    = &cert->source[cert->srcIdx];
02792             cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
02793             cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
02794         }
02795         DecodeCertExtensions(cert);
02796         /* advance past extensions */
02797         cert->srcIdx =  cert->sigIndex;
02798     }
02799 
02800     if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
02801                          cert->maxIdx)) < 0)
02802         return ret;
02803 
02804     if ((ret = GetSignature(cert)) < 0)
02805         return ret;
02806 
02807     if (confirmOID != cert->signatureOID)
02808         return ASN_SIG_OID_E;
02809 
02810     #ifndef NO_SKID
02811         if (cert->extSubjKeyIdSet == 0) {
02812             Sha sha;
02813             InitSha(&sha);
02814             ShaUpdate(&sha, cert->publicKey, cert->pubKeySize);
02815             ShaFinal(&sha, cert->extSubjKeyId);
02816             cert->extSubjKeyIdSet = 1;
02817         }
02818     #endif
02819 
02820     if (verify && type != CA_TYPE) {
02821         Signer* ca = NULL;
02822         #ifndef NO_SKID
02823             if (cert->extAuthKeyIdSet)
02824                 ca = GetCA(cm, cert->extAuthKeyId);
02825             if (ca == NULL)
02826                 ca = GetCAByName(cm, cert->issuerHash);
02827         #else /* NO_SKID */
02828             ca = GetCA(cm, cert->issuerHash);
02829         #endif /* NO SKID */
02830         CYASSL_MSG("About to verify certificate signature");
02831  
02832         if (ca) {
02833 #ifdef HAVE_OCSP
02834             /* Need the ca's public key hash for OCSP */
02835             {
02836                 Sha sha;
02837                 InitSha(&sha);
02838                 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize);
02839                 ShaFinal(&sha, cert->issuerKeyHash);
02840             }
02841 #endif /* HAVE_OCSP */
02842             /* try to confirm/verify signature */
02843             if (!ConfirmSignature(cert->source + cert->certBegin,
02844                         cert->sigIndex - cert->certBegin,
02845                     ca->publicKey, ca->pubKeySize, ca->keyOID,
02846                     cert->signature, cert->sigLength, cert->signatureOID,
02847                     cert->heap)) {
02848                 CYASSL_MSG("Confirm signature failed");
02849                 return ASN_SIG_CONFIRM_E;
02850             }
02851         }
02852         else {
02853             /* no signer */
02854             CYASSL_MSG("No CA signer to verify with");
02855             return ASN_NO_SIGNER_E;
02856         }
02857     }
02858 
02859     if (badDate != 0)
02860         return badDate;
02861 
02862     return 0;
02863 }
02864 
02865 
02866 /* Create and init an new signer */
02867 Signer* MakeSigner(void* heap)
02868 {
02869     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
02870                                        DYNAMIC_TYPE_SIGNER);
02871     if (signer) {
02872         signer->pubKeySize = 0;
02873         signer->keyOID     = 0;
02874         signer->publicKey  = NULL;
02875         signer->nameLen    = 0;
02876         signer->name       = NULL;
02877         signer->next       = NULL;
02878     }
02879     (void)heap;
02880 
02881     return signer;
02882 }
02883 
02884 
02885 /* Free an individual signer */
02886 void FreeSigner(Signer* signer, void* heap)
02887 {
02888     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
02889     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
02890     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
02891 
02892     (void)heap;
02893 }
02894 
02895 
02896 /* Free the whole singer table with number of rows */
02897 void FreeSignerTable(Signer** table, int rows, void* heap)
02898 {
02899     int i;
02900 
02901     for (i = 0; i < rows; i++) {
02902         Signer* signer = table[i];
02903         while (signer) {
02904             Signer* next = signer->next;
02905             FreeSigner(signer, heap);
02906             signer = next;
02907         }
02908         table[i] = NULL;
02909     }
02910 }
02911 
02912 
02913 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
02914 
02915 static int SetMyVersion(word32 version, byte* output, int header)
02916 {
02917     int i = 0;
02918 
02919     if (header) {
02920         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
02921         output[i++] = ASN_BIT_STRING;
02922     }
02923     output[i++] = ASN_INTEGER;
02924     output[i++] = 0x01;
02925     output[i++] = (byte)version;
02926 
02927     return i;
02928 }
02929 
02930 
02931 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
02932              int type)
02933 {
02934     char header[80];
02935     char footer[80];
02936 
02937     int headerLen;
02938     int footerLen;
02939     int i;
02940     int err;
02941     int outLen;   /* return length or error */
02942 
02943     if (type == CERT_TYPE) {
02944         XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header));
02945         XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer));
02946     }
02947     else if (type == PRIVATEKEY_TYPE) {
02948         XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header));
02949         XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer));
02950     }
02951     #ifdef HAVE_ECC
02952     else if (type == ECC_PRIVATEKEY_TYPE) {
02953         XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", sizeof(header));
02954         XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", sizeof(footer));
02955     }
02956     #endif
02957     else
02958         return BAD_FUNC_ARG;
02959 
02960     headerLen = (int)XSTRLEN(header);
02961     footerLen = (int)XSTRLEN(footer);
02962 
02963     if (!der || !output)
02964         return BAD_FUNC_ARG;
02965 
02966     /* don't even try if outSz too short */
02967     if (outSz < headerLen + footerLen + derSz)
02968         return BAD_FUNC_ARG;
02969 
02970     /* header */
02971     XMEMCPY(output, header, headerLen);
02972     i = headerLen;
02973 
02974     /* body */
02975     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
02976     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0)
02977         return err;
02978     i += outLen;
02979 
02980     /* footer */
02981     if ( (i + footerLen) > (int)outSz)
02982         return BAD_FUNC_ARG;
02983     XMEMCPY(output + i, footer, footerLen);
02984 
02985     return outLen + headerLen + footerLen;
02986 }
02987 
02988 
02989 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
02990 
02991 
02992 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA)
02993 
02994 
02995 static mp_int* GetRsaInt(RsaKey* key, int idx)
02996 {
02997     if (idx == 0)
02998         return &key->n;
02999     if (idx == 1)
03000         return &key->e;
03001     if (idx == 2)
03002         return &key->d;
03003     if (idx == 3)
03004         return &key->p;
03005     if (idx == 4)
03006         return &key->q;
03007     if (idx == 5)
03008         return &key->dP;
03009     if (idx == 6)
03010         return &key->dQ;
03011     if (idx == 7)
03012         return &key->u;
03013 
03014     return NULL;
03015 }
03016 
03017 
03018 /* Release Tmp RSA resources */
03019 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
03020 {
03021     int i;
03022 
03023     (void)heap;
03024 
03025     for (i = 0; i < RSA_INTS; i++) 
03026         XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
03027 }
03028 
03029 
03030 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
03031    written */
03032 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
03033 {
03034     word32 seqSz, verSz, rawLen, intTotalLen = 0;
03035     word32 sizes[RSA_INTS];
03036     int    i, j, outLen, ret = 0;
03037 
03038     byte  seq[MAX_SEQ_SZ];
03039     byte  ver[MAX_VERSION_SZ];
03040     byte* tmps[RSA_INTS];
03041 
03042     if (!key || !output)
03043         return BAD_FUNC_ARG;
03044 
03045     if (key->type != RSA_PRIVATE)
03046         return BAD_FUNC_ARG;
03047 
03048     for (i = 0; i < RSA_INTS; i++)
03049         tmps[i] = NULL;
03050 
03051     /* write all big ints from key to DER tmps */
03052     for (i = 0; i < RSA_INTS; i++) {
03053         mp_int* keyInt = GetRsaInt(key, i);
03054         rawLen = mp_unsigned_bin_size(keyInt);
03055         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
03056                                  DYNAMIC_TYPE_RSA);
03057         if (tmps[i] == NULL) {
03058             ret = MEMORY_E;
03059             break;
03060         }
03061 
03062         tmps[i][0] = ASN_INTEGER;
03063         sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1;  /* int tag */
03064 
03065         if (sizes[i] <= MAX_SEQ_SZ) {
03066             int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
03067             if (err == MP_OKAY) {
03068                 sizes[i] += rawLen;
03069                 intTotalLen += sizes[i];
03070             }
03071             else {
03072                 ret = err;
03073                 break;
03074             }
03075         }
03076         else {
03077             ret = ASN_INPUT_E;
03078             break;
03079         }
03080     }
03081 
03082     if (ret != 0) {
03083         FreeTmpRsas(tmps, key->heap);
03084         return ret;
03085     }
03086 
03087     /* make headers */
03088     verSz = SetMyVersion(0, ver, FALSE);
03089     seqSz = SetSequence(verSz + intTotalLen, seq);
03090 
03091     outLen = seqSz + verSz + intTotalLen;
03092     if (outLen > (int)inLen)
03093         return BAD_FUNC_ARG;
03094 
03095     /* write to output */
03096     XMEMCPY(output, seq, seqSz);
03097     j = seqSz;
03098     XMEMCPY(output + j, ver, verSz);
03099     j += verSz;
03100 
03101     for (i = 0; i < RSA_INTS; i++) {
03102         XMEMCPY(output + j, tmps[i], sizes[i]);
03103         j += sizes[i];
03104     }
03105     FreeTmpRsas(tmps, key->heap);
03106 
03107     return outLen;
03108 }
03109 
03110 #endif /* CYASSL_KEY_GEN && !NO_RSA */
03111 
03112 
03113 #if defined(CYASSL_CERT_GEN) && !defined(NO_RSA)
03114 
03115 
03116 #ifndef min
03117 
03118     static INLINE word32 min(word32 a, word32 b)
03119     {
03120         return a > b ? b : a;
03121     }
03122 
03123 #endif /* min */
03124 
03125 
03126 /* Initialize and Set Certficate defaults:
03127    version    = 3 (0x2)
03128    serial     = 0
03129    sigType    = SHA_WITH_RSA
03130    issuer     = blank
03131    daysValid  = 500
03132    selfSigned = 1 (true) use subject as issuer
03133    subject    = blank
03134 */
03135 void InitCert(Cert* cert)
03136 {
03137     cert->version    = 2;   /* version 3 is hex 2 */
03138     cert->sigType    = CTC_SHAwRSA;
03139     cert->daysValid  = 500;
03140     cert->selfSigned = 1;
03141     cert->isCA       = 0;
03142     cert->bodySz     = 0;
03143 #ifdef CYASSL_ALT_NAMES
03144     cert->altNamesSz   = 0;
03145     cert->beforeDateSz = 0;
03146     cert->afterDateSz  = 0;
03147 #endif
03148     cert->keyType    = RSA_KEY;
03149     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
03150 
03151     cert->issuer.country[0] = '\0';
03152     cert->issuer.state[0] = '\0';
03153     cert->issuer.locality[0] = '\0';
03154     cert->issuer.sur[0] = '\0';
03155     cert->issuer.org[0] = '\0';
03156     cert->issuer.unit[0] = '\0';
03157     cert->issuer.commonName[0] = '\0';
03158     cert->issuer.email[0] = '\0';
03159 
03160     cert->subject.country[0] = '\0';
03161     cert->subject.state[0] = '\0';
03162     cert->subject.locality[0] = '\0';
03163     cert->subject.sur[0] = '\0';
03164     cert->subject.org[0] = '\0';
03165     cert->subject.unit[0] = '\0';
03166     cert->subject.commonName[0] = '\0';
03167     cert->subject.email[0] = '\0';
03168 }
03169 
03170 
03171 /* DER encoded x509 Certificate */
03172 typedef struct DerCert {
03173     byte size[MAX_LENGTH_SZ];          /* length encoded */
03174     byte version[MAX_VERSION_SZ];      /* version encoded */
03175     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
03176     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
03177     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
03178     byte subject[ASN_NAME_MAX];        /* subject encoded */
03179     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
03180     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
03181     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
03182     byte extensions[MAX_EXTENSIONS_SZ];  /* all extensions */
03183     int  sizeSz;                       /* encoded size length */
03184     int  versionSz;                    /* encoded version length */
03185     int  serialSz;                     /* encoded serial length */
03186     int  sigAlgoSz;                    /* enocded sig alog length */
03187     int  issuerSz;                     /* encoded issuer length */
03188     int  subjectSz;                    /* encoded subject length */
03189     int  validitySz;                   /* encoded validity length */
03190     int  publicKeySz;                  /* encoded public key length */
03191     int  caSz;                         /* encoded CA extension length */
03192     int  extensionsSz;                 /* encoded extensions total length */
03193     int  total;                        /* total encoded lengths */
03194 } DerCert;
03195 
03196 
03197 /* Write a set header to output */
03198 static word32 SetSet(word32 len, byte* output)
03199 {
03200     output[0] = ASN_SET | ASN_CONSTRUCTED;
03201     return SetLength(len, output + 1) + 1;
03202 }
03203 
03204 
03205 /* Write a serial number to output */
03206 static int SetSerial(const byte* serial, byte* output)
03207 {
03208     int length = 0;
03209 
03210     output[length++] = ASN_INTEGER;
03211     length += SetLength(CTC_SERIAL_SIZE, &output[length]);
03212     XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
03213 
03214     return length + CTC_SERIAL_SIZE;
03215 }
03216 
03217 
03218 /* Write a public RSA key to output */
03219 static int SetPublicKey(byte* output, RsaKey* key)
03220 {
03221     byte n[MAX_RSA_INT_SZ];
03222     byte e[MAX_RSA_E_SZ];
03223     byte algo[MAX_ALGO_SZ];
03224     byte seq[MAX_SEQ_SZ];
03225     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
03226     int  nSz;
03227     int  eSz;
03228     int  algoSz;
03229     int  seqSz;
03230     int  lenSz;
03231     int  idx;
03232     int  rawLen;
03233 
03234     /* n */
03235     rawLen = mp_unsigned_bin_size(&key->n);
03236     n[0] = ASN_INTEGER;
03237     nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
03238 
03239     if ( (nSz + rawLen) < (int)sizeof(n)) {
03240         int err = mp_to_unsigned_bin(&key->n, n + nSz);
03241         if (err == MP_OKAY)
03242             nSz += rawLen;
03243         else
03244             return MP_TO_E;
03245     }
03246     else
03247         return BUFFER_E;
03248 
03249     /* e */
03250     rawLen = mp_unsigned_bin_size(&key->e);
03251     e[0] = ASN_INTEGER;
03252     eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
03253 
03254     if ( (eSz + rawLen) < (int)sizeof(e)) {
03255         int err = mp_to_unsigned_bin(&key->e, e + eSz);
03256         if (err == MP_OKAY)
03257             eSz += rawLen;
03258         else
03259             return MP_TO_E;
03260     }
03261     else
03262         return BUFFER_E;
03263 
03264     /* headers */
03265     algoSz = SetAlgoID(RSAk, algo, keyType);
03266     seqSz  = SetSequence(nSz + eSz, seq);
03267     lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
03268     len[lenSz++] = 0;   /* trailing 0 */
03269 
03270     /* write */
03271     idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
03272         /* 1 is for ASN_BIT_STRING */
03273     /* algo */
03274     XMEMCPY(output + idx, algo, algoSz);
03275     idx += algoSz;
03276     /* bit string */
03277     output[idx++] = ASN_BIT_STRING;
03278     /* length */
03279     XMEMCPY(output + idx, len, lenSz);
03280     idx += lenSz;
03281     /* seq */
03282     XMEMCPY(output + idx, seq, seqSz);
03283     idx += seqSz;
03284     /* n */
03285     XMEMCPY(output + idx, n, nSz);
03286     idx += nSz;
03287     /* e */
03288     XMEMCPY(output + idx, e, eSz);
03289     idx += eSz;
03290 
03291     return idx;
03292 }
03293 
03294 
03295 static INLINE byte itob(int number)
03296 {
03297     return (byte)number + 0x30;
03298 }
03299 
03300 
03301 /* write time to output, format */
03302 static void SetTime(struct tm* date, byte* output)
03303 {
03304     int i = 0;
03305 
03306     output[i++] = itob((date->tm_year % 10000) / 1000);
03307     output[i++] = itob((date->tm_year % 1000)  /  100);
03308     output[i++] = itob((date->tm_year % 100)   /   10);
03309     output[i++] = itob( date->tm_year % 10);
03310 
03311     output[i++] = itob(date->tm_mon / 10);
03312     output[i++] = itob(date->tm_mon % 10);
03313 
03314     output[i++] = itob(date->tm_mday / 10);
03315     output[i++] = itob(date->tm_mday % 10);
03316 
03317     output[i++] = itob(date->tm_hour / 10);
03318     output[i++] = itob(date->tm_hour % 10);
03319 
03320     output[i++] = itob(date->tm_min / 10);
03321     output[i++] = itob(date->tm_min % 10);
03322 
03323     output[i++] = itob(date->tm_sec / 10);
03324     output[i++] = itob(date->tm_sec % 10);
03325     
03326     output[i] = 'Z';  /* Zulu profile */
03327 }
03328 
03329 
03330 #ifdef CYASSL_ALT_NAMES
03331 
03332 /* Copy Dates from cert, return bytes written */
03333 static int CopyValidity(byte* output, Cert* cert)
03334 {
03335     int seqSz;
03336 
03337     CYASSL_ENTER("CopyValidity");
03338 
03339     /* headers and output */
03340     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
03341     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
03342     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
03343                                                  cert->afterDateSz);
03344     return seqSz + cert->beforeDateSz + cert->afterDateSz;
03345 }
03346 
03347 #endif
03348 
03349 
03350 /* Set Date validity from now until now + daysValid */
03351 static int SetValidity(byte* output, int daysValid)
03352 {
03353     byte before[MAX_DATE_SIZE];
03354     byte  after[MAX_DATE_SIZE];
03355 
03356     int beforeSz;
03357     int afterSz;
03358     int seqSz;
03359 
03360     time_t     ticks;
03361     struct tm* now;
03362     struct tm  local;
03363 
03364     ticks = XTIME(0);
03365     now   = XGMTIME(&ticks);
03366 
03367     /* before now */
03368     local = *now;
03369     before[0] = ASN_GENERALIZED_TIME;
03370     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
03371 
03372     /* subtract 1 day for more compliance */
03373     local.tm_mday -= 1;
03374     mktime(&local);
03375 
03376     /* adjust */
03377     local.tm_year += 1900;
03378     local.tm_mon  +=    1;
03379 
03380     SetTime(&local, before + beforeSz);
03381     beforeSz += ASN_GEN_TIME_SZ;
03382     
03383     /* after now + daysValid */
03384     local = *now;
03385     after[0] = ASN_GENERALIZED_TIME;
03386     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
03387 
03388     /* add daysValid */
03389     local.tm_mday += daysValid;
03390     mktime(&local);
03391 
03392     /* adjust */
03393     local.tm_year += 1900;
03394     local.tm_mon  +=    1;
03395 
03396     SetTime(&local, after + afterSz);
03397     afterSz += ASN_GEN_TIME_SZ;
03398 
03399     /* headers and output */
03400     seqSz = SetSequence(beforeSz + afterSz, output);
03401     XMEMCPY(output + seqSz, before, beforeSz);
03402     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
03403 
03404     return seqSz + beforeSz + afterSz;
03405 }
03406 
03407 
03408 /* ASN Encoded Name field */
03409 typedef struct EncodedName {
03410     int  nameLen;                /* actual string value length */
03411     int  totalLen;               /* total encoded length */
03412     int  type;                   /* type of name */
03413     int  used;                   /* are we actually using this one */
03414     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
03415 } EncodedName;
03416 
03417 
03418 /* Get Which Name from index */
03419 static const char* GetOneName(CertName* name, int idx)
03420 {
03421     switch (idx) {
03422     case 0:
03423        return name->country;
03424 
03425     case 1:
03426        return name->state;
03427 
03428     case 2:
03429        return name->locality;
03430 
03431     case 3:
03432        return name->sur;
03433 
03434     case 4:
03435        return name->org;
03436 
03437     case 5:
03438        return name->unit;
03439 
03440     case 6:
03441        return name->commonName;
03442 
03443     case 7:
03444        return name->email;
03445 
03446     default:
03447        return 0;
03448     }
03449 }
03450 
03451 
03452 /* Get ASN Name from index */
03453 static byte GetNameId(int idx)
03454 {
03455     switch (idx) {
03456     case 0:
03457        return ASN_COUNTRY_NAME;
03458 
03459     case 1:
03460        return ASN_STATE_NAME;
03461 
03462     case 2:
03463        return ASN_LOCALITY_NAME;
03464 
03465     case 3:
03466        return ASN_SUR_NAME;
03467 
03468     case 4:
03469        return ASN_ORG_NAME;
03470 
03471     case 5:
03472        return ASN_ORGUNIT_NAME;
03473 
03474     case 6:
03475        return ASN_COMMON_NAME;
03476 
03477     case 7:
03478        /* email uses different id type */
03479        return 0;
03480 
03481     default:
03482        return 0;
03483     }
03484 }
03485 
03486 
03487 /* encode all extensions, return total bytes written */
03488 static int SetExtensions(byte* output, const byte* ext, int extSz)
03489 {
03490     byte sequence[MAX_SEQ_SZ];
03491     byte len[MAX_LENGTH_SZ];
03492 
03493     int sz = 0;
03494     int seqSz = SetSequence(extSz, sequence);
03495     int lenSz = SetLength(seqSz + extSz, len);
03496 
03497     output[0] = ASN_EXTENSIONS; /* extensions id */
03498     sz++;
03499     XMEMCPY(&output[sz], len, lenSz);  /* length */
03500     sz += lenSz; 
03501     XMEMCPY(&output[sz], sequence, seqSz);  /* sequence */
03502     sz += seqSz;
03503     XMEMCPY(&output[sz], ext, extSz);  /* extensions */
03504     sz += extSz;
03505 
03506     return sz;
03507 }
03508 
03509 
03510 /* encode CA basic constraint true, return total bytes written */
03511 static int SetCa(byte* output)
03512 {
03513     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
03514                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
03515     
03516     XMEMCPY(output, ca, sizeof(ca));
03517 
03518     return (int)sizeof(ca);
03519 }
03520 
03521 
03522 /* encode CertName into output, return total bytes written */
03523 static int SetName(byte* output, CertName* name)
03524 {
03525     int         totalBytes = 0, i, idx;
03526     EncodedName names[NAME_ENTRIES];
03527 
03528     for (i = 0; i < NAME_ENTRIES; i++) {
03529         const char* nameStr = GetOneName(name, i);
03530         if (nameStr) {
03531             /* bottom up */
03532             byte firstLen[MAX_LENGTH_SZ];
03533             byte secondLen[MAX_LENGTH_SZ];
03534             byte sequence[MAX_SEQ_SZ];
03535             byte set[MAX_SET_SZ];
03536 
03537             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
03538             int strLen  = (int)XSTRLEN(nameStr);
03539             int thisLen = strLen;
03540             int firstSz, secondSz, seqSz, setSz;
03541 
03542             if (strLen == 0) { /* no user data for this item */
03543                 names[i].used = 0;
03544                 continue;
03545             }
03546 
03547             secondSz = SetLength(strLen, secondLen);
03548             thisLen += secondSz;
03549             if (email) {
03550                 thisLen += EMAIL_JOINT_LEN;
03551                 thisLen ++;                               /* id type */
03552                 firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
03553             }
03554             else {
03555                 thisLen++;                                 /* str type */
03556                 thisLen++;                                 /* id  type */
03557                 thisLen += JOINT_LEN;    
03558                 firstSz = SetLength(JOINT_LEN + 1, firstLen);
03559             }
03560             thisLen += firstSz;
03561             thisLen++;                                /* object id */
03562 
03563             seqSz = SetSequence(thisLen, sequence);
03564             thisLen += seqSz;
03565             setSz = SetSet(thisLen, set);
03566             thisLen += setSz;
03567 
03568             if (thisLen > (int)sizeof(names[i].encoded))
03569                 return BUFFER_E;
03570 
03571             /* store it */
03572             idx = 0;
03573             /* set */
03574             XMEMCPY(names[i].encoded, set, setSz);
03575             idx += setSz;
03576             /* seq */
03577             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
03578             idx += seqSz;
03579             /* asn object id */
03580             names[i].encoded[idx++] = ASN_OBJECT_ID;
03581             /* first length */
03582             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
03583             idx += firstSz;
03584             if (email) {
03585                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
03586                                            0x01, 0x09, 0x01, 0x16 };
03587                 /* email joint id */
03588                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
03589                 idx += (int)sizeof(EMAIL_OID);
03590             }
03591             else {
03592                 /* joint id */
03593                 names[i].encoded[idx++] = 0x55;
03594                 names[i].encoded[idx++] = 0x04;
03595                 /* id type */
03596                 names[i].encoded[idx++] = GetNameId(i);
03597                 /* str type */
03598                 names[i].encoded[idx++] = 0x13;
03599             }
03600             /* second length */
03601             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
03602             idx += secondSz;
03603             /* str value */
03604             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
03605             idx += strLen;
03606 
03607             totalBytes += idx;
03608             names[i].totalLen = idx;
03609             names[i].used = 1;
03610         }
03611         else
03612             names[i].used = 0;
03613     }
03614 
03615     /* header */
03616     idx = SetSequence(totalBytes, output);
03617     totalBytes += idx;
03618     if (totalBytes > ASN_NAME_MAX)
03619         return BUFFER_E;
03620 
03621     for (i = 0; i < NAME_ENTRIES; i++) {
03622         if (names[i].used) {
03623             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
03624             idx += names[i].totalLen;
03625         }
03626     }
03627     return totalBytes;
03628 }
03629 
03630 /* encode info from cert into DER enocder format */
03631 static int EncodeCert(
03632 Cert* cert, 
03633 DerCert* der, 
03634 RsaKey* rsaKey, 
03635 RNG* rng,
03636                       const byte* ntruKey, 
03637 word16 ntruSz)
03638 {
03639     (void)ntruKey;
03640     (void)ntruSz;
03641 
03642     /* init */
03643     XMEMSET(der, 0, sizeof(DerCert));
03644 
03645     /* version */
03646     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
03647 
03648     /* serial number */
03649     RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
03650     cert->serial[0] = 0x01;   /* ensure positive */
03651     der->serialSz  = SetSerial(cert->serial, der->serial);
03652 
03653     /* signature algo */
03654     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType);
03655     if (der->sigAlgoSz == 0)
03656         return ALGO_ID_E;
03657 
03658     /* public key */
03659     if (cert->keyType == RSA_KEY) {
03660         der->publicKeySz = SetPublicKey(der->publicKey, rsaKey);
03661         if (der->publicKeySz == 0)
03662             return PUBLIC_KEY_E;
03663     }
03664     else {
03665 #ifdef HAVE_NTRU
03666         word32 rc;
03667         word16 encodedSz;
03668 
03669         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
03670                                               ntruKey, &encodedSz, NULL);
03671         if (rc != NTRU_OK)
03672             return PUBLIC_KEY_E;
03673         if (encodedSz > MAX_PUBLIC_KEY_SZ)
03674             return PUBLIC_KEY_E;
03675 
03676         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
03677                               ntruKey, &encodedSz, der->publicKey);
03678         if (rc != NTRU_OK)
03679             return PUBLIC_KEY_E;
03680 
03681         der->publicKeySz = encodedSz;
03682 #endif
03683     }
03684 
03685     der->validitySz = 0;
03686 #ifdef CYASSL_ALT_NAMES
03687     /* date validity copy ? */
03688     if (cert->beforeDateSz && cert->afterDateSz) {
03689         der->validitySz = CopyValidity(der->validity, cert);
03690         if (der->validitySz == 0)
03691             return DATE_E;
03692     }
03693 #endif
03694 
03695     /* date validity */
03696     if (der->validitySz == 0) {
03697         der->validitySz = SetValidity(der->validity, cert->daysValid);
03698         if (der->validitySz == 0)
03699             return DATE_E;
03700     }
03701 
03702     /* subject name */
03703     der->subjectSz = SetName(der->subject, &cert->subject);
03704     if (der->subjectSz == 0)
03705         return SUBJECT_E;
03706 
03707     /* issuer name */
03708     der->issuerSz = SetName(der->issuer, cert->selfSigned ?
03709              &cert->subject : &cert->issuer);
03710     if (der->issuerSz == 0)
03711         return ISSUER_E;
03712 
03713     /* CA */
03714     if (cert->isCA) {
03715         der->caSz = SetCa(der->ca);
03716         if (der->caSz == 0)
03717             return CA_TRUE_E;
03718     }
03719     else
03720         der->caSz = 0;
03721 
03722     /* extensions, just CA now */
03723     if (cert->isCA) {
03724         der->extensionsSz = SetExtensions(der->extensions, der->ca, der->caSz);
03725         if (der->extensionsSz == 0)
03726             return EXTENSIONS_E;
03727     }
03728     else
03729         der->extensionsSz = 0;
03730 
03731 #ifdef CYASSL_ALT_NAMES
03732     if (der->extensionsSz == 0 && cert->altNamesSz) {
03733         der->extensionsSz = SetExtensions(der->extensions, cert->altNames,
03734                                           cert->altNamesSz);
03735         if (der->extensionsSz == 0)
03736             return EXTENSIONS_E;
03737     }
03738 #endif
03739 
03740     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
03741         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
03742         der->extensionsSz;
03743 
03744     return 0;
03745 }
03746 
03747 
03748 /* write DER encoded cert to buffer, size already checked */
03749 static int WriteCertBody(DerCert* der, byte* buffer)
03750 {
03751     int idx;
03752 
03753     /* signed part header */
03754     idx = SetSequence(der->total, buffer);
03755     /* version */
03756     XMEMCPY(buffer + idx, der->version, der->versionSz);
03757     idx += der->versionSz;
03758     /* serial */
03759     XMEMCPY(buffer + idx, der->serial, der->serialSz);
03760     idx += der->serialSz;
03761     /* sig algo */
03762     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
03763     idx += der->sigAlgoSz;
03764     /* issuer */
03765     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
03766     idx += der->issuerSz;
03767     /* validity */
03768     XMEMCPY(buffer + idx, der->validity, der->validitySz);
03769     idx += der->validitySz;
03770     /* subject */
03771     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
03772     idx += der->subjectSz;
03773     /* public key */
03774     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
03775     idx += der->publicKeySz;
03776     if (der->extensionsSz) {
03777         /* extensions */
03778         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
03779                                                    sizeof(der->extensions)));
03780         idx += der->extensionsSz;
03781     }
03782 
03783     return idx;
03784 }
03785 
03786 
03787 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
03788 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
03789                          RsaKey* key, RNG* rng, int sigAlgoType)
03790 {
03791     byte    digest[SHA256_DIGEST_SIZE];     /* max size */
03792     byte    encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
03793     int     encSigSz, digestSz, typeH;
03794 
03795     if (sigAlgoType == CTC_MD5wRSA) {
03796         Md5     md5;
03797         InitMd5(&md5);
03798         Md5Update(&md5, buffer, sz);
03799         Md5Final(&md5, digest);
03800         digestSz = MD5_DIGEST_SIZE;
03801         typeH    = MD5h;
03802     }
03803     else if (sigAlgoType == CTC_SHAwRSA) {
03804         Sha     sha;
03805         InitSha(&sha);
03806         ShaUpdate(&sha, buffer, sz);
03807         ShaFinal(&sha, digest);
03808         digestSz = SHA_DIGEST_SIZE;
03809         typeH    = SHAh;
03810     }
03811     else if (sigAlgoType == CTC_SHA256wRSA) {
03812         Sha256     sha256;
03813         InitSha256(&sha256);
03814         Sha256Update(&sha256, buffer, sz);
03815         Sha256Final(&sha256, digest);
03816         digestSz = SHA256_DIGEST_SIZE;
03817         typeH    = SHA256h;
03818     }
03819     else
03820         return ALGO_ID_E;
03821 
03822     /* signature */
03823     encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
03824     return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng);
03825 }
03826 
03827 
03828 /* add signature to end of buffer, size of buffer assumed checked, return
03829    new length */
03830 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
03831                         int sigAlgoType)
03832 {
03833     byte seq[MAX_SEQ_SZ];
03834     int  idx = bodySz, seqSz;
03835 
03836     /* algo */
03837     idx += SetAlgoID(sigAlgoType, buffer + idx, sigType);
03838     /* bit string */
03839     buffer[idx++] = ASN_BIT_STRING;
03840     /* length */
03841     idx += SetLength(sigSz + 1, buffer + idx);
03842     buffer[idx++] = 0;   /* trailing 0 */
03843     /* signature */
03844     XMEMCPY(buffer + idx, sig, sigSz);
03845     idx += sigSz;
03846 
03847     /* make room for overall header */
03848     seqSz = SetSequence(idx, seq);
03849     XMEMMOVE(buffer + seqSz, buffer, idx);
03850     XMEMCPY(buffer, seq, seqSz);
03851 
03852     return idx + seqSz;
03853 }
03854 
03855 
03856 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
03857 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
03858                    RsaKey* rsaKey, RNG* rng, const byte* ntruKey, word16 ntruSz)
03859 {
03860     DerCert der;
03861     int     ret;
03862 
03863     cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY;
03864     ret = EncodeCert(cert, &der, rsaKey, rng, ntruKey, ntruSz);
03865     if (ret != 0)
03866         return ret;
03867 
03868     if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
03869         return BUFFER_E;
03870 
03871     return cert->bodySz = WriteCertBody(&der, derBuffer);
03872 }
03873 
03874 
03875 /* Make an x509 Certificate v3 RSA from cert input, write to buffer */
03876 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,RNG* rng)
03877 {
03878     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, rng, NULL, 0);
03879 }
03880 
03881 
03882 #ifdef HAVE_NTRU
03883 
03884 int  MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
03885                   const byte* ntruKey, word16 keySz, RNG* rng)
03886 {
03887     return MakeAnyCert(cert, derBuffer, derSz, NULL, rng, ntruKey, keySz);
03888 }
03889 
03890 #endif /* HAVE_NTRU */
03891 
03892 
03893 int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
03894 {
03895     byte    sig[MAX_ENCODED_SIG_SZ];
03896     int     sigSz;
03897     int     bodySz = cert->bodySz;
03898 
03899     if (bodySz < 0)
03900         return bodySz;
03901 
03902     sigSz  = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng,
03903                            cert->sigType);
03904     if (sigSz < 0)
03905         return sigSz; 
03906 
03907     if (bodySz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
03908         return BUFFER_E; 
03909 
03910     return AddSignature(buffer, bodySz, sig, sigSz, cert->sigType);
03911 }
03912 
03913 
03914 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
03915 {
03916     int ret = MakeCert(cert, buffer, buffSz, key, rng);
03917 
03918     if (ret < 0)
03919         return ret;
03920 
03921     return SignCert(cert, buffer, buffSz, key, rng);
03922 }
03923 
03924 
03925 #ifdef CYASSL_ALT_NAMES 
03926 
03927 /* Set Alt Names from der cert, return 0 on success */
03928 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
03929 {
03930     DecodedCert decoded;
03931     int         ret;
03932 
03933     if (derSz < 0)
03934         return derSz;
03935 
03936     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
03937     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
03938 
03939     if (ret < 0) {
03940         FreeDecodedCert(&decoded);
03941         return ret;
03942     }
03943 
03944     if (decoded.extensions) {
03945         byte   b;
03946         int    length;
03947         word32 maxExtensionsIdx;
03948 
03949         decoded.srcIdx = decoded.extensionsIdx;
03950         b = decoded.source[decoded.srcIdx++];
03951         if (b != ASN_EXTENSIONS) {
03952             FreeDecodedCert(&decoded);
03953             return ASN_PARSE_E;
03954         }
03955 
03956         if (GetLength(decoded.source, &decoded.srcIdx, &length,
03957                       decoded.maxIdx) < 0) {
03958             FreeDecodedCert(&decoded);
03959             return ASN_PARSE_E;
03960         }
03961 
03962         if (GetSequence(decoded.source, &decoded.srcIdx, &length,
03963                         decoded.maxIdx) < 0) {
03964             FreeDecodedCert(&decoded);
03965             return ASN_PARSE_E;
03966         }
03967 
03968         maxExtensionsIdx = decoded.srcIdx + length;
03969 
03970         while (decoded.srcIdx < maxExtensionsIdx) {
03971             word32 oid;
03972             word32 startIdx = decoded.srcIdx;
03973             word32 tmpIdx;
03974 
03975             if (GetSequence(decoded.source, &decoded.srcIdx, &length,
03976                         decoded.maxIdx) < 0) {
03977                 FreeDecodedCert(&decoded);
03978                 return ASN_PARSE_E;
03979             }
03980 
03981             tmpIdx = decoded.srcIdx;
03982             decoded.srcIdx = startIdx;
03983 
03984             if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid,
03985                           decoded.maxIdx) < 0) {
03986                 FreeDecodedCert(&decoded);
03987                 return ASN_PARSE_E;
03988             }
03989 
03990             if (oid == ALT_NAMES_OID) {
03991                 cert->altNamesSz = length + (tmpIdx - startIdx);
03992 
03993                 if (cert->altNamesSz < (int)sizeof(cert->altNames))
03994                     XMEMCPY(cert->altNames, &decoded.source[startIdx],
03995                         cert->altNamesSz);
03996                 else {
03997                     cert->altNamesSz = 0;
03998                     CYASSL_MSG("AltNames extensions too big");
03999                     FreeDecodedCert(&decoded);
04000                     return ALT_NAME_E;
04001                 }
04002             }
04003             decoded.srcIdx = tmpIdx + length;
04004         }
04005     }
04006     FreeDecodedCert(&decoded);
04007 
04008     return 0;
04009 }
04010 
04011 
04012 /* Set Dates from der cert, return 0 on success */
04013 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
04014 {
04015     DecodedCert decoded;
04016     int         ret;
04017 
04018     CYASSL_ENTER("SetDatesFromCert");
04019     if (derSz < 0)
04020         return derSz;
04021 
04022     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
04023     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
04024 
04025     if (ret < 0) {
04026         CYASSL_MSG("ParseCertRelative error");
04027         FreeDecodedCert(&decoded);
04028         return ret;
04029     }
04030 
04031     if (decoded.beforeDate == NULL || decoded.afterDate == NULL) {
04032         CYASSL_MSG("Couldn't extract dates");
04033         FreeDecodedCert(&decoded);
04034         return -1;
04035     }
04036 
04037     if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen >
04038                                                  MAX_DATE_SIZE) {
04039         CYASSL_MSG("Bad date size");
04040         FreeDecodedCert(&decoded);
04041         return -1;
04042     }
04043 
04044     XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen);
04045     XMEMCPY(cert->afterDate,  decoded.afterDate,  decoded.afterDateLen);
04046 
04047     cert->beforeDateSz = decoded.beforeDateLen;
04048     cert->afterDateSz  = decoded.afterDateLen;
04049 
04050     return 0;
04051 }
04052 
04053 
04054 #endif /* CYASSL_ALT_NAMES && !NO_RSA */
04055 
04056 
04057 /* Set cn name from der buffer, return 0 on success */
04058 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
04059 {
04060     DecodedCert decoded;
04061     int         ret;
04062     int         sz;
04063 
04064     if (derSz < 0)
04065         return derSz;
04066 
04067     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
04068     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
04069 
04070     if (ret < 0)
04071         return ret;
04072 
04073     if (decoded.subjectCN) {
04074         sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen :
04075                                                   CTC_NAME_SIZE - 1;
04076         strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE);
04077         cn->commonName[sz] = 0;
04078     }
04079     if (decoded.subjectC) {
04080         sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen :
04081                                                  CTC_NAME_SIZE - 1;
04082         strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE);
04083         cn->country[sz] = 0;
04084     }
04085     if (decoded.subjectST) {
04086         sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen :
04087                                                   CTC_NAME_SIZE - 1;
04088         strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE);
04089         cn->state[sz] = 0;
04090     }
04091     if (decoded.subjectL) {
04092         sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen :
04093                                                  CTC_NAME_SIZE - 1;
04094         strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE);
04095         cn->locality[sz] = 0;
04096     }
04097     if (decoded.subjectO) {
04098         sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen :
04099                                                  CTC_NAME_SIZE - 1;
04100         strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE);
04101         cn->org[sz] = 0;
04102     }
04103     if (decoded.subjectOU) {
04104         sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen :
04105                                                   CTC_NAME_SIZE - 1;
04106         strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE);
04107         cn->unit[sz] = 0;
04108     }
04109     if (decoded.subjectSN) {
04110         sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen :
04111                                                   CTC_NAME_SIZE - 1;
04112         strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE);
04113         cn->sur[sz] = 0;
04114     }
04115     if (decoded.subjectEmail) {
04116         sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ?
04117                               decoded.subjectEmailLen : CTC_NAME_SIZE - 1;
04118         strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE);
04119         cn->email[sz] = 0;
04120     }
04121 
04122     FreeDecodedCert(&decoded);
04123 
04124     return 0;
04125 }
04126 
04127 
04128 #ifndef NO_FILESYSTEM
04129 
04130 /* forward from CyaSSL */
04131 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
04132 
04133 /* Set cert issuer from issuerFile in PEM */
04134 int SetIssuer(Cert* cert, const char* issuerFile)
04135 {
04136     int         ret;
04137     int         derSz;
04138     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
04139 
04140     if (der == NULL) {
04141         CYASSL_MSG("SetIssuer OOF Problem");
04142         return MEMORY_E;
04143     }
04144     derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
04145     cert->selfSigned = 0;
04146     ret = SetNameFromCert(&cert->issuer, der, derSz);
04147     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
04148 
04149     return ret;
04150 }
04151 
04152 
04153 /* Set cert subject from subjectFile in PEM */
04154 int SetSubject(Cert* cert, const char* subjectFile)
04155 {
04156     int         ret;
04157     int         derSz;
04158     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
04159 
04160     if (der == NULL) {
04161         CYASSL_MSG("SetSubject OOF Problem");
04162         return MEMORY_E;
04163     }
04164     derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
04165     ret = SetNameFromCert(&cert->subject, der, derSz);
04166     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
04167 
04168     return ret;
04169 }
04170 
04171 
04172 #ifdef CYASSL_ALT_NAMES
04173 
04174 /* Set atl names from file in PEM */
04175 int SetAltNames(Cert* cert, const char* file)
04176 {
04177     int         ret;
04178     int         derSz;
04179     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
04180 
04181     if (der == NULL) {
04182         CYASSL_MSG("SetAltNames OOF Problem");
04183         return MEMORY_E;
04184     }
04185     derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF);
04186     ret = SetAltNamesFromCert(cert, der, derSz);
04187     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
04188 
04189     return ret;
04190 }
04191 
04192 #endif /* CYASSL_ALT_NAMES */
04193 
04194 #endif /* NO_FILESYSTEM */
04195 
04196 /* Set cert issuer from DER buffer */
04197 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
04198 {
04199     cert->selfSigned = 0;
04200     return SetNameFromCert(&cert->issuer, der, derSz);
04201 }
04202 
04203 
04204 /* Set cert subject from DER buffer */
04205 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
04206 {
04207     return SetNameFromCert(&cert->subject, der, derSz);
04208 }
04209 
04210 
04211 #ifdef CYASSL_ALT_NAMES
04212 
04213 /* Set cert alt names from DER buffer */
04214 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
04215 {
04216     return SetAltNamesFromCert(cert, der, derSz);
04217 }
04218 
04219 /* Set cert dates from DER buffer */
04220 int SetDatesBuffer(Cert* cert, const byte* der, int derSz)
04221 {
04222     return SetDatesFromCert(cert, der, derSz);
04223 }
04224 
04225 #endif /* CYASSL_ALT_NAMES */
04226 
04227 #endif /* CYASSL_CERT_GEN */
04228 
04229 
04230 #ifdef HAVE_ECC
04231 
04232 /* Der Encode r & s ints into out, outLen is (in/out) size */
04233 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
04234 {
04235     word32 idx = 0;
04236     word32 rSz;                           /* encoding size */
04237     word32 sSz;
04238     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
04239 
04240     int rLen = mp_unsigned_bin_size(r);   /* big int size */
04241     int sLen = mp_unsigned_bin_size(s);
04242     int err;
04243 
04244     if (*outLen < (rLen + sLen + headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
04245         return BAD_FUNC_ARG;
04246 
04247     idx = SetSequence(rLen + sLen + headerSz, out);
04248 
04249     /* store r */
04250     out[idx++] = ASN_INTEGER;
04251     rSz = SetLength(rLen, &out[idx]);
04252     idx += rSz;
04253     err = mp_to_unsigned_bin(r, &out[idx]);
04254     if (err != MP_OKAY) return err;
04255     idx += rLen;
04256 
04257     /* store s */
04258     out[idx++] = ASN_INTEGER;
04259     sSz = SetLength(sLen, &out[idx]);
04260     idx += sSz;
04261     err = mp_to_unsigned_bin(s, &out[idx]);
04262     if (err != MP_OKAY) return err;
04263     idx += sLen;
04264 
04265     *outLen = idx;
04266 
04267     return 0;
04268 }
04269 
04270 
04271 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */
04272 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
04273 {
04274     word32 idx = 0;
04275     int    len = 0;
04276 
04277     if (GetSequence(sig, &idx, &len, sigLen) < 0)
04278         return ASN_ECC_KEY_E;
04279 
04280     if ((word32)len > (sigLen - idx))
04281         return ASN_ECC_KEY_E;
04282 
04283     if (GetInt(r, sig, &idx, sigLen) < 0)
04284         return ASN_ECC_KEY_E;
04285 
04286     if (GetInt(s, sig, &idx, sigLen) < 0)
04287         return ASN_ECC_KEY_E;
04288 
04289     return 0;
04290 }
04291 
04292 
04293 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
04294                         word32 inSz)
04295 {
04296     word32 oid = 0;
04297     int    version, length;
04298     int    privSz, pubSz;
04299     byte   b;
04300     byte   priv[ECC_MAXSIZE];
04301     byte   pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */
04302 
04303     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
04304         return ASN_PARSE_E;
04305 
04306     if (GetMyVersion(input, inOutIdx, &version) < 0)
04307         return ASN_PARSE_E;
04308 
04309     b = input[*inOutIdx];
04310     *inOutIdx += 1;
04311 
04312     /* priv type */
04313     if (b != 4 && b != 6 && b != 7) 
04314         return ASN_PARSE_E;
04315 
04316     if (GetLength(input, inOutIdx, &length, inSz) < 0)
04317         return ASN_PARSE_E;
04318 
04319     /* priv key */
04320     privSz = length;
04321     XMEMCPY(priv, &input[*inOutIdx], privSz);
04322     *inOutIdx += length;
04323 
04324     /* prefix 0, may have */
04325     b = input[*inOutIdx];
04326     if (b == ECC_PREFIX_0) {
04327         *inOutIdx += 1;
04328 
04329         if (GetLength(input, inOutIdx, &length, inSz) < 0)
04330             return ASN_PARSE_E;
04331 
04332         /* object id */
04333         b = input[*inOutIdx];
04334         *inOutIdx += 1;
04335     
04336         if (b != ASN_OBJECT_ID) 
04337             return ASN_OBJECT_ID_E;
04338 
04339         if (GetLength(input, inOutIdx, &length, inSz) < 0)
04340             return ASN_PARSE_E;
04341 
04342         while(length--) {
04343             oid += input[*inOutIdx];
04344             *inOutIdx += 1;
04345         }
04346         if (CheckCurve(oid) < 0)
04347             return ECC_CURVE_OID_E;
04348     }
04349     
04350     /* prefix 1 */
04351     b = input[*inOutIdx];
04352     *inOutIdx += 1;
04353     if (b != ECC_PREFIX_1)
04354         return ASN_ECC_KEY_E;
04355 
04356     if (GetLength(input, inOutIdx, &length, inSz) < 0)
04357         return ASN_PARSE_E;
04358 
04359     /* key header */
04360     b = input[*inOutIdx];
04361     *inOutIdx += 1;
04362     if (b != ASN_BIT_STRING)
04363         return ASN_BITSTR_E;
04364 
04365     if (GetLength(input, inOutIdx, &length, inSz) < 0)
04366         return ASN_PARSE_E;
04367     b = input[*inOutIdx];
04368     *inOutIdx += 1;
04369     if (b != 0x00)
04370         return ASN_EXPECT_0_E;
04371 
04372     pubSz = length - 1;  /* null prefix */
04373     XMEMCPY(pub, &input[*inOutIdx], pubSz);
04374 
04375     *inOutIdx += length;
04376     
04377     return ecc_import_private_key(priv, privSz, pub, pubSz, key);
04378 }
04379 
04380 #endif  /* HAVE_ECC */
04381 
04382 
04383 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
04384 
04385 /* Get raw Date only, no processing, 0 on success */
04386 static int GetBasicDate(const byte* source, word32* idx, byte* date,
04387                         byte* format, int maxIdx)
04388 {
04389     int    length;
04390 
04391     CYASSL_ENTER("GetBasicDate");
04392 
04393     *format = source[*idx];
04394     *idx += 1;
04395     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
04396         return ASN_TIME_E;
04397 
04398     if (GetLength(source, idx, &length, maxIdx) < 0)
04399         return ASN_PARSE_E;
04400 
04401     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
04402         return ASN_DATE_SZ_E;
04403 
04404     XMEMCPY(date, &source[*idx], length);
04405     *idx += length;
04406 
04407     return 0;
04408 }
04409 
04410 #endif
04411 
04412 
04413 #ifdef HAVE_OCSP
04414 
04415 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
04416 {
04417     word32 idx = *inOutIdx;
04418     word32 len;
04419 
04420     CYASSL_ENTER("GetEnumerated");
04421 
04422     *value = 0;
04423 
04424     if (input[idx++] != ASN_ENUMERATED)
04425         return ASN_PARSE_E;
04426 
04427     len = input[idx++];
04428     if (len > 4)
04429         return ASN_PARSE_E;
04430 
04431     while (len--) {
04432         *value  = *value << 8 | input[idx++];
04433     }
04434 
04435     *inOutIdx = idx;
04436 
04437     return *value;
04438 }
04439 
04440 
04441 static int DecodeSingleResponse(byte* source,
04442                             word32* ioIndex, OcspResponse* resp, word32 size)
04443 {
04444     word32 idx = *ioIndex, prevIndex, oid;
04445     int length, wrapperSz;
04446     CertStatus* cs = resp->status;
04447 
04448     CYASSL_ENTER("DecodeSingleResponse");
04449 
04450     /* Outer wrapper of the SEQUENCE OF Single Responses. */
04451     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
04452         return ASN_PARSE_E;
04453 
04454     prevIndex = idx;
04455 
04456     /* When making a request, we only request one status on one certificate
04457      * at a time. There should only be one SingleResponse */
04458 
04459     /* Wrapper around the Single Response */
04460     if (GetSequence(source, &idx, &length, size) < 0)
04461         return ASN_PARSE_E;
04462 
04463     /* Wrapper around the CertID */
04464     if (GetSequence(source, &idx, &length, size) < 0)
04465         return ASN_PARSE_E;
04466     /* Skip the hash algorithm */
04467     if (GetAlgoId(source, &idx, &oid, size) < 0)
04468         return ASN_PARSE_E;
04469     /* Save reference to the hash of CN */
04470     if (source[idx++] != ASN_OCTET_STRING)
04471         return ASN_PARSE_E;
04472     if (GetLength(source, &idx, &length, size) < 0)
04473         return ASN_PARSE_E;
04474     resp->issuerHash = source + idx;
04475     idx += length;
04476     /* Save reference to the hash of the issuer public key */
04477     if (source[idx++] != ASN_OCTET_STRING)
04478         return ASN_PARSE_E;
04479     if (GetLength(source, &idx, &length, size) < 0)
04480         return ASN_PARSE_E;
04481     resp->issuerKeyHash = source + idx;
04482     idx += length;
04483 
04484     /* Read the serial number, it is handled as a string, not as a 
04485      * proper number. Just XMEMCPY the data over, rather than load it
04486      * as an mp_int. */
04487     if (source[idx++] != ASN_INTEGER)
04488         return ASN_PARSE_E;
04489     if (GetLength(source, &idx, &length, size) < 0)
04490         return ASN_PARSE_E;
04491     if (length <= EXTERNAL_SERIAL_SIZE)
04492     {
04493         if (source[idx] == 0)
04494         {
04495             idx++;
04496             length--;
04497         }
04498         XMEMCPY(cs->serial, source + idx, length);
04499         cs->serialSz = length;
04500     }
04501     else
04502     {
04503         return ASN_GETINT_E;
04504     }
04505     idx += length;
04506 
04507     /* CertStatus */
04508     switch (source[idx++])
04509     {
04510         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
04511             cs->status = CERT_GOOD;
04512             idx++;
04513             break;
04514         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
04515             cs->status = CERT_REVOKED;
04516             if (GetLength(source, &idx, &length, size) < 0)
04517                 return ASN_PARSE_E;
04518             idx += length;
04519             break;
04520         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
04521             cs->status = CERT_UNKNOWN;
04522             idx++;
04523             break;
04524         default:
04525             return ASN_PARSE_E;
04526     }
04527 
04528     if (GetBasicDate(source, &idx, cs->thisDate,
04529                                                 &cs->thisDateFormat, size) < 0)
04530         return ASN_PARSE_E;
04531     if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
04532         return ASN_BEFORE_DATE_E;
04533     
04534     /* The following items are optional. Only check for them if there is more
04535      * unprocessed data in the singleResponse wrapper. */
04536     
04537     if (((int)(idx - prevIndex) < wrapperSz) &&
04538         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
04539     {
04540         idx++;
04541         if (GetLength(source, &idx, &length, size) < 0)
04542             return ASN_PARSE_E;
04543         if (GetBasicDate(source, &idx, cs->nextDate,
04544                                                 &cs->nextDateFormat, size) < 0)
04545             return ASN_PARSE_E;
04546     }
04547     if (((int)(idx - prevIndex) < wrapperSz) &&
04548         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
04549     {
04550         idx++;
04551         if (GetLength(source, &idx, &length, size) < 0)
04552             return ASN_PARSE_E;
04553         idx += length;
04554     }
04555 
04556     *ioIndex = idx;
04557 
04558     return 0;
04559 }
04560 
04561 static int DecodeOcspRespExtensions(byte* source,
04562                             word32* ioIndex, OcspResponse* resp, word32 sz)
04563 {
04564     word32 idx = *ioIndex;
04565     int length;
04566     int ext_bound; /* boundary index for the sequence of extensions */
04567     word32 oid;
04568 
04569     CYASSL_ENTER("DecodeOcspRespExtensions");
04570 
04571     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
04572         return ASN_PARSE_E;
04573 
04574     if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
04575 
04576     if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
04577    
04578     ext_bound = idx + length;
04579 
04580     while (idx < (word32)ext_bound) {
04581         if (GetSequence(source, &idx, &length, sz) < 0) {
04582             CYASSL_MSG("\tfail: should be a SEQUENCE");
04583             return ASN_PARSE_E;
04584         }
04585 
04586         oid = 0;
04587         if (GetObjectId(source, &idx, &oid, sz) < 0) {
04588             CYASSL_MSG("\tfail: OBJECT ID");
04589             return ASN_PARSE_E;
04590         }
04591 
04592         /* check for critical flag */
04593         if (source[idx] == ASN_BOOLEAN) {
04594             CYASSL_MSG("\tfound optional critical flag, moving past");
04595             idx += (ASN_BOOL_SIZE + 1);
04596         }
04597 
04598         /* process the extension based on the OID */
04599         if (source[idx++] != ASN_OCTET_STRING) {
04600             CYASSL_MSG("\tfail: should be an OCTET STRING");
04601             return ASN_PARSE_E;
04602         }
04603 
04604         if (GetLength(source, &idx, &length, sz) < 0) {
04605             CYASSL_MSG("\tfail: extension data length");
04606             return ASN_PARSE_E;
04607         }
04608 
04609         if (oid == OCSP_NONCE_OID) {
04610             resp->nonce = source + idx;
04611             resp->nonceSz = length;
04612         }
04613 
04614         idx += length;
04615     }
04616 
04617     *ioIndex = idx;
04618     return 0;
04619 }
04620 
04621 
04622 static int DecodeResponseData(byte* source,
04623                             word32* ioIndex, OcspResponse* resp, word32 size)
04624 {
04625     word32 idx = *ioIndex, prev_idx;
04626     int length;
04627     int version;
04628     word32 responderId = 0;
04629 
04630     CYASSL_ENTER("DecodeResponseData");
04631 
04632     resp->response = source + idx;
04633     prev_idx = idx;
04634     if (GetSequence(source, &idx, &length, size) < 0)
04635         return ASN_PARSE_E;
04636     resp->responseSz = length + idx - prev_idx;
04637 
04638     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
04639      * item isn't an EXPLICIT[0], then set version to zero and move
04640      * onto the next item.
04641      */
04642     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
04643     {    
04644         idx += 2; /* Eat the value and length */
04645         if (GetMyVersion(source, &idx, &version) < 0)
04646             return ASN_PARSE_E;
04647     } else
04648         version = 0;
04649 
04650     responderId = source[idx++];
04651     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
04652         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
04653     {
04654         if (GetLength(source, &idx, &length, size) < 0)
04655             return ASN_PARSE_E;
04656         idx += length;
04657     }
04658     else
04659         return ASN_PARSE_E;
04660     
04661     /* save pointer to the producedAt time */
04662     if (GetBasicDate(source, &idx, resp->producedDate,
04663                                         &resp->producedDateFormat, size) < 0)
04664         return ASN_PARSE_E;
04665 
04666     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
04667         return ASN_PARSE_E;
04668 
04669     if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
04670         return ASN_PARSE_E;
04671 
04672     *ioIndex = idx;
04673     return 0;
04674 }
04675 
04676 
04677 static int DecodeCerts(byte* source,
04678                             word32* ioIndex, OcspResponse* resp, word32 size)
04679 {
04680     word32 idx = *ioIndex;
04681 
04682     CYASSL_ENTER("DecodeCerts");
04683 
04684     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
04685     {
04686         int length;
04687 
04688         if (GetLength(source, &idx, &length, size) < 0)
04689             return ASN_PARSE_E;
04690 
04691         if (GetSequence(source, &idx, &length, size) < 0)
04692             return ASN_PARSE_E;
04693 
04694         resp->cert = source + idx;
04695         resp->certSz = length;
04696 
04697         idx += length;
04698     }
04699     *ioIndex = idx;
04700     return 0;
04701 }
04702 
04703 static int DecodeBasicOcspResponse(byte* source,
04704                             word32* ioIndex, OcspResponse* resp, word32 size)
04705 {
04706     int length;
04707     word32 idx = *ioIndex;
04708     word32 end_index;
04709 
04710     CYASSL_ENTER("DecodeBasicOcspResponse");
04711 
04712     if (GetSequence(source, &idx, &length, size) < 0)
04713         return ASN_PARSE_E;
04714 
04715     if (idx + length > size)
04716         return ASN_INPUT_E;
04717     end_index = idx + length;
04718 
04719     if (DecodeResponseData(source, &idx, resp, size) < 0)
04720         return ASN_PARSE_E;
04721     
04722     /* Get the signature algorithm */
04723     if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
04724         return ASN_PARSE_E;
04725 
04726     /* Obtain pointer to the start of the signature, and save the size */
04727     if (source[idx++] == ASN_BIT_STRING)
04728     {
04729         int sigLength = 0;
04730         if (GetLength(source, &idx, &sigLength, size) < 0)
04731             return ASN_PARSE_E;
04732         resp->sigSz = sigLength;
04733         resp->sig = source + idx;
04734         idx += sigLength;
04735     }
04736 
04737     /*
04738      * Check the length of the BasicOcspResponse against the current index to
04739      * see if there are certificates, they are optional.
04740      */
04741     if (idx < end_index)
04742     {
04743         DecodedCert cert;
04744         int ret;
04745 
04746         if (DecodeCerts(source, &idx, resp, size) < 0)
04747             return ASN_PARSE_E;
04748 
04749         InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
04750         ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
04751         if (ret < 0)
04752             return ret;
04753 
04754         ret = ConfirmSignature(resp->response, resp->responseSz,
04755                             cert.publicKey, cert.pubKeySize, cert.keyOID,
04756                             resp->sig, resp->sigSz, resp->sigOID, NULL);
04757         FreeDecodedCert(&cert);
04758 
04759         if (ret == 0)
04760         {
04761             CYASSL_MSG("\tOCSP Confirm signature failed");
04762             return ASN_OCSP_CONFIRM_E;
04763         }
04764     }
04765 
04766     *ioIndex = idx;
04767     return 0;
04768 }
04769 
04770 
04771 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
04772                                                     byte* source, word32 inSz)
04773 {
04774     CYASSL_ENTER("InitOcspResponse");
04775 
04776     resp->responseStatus = -1;
04777     resp->response = NULL;
04778     resp->responseSz = 0;
04779     resp->producedDateFormat = 0;
04780     resp->issuerHash = NULL;
04781     resp->issuerKeyHash = NULL;
04782     resp->sig = NULL;
04783     resp->sigSz = 0;
04784     resp->sigOID = 0;
04785     resp->status = status;
04786     resp->nonce = NULL;
04787     resp->nonceSz = 0;
04788     resp->source = source;
04789     resp->maxIdx = inSz;
04790 }
04791 
04792 
04793 int OcspResponseDecode(OcspResponse* resp)
04794 {
04795     int length = 0;
04796     word32 idx = 0;
04797     byte* source = resp->source;
04798     word32 size = resp->maxIdx;
04799     word32 oid;
04800 
04801     CYASSL_ENTER("OcspResponseDecode");
04802 
04803     /* peel the outer SEQUENCE wrapper */
04804     if (GetSequence(source, &idx, &length, size) < 0)
04805         return ASN_PARSE_E;
04806     
04807     /* First get the responseStatus, an ENUMERATED */
04808     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
04809         return ASN_PARSE_E;
04810 
04811     if (resp->responseStatus != OCSP_SUCCESSFUL)
04812         return 0;
04813 
04814     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
04815     if (idx >= size)
04816         return ASN_INPUT_E;
04817     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
04818         return ASN_PARSE_E;
04819     if (GetLength(source, &idx, &length, size) < 0)
04820         return ASN_PARSE_E;
04821 
04822     /* Get the responseBytes SEQUENCE */
04823     if (GetSequence(source, &idx, &length, size) < 0)
04824         return ASN_PARSE_E;
04825 
04826     /* Check ObjectID for the resposeBytes */
04827     if (GetObjectId(source, &idx, &oid, size) < 0)
04828         return ASN_PARSE_E;
04829     if (oid != OCSP_BASIC_OID)
04830         return ASN_PARSE_E;
04831     if (source[idx++] != ASN_OCTET_STRING)
04832         return ASN_PARSE_E;
04833 
04834     if (GetLength(source, &idx, &length, size) < 0)
04835         return ASN_PARSE_E;
04836 
04837     if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
04838         return ASN_PARSE_E;
04839     
04840     return 0;
04841 }
04842 
04843 
04844 static int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
04845 {
04846     int result = 0;
04847 
04848     CYASSL_ENTER("SetSerialNumber");
04849 
04850     if (snSz <= EXTERNAL_SERIAL_SIZE) {
04851         output[0] = ASN_INTEGER;
04852         output[1] = snSz + 1;
04853         output[2] = 0;
04854         XMEMCPY(&output[3], sn, snSz);
04855         result = snSz + 3;
04856     }
04857     return result;
04858 }
04859 
04860 
04861 static word32 SetOcspReqExtensions(word32 extSz, byte* output,
04862                                             const byte* nonce, word32 nonceSz)
04863 {
04864     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
04865                                        0x30, 0x01, 0x02 };
04866     byte seqArray[5][MAX_SEQ_SZ];
04867     word32 seqSz[5], totalSz;
04868 
04869     CYASSL_ENTER("SetOcspReqExtensions");
04870 
04871     if (nonce == NULL || nonceSz == 0) return 0;
04872     
04873     seqArray[0][0] = ASN_OCTET_STRING;
04874     seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
04875 
04876     seqArray[1][0] = ASN_OBJECT_ID;
04877     seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
04878 
04879     totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
04880 
04881     seqSz[2] = SetSequence(totalSz, seqArray[2]);
04882     totalSz += seqSz[2];
04883 
04884     seqSz[3] = SetSequence(totalSz, seqArray[3]);
04885     totalSz += seqSz[3];
04886 
04887     seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
04888     seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
04889     totalSz += seqSz[4];
04890 
04891     if (totalSz < extSz)
04892     {
04893         totalSz = 0;
04894         XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
04895         totalSz += seqSz[4];
04896         XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
04897         totalSz += seqSz[3];
04898         XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
04899         totalSz += seqSz[2];
04900         XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
04901         totalSz += seqSz[1];
04902         XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
04903         totalSz += (word32)sizeof(NonceObjId);
04904         XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
04905         totalSz += seqSz[0];
04906         XMEMCPY(output + totalSz, nonce, nonceSz);
04907         totalSz += nonceSz;
04908     }
04909 
04910     return totalSz;
04911 }
04912 
04913 
04914 int EncodeOcspRequest(OcspRequest* req)
04915 {
04916     byte seqArray[5][MAX_SEQ_SZ];
04917     /* The ASN.1 of the OCSP Request is an onion of sequences */
04918     byte algoArray[MAX_ALGO_SZ];
04919     byte issuerArray[MAX_ENCODED_DIG_SZ];
04920     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
04921     byte snArray[MAX_SN_SZ];
04922     byte extArray[MAX_OCSP_EXT_SZ];
04923     byte* output = req->dest;
04924     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
04925     int i;
04926 
04927     CYASSL_ENTER("EncodeOcspRequest");
04928 
04929     algoSz = SetAlgoID(SHAh, algoArray, hashType);
04930 
04931     req->issuerHash = req->cert->issuerHash;
04932     issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray);
04933     
04934     req->issuerKeyHash = req->cert->issuerKeyHash;
04935     issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray);
04936 
04937     req->serial = req->cert->serial;
04938     req->serialSz = req->cert->serialSz;
04939     snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
04940 
04941     extSz = 0;
04942     if (req->useNonce) {
04943         RNG rng;
04944         if (InitRng(&rng) != 0) {
04945             CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
04946         } else {
04947             req->nonceSz = MAX_OCSP_NONCE_SZ;
04948             RNG_GenerateBlock(&rng, req->nonce, req->nonceSz);
04949             extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
04950                                                       req->nonce, req->nonceSz);
04951         }
04952     }
04953 
04954     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
04955 
04956     for (i = 4; i >= 0; i--) {
04957         seqSz[i] = SetSequence(totalSz, seqArray[i]);
04958         totalSz += seqSz[i];
04959         if (i == 2) totalSz += extSz;
04960     }
04961     totalSz = 0;
04962     for (i = 0; i < 5; i++) {
04963         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
04964         totalSz += seqSz[i];
04965     }
04966     XMEMCPY(output + totalSz, algoArray, algoSz);
04967     totalSz += algoSz;
04968     XMEMCPY(output + totalSz, issuerArray, issuerSz);
04969     totalSz += issuerSz;
04970     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
04971     totalSz += issuerKeySz;
04972     XMEMCPY(output + totalSz, snArray, snSz);
04973     totalSz += snSz;
04974     if (extSz != 0) {
04975         XMEMCPY(output + totalSz, extArray, extSz);
04976         totalSz += extSz;
04977     }
04978 
04979     return totalSz;
04980 }
04981 
04982 
04983 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
04984                                                     byte* dest, word32 destSz)
04985 {
04986     CYASSL_ENTER("InitOcspRequest");
04987 
04988     req->cert = cert;
04989     req->useNonce = useNonce;
04990     req->nonceSz = 0;
04991     req->issuerHash = NULL;
04992     req->issuerKeyHash = NULL;
04993     req->serial = NULL;
04994     req->dest = dest;
04995     req->destSz = destSz;
04996 }
04997 
04998 
04999 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
05000 {
05001     int cmp;
05002 
05003     CYASSL_ENTER("CompareOcspReqResp");
05004 
05005     if (req == NULL)
05006     {
05007         CYASSL_MSG("\tReq missing");
05008         return -1;
05009     }
05010 
05011     if (resp == NULL)
05012     {
05013         CYASSL_MSG("\tResp missing");
05014         return 1;
05015     }
05016 
05017     if (req->useNonce) {
05018         cmp = req->nonceSz - resp->nonceSz;
05019         if (cmp != 0)
05020         {
05021             CYASSL_MSG("\tnonceSz mismatch");
05022             return cmp;
05023         }
05024     
05025         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
05026         if (cmp != 0)
05027         {
05028             CYASSL_MSG("\tnonce mismatch");
05029             return cmp;
05030         }
05031     }
05032 
05033     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE);
05034     if (cmp != 0)
05035     {
05036         CYASSL_MSG("\tissuerHash mismatch");
05037         return cmp;
05038     }
05039 
05040     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE);
05041     if (cmp != 0)
05042     {
05043         CYASSL_MSG("\tissuerKeyHash mismatch");
05044         return cmp;
05045     }
05046 
05047     cmp = req->serialSz - resp->status->serialSz;
05048     if (cmp != 0)
05049     {
05050         CYASSL_MSG("\tserialSz mismatch");
05051         return cmp;
05052     }
05053 
05054     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
05055     if (cmp != 0)
05056     {
05057         CYASSL_MSG("\tserial mismatch");
05058         return cmp;
05059     }
05060 
05061     return 0;
05062 }
05063 
05064 #endif
05065 
05066 
05067 #ifdef HAVE_CRL
05068 
05069 /* initialize decoded CRL */
05070 void InitDecodedCRL(DecodedCRL* dcrl)
05071 {
05072     CYASSL_MSG("InitDecodedCRL");
05073 
05074     dcrl->certBegin    = 0;
05075     dcrl->sigIndex     = 0;
05076     dcrl->sigLength    = 0;
05077     dcrl->signatureOID = 0;
05078     dcrl->certs        = NULL;
05079     dcrl->totalCerts   = 0;
05080 }
05081 
05082 
05083 /* free decoded CRL resources */
05084 void FreeDecodedCRL(DecodedCRL* dcrl)
05085 {
05086     RevokedCert* tmp = dcrl->certs;
05087 
05088     CYASSL_MSG("FreeDecodedCRL");
05089 
05090     while(tmp) {
05091         RevokedCert* next = tmp->next;
05092         XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
05093         tmp = next;
05094     }
05095 }
05096 
05097 
05098 /* store SHA1 hash of NAME */
05099 static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
05100 {
05101     Sha    sha;
05102     int    length;  /* length of all distinguished names */
05103     word32 dummy;
05104 
05105     CYASSL_ENTER("GetNameHash");
05106 
05107     if (source[*idx] == ASN_OBJECT_ID) {
05108         CYASSL_MSG("Trying optional prefix...");
05109 
05110         if (GetLength(source, idx, &length, maxIdx) < 0)
05111             return ASN_PARSE_E;
05112 
05113         *idx += length;
05114         CYASSL_MSG("Got optional prefix");
05115     }
05116 
05117     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
05118      * calculated over the entire DER encoding of the Name field, including
05119      * the tag and length. */
05120     dummy = *idx;
05121     if (GetSequence(source, idx, &length, maxIdx) < 0)
05122         return ASN_PARSE_E;
05123 
05124     InitSha(&sha);
05125     ShaUpdate(&sha, source + dummy, length + *idx - dummy);
05126     ShaFinal(&sha, hash);
05127 
05128     *idx += length;
05129 
05130     return 0;
05131 }
05132 
05133 
05134 /* Get Revoked Cert list, 0 on success */
05135 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
05136                       int maxIdx)
05137 {
05138     int    len;
05139     word32 end;
05140     byte   b;
05141     RevokedCert* rc;
05142 
05143     CYASSL_ENTER("GetRevoked");
05144 
05145     if (GetSequence(buff, idx, &len, maxIdx) < 0)
05146         return ASN_PARSE_E;
05147 
05148     end = *idx + len;
05149 
05150     /* get serial number */
05151     b = buff[*idx];
05152     *idx += 1;
05153 
05154     if (b != ASN_INTEGER) {
05155         CYASSL_MSG("Expecting Integer");
05156         return ASN_PARSE_E;
05157     }
05158 
05159     if (GetLength(buff, idx, &len, maxIdx) < 0)
05160         return ASN_PARSE_E;
05161 
05162     if (len > EXTERNAL_SERIAL_SIZE) {
05163         CYASSL_MSG("Serial Size too big");
05164         return ASN_PARSE_E;
05165     }
05166 
05167     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
05168     if (rc == NULL) {
05169         CYASSL_MSG("Alloc Revoked Cert failed");
05170         return MEMORY_E;
05171     }
05172 
05173     XMEMCPY(rc->serialNumber, &buff[*idx], len);
05174     rc->serialSz = len;
05175 
05176     /* add to list */
05177     rc->next = dcrl->certs;
05178     dcrl->certs = rc;
05179     dcrl->totalCerts++;
05180 
05181     *idx += len;
05182 
05183     /* get date */
05184     b = buff[*idx];
05185     *idx += 1;
05186 
05187     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
05188         CYASSL_MSG("Expecting Date");
05189         return ASN_PARSE_E;
05190     }
05191 
05192     if (GetLength(buff, idx, &len, maxIdx) < 0)
05193         return ASN_PARSE_E;
05194 
05195     /* skip for now */
05196     *idx += len;
05197 
05198     if (*idx != end)  /* skip extensions */
05199         *idx = end;
05200 
05201     return 0;
05202 }
05203 
05204 
05205 /* Get CRL Signature, 0 on success */
05206 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
05207                             int maxIdx)
05208 {
05209     int    length;
05210     byte   b;
05211 
05212     CYASSL_ENTER("GetCRL_Signature");
05213 
05214     b = source[*idx];
05215     *idx += 1;
05216     if (b != ASN_BIT_STRING)
05217         return ASN_BITSTR_E;
05218 
05219     if (GetLength(source, idx, &length, maxIdx) < 0)
05220         return ASN_PARSE_E;
05221 
05222     dcrl->sigLength = length;
05223 
05224     b = source[*idx];
05225     *idx += 1;
05226     if (b != 0x00)
05227         return ASN_EXPECT_0_E;
05228 
05229     dcrl->sigLength--;
05230     dcrl->signature = (byte*)&source[*idx];
05231 
05232     *idx += dcrl->sigLength;
05233 
05234     return 0;
05235 }
05236 
05237 
05238 /* prase crl buffer into decoded state, 0 on success */
05239 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
05240 {
05241     int     version, len;
05242     word32  oid, idx = 0;
05243     Signer* ca = NULL;
05244 
05245     CYASSL_MSG("ParseCRL");
05246 
05247     /* raw crl hash */
05248     /* hash here if needed for optimized comparisons
05249      * Sha     sha;
05250      * InitSha(&sha);
05251      * ShaUpdate(&sha, buff, sz);
05252      * ShaFinal(&sha, dcrl->crlHash); */
05253 
05254     if (GetSequence(buff, &idx, &len, sz) < 0)
05255         return ASN_PARSE_E;
05256 
05257     dcrl->certBegin = idx;
05258 
05259     if (GetSequence(buff, &idx, &len, sz) < 0)
05260         return ASN_PARSE_E;
05261     dcrl->sigIndex = len + idx;
05262 
05263     /* may have version */
05264     if (buff[idx] == ASN_INTEGER) {
05265         if (GetMyVersion(buff, &idx, &version) < 0)
05266             return ASN_PARSE_E;
05267     }
05268 
05269     if (GetAlgoId(buff, &idx, &oid, sz) < 0)
05270         return ASN_PARSE_E;
05271 
05272     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
05273         return ASN_PARSE_E;
05274 
05275     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
05276         return ASN_PARSE_E;
05277 
05278     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
05279         return ASN_PARSE_E;
05280 
05281     if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
05282         CYASSL_MSG("CRL after date is no longer valid");
05283         return ASN_AFTER_DATE_E;
05284     }
05285 
05286     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
05287         if (GetSequence(buff, &idx, &len, sz) < 0)
05288             return ASN_PARSE_E;
05289 
05290         len += idx;
05291 
05292         while (idx < (word32)len) {
05293             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
05294                 return ASN_PARSE_E;
05295         }
05296     }
05297 
05298     if (idx != dcrl->sigIndex)
05299         idx = dcrl->sigIndex;   /* skip extensions */
05300 
05301     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
05302         return ASN_PARSE_E;
05303 
05304     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
05305         return ASN_PARSE_E;
05306 
05307     /* openssl doesn't add skid by default for CRLs cause firefox chokes
05308        we're not assuming it's available yet */
05309     #if !defined(NO_SKID) && defined(CRL_SKID_READY)
05310         if (dcrl->extAuthKeyIdSet)
05311             ca = GetCA(cm, dcrl->extAuthKeyId);
05312         if (ca == NULL)
05313             ca = GetCAByName(cm, dcrl->issuerHash);
05314     #else /* NO_SKID */
05315         ca = GetCA(cm, dcrl->issuerHash);
05316     #endif /* NO_SKID */
05317     CYASSL_MSG("About to verify CRL signature");
05318 
05319     if (ca) {
05320         CYASSL_MSG("Found CRL issuer CA");
05321         /* try to confirm/verify signature */
05322         if (!ConfirmSignature(buff + dcrl->certBegin,
05323                 dcrl->sigIndex - dcrl->certBegin,
05324                 ca->publicKey, ca->pubKeySize, ca->keyOID,
05325                 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
05326             CYASSL_MSG("CRL Confirm signature failed");
05327             return ASN_CRL_CONFIRM_E;
05328         }
05329     }
05330     else {
05331         CYASSL_MSG("Did NOT find CRL issuer CA");
05332         return ASN_CRL_NO_SIGNER_E;
05333     }
05334 
05335     return 0;
05336 }
05337 
05338 #endif /* HAVE_CRL */
05339 #endif
05340