wolf SSL / CyaSSL-2.9.4

Dependents:  

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