d 0773d / CyaSSL

Dependents:   CyaSSL_Example

Fork of CyaSSL by wolf SSL

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-2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_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 #ifndef IGNORE_NAME_CONSTRAINTS
01276     cert->altEmailNames   = NULL;
01277     cert->permittedNames  = NULL;
01278     cert->excludedNames   = NULL;
01279 #endif /* IGNORE_NAME_CONSTRAINTS */
01280     cert->issuer[0]       = '\0';
01281     cert->subject[0]      = '\0';
01282     cert->source          = source;  /* don't own */
01283     cert->srcIdx          = 0;
01284     cert->maxIdx          = inSz;    /* can't go over this index */
01285     cert->heap            = heap;
01286     XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
01287     cert->serialSz        = 0;
01288     cert->extensions      = 0;
01289     cert->extensionsSz    = 0;
01290     cert->extensionsIdx   = 0;
01291     cert->extAuthInfo     = NULL;
01292     cert->extAuthInfoSz   = 0;
01293     cert->extCrlInfo      = NULL;
01294     cert->extCrlInfoSz    = 0;
01295     XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE);
01296     cert->extSubjKeyIdSet = 0;
01297     XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE);
01298     cert->extAuthKeyIdSet = 0;
01299     cert->extKeyUsageSet  = 0;
01300     cert->extKeyUsage     = 0;
01301     cert->extExtKeyUsageSet = 0;
01302     cert->extExtKeyUsage    = 0;
01303     cert->isCA            = 0;
01304 #ifdef HAVE_PKCS7
01305     cert->issuerRaw       = NULL;
01306     cert->issuerRawLen    = 0;
01307 #endif
01308 #ifdef CYASSL_CERT_GEN
01309     cert->subjectSN       = 0;
01310     cert->subjectSNLen    = 0;
01311     cert->subjectC        = 0;
01312     cert->subjectCLen     = 0;
01313     cert->subjectL        = 0;
01314     cert->subjectLLen     = 0;
01315     cert->subjectST       = 0;
01316     cert->subjectSTLen    = 0;
01317     cert->subjectO        = 0;
01318     cert->subjectOLen     = 0;
01319     cert->subjectOU       = 0;
01320     cert->subjectOULen    = 0;
01321     cert->subjectEmail    = 0;
01322     cert->subjectEmailLen = 0;
01323 #endif /* CYASSL_CERT_GEN */
01324     cert->beforeDate      = NULL;
01325     cert->beforeDateLen   = 0;
01326     cert->afterDate       = NULL;
01327     cert->afterDateLen    = 0;
01328 #ifdef OPENSSL_EXTRA
01329     XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
01330     XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
01331     cert->extBasicConstSet = 0;
01332     cert->extBasicConstCrit = 0;
01333     cert->extBasicConstPlSet = 0;
01334     cert->pathLength = 0;
01335     cert->extSubjAltNameSet = 0;
01336     cert->extSubjAltNameCrit = 0;
01337     cert->extAuthKeyIdCrit = 0;
01338     cert->extSubjKeyIdCrit = 0;
01339     cert->extKeyUsageCrit = 0;
01340     cert->extExtKeyUsageCrit = 0;
01341     cert->extExtKeyUsageSrc = NULL;
01342     cert->extExtKeyUsageSz = 0;
01343     cert->extExtKeyUsageCount = 0;
01344     cert->extAuthKeyIdSrc = NULL;
01345     cert->extAuthKeyIdSz = 0;
01346     cert->extSubjKeyIdSrc = NULL;
01347     cert->extSubjKeyIdSz = 0;
01348 #endif /* OPENSSL_EXTRA */
01349 #if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS)
01350     cert->extNameConstraintSet = 0;
01351 #endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */
01352 #ifdef HAVE_ECC
01353     cert->pkCurveOID = 0;
01354 #endif /* HAVE_ECC */
01355 #ifdef CYASSL_SEP
01356     cert->deviceTypeSz = 0;
01357     cert->deviceType = NULL;
01358     cert->hwTypeSz = 0;
01359     cert->hwType = NULL;
01360     cert->hwSerialNumSz = 0;
01361     cert->hwSerialNum = NULL;
01362     #ifdef OPENSSL_EXTRA
01363         cert->extCertPolicySet = 0;
01364         cert->extCertPolicyCrit = 0;
01365     #endif /* OPENSSL_EXTRA */
01366 #endif /* CYASSL_SEP */
01367 }
01368 
01369 
01370 void FreeAltNames(DNS_entry* altNames, void* heap)
01371 {
01372     (void)heap;
01373 
01374     while (altNames) {
01375         DNS_entry* tmp = altNames->next;
01376 
01377         XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
01378         XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
01379         altNames = tmp;
01380     }
01381 }
01382 
01383 #ifndef IGNORE_NAME_CONSTRAINTS
01384 
01385 void FreeNameSubtrees(Base_entry* names, void* heap)
01386 {
01387     (void)heap;
01388 
01389     while (names) {
01390         Base_entry* tmp = names->next;
01391 
01392         XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
01393         XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
01394         names = tmp;
01395     }
01396 }
01397 
01398 #endif /* IGNORE_NAME_CONSTRAINTS */
01399 
01400 void FreeDecodedCert(DecodedCert* cert)
01401 {
01402     if (cert->subjectCNStored == 1)
01403         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
01404     if (cert->pubKeyStored == 1)
01405         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
01406     if (cert->altNames)
01407         FreeAltNames(cert->altNames, cert->heap);
01408 #ifndef IGNORE_NAME_CONSTRAINTS
01409     if (cert->altEmailNames)
01410         FreeAltNames(cert->altEmailNames, cert->heap);
01411     if (cert->permittedNames)
01412         FreeNameSubtrees(cert->permittedNames, cert->heap);
01413     if (cert->excludedNames)
01414         FreeNameSubtrees(cert->excludedNames, cert->heap);
01415 #endif /* IGNORE_NAME_CONSTRAINTS */
01416 #ifdef CYASSL_SEP
01417     XFREE(cert->deviceType, cert->heap, 0);
01418     XFREE(cert->hwType, cert->heap, 0);
01419     XFREE(cert->hwSerialNum, cert->heap, 0);
01420 #endif /* CYASSL_SEP */
01421 #ifdef OPENSSL_EXTRA
01422     if (cert->issuerName.fullName != NULL)
01423         XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509);
01424     if (cert->subjectName.fullName != NULL)
01425         XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509);
01426 #endif /* OPENSSL_EXTRA */
01427 }
01428 
01429 
01430 static int GetCertHeader(DecodedCert* cert)
01431 {
01432     int    ret = 0, len;
01433     byte   serialTmp[EXTERNAL_SERIAL_SIZE];
01434     mp_int mpi;
01435 
01436     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
01437         return ASN_PARSE_E;
01438 
01439     cert->certBegin = cert->srcIdx;
01440 
01441     if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
01442         return ASN_PARSE_E;
01443     cert->sigIndex = len + cert->srcIdx;
01444 
01445     if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
01446         return ASN_PARSE_E;
01447 
01448     if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) 
01449         return ASN_PARSE_E;
01450 
01451     len = mp_unsigned_bin_size(&mpi);
01452     if (len < (int)sizeof(serialTmp)) {
01453         if ( (ret = mp_to_unsigned_bin(&mpi, serialTmp)) == MP_OKAY) {
01454             if (len > EXTERNAL_SERIAL_SIZE)
01455                 len = EXTERNAL_SERIAL_SIZE;
01456             XMEMCPY(cert->serial, serialTmp, len);
01457             cert->serialSz = len;
01458         }
01459     }
01460     mp_clear(&mpi);
01461     return ret;
01462 }
01463 
01464 #if !defined(NO_RSA)
01465 /* Store Rsa Key, may save later, Dsa could use in future */
01466 static int StoreRsaKey(DecodedCert* cert)
01467 {
01468     int    length;
01469     word32 recvd = cert->srcIdx;
01470 
01471     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01472         return ASN_PARSE_E;
01473    
01474     recvd = cert->srcIdx - recvd;
01475     length += recvd;
01476 
01477     while (recvd--)
01478        cert->srcIdx--;
01479 
01480     cert->pubKeySize = length;
01481     cert->publicKey = cert->source + cert->srcIdx;
01482     cert->srcIdx += length;
01483 
01484     return 0;
01485 }
01486 #endif
01487 
01488 
01489 #ifdef HAVE_ECC
01490 
01491     /* return 0 on sucess if the ECC curve oid sum is supported */
01492     static int CheckCurve(word32 oid)
01493     {
01494         if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid !=
01495                    ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1)
01496             return ALGO_ID_E; 
01497 
01498         return 0;
01499     }
01500 
01501 #endif /* HAVE_ECC */
01502 
01503 
01504 static int GetKey(DecodedCert* cert)
01505 {
01506     int length;
01507 #ifdef HAVE_NTRU
01508     int tmpIdx = cert->srcIdx;
01509 #endif
01510 
01511     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01512         return ASN_PARSE_E;
01513    
01514     if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
01515         return ASN_PARSE_E;
01516 
01517     switch (cert->keyOID) {
01518    #ifndef NO_RSA
01519         case RSAk:
01520         {
01521             byte b = cert->source[cert->srcIdx++];
01522             if (b != ASN_BIT_STRING)
01523                 return ASN_BITSTR_E;
01524 
01525             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
01526                 return ASN_PARSE_E;
01527             b = cert->source[cert->srcIdx++];
01528             if (b != 0x00)
01529                 return ASN_EXPECT_0_E;
01530     
01531             return StoreRsaKey(cert);
01532         }
01533 
01534     #endif /* NO_RSA */
01535     #ifdef HAVE_NTRU
01536         case NTRUk:
01537         {
01538             const byte* key = &cert->source[tmpIdx];
01539             byte*       next = (byte*)key;
01540             word16      keyLen;
01541             byte        keyBlob[MAX_NTRU_KEY_SZ];
01542 
01543             word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
01544                                 &keyLen, NULL, &next);
01545 
01546             if (rc != NTRU_OK)
01547                 return ASN_NTRU_KEY_E;
01548             if (keyLen > sizeof(keyBlob))
01549                 return ASN_NTRU_KEY_E;
01550 
01551             rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen,
01552                                                                 keyBlob, &next);
01553             if (rc != NTRU_OK)
01554                 return ASN_NTRU_KEY_E;
01555 
01556             if ( (next - key) < 0)
01557                 return ASN_NTRU_KEY_E;
01558 
01559             cert->srcIdx = tmpIdx + (int)(next - key);
01560 
01561             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
01562                                               DYNAMIC_TYPE_PUBLIC_KEY);
01563             if (cert->publicKey == NULL)
01564                 return MEMORY_E;
01565             XMEMCPY(cert->publicKey, keyBlob, keyLen);
01566             cert->pubKeyStored = 1;
01567             cert->pubKeySize   = keyLen;
01568 
01569             return 0;
01570         }
01571     #endif /* HAVE_NTRU */
01572     #ifdef HAVE_ECC
01573         case ECDSAk:
01574         {
01575             int    oidSz = 0;
01576             byte   b = cert->source[cert->srcIdx++];
01577         
01578             if (b != ASN_OBJECT_ID) 
01579                 return ASN_OBJECT_ID_E;
01580 
01581             if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0)
01582                 return ASN_PARSE_E;
01583 
01584             while(oidSz--)
01585                 cert->pkCurveOID += cert->source[cert->srcIdx++];
01586 
01587             if (CheckCurve(cert->pkCurveOID) < 0)
01588                 return ECC_CURVE_OID_E;
01589 
01590             /* key header */
01591             b = cert->source[cert->srcIdx++];
01592             if (b != ASN_BIT_STRING)
01593                 return ASN_BITSTR_E;
01594 
01595             if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
01596                 return ASN_PARSE_E;
01597             b = cert->source[cert->srcIdx++];
01598             if (b != 0x00)
01599                 return ASN_EXPECT_0_E;
01600 
01601             /* actual key, use length - 1 since ate preceding 0 */
01602             length -= 1;
01603 
01604             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
01605                                               DYNAMIC_TYPE_PUBLIC_KEY);
01606             if (cert->publicKey == NULL)
01607                 return MEMORY_E;
01608             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
01609             cert->pubKeyStored = 1;
01610             cert->pubKeySize   = length;
01611 
01612             cert->srcIdx += length;
01613 
01614             return 0;
01615         }
01616     #endif /* HAVE_ECC */
01617         default:
01618             return ASN_UNKNOWN_OID_E;
01619     }
01620 }
01621 
01622 
01623 /* process NAME, either issuer or subject */
01624 static int GetName(DecodedCert* cert, int nameType)
01625 {
01626     Sha    sha;     /* MUST have SHA-1 hash for cert names */
01627     int    length;  /* length of all distinguished names */
01628     int    dummy;
01629     int    ret;
01630     char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
01631     word32 idx;
01632     #ifdef OPENSSL_EXTRA
01633         DecodedName* dName =
01634                   (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
01635     #endif /* OPENSSL_EXTRA */
01636 
01637     CYASSL_MSG("Getting Cert Name");
01638 
01639     if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
01640         CYASSL_MSG("Trying optional prefix...");
01641 
01642         if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01643             return ASN_PARSE_E;
01644 
01645         cert->srcIdx += length;
01646         CYASSL_MSG("Got optional prefix");
01647     }
01648 
01649     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
01650      * calculated over the entire DER encoding of the Name field, including
01651      * the tag and length. */
01652     idx = cert->srcIdx;
01653     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
01654         return ASN_PARSE_E;
01655 
01656     ret = InitSha(&sha);
01657     if (ret != 0)
01658         return ret;
01659     ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx);
01660     if (nameType == ISSUER)
01661         ShaFinal(&sha, cert->issuerHash);
01662     else
01663         ShaFinal(&sha, cert->subjectHash);
01664 
01665     length += cert->srcIdx;
01666     idx = 0;
01667 
01668 #ifdef HAVE_PKCS7
01669     /* store pointer to raw issuer */
01670     if (nameType == ISSUER) {
01671         cert->issuerRaw = &cert->source[cert->srcIdx];
01672         cert->issuerRawLen = length - cert->srcIdx;
01673     }
01674 #endif
01675 #ifndef IGNORE_NAME_CONSTRAINTS
01676     if (nameType == SUBJECT) {
01677         cert->subjectRaw = &cert->source[cert->srcIdx];
01678         cert->subjectRawLen = length - cert->srcIdx;
01679     }
01680 #endif
01681 
01682     while (cert->srcIdx < (word32)length) {
01683         byte   b;
01684         byte   joint[2];
01685         byte   tooBig = FALSE;
01686         int    oidSz;
01687 
01688         if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
01689             CYASSL_MSG("Cert name lacks set header, trying sequence");
01690         }
01691 
01692         if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
01693             return ASN_PARSE_E;
01694 
01695         b = cert->source[cert->srcIdx++];
01696         if (b != ASN_OBJECT_ID) 
01697             return ASN_OBJECT_ID_E;
01698 
01699         if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
01700             return ASN_PARSE_E;
01701 
01702         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
01703 
01704         /* v1 name types */
01705         if (joint[0] == 0x55 && joint[1] == 0x04) {
01706             byte   id;
01707             byte   copy = FALSE;
01708             int    strLen;
01709 
01710             cert->srcIdx += 2;
01711             id = cert->source[cert->srcIdx++]; 
01712             b  = cert->source[cert->srcIdx++];    /* strType */
01713             (void)b;                              /* may want to validate? */
01714 
01715             if (GetLength(cert->source, &cert->srcIdx, &strLen,
01716                           cert->maxIdx) < 0)
01717                 return ASN_PARSE_E;
01718 
01719             if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
01720                 /* include biggest pre fix header too 4 = "/serialNumber=" */
01721                 CYASSL_MSG("ASN Name too big, skipping");
01722                 tooBig = TRUE;
01723             }
01724 
01725             if (id == ASN_COMMON_NAME) {
01726                 if (nameType == SUBJECT) {
01727                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
01728                     cert->subjectCNLen = strLen;
01729                 }
01730 
01731                 if (!tooBig) {
01732                     XMEMCPY(&full[idx], "/CN=", 4);
01733                     idx += 4;
01734                     copy = TRUE;
01735                 }
01736                 #ifdef OPENSSL_EXTRA
01737                     dName->cnIdx = cert->srcIdx;
01738                     dName->cnLen = strLen;
01739                 #endif /* OPENSSL_EXTRA */
01740             }
01741             else if (id == ASN_SUR_NAME) {
01742                 if (!tooBig) {
01743                     XMEMCPY(&full[idx], "/SN=", 4);
01744                     idx += 4;
01745                     copy = TRUE;
01746                 }
01747                 #ifdef CYASSL_CERT_GEN
01748                     if (nameType == SUBJECT) {
01749                         cert->subjectSN = (char*)&cert->source[cert->srcIdx];
01750                         cert->subjectSNLen = strLen;
01751                     }
01752                 #endif /* CYASSL_CERT_GEN */
01753                 #ifdef OPENSSL_EXTRA
01754                     dName->snIdx = cert->srcIdx;
01755                     dName->snLen = strLen;
01756                 #endif /* OPENSSL_EXTRA */
01757             }
01758             else if (id == ASN_COUNTRY_NAME) {
01759                 if (!tooBig) {
01760                     XMEMCPY(&full[idx], "/C=", 3);
01761                     idx += 3;
01762                     copy = TRUE;
01763                 }
01764                 #ifdef CYASSL_CERT_GEN
01765                     if (nameType == SUBJECT) {
01766                         cert->subjectC = (char*)&cert->source[cert->srcIdx];
01767                         cert->subjectCLen = strLen;
01768                     }
01769                 #endif /* CYASSL_CERT_GEN */
01770                 #ifdef OPENSSL_EXTRA
01771                     dName->cIdx = cert->srcIdx;
01772                     dName->cLen = strLen;
01773                 #endif /* OPENSSL_EXTRA */
01774             }
01775             else if (id == ASN_LOCALITY_NAME) {
01776                 if (!tooBig) {
01777                     XMEMCPY(&full[idx], "/L=", 3);
01778                     idx += 3;
01779                     copy = TRUE;
01780                 }
01781                 #ifdef CYASSL_CERT_GEN
01782                     if (nameType == SUBJECT) {
01783                         cert->subjectL = (char*)&cert->source[cert->srcIdx];
01784                         cert->subjectLLen = strLen;
01785                     }
01786                 #endif /* CYASSL_CERT_GEN */
01787                 #ifdef OPENSSL_EXTRA
01788                     dName->lIdx = cert->srcIdx;
01789                     dName->lLen = strLen;
01790                 #endif /* OPENSSL_EXTRA */
01791             }
01792             else if (id == ASN_STATE_NAME) {
01793                 if (!tooBig) {
01794                     XMEMCPY(&full[idx], "/ST=", 4);
01795                     idx += 4;
01796                     copy = TRUE;
01797                 }
01798                 #ifdef CYASSL_CERT_GEN
01799                     if (nameType == SUBJECT) {
01800                         cert->subjectST = (char*)&cert->source[cert->srcIdx];
01801                         cert->subjectSTLen = strLen;
01802                     }
01803                 #endif /* CYASSL_CERT_GEN */
01804                 #ifdef OPENSSL_EXTRA
01805                     dName->stIdx = cert->srcIdx;
01806                     dName->stLen = strLen;
01807                 #endif /* OPENSSL_EXTRA */
01808             }
01809             else if (id == ASN_ORG_NAME) {
01810                 if (!tooBig) {
01811                     XMEMCPY(&full[idx], "/O=", 3);
01812                     idx += 3;
01813                     copy = TRUE;
01814                 }
01815                 #ifdef CYASSL_CERT_GEN
01816                     if (nameType == SUBJECT) {
01817                         cert->subjectO = (char*)&cert->source[cert->srcIdx];
01818                         cert->subjectOLen = strLen;
01819                     }
01820                 #endif /* CYASSL_CERT_GEN */
01821                 #ifdef OPENSSL_EXTRA
01822                     dName->oIdx = cert->srcIdx;
01823                     dName->oLen = strLen;
01824                 #endif /* OPENSSL_EXTRA */
01825             }
01826             else if (id == ASN_ORGUNIT_NAME) {
01827                 if (!tooBig) {
01828                     XMEMCPY(&full[idx], "/OU=", 4);
01829                     idx += 4;
01830                     copy = TRUE;
01831                 }
01832                 #ifdef CYASSL_CERT_GEN
01833                     if (nameType == SUBJECT) {
01834                         cert->subjectOU = (char*)&cert->source[cert->srcIdx];
01835                         cert->subjectOULen = strLen;
01836                     }
01837                 #endif /* CYASSL_CERT_GEN */
01838                 #ifdef OPENSSL_EXTRA
01839                     dName->ouIdx = cert->srcIdx;
01840                     dName->ouLen = strLen;
01841                 #endif /* OPENSSL_EXTRA */
01842             }
01843             else if (id == ASN_SERIAL_NUMBER) {
01844                 if (!tooBig) {
01845                    XMEMCPY(&full[idx], "/serialNumber=", 14);
01846                    idx += 14;
01847                    copy = TRUE;
01848                 }
01849                 #ifdef OPENSSL_EXTRA
01850                     dName->snIdx = cert->srcIdx;
01851                     dName->snLen = strLen;
01852                 #endif /* OPENSSL_EXTRA */
01853             }
01854 
01855             if (copy && !tooBig) {
01856                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
01857                 idx += strLen;
01858             }
01859 
01860             cert->srcIdx += strLen;
01861         }
01862         else {
01863             /* skip */
01864             byte email = FALSE;
01865             byte uid   = FALSE;
01866             int  adv;
01867 
01868             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
01869                 email = TRUE;
01870 
01871             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
01872                 uid = TRUE;
01873 
01874             cert->srcIdx += oidSz + 1;
01875 
01876             if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
01877                 return ASN_PARSE_E;
01878 
01879             if (adv > (int)(ASN_NAME_MAX - idx)) {
01880                 CYASSL_MSG("ASN name too big, skipping");
01881                 tooBig = TRUE;
01882             }
01883 
01884             if (email) {
01885                 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
01886                     CYASSL_MSG("ASN name too big, skipping");
01887                     tooBig = TRUE;
01888                 }
01889                 if (!tooBig) {
01890                     XMEMCPY(&full[idx], "/emailAddress=", 14);
01891                     idx += 14;
01892                 }
01893 
01894                 #ifdef CYASSL_CERT_GEN
01895                     if (nameType == SUBJECT) {
01896                         cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
01897                         cert->subjectEmailLen = adv;
01898                     }
01899                 #endif /* CYASSL_CERT_GEN */
01900                 #ifdef OPENSSL_EXTRA
01901                     dName->emailIdx = cert->srcIdx;
01902                     dName->emailLen = adv;
01903                 #endif /* OPENSSL_EXTRA */
01904                 #ifndef IGNORE_NAME_CONSTRAINTS
01905                     {
01906                         DNS_entry* emailName = NULL;
01907 
01908                         emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
01909                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
01910                         if (emailName == NULL) {
01911                             CYASSL_MSG("\tOut of Memory");
01912                             return MEMORY_E;
01913                         }
01914                         emailName->name = (char*)XMALLOC(adv + 1,
01915                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
01916                         if (emailName->name == NULL) {
01917                             CYASSL_MSG("\tOut of Memory");
01918                             return MEMORY_E;
01919                         }
01920                         XMEMCPY(emailName->name,
01921                                               &cert->source[cert->srcIdx], adv);
01922                         emailName->name[adv] = 0;
01923 
01924                         emailName->next = cert->altEmailNames;
01925                         cert->altEmailNames = emailName;
01926                     }
01927                 #endif /* IGNORE_NAME_CONSTRAINTS */
01928                 if (!tooBig) {
01929                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
01930                     idx += adv;
01931                 }
01932             }
01933 
01934             if (uid) {
01935                 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
01936                     CYASSL_MSG("ASN name too big, skipping");
01937                     tooBig = TRUE;
01938                 }
01939                 if (!tooBig) {
01940                     XMEMCPY(&full[idx], "/UID=", 5);
01941                     idx += 5;
01942 
01943                     XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
01944                     idx += adv;
01945                 }
01946                 #ifdef OPENSSL_EXTRA
01947                     dName->uidIdx = cert->srcIdx;
01948                     dName->uidLen = adv;
01949                 #endif /* OPENSSL_EXTRA */
01950             }
01951 
01952             cert->srcIdx += adv;
01953         }
01954     }
01955     full[idx++] = 0;
01956 
01957     #ifdef OPENSSL_EXTRA
01958     {
01959         int totalLen = 0;
01960 
01961         if (dName->cnLen != 0)
01962             totalLen += dName->cnLen + 4;
01963         if (dName->snLen != 0)
01964             totalLen += dName->snLen + 4;
01965         if (dName->cLen != 0)
01966             totalLen += dName->cLen + 3;
01967         if (dName->lLen != 0)
01968             totalLen += dName->lLen + 3;
01969         if (dName->stLen != 0)
01970             totalLen += dName->stLen + 4;
01971         if (dName->oLen != 0)
01972             totalLen += dName->oLen + 3;
01973         if (dName->ouLen != 0)
01974             totalLen += dName->ouLen + 4;
01975         if (dName->emailLen != 0)
01976             totalLen += dName->emailLen + 14;
01977         if (dName->uidLen != 0)
01978             totalLen += dName->uidLen + 5;
01979         if (dName->serialLen != 0)
01980             totalLen += dName->serialLen + 14;
01981 
01982         dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
01983         if (dName->fullName != NULL) {
01984             idx = 0;
01985 
01986             if (dName->cnLen != 0) {
01987                 dName->entryCount++;
01988                 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
01989                 idx += 4;
01990                 XMEMCPY(&dName->fullName[idx],
01991                                      &cert->source[dName->cnIdx], dName->cnLen);
01992                 dName->cnIdx = idx;
01993                 idx += dName->cnLen;
01994             }
01995             if (dName->snLen != 0) {
01996                 dName->entryCount++;
01997                 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
01998                 idx += 4;
01999                 XMEMCPY(&dName->fullName[idx],
02000                                      &cert->source[dName->snIdx], dName->snLen);
02001                 dName->snIdx = idx;
02002                 idx += dName->snLen;
02003             }
02004             if (dName->cLen != 0) {
02005                 dName->entryCount++;
02006                 XMEMCPY(&dName->fullName[idx], "/C=", 3);
02007                 idx += 3;
02008                 XMEMCPY(&dName->fullName[idx],
02009                                        &cert->source[dName->cIdx], dName->cLen);
02010                 dName->cIdx = idx;
02011                 idx += dName->cLen;
02012             }
02013             if (dName->lLen != 0) {
02014                 dName->entryCount++;
02015                 XMEMCPY(&dName->fullName[idx], "/L=", 3);
02016                 idx += 3;
02017                 XMEMCPY(&dName->fullName[idx],
02018                                        &cert->source[dName->lIdx], dName->lLen);
02019                 dName->lIdx = idx;
02020                 idx += dName->lLen;
02021             }
02022             if (dName->stLen != 0) {
02023                 dName->entryCount++;
02024                 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
02025                 idx += 4;
02026                 XMEMCPY(&dName->fullName[idx],
02027                                      &cert->source[dName->stIdx], dName->stLen);
02028                 dName->stIdx = idx;
02029                 idx += dName->stLen;
02030             }
02031             if (dName->oLen != 0) {
02032                 dName->entryCount++;
02033                 XMEMCPY(&dName->fullName[idx], "/O=", 3);
02034                 idx += 3;
02035                 XMEMCPY(&dName->fullName[idx],
02036                                        &cert->source[dName->oIdx], dName->oLen);
02037                 dName->oIdx = idx;
02038                 idx += dName->oLen;
02039             }
02040             if (dName->ouLen != 0) {
02041                 dName->entryCount++;
02042                 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
02043                 idx += 4;
02044                 XMEMCPY(&dName->fullName[idx],
02045                                      &cert->source[dName->ouIdx], dName->ouLen);
02046                 dName->ouIdx = idx;
02047                 idx += dName->ouLen;
02048             }
02049             if (dName->emailLen != 0) {
02050                 dName->entryCount++;
02051                 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
02052                 idx += 14;
02053                 XMEMCPY(&dName->fullName[idx],
02054                                &cert->source[dName->emailIdx], dName->emailLen);
02055                 dName->emailIdx = idx;
02056                 idx += dName->emailLen;
02057             }
02058             if (dName->uidLen != 0) {
02059                 dName->entryCount++;
02060                 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
02061                 idx += 5;
02062                 XMEMCPY(&dName->fullName[idx],
02063                                    &cert->source[dName->uidIdx], dName->uidLen);
02064                 dName->uidIdx = idx;
02065                 idx += dName->uidLen;
02066             }
02067             if (dName->serialLen != 0) {
02068                 dName->entryCount++;
02069                 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
02070                 idx += 14;
02071                 XMEMCPY(&dName->fullName[idx],
02072                              &cert->source[dName->serialIdx], dName->serialLen);
02073                 dName->serialIdx = idx;
02074                 idx += dName->serialLen;
02075             }
02076             dName->fullName[idx] = '\0';
02077             dName->fullNameLen = totalLen;
02078         }
02079     }
02080     #endif /* OPENSSL_EXTRA */
02081 
02082     return 0;
02083 }
02084 
02085 
02086 #ifndef NO_TIME_H
02087 
02088 /* to the second */
02089 static int DateGreaterThan(const struct tm* a, const struct tm* b)
02090 {
02091     if (a->tm_year > b->tm_year)
02092         return 1;
02093 
02094     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
02095         return 1;
02096     
02097     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
02098            a->tm_mday > b->tm_mday)
02099         return 1;
02100 
02101     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
02102         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
02103         return 1;
02104 
02105     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
02106         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
02107         a->tm_min > b->tm_min)
02108         return 1;
02109 
02110     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
02111         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
02112         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
02113         return 1;
02114 
02115     return 0; /* false */
02116 }
02117 
02118 
02119 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
02120 {
02121     return !DateGreaterThan(a,b);
02122 }
02123 
02124 
02125 /* like atoi but only use first byte */
02126 /* Make sure before and after dates are valid */
02127 int ValidateDate(const byte* date, byte format, int dateType)
02128 {
02129     time_t ltime;
02130     struct tm  certTime;
02131     struct tm* localTime;
02132     int    i = 0;
02133 
02134     ltime = XTIME(0);
02135     XMEMSET(&certTime, 0, sizeof(certTime));
02136 
02137     if (format == ASN_UTC_TIME) {
02138         if (btoi(date[0]) >= 5)
02139             certTime.tm_year = 1900;
02140         else
02141             certTime.tm_year = 2000;
02142     }
02143     else  { /* format == GENERALIZED_TIME */
02144         certTime.tm_year += btoi(date[i++]) * 1000;
02145         certTime.tm_year += btoi(date[i++]) * 100;
02146     }
02147 
02148     GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
02149     GetTime(&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;    /* adjust */
02150     GetTime(&certTime.tm_mday, date, &i);
02151     GetTime(&certTime.tm_hour, date, &i); 
02152     GetTime(&certTime.tm_min,  date, &i); 
02153     GetTime(&certTime.tm_sec,  date, &i); 
02154         
02155         if (date[i] != 'Z') {     /* only Zulu supported for this profile */
02156         CYASSL_MSG("Only Zulu time supported for this profile"); 
02157         return 0;
02158     }
02159 
02160     localTime = XGMTIME(&ltime);
02161 
02162     if (dateType == BEFORE) {
02163         if (DateLessThan(localTime, &certTime))
02164             return 0;
02165     }
02166     else
02167         if (DateGreaterThan(localTime, &certTime))
02168             return 0;
02169 
02170     return 1;
02171 }
02172 
02173 #endif /* NO_TIME_H */
02174 
02175 
02176 static int GetDate(DecodedCert* cert, int dateType)
02177 {
02178     int    length;
02179     byte   date[MAX_DATE_SIZE];
02180     byte   b;
02181     word32 startIdx = 0;
02182 
02183     if (dateType == BEFORE)
02184         cert->beforeDate = &cert->source[cert->srcIdx];
02185     else
02186         cert->afterDate = &cert->source[cert->srcIdx];
02187     startIdx = cert->srcIdx;
02188 
02189     b = cert->source[cert->srcIdx++];
02190     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
02191         return ASN_TIME_E;
02192 
02193     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
02194         return ASN_PARSE_E;
02195 
02196     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
02197         return ASN_DATE_SZ_E;
02198 
02199     XMEMCPY(date, &cert->source[cert->srcIdx], length);
02200     cert->srcIdx += length;
02201 
02202     if (dateType == BEFORE)
02203         cert->beforeDateLen = cert->srcIdx - startIdx;
02204     else
02205         cert->afterDateLen  = cert->srcIdx - startIdx;
02206 
02207     if (!XVALIDATE_DATE(date, b, dateType)) {
02208         if (dateType == BEFORE)
02209             return ASN_BEFORE_DATE_E;
02210         else
02211             return ASN_AFTER_DATE_E;
02212     }
02213 
02214     return 0;
02215 }
02216 
02217 
02218 static int GetValidity(DecodedCert* cert, int verify)
02219 {
02220     int length;
02221     int badDate = 0;
02222 
02223     if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
02224         return ASN_PARSE_E;
02225 
02226     if (GetDate(cert, BEFORE) < 0 && verify)
02227         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
02228     
02229     if (GetDate(cert, AFTER) < 0 && verify)
02230         return ASN_AFTER_DATE_E;
02231    
02232     if (badDate != 0)
02233         return badDate;
02234 
02235     return 0;
02236 }
02237 
02238 
02239 int DecodeToKey(DecodedCert* cert, int verify)
02240 {
02241     int badDate = 0;
02242     int ret;
02243 
02244     if ( (ret = GetCertHeader(cert)) < 0)
02245         return ret;
02246 
02247     CYASSL_MSG("Got Cert Header");
02248 
02249     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
02250                           cert->maxIdx)) < 0)
02251         return ret;
02252 
02253     CYASSL_MSG("Got Algo ID");
02254 
02255     if ( (ret = GetName(cert, ISSUER)) < 0)
02256         return ret;
02257 
02258     if ( (ret = GetValidity(cert, verify)) < 0)
02259         badDate = ret;
02260 
02261     if ( (ret = GetName(cert, SUBJECT)) < 0)
02262         return ret;
02263 
02264     CYASSL_MSG("Got Subject Name");
02265 
02266     if ( (ret = GetKey(cert)) < 0)
02267         return ret;
02268 
02269     CYASSL_MSG("Got Key");
02270 
02271     if (badDate != 0)
02272         return badDate;
02273 
02274     return ret;
02275 }
02276 
02277 
02278 static int GetSignature(DecodedCert* cert)
02279 {
02280     int    length;
02281     byte   b = cert->source[cert->srcIdx++];
02282 
02283     if (b != ASN_BIT_STRING)
02284         return ASN_BITSTR_E;
02285 
02286     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
02287         return ASN_PARSE_E;
02288 
02289     cert->sigLength = length;
02290 
02291     b = cert->source[cert->srcIdx++];
02292     if (b != 0x00)
02293         return ASN_EXPECT_0_E;
02294 
02295     cert->sigLength--;
02296     cert->signature = &cert->source[cert->srcIdx];
02297     cert->srcIdx += cert->sigLength;
02298 
02299     return 0;
02300 }
02301 
02302 
02303 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
02304 {
02305     output[0] = ASN_OCTET_STRING;
02306     output[1] = (byte)digSz;
02307     XMEMCPY(&output[2], digest, digSz);
02308 
02309     return digSz + 2;
02310 } 
02311 
02312 
02313 static word32 BytePrecision(word32 value)
02314 {
02315     word32 i;
02316     for (i = sizeof(value); i; --i)
02317         if (value >> ((i - 1) * CYASSL_BIT_SIZE))
02318             break;
02319 
02320     return i;
02321 }
02322 
02323 
02324 CYASSL_LOCAL word32 SetLength(word32 length, byte* output)
02325 {
02326     word32 i = 0, j;
02327 
02328     if (length < ASN_LONG_LENGTH)
02329         output[i++] = (byte)length;
02330     else {
02331         output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
02332       
02333         for (j = BytePrecision(length); j; --j) {
02334             output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE));
02335             i++;
02336         }
02337     }
02338 
02339     return i;
02340 }
02341 
02342 
02343 CYASSL_LOCAL word32 SetSequence(word32 len, byte* output)
02344 {
02345     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
02346     return SetLength(len, output + 1) + 1;
02347 }
02348 
02349 CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output)
02350 {
02351     output[0] = ASN_OCTET_STRING;
02352     return SetLength(len, output + 1) + 1;
02353 }
02354 
02355 /* Write a set header to output */
02356 CYASSL_LOCAL word32 SetSet(word32 len, byte* output)
02357 {
02358     output[0] = ASN_SET | ASN_CONSTRUCTED;
02359     return SetLength(len, output + 1) + 1;
02360 }
02361 
02362 CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
02363 {
02364 
02365     output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
02366                     | ASN_CONTEXT_SPECIFIC | number;
02367     return SetLength(len, output + 1) + 1;
02368 }
02369 
02370 CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
02371 {
02372     output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
02373     return SetLength(len, output + 1) + 1;
02374 }
02375 
02376 
02377 #if defined(HAVE_ECC) && defined(CYASSL_CERT_GEN)
02378 
02379 static word32 SetCurve(ecc_key* key, byte* output)
02380 {
02381 
02382     /* curve types */
02383     static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
02384                                              0x03, 0x01, 0x01};
02385     static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
02386                                             0x03, 0x01, 0x07};
02387     static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
02388                                              0x02};
02389     static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
02390                                              0x21};
02391     static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
02392                                              0x22};
02393     static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
02394                                              0x23};
02395 
02396     int    oidSz = 0;
02397     int    idx = 0;
02398     int    lenSz = 0;
02399     const  byte* oid = 0;
02400 
02401     output[0] = ASN_OBJECT_ID;
02402     idx++;
02403 
02404     switch (key->dp->size) {
02405         case 20:
02406             oidSz = sizeof(ECC_160r1_AlgoID);
02407             oid   =        ECC_160r1_AlgoID;
02408             break;
02409 
02410         case 24:
02411             oidSz = sizeof(ECC_192v1_AlgoID);
02412             oid   =        ECC_192v1_AlgoID;
02413             break;
02414 
02415         case 28:
02416             oidSz = sizeof(ECC_224r1_AlgoID);
02417             oid   =        ECC_224r1_AlgoID;
02418             break;
02419 
02420         case 32:
02421             oidSz = sizeof(ECC_256v1_AlgoID);
02422             oid   =        ECC_256v1_AlgoID;
02423             break;
02424 
02425         case 48:
02426             oidSz = sizeof(ECC_384r1_AlgoID);
02427             oid   =        ECC_384r1_AlgoID;
02428             break;
02429 
02430         case 66:
02431             oidSz = sizeof(ECC_521r1_AlgoID);
02432             oid   =        ECC_521r1_AlgoID;
02433             break;
02434 
02435         default:
02436             return ASN_UNKNOWN_OID_E;
02437     }
02438     lenSz = SetLength(oidSz, output+idx);
02439     idx += lenSz;
02440 
02441     XMEMCPY(output+idx, oid, oidSz);
02442     idx += oidSz;
02443 
02444     return idx;
02445 }
02446 
02447 #endif /* HAVE_ECC && CYASSL_CERT_GEN */
02448 
02449 
02450 CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
02451 {
02452     /* adding TAG_NULL and 0 to end */
02453     
02454     /* hashTypes */
02455     static const byte shaAlgoID[]    = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
02456                                          0x05, 0x00 };
02457     static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02458                                          0x04, 0x02, 0x01, 0x05, 0x00 };
02459     static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02460                                          0x04, 0x02, 0x02, 0x05, 0x00 };
02461     static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
02462                                          0x04, 0x02, 0x03, 0x05, 0x00 };
02463     static const byte md5AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02464                                          0x02, 0x05, 0x05, 0x00  };
02465     static const byte md2AlgoID[]    = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02466                                          0x02, 0x02, 0x05, 0x00};
02467 
02468     /* blkTypes, no NULL tags because IV is there instead */
02469     static const byte desCbcAlgoID[]  = { 0x2B, 0x0E, 0x03, 0x02, 0x07 };
02470     static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
02471                                           0x0D, 0x03, 0x07 };
02472 
02473     /* RSA sigTypes */
02474     #ifndef NO_RSA
02475         static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02476                                             0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
02477         static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02478                                             0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
02479         static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
02480                                             0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
02481         static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
02482                                             0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
02483         static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
02484                                             0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
02485     #endif /* NO_RSA */
02486  
02487     /* ECDSA sigTypes */
02488     #ifdef HAVE_ECC 
02489         static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
02490                                                  0x04, 0x01, 0x05, 0x00};
02491         static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
02492                                                  0x04, 0x03, 0x02, 0x05, 0x00};
02493         static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
02494                                                  0x04, 0x03, 0x03, 0x05, 0x00};
02495         static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
02496                                                  0x04, 0x03, 0x04, 0x05, 0x00};
02497     #endif /* HAVE_ECC */
02498  
02499     /* RSA keyType */
02500     #ifndef NO_RSA
02501         static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02502                                             0x01, 0x01, 0x01, 0x05, 0x00};
02503     #endif /* NO_RSA */
02504 
02505     #ifdef HAVE_ECC 
02506         /* ECC keyType */
02507         /* no tags, so set tagSz smaller later */
02508         static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
02509                                            0x02, 0x01};
02510     #endif /* HAVE_ECC */
02511 
02512     int    algoSz = 0;
02513     int    tagSz  = 2;   /* tag null and terminator */
02514     word32 idSz, seqSz;
02515     const  byte* algoName = 0;
02516     byte ID_Length[MAX_LENGTH_SZ];
02517     byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
02518 
02519     if (type == hashType) {
02520         switch (algoOID) {
02521         case SHAh:
02522             algoSz = sizeof(shaAlgoID);
02523             algoName = shaAlgoID;
02524             break;
02525 
02526         case SHA256h:
02527             algoSz = sizeof(sha256AlgoID);
02528             algoName = sha256AlgoID;
02529             break;
02530 
02531         case SHA384h:
02532             algoSz = sizeof(sha384AlgoID);
02533             algoName = sha384AlgoID;
02534             break;
02535 
02536         case SHA512h:
02537             algoSz = sizeof(sha512AlgoID);
02538             algoName = sha512AlgoID;
02539             break;
02540 
02541         case MD2h:
02542             algoSz = sizeof(md2AlgoID);
02543             algoName = md2AlgoID;
02544             break;
02545 
02546         case MD5h:
02547             algoSz = sizeof(md5AlgoID);
02548             algoName = md5AlgoID;
02549             break;
02550 
02551         default:
02552             CYASSL_MSG("Unknown Hash Algo");
02553             return 0;  /* UNKOWN_HASH_E; */
02554         }
02555     }
02556     else if (type == blkType) {
02557         switch (algoOID) {
02558         case DESb:
02559             algoSz = sizeof(desCbcAlgoID);
02560             algoName = desCbcAlgoID;
02561             tagSz = 0;
02562             break;
02563         case DES3b:
02564             algoSz = sizeof(des3CbcAlgoID);
02565             algoName = des3CbcAlgoID;
02566             tagSz = 0;
02567             break;
02568         default:
02569             CYASSL_MSG("Unknown Block Algo");
02570             return 0;
02571         }
02572     }
02573     else if (type == sigType) {    /* sigType */
02574         switch (algoOID) {
02575         #ifndef NO_RSA
02576             case CTC_MD5wRSA:
02577                 algoSz = sizeof(md5wRSA_AlgoID);
02578                 algoName = md5wRSA_AlgoID;
02579                 break;
02580 
02581             case CTC_SHAwRSA:
02582                 algoSz = sizeof(shawRSA_AlgoID);
02583                 algoName = shawRSA_AlgoID;
02584                 break;
02585 
02586             case CTC_SHA256wRSA:
02587                 algoSz = sizeof(sha256wRSA_AlgoID);
02588                 algoName = sha256wRSA_AlgoID;
02589                 break;
02590 
02591             case CTC_SHA384wRSA:
02592                 algoSz = sizeof(sha384wRSA_AlgoID);
02593                 algoName = sha384wRSA_AlgoID;
02594                 break;
02595 
02596             case CTC_SHA512wRSA:
02597                 algoSz = sizeof(sha512wRSA_AlgoID);
02598                 algoName = sha512wRSA_AlgoID;
02599                 break;
02600         #endif /* NO_RSA */
02601         #ifdef HAVE_ECC 
02602             case CTC_SHAwECDSA:
02603                 algoSz = sizeof(shawECDSA_AlgoID);
02604                 algoName = shawECDSA_AlgoID;
02605                 break;
02606 
02607             case CTC_SHA256wECDSA:
02608                 algoSz = sizeof(sha256wECDSA_AlgoID);
02609                 algoName = sha256wECDSA_AlgoID;
02610                 break;
02611 
02612             case CTC_SHA384wECDSA:
02613                 algoSz = sizeof(sha384wECDSA_AlgoID);
02614                 algoName = sha384wECDSA_AlgoID;
02615                 break;
02616 
02617             case CTC_SHA512wECDSA:
02618                 algoSz = sizeof(sha512wECDSA_AlgoID);
02619                 algoName = sha512wECDSA_AlgoID;
02620                 break;
02621         #endif /* HAVE_ECC */
02622         default:
02623             CYASSL_MSG("Unknown Signature Algo");
02624             return 0;
02625         }
02626     }
02627     else if (type == keyType) {    /* keyType */
02628         switch (algoOID) {
02629         #ifndef NO_RSA
02630             case RSAk:
02631                 algoSz = sizeof(RSA_AlgoID);
02632                 algoName = RSA_AlgoID;
02633                 break;
02634         #endif /* NO_RSA */
02635         #ifdef HAVE_ECC 
02636             case ECDSAk:
02637                 algoSz = sizeof(ECC_AlgoID);
02638                 algoName = ECC_AlgoID;
02639                 tagSz = 0;
02640                 break;
02641         #endif /* HAVE_ECC */
02642         default:
02643             CYASSL_MSG("Unknown Key Algo");
02644             return 0;
02645         }
02646     }
02647     else {
02648         CYASSL_MSG("Unknown Algo type");
02649         return 0;
02650     }
02651 
02652     idSz  = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
02653     seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray); 
02654                  /* +1 for object id, curveID of curveSz follows for ecc */
02655     seqArray[seqSz++] = ASN_OBJECT_ID;
02656 
02657     XMEMCPY(output, seqArray, seqSz);
02658     XMEMCPY(output + seqSz, ID_Length, idSz);
02659     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
02660 
02661     return seqSz + idSz + algoSz;
02662 
02663 }
02664 
02665 
02666 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
02667 {
02668     byte digArray[MAX_ENCODED_DIG_SZ];
02669     byte algoArray[MAX_ALGO_SZ];
02670     byte seqArray[MAX_SEQ_SZ];
02671     word32 encDigSz, algoSz, seqSz; 
02672 
02673     encDigSz = SetDigest(digest, digSz, digArray);
02674     algoSz   = SetAlgoID(hashOID, algoArray, hashType, 0);
02675     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
02676 
02677     XMEMCPY(out, seqArray, seqSz);
02678     XMEMCPY(out + seqSz, algoArray, algoSz);
02679     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
02680 
02681     return encDigSz + algoSz + seqSz;
02682 }
02683 
02684 
02685 /* return true (1) for Confirmation */
02686 static int ConfirmSignature(const byte* buf, word32 bufSz,
02687     const byte* key, word32 keySz, word32 keyOID,
02688     const byte* sig, word32 sigSz, word32 sigOID,
02689     void* heap)
02690 {
02691 #ifdef CYASSL_SHA512
02692     byte digest[SHA512_DIGEST_SIZE]; /* max size */
02693 #elif !defined(NO_SHA256)
02694     byte digest[SHA256_DIGEST_SIZE]; /* max size */
02695 #else
02696     byte digest[SHA_DIGEST_SIZE];    /* max size */
02697 #endif
02698     int  typeH, digestSz, ret = 0;
02699 
02700     (void)key;
02701     (void)keySz;
02702     (void)sig;
02703     (void)sigSz;
02704     (void)heap;
02705     (void)ret;
02706 
02707     switch (sigOID) {
02708 #ifndef NO_MD5
02709         case CTC_MD5wRSA:
02710         {
02711             Md5 md5;
02712             InitMd5(&md5);
02713             Md5Update(&md5, buf, bufSz);
02714             Md5Final(&md5, digest);
02715             typeH    = MD5h;
02716             digestSz = MD5_DIGEST_SIZE;
02717         }
02718         break;
02719 #endif
02720     #if defined(CYASSL_MD2)
02721         case CTC_MD2wRSA:
02722         {
02723             Md2 md2;
02724             InitMd2(&md2);
02725             Md2Update(&md2, buf, bufSz);
02726             Md2Final(&md2, digest);
02727             typeH    = MD2h;
02728             digestSz = MD2_DIGEST_SIZE;
02729         }
02730         break;
02731     #endif
02732 #ifndef NO_SHA
02733         case CTC_SHAwRSA:
02734         case CTC_SHAwDSA:
02735         case CTC_SHAwECDSA:
02736         {
02737             Sha sha;
02738             ret = InitSha(&sha);
02739             if (ret != 0) {
02740                 CYASSL_MSG("InitSha failed");
02741                 return 0;  /*  not confirmed */
02742             }
02743             ShaUpdate(&sha, buf, bufSz);
02744             ShaFinal(&sha, digest);
02745             typeH    = SHAh;
02746             digestSz = SHA_DIGEST_SIZE;
02747         }
02748         break;
02749 #endif
02750     #ifndef NO_SHA256
02751         case CTC_SHA256wRSA:
02752         case CTC_SHA256wECDSA:
02753         {
02754             Sha256 sha256;
02755             ret = InitSha256(&sha256);
02756             if (ret != 0) {
02757                 CYASSL_MSG("InitSha256 failed");
02758                 return 0;  /*  not confirmed */
02759             }
02760 
02761             ret = Sha256Update(&sha256, buf, bufSz);
02762             if (ret != 0) {
02763                 CYASSL_MSG("Sha256Update failed");
02764                 return 0;  /*  not confirmed */
02765             }
02766 
02767             ret = Sha256Final(&sha256, digest);
02768             if (ret != 0) {
02769                 CYASSL_MSG("Sha256Final failed");
02770                 return 0;  /*  not confirmed */
02771             }
02772 
02773             typeH    = SHA256h;
02774             digestSz = SHA256_DIGEST_SIZE;
02775         }
02776         break;
02777     #endif
02778     #ifdef CYASSL_SHA512
02779         case CTC_SHA512wRSA:
02780         case CTC_SHA512wECDSA:
02781         {
02782             Sha512 sha512;
02783             ret = InitSha512(&sha512);
02784             if (ret != 0) {
02785                 CYASSL_MSG("InitSha512 failed");
02786                 return 0;  /*  not confirmed */
02787             }
02788 
02789             ret = Sha512Update(&sha512, buf, bufSz);
02790             if (ret != 0) {
02791                 CYASSL_MSG("Sha512Update failed");
02792                 return 0;  /*  not confirmed */
02793             }
02794 
02795             ret = Sha512Final(&sha512, digest);
02796             if (ret != 0) {
02797                 CYASSL_MSG("Sha512Final failed");
02798                 return 0;  /*  not confirmed */
02799             }
02800 
02801             typeH    = SHA512h;
02802             digestSz = SHA512_DIGEST_SIZE;
02803         }
02804         break;
02805     #endif
02806     #ifdef CYASSL_SHA384
02807         case CTC_SHA384wRSA:
02808         case CTC_SHA384wECDSA:
02809         {
02810             Sha384 sha384;
02811             ret = InitSha384(&sha384);
02812             if (ret != 0) {
02813                 CYASSL_MSG("InitSha384 failed");
02814                 return 0;  /*  not confirmed */
02815             }
02816 
02817             ret = Sha384Update(&sha384, buf, bufSz);
02818             if (ret != 0) {
02819                 CYASSL_MSG("Sha384Update failed");
02820                 return 0;  /*  not confirmed */
02821             }
02822 
02823             ret = Sha384Final(&sha384, digest);
02824             if (ret != 0) {
02825                 CYASSL_MSG("Sha384Final failed");
02826                 return 0;  /*  not confirmed */
02827             }
02828 
02829             typeH    = SHA384h;
02830             digestSz = SHA384_DIGEST_SIZE;
02831         }
02832         break;
02833     #endif
02834         default:
02835             CYASSL_MSG("Verify Signautre has unsupported type");
02836             return 0;
02837     }
02838     (void)typeH;  /* some builds won't read */
02839 
02840     switch (keyOID) {
02841     #ifndef NO_RSA
02842         case RSAk:
02843         {
02844             RsaKey pubKey;
02845             byte   encodedSig[MAX_ENCODED_SIG_SZ];
02846             byte   plain[MAX_ENCODED_SIG_SZ];
02847             word32 idx = 0;
02848             int    encodedSigSz, verifySz;
02849             byte*  out;
02850 
02851             if (sigSz > MAX_ENCODED_SIG_SZ) {
02852                 CYASSL_MSG("Verify Signautre is too big");
02853                 return 0;
02854             }
02855                 
02856             ret = InitRsaKey(&pubKey, heap);
02857             if (ret != 0) return ret;
02858             if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) {
02859                 CYASSL_MSG("ASN Key decode error RSA");
02860                 ret = 0;
02861             }
02862             else {
02863                 XMEMCPY(plain, sig, sigSz);
02864                 if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out,
02865                                                &pubKey)) < 0) {
02866                     CYASSL_MSG("Rsa SSL verify error");
02867                     ret = 0;
02868                 }
02869                 else {
02870                     /* make sure we're right justified */
02871                     encodedSigSz =
02872                         EncodeSignature(encodedSig, digest, digestSz, typeH);
02873                     if (encodedSigSz != verifySz ||
02874                                 XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
02875                         CYASSL_MSG("Rsa SSL verify match encode error");
02876                         ret = 0;
02877                     }
02878                     else
02879                         ret = 1; /* match */
02880 
02881                     #ifdef CYASSL_DEBUG_ENCODING
02882                     {
02883                     int x;
02884                     printf("cyassl encodedSig:\n");
02885                     for (x = 0; x < encodedSigSz; x++) {
02886                         printf("%02x ", encodedSig[x]);
02887                         if ( (x % 16) == 15)
02888                             printf("\n");
02889                     }
02890                     printf("\n");
02891                     printf("actual digest:\n");
02892                     for (x = 0; x < verifySz; x++) {
02893                         printf("%02x ", out[x]);
02894                         if ( (x % 16) == 15)
02895                             printf("\n");
02896                     }
02897                     printf("\n");
02898                     }
02899                     #endif /* CYASSL_DEBUG_ENCODING */
02900                 }
02901             }
02902             FreeRsaKey(&pubKey);
02903             return ret;
02904         }
02905 
02906     #endif /* NO_RSA */
02907     #ifdef HAVE_ECC
02908         case ECDSAk:
02909         {
02910             ecc_key pubKey;
02911             int     verify = 0;
02912             
02913             if (ecc_import_x963(key, keySz, &pubKey) < 0) {
02914                 CYASSL_MSG("ASN Key import error ECC");
02915                 return 0;
02916             }
02917         
02918             ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey);
02919             ecc_free(&pubKey);
02920             if (ret == 0 && verify == 1)
02921                 return 1;  /* match */
02922 
02923             CYASSL_MSG("ECC Verify didn't match");
02924             return 0;
02925         }
02926     #endif /* HAVE_ECC */
02927         default:
02928             CYASSL_MSG("Verify Key type unknown");
02929             return 0;
02930     }
02931 }
02932 
02933 
02934 #ifndef IGNORE_NAME_CONSTRAINTS
02935 
02936 static int MatchBaseName(int type, const char* name, int nameSz,
02937                                                    const char* base, int baseSz)
02938 {
02939     if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
02940             name[0] == '.' || nameSz < baseSz ||
02941             (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
02942         return 0;
02943 
02944     /* If an email type, handle special cases where the base is only
02945      * a domain, or is an email address itself. */
02946     if (type == ASN_RFC822_TYPE) {
02947         const char* p = NULL;
02948         int count = 0;
02949 
02950         if (base[0] != '.') {
02951             p = base;
02952             count = 0;
02953 
02954             /* find the '@' in the base */
02955             while (*p != '@' && count < baseSz) {
02956                 count++;
02957                 p++;
02958             }
02959 
02960             /* No '@' in base, reset p to NULL */
02961             if (count >= baseSz)
02962                 p = NULL;
02963         }
02964 
02965         if (p == NULL) {
02966             /* Base isn't an email address, it is a domain name,
02967              * wind the name forward one character past its '@'. */
02968             p = name;
02969             count = 0;
02970             while (*p != '@' && count < baseSz) {
02971                 count++;
02972                 p++;
02973             }
02974 
02975             if (count < baseSz && *p == '@') {
02976                 name = p + 1;
02977                 nameSz -= count + 1;
02978             }
02979         }
02980     }
02981 
02982     if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
02983         int szAdjust = nameSz - baseSz;
02984         name += szAdjust;
02985         nameSz -= szAdjust;
02986     }
02987 
02988     while (nameSz > 0) {
02989         if (XTOLOWER(*name++) != XTOLOWER(*base++))
02990             return 0;
02991         nameSz--;
02992     }
02993 
02994     return 1;
02995 }
02996 
02997 
02998 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
02999 {
03000     if (signer == NULL || cert == NULL)
03001         return 0;
03002 
03003     /* Check against the excluded list */
03004     if (signer->excludedNames) {
03005         Base_entry* base = signer->excludedNames;
03006 
03007         while (base != NULL) {
03008             if (base->type == ASN_DNS_TYPE) {
03009                 DNS_entry* name = cert->altNames;
03010                 while (name != NULL) {
03011                     if (MatchBaseName(ASN_DNS_TYPE,
03012                                           name->name, (int)XSTRLEN(name->name),
03013                                           base->name, base->nameSz))
03014                         return 0;
03015                     name = name->next;
03016                 }
03017             }
03018             else if (base->type == ASN_RFC822_TYPE) {
03019                 DNS_entry* name = cert->altEmailNames;
03020                 while (name != NULL) {
03021                     if (MatchBaseName(ASN_RFC822_TYPE,
03022                                           name->name, (int)XSTRLEN(name->name),
03023                                           base->name, base->nameSz))
03024                         return 0;
03025 
03026                     name = name->next;
03027                 }
03028             }
03029             else if (base->type == ASN_DIR_TYPE) {
03030                 if (cert->subjectRawLen == base->nameSz &&
03031                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
03032 
03033                     return 0;
03034                 }
03035             }
03036             base = base->next;
03037         }
03038     }
03039 
03040     /* Check against the permitted list */
03041     if (signer->permittedNames != NULL) {
03042         int needDns = 0;
03043         int matchDns = 0;
03044         int needEmail = 0;
03045         int matchEmail = 0;
03046         int needDir = 0;
03047         int matchDir = 0;
03048         Base_entry* base = signer->permittedNames;
03049 
03050         while (base != NULL) {
03051             if (base->type == ASN_DNS_TYPE) {
03052                 DNS_entry* name = cert->altNames;
03053 
03054                 if (name != NULL)
03055                     needDns = 1;
03056 
03057                 while (name != NULL) {
03058                     matchDns = MatchBaseName(ASN_DNS_TYPE,
03059                                           name->name, (int)XSTRLEN(name->name),
03060                                           base->name, base->nameSz);
03061                     name = name->next;
03062                 }
03063             }
03064             else if (base->type == ASN_RFC822_TYPE) {
03065                 DNS_entry* name = cert->altEmailNames;
03066 
03067                 if (name != NULL)
03068                     needEmail = 1;
03069 
03070                 while (name != NULL) {
03071                     matchEmail = MatchBaseName(ASN_DNS_TYPE,
03072                                           name->name, (int)XSTRLEN(name->name),
03073                                           base->name, base->nameSz);
03074                     name = name->next;
03075                 }
03076             }
03077             else if (base->type == ASN_DIR_TYPE) {
03078                 needDir = 1;
03079                 if (cert->subjectRaw != NULL &&
03080                     cert->subjectRawLen == base->nameSz &&
03081                     XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
03082 
03083                     matchDir = 1;
03084                 }
03085             }
03086             base = base->next;
03087         }
03088 
03089         if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
03090             (needDir && !matchDir)) {
03091 
03092             return 0;
03093         }
03094     }
03095 
03096     return 1;
03097 }
03098 
03099 #endif /* IGNORE_NAME_CONSTRAINTS */
03100 
03101 
03102 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
03103 {
03104     word32 idx = 0;
03105     int length = 0;
03106 
03107     CYASSL_ENTER("DecodeAltNames");
03108 
03109     if (GetSequence(input, &idx, &length, sz) < 0) {
03110         CYASSL_MSG("\tBad Sequence");
03111         return ASN_PARSE_E;
03112     }
03113 
03114     while (length > 0) {
03115         byte       b = input[idx++];
03116 
03117         length--;
03118 
03119         /* Save DNS Type names in the altNames list. */
03120         /* Save Other Type names in the cert's OidMap */
03121         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
03122             DNS_entry* dnsEntry;
03123             int strLen;
03124             word32 lenStartIdx = idx;
03125 
03126             if (GetLength(input, &idx, &strLen, sz) < 0) {
03127                 CYASSL_MSG("\tfail: str length");
03128                 return ASN_PARSE_E;
03129             }
03130             length -= (idx - lenStartIdx);
03131 
03132             dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
03133                                         DYNAMIC_TYPE_ALTNAME);
03134             if (dnsEntry == NULL) {
03135                 CYASSL_MSG("\tOut of Memory");
03136                 return ASN_PARSE_E;
03137             }
03138 
03139             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
03140                                          DYNAMIC_TYPE_ALTNAME);
03141             if (dnsEntry->name == NULL) {
03142                 CYASSL_MSG("\tOut of Memory");
03143                 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
03144                 return ASN_PARSE_E;
03145             }
03146 
03147             XMEMCPY(dnsEntry->name, &input[idx], strLen);
03148             dnsEntry->name[strLen] = '\0';
03149 
03150             dnsEntry->next = cert->altNames;
03151             cert->altNames = dnsEntry;
03152 
03153             length -= strLen;
03154             idx    += strLen;
03155         }
03156 #ifndef IGNORE_NAME_CONSTRAINTS
03157         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
03158             DNS_entry* emailEntry;
03159             int strLen;
03160             word32 lenStartIdx = idx;
03161 
03162             if (GetLength(input, &idx, &strLen, sz) < 0) {
03163                 CYASSL_MSG("\tfail: str length");
03164                 return ASN_PARSE_E;
03165             }
03166             length -= (idx - lenStartIdx);
03167 
03168             emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
03169                                         DYNAMIC_TYPE_ALTNAME);
03170             if (emailEntry == NULL) {
03171                 CYASSL_MSG("\tOut of Memory");
03172                 return ASN_PARSE_E;
03173             }
03174 
03175             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
03176                                          DYNAMIC_TYPE_ALTNAME);
03177             if (emailEntry->name == NULL) {
03178                 CYASSL_MSG("\tOut of Memory");
03179                 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
03180                 return ASN_PARSE_E;
03181             }
03182 
03183             XMEMCPY(emailEntry->name, &input[idx], strLen);
03184             emailEntry->name[strLen] = '\0';
03185 
03186             emailEntry->next = cert->altEmailNames;
03187             cert->altEmailNames = emailEntry;
03188 
03189             length -= strLen;
03190             idx    += strLen;
03191         }
03192 #endif /* IGNORE_NAME_CONSTRAINTS */
03193 #ifdef CYASSL_SEP
03194         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
03195         {
03196             int strLen;
03197             word32 lenStartIdx = idx;
03198             word32 oid = 0;
03199 
03200             if (GetLength(input, &idx, &strLen, sz) < 0) {
03201                 CYASSL_MSG("\tfail: other name length");
03202                 return ASN_PARSE_E;
03203             }
03204             /* Consume the rest of this sequence. */
03205             length -= (strLen + idx - lenStartIdx);
03206 
03207             if (GetObjectId(input, &idx, &oid, sz) < 0) {
03208                 CYASSL_MSG("\tbad OID");
03209                 return ASN_PARSE_E;
03210             }
03211 
03212             if (oid != HW_NAME_OID) {
03213                 CYASSL_MSG("\tincorrect OID");
03214                 return ASN_PARSE_E;
03215             }
03216 
03217             if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
03218                 CYASSL_MSG("\twrong type");
03219                 return ASN_PARSE_E;
03220             }
03221 
03222             if (GetLength(input, &idx, &strLen, sz) < 0) {
03223                 CYASSL_MSG("\tfail: str len");
03224                 return ASN_PARSE_E;
03225             }
03226 
03227             if (GetSequence(input, &idx, &strLen, sz) < 0) {
03228                 CYASSL_MSG("\tBad Sequence");
03229                 return ASN_PARSE_E;
03230             }
03231 
03232             if (input[idx++] != ASN_OBJECT_ID) {
03233                 CYASSL_MSG("\texpected OID");
03234                 return ASN_PARSE_E;
03235             }
03236 
03237             if (GetLength(input, &idx, &strLen, sz) < 0) {
03238                 CYASSL_MSG("\tfailed: str len");
03239                 return ASN_PARSE_E;
03240             }
03241 
03242             cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
03243             if (cert->hwType == NULL) {
03244                 CYASSL_MSG("\tOut of Memory");
03245                 return MEMORY_E;
03246             }
03247 
03248             XMEMCPY(cert->hwType, &input[idx], strLen);
03249             cert->hwTypeSz = strLen;
03250             idx += strLen;
03251 
03252             if (input[idx++] != ASN_OCTET_STRING) {
03253                 CYASSL_MSG("\texpected Octet String");
03254                 return ASN_PARSE_E;
03255             }
03256 
03257             if (GetLength(input, &idx, &strLen, sz) < 0) {
03258                 CYASSL_MSG("\tfailed: str len");
03259                 return ASN_PARSE_E;
03260             }
03261 
03262             cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
03263             if (cert->hwSerialNum == NULL) {
03264                 CYASSL_MSG("\tOut of Memory");
03265                 return MEMORY_E;
03266             }
03267 
03268             XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
03269             cert->hwSerialNum[strLen] = '\0';
03270             cert->hwSerialNumSz = strLen;
03271             idx += strLen;
03272         }
03273 #endif /* CYASSL_SEP */
03274         else {
03275             int strLen;
03276             word32 lenStartIdx = idx;
03277 
03278             CYASSL_MSG("\tUnsupported name type, skipping");
03279 
03280             if (GetLength(input, &idx, &strLen, sz) < 0) {
03281                 CYASSL_MSG("\tfail: unsupported name length");
03282                 return ASN_PARSE_E;
03283             }
03284             length -= (strLen + idx - lenStartIdx);
03285             idx += strLen;
03286         }
03287     }
03288     return 0;
03289 }
03290 
03291 
03292 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
03293 {
03294     word32 idx = 0;
03295     int length = 0;
03296 
03297     CYASSL_ENTER("DecodeBasicCaConstraint");
03298     if (GetSequence(input, &idx, &length, sz) < 0) {
03299         CYASSL_MSG("\tfail: bad SEQUENCE");
03300         return ASN_PARSE_E;
03301     }
03302 
03303     if (length == 0)
03304         return 0;
03305 
03306     /* If the basic ca constraint is false, this extension may be named, but
03307      * left empty. So, if the length is 0, just return. */
03308 
03309     if (input[idx++] != ASN_BOOLEAN)
03310     {
03311         CYASSL_MSG("\tfail: constraint not BOOLEAN");
03312         return ASN_PARSE_E;
03313     }
03314 
03315     if (GetLength(input, &idx, &length, sz) < 0)
03316     {
03317         CYASSL_MSG("\tfail: length");
03318         return ASN_PARSE_E;
03319     }
03320 
03321     if (input[idx++])
03322         cert->isCA = 1;
03323 
03324     #ifdef OPENSSL_EXTRA
03325         /* If there isn't any more data, return. */
03326         if (idx >= (word32)sz)
03327             return 0;
03328 
03329         /* Anything left should be the optional pathlength */
03330         if (input[idx++] != ASN_INTEGER) {
03331             CYASSL_MSG("\tfail: pathlen not INTEGER");
03332             return ASN_PARSE_E;
03333         }
03334 
03335         if (input[idx++] != 1) {
03336             CYASSL_MSG("\tfail: pathlen too long");
03337             return ASN_PARSE_E;
03338         }
03339 
03340         cert->pathLength = input[idx];
03341         cert->extBasicConstPlSet = 1;
03342     #endif /* OPENSSL_EXTRA */
03343 
03344     return 0;
03345 }
03346 
03347 
03348 #define CRLDP_FULL_NAME 0
03349     /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
03350 #define GENERALNAME_URI 6
03351     /* From RFC3280 SS4.2.1.7, GeneralName */
03352 
03353 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
03354 {
03355     word32 idx = 0;
03356     int length = 0;
03357 
03358     CYASSL_ENTER("DecodeCrlDist");
03359 
03360     /* Unwrap the list of Distribution Points*/
03361     if (GetSequence(input, &idx, &length, sz) < 0)
03362         return ASN_PARSE_E;
03363 
03364     /* Unwrap a single Distribution Point */
03365     if (GetSequence(input, &idx, &length, sz) < 0)
03366         return ASN_PARSE_E;
03367 
03368     /* The Distribution Point has three explicit optional members
03369      *  First check for a DistributionPointName
03370      */
03371     if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
03372     {
03373         idx++;
03374         if (GetLength(input, &idx, &length, sz) < 0)
03375             return ASN_PARSE_E;
03376 
03377         if (input[idx] == 
03378                     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
03379         {
03380             idx++;
03381             if (GetLength(input, &idx, &length, sz) < 0)
03382                 return ASN_PARSE_E;
03383 
03384             if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
03385             {
03386                 idx++;
03387                 if (GetLength(input, &idx, &length, sz) < 0)
03388                     return ASN_PARSE_E;
03389 
03390                 cert->extCrlInfoSz = length;
03391                 cert->extCrlInfo = input + idx;
03392                 idx += length;
03393             }
03394             else
03395                 /* This isn't a URI, skip it. */
03396                 idx += length;
03397         }
03398         else
03399             /* This isn't a FULLNAME, skip it. */
03400             idx += length;
03401     }
03402 
03403     /* Check for reasonFlags */
03404     if (idx < (word32)sz &&
03405         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
03406     {
03407         idx++;
03408         if (GetLength(input, &idx, &length, sz) < 0)
03409             return ASN_PARSE_E;
03410         idx += length;
03411     }
03412 
03413     /* Check for cRLIssuer */
03414     if (idx < (word32)sz &&
03415         input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
03416     {
03417         idx++;
03418         if (GetLength(input, &idx, &length, sz) < 0)
03419             return ASN_PARSE_E;
03420         idx += length;
03421     }
03422 
03423     if (idx < (word32)sz)
03424     {
03425         CYASSL_MSG("\tThere are more CRL Distribution Point records, "
03426                    "but we only use the first one.");
03427     }
03428 
03429     return 0;
03430 }
03431 
03432 
03433 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
03434 /*
03435  *  Read the first of the Authority Information Access records. If there are
03436  *  any issues, return without saving the record.
03437  */
03438 {
03439     word32 idx = 0;
03440     int length = 0;
03441     byte b;
03442     word32 oid;
03443 
03444     CYASSL_ENTER("DecodeAuthInfo");
03445 
03446     /* Unwrap the list of AIAs */
03447     if (GetSequence(input, &idx, &length, sz) < 0)
03448         return ASN_PARSE_E;
03449 
03450     while (idx < (word32)sz) {
03451         /* Unwrap a single AIA */
03452         if (GetSequence(input, &idx, &length, sz) < 0)
03453             return ASN_PARSE_E;
03454 
03455         oid = 0;
03456         if (GetObjectId(input, &idx, &oid, sz) < 0)
03457             return ASN_PARSE_E;
03458 
03459         /* Only supporting URIs right now. */
03460         b = input[idx++];
03461         if (GetLength(input, &idx, &length, sz) < 0)
03462             return ASN_PARSE_E;
03463 
03464         if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
03465             oid == AIA_OCSP_OID)
03466         {
03467             cert->extAuthInfoSz = length;
03468             cert->extAuthInfo = input + idx;
03469             break;
03470         }
03471         idx += length;
03472     }
03473 
03474     return 0;
03475 }
03476 
03477 
03478 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
03479 {
03480     word32 idx = 0;
03481     int length = 0, ret = 0;
03482 
03483     CYASSL_ENTER("DecodeAuthKeyId");
03484 
03485     if (GetSequence(input, &idx, &length, sz) < 0) {
03486         CYASSL_MSG("\tfail: should be a SEQUENCE\n");
03487         return ASN_PARSE_E;
03488     }
03489 
03490     if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
03491         CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n");
03492         return ASN_PARSE_E;
03493     }
03494 
03495     if (GetLength(input, &idx, &length, sz) < 0) {
03496         CYASSL_MSG("\tfail: extension data length");
03497         return ASN_PARSE_E;
03498     }
03499 
03500     #ifdef OPENSSL_EXTRA
03501         cert->extAuthKeyIdSrc = &input[idx];
03502         cert->extAuthKeyIdSz = length;
03503     #endif /* OPENSSL_EXTRA */
03504 
03505     if (length == SHA_SIZE) {
03506         XMEMCPY(cert->extAuthKeyId, input + idx, length);
03507     }
03508     else {
03509         Sha sha;
03510         ret = InitSha(&sha);
03511         if (ret != 0)
03512             return ret;
03513         ShaUpdate(&sha, input + idx, length);
03514         ShaFinal(&sha, cert->extAuthKeyId);
03515     }
03516 
03517     return 0;
03518 }
03519 
03520 
03521 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
03522 {
03523     word32 idx = 0;
03524     int length = 0, ret = 0;
03525 
03526     CYASSL_ENTER("DecodeSubjKeyId");
03527 
03528     if (input[idx++] != ASN_OCTET_STRING) {
03529         CYASSL_MSG("\tfail: should be an OCTET STRING");
03530         return ASN_PARSE_E;
03531     }
03532 
03533     if (GetLength(input, &idx, &length, sz) < 0) {
03534         CYASSL_MSG("\tfail: extension data length");
03535         return ASN_PARSE_E;
03536     }
03537 
03538     #ifdef OPENSSL_EXTRA
03539         cert->extSubjKeyIdSrc = &input[idx];
03540         cert->extSubjKeyIdSz = length;
03541     #endif /* OPENSSL_EXTRA */
03542 
03543     if (length == SIGNER_DIGEST_SIZE) {
03544         XMEMCPY(cert->extSubjKeyId, input + idx, length);
03545     }
03546     else {
03547         Sha sha;
03548         ret = InitSha(&sha);
03549         if (ret != 0)
03550             return ret;
03551         ShaUpdate(&sha, input + idx, length);
03552         ShaFinal(&sha, cert->extSubjKeyId);
03553     }
03554 
03555     return ret;
03556 }
03557 
03558 
03559 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
03560 {
03561     word32 idx = 0;
03562     int length;
03563     byte unusedBits;
03564     CYASSL_ENTER("DecodeKeyUsage");
03565 
03566     if (input[idx++] != ASN_BIT_STRING) {
03567         CYASSL_MSG("\tfail: key usage expected bit string");
03568         return ASN_PARSE_E;
03569     }
03570 
03571     if (GetLength(input, &idx, &length, sz) < 0) {
03572         CYASSL_MSG("\tfail: key usage bad length");
03573         return ASN_PARSE_E;
03574     }
03575 
03576     unusedBits = input[idx++];
03577     length--;
03578 
03579     if (length == 2) {
03580         cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]);
03581         cert->extKeyUsage >>= unusedBits;
03582     }
03583     else if (length == 1)
03584         cert->extKeyUsage = (word16)(input[idx] << 1);
03585 
03586     return 0;
03587 }
03588 
03589 
03590 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
03591 {
03592     word32 idx = 0, oid;
03593     int length;
03594 
03595     CYASSL_ENTER("DecodeExtKeyUsage");
03596 
03597     if (GetSequence(input, &idx, &length, sz) < 0) {
03598         CYASSL_MSG("\tfail: should be a SEQUENCE");
03599         return ASN_PARSE_E;
03600     }
03601 
03602     #ifdef OPENSSL_EXTRA
03603         cert->extExtKeyUsageSrc = input + idx;
03604         cert->extExtKeyUsageSz = length;
03605     #endif
03606 
03607     while (idx < (word32)sz) {
03608         if (GetObjectId(input, &idx, &oid, sz) < 0)
03609             return ASN_PARSE_E;
03610 
03611         switch (oid) {
03612             case EKU_ANY_OID:
03613                 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
03614                 break;
03615             case EKU_SERVER_AUTH_OID:
03616                 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
03617                 break;
03618             case EKU_CLIENT_AUTH_OID:
03619                 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
03620                 break;
03621             case EKU_OCSP_SIGN_OID:
03622                 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
03623                 break;
03624         }
03625 
03626         #ifdef OPENSSL_EXTRA
03627             cert->extExtKeyUsageCount++;
03628         #endif
03629     }
03630 
03631     return 0;
03632 }
03633 
03634 
03635 #ifndef IGNORE_NAME_CONSTRAINTS
03636 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
03637 {
03638     word32 idx = 0;
03639 
03640     (void)heap;
03641 
03642     while (idx < (word32)sz) {
03643         int seqLength, strLength;
03644         word32 nameIdx;
03645         byte b;
03646 
03647         if (GetSequence(input, &idx, &seqLength, sz) < 0) {
03648             CYASSL_MSG("\tfail: should be a SEQUENCE");
03649             return ASN_PARSE_E;
03650         }
03651 
03652         nameIdx = idx;
03653         b = input[nameIdx++];
03654         if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
03655             CYASSL_MSG("\tinvalid length");
03656             return ASN_PARSE_E;
03657         }
03658 
03659         if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
03660             b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
03661             b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
03662 
03663             Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
03664                                                     heap, DYNAMIC_TYPE_ALTNAME);
03665 
03666             if (entry == NULL) {
03667                 CYASSL_MSG("allocate error");
03668                 return MEMORY_E;
03669             }
03670 
03671             entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
03672             if (entry->name == NULL) {
03673                 CYASSL_MSG("allocate error");
03674                 return MEMORY_E;
03675             }
03676 
03677             XMEMCPY(entry->name, &input[nameIdx], strLength);
03678             entry->nameSz = strLength;
03679             entry->type = b & 0x0F;
03680 
03681             entry->next = *head;
03682             *head = entry;
03683         }
03684 
03685         idx += seqLength;
03686     }
03687 
03688     return 0;
03689 }
03690 
03691 
03692 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
03693 {
03694     word32 idx = 0;
03695     int length = 0;
03696 
03697     CYASSL_ENTER("DecodeNameConstraints");
03698 
03699     if (GetSequence(input, &idx, &length, sz) < 0) {
03700         CYASSL_MSG("\tfail: should be a SEQUENCE");
03701         return ASN_PARSE_E;
03702     }
03703 
03704     while (idx < (word32)sz) {
03705         byte b = input[idx++];
03706         Base_entry** subtree = NULL;
03707 
03708         if (GetLength(input, &idx, &length, sz) <= 0) {
03709             CYASSL_MSG("\tinvalid length");
03710             return ASN_PARSE_E;
03711         }
03712 
03713         if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
03714             subtree = &cert->permittedNames;
03715         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
03716             subtree = &cert->excludedNames;
03717         else {
03718             CYASSL_MSG("\tinvalid subtree");
03719             return ASN_PARSE_E;
03720         }
03721 
03722         DecodeSubtree(input + idx, length, subtree, cert->heap);
03723 
03724         idx += length;
03725     }
03726 
03727     return 0;
03728 }
03729 #endif /* IGNORE_NAME_CONSTRAINTS */
03730 
03731 
03732 #ifdef CYASSL_SEP
03733     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
03734     {
03735         word32 idx = 0;
03736         int length = 0;
03737 
03738         CYASSL_ENTER("DecodeCertPolicy");
03739 
03740         /* Unwrap certificatePolicies */
03741         if (GetSequence(input, &idx, &length, sz) < 0) {
03742             CYASSL_MSG("\tdeviceType isn't OID");
03743             return ASN_PARSE_E;
03744         }
03745 
03746         if (GetSequence(input, &idx, &length, sz) < 0) {
03747             CYASSL_MSG("\tdeviceType isn't OID");
03748             return ASN_PARSE_E;
03749         }
03750 
03751         if (input[idx++] != ASN_OBJECT_ID) {
03752             CYASSL_MSG("\tdeviceType isn't OID");
03753             return ASN_PARSE_E;
03754         }
03755 
03756         if (GetLength(input, &idx, &length, sz) < 0) {
03757             CYASSL_MSG("\tCouldn't read length of deviceType");
03758             return ASN_PARSE_E;
03759         }
03760 
03761         if (length > 0) {
03762             cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
03763             if (cert->deviceType == NULL) {
03764                 CYASSL_MSG("\tCouldn't alloc memory for deviceType");
03765                 return MEMORY_E;
03766             }
03767             cert->deviceTypeSz = length;
03768             XMEMCPY(cert->deviceType, input + idx, length);
03769         }
03770 
03771         CYASSL_LEAVE("DecodeCertPolicy", 0);
03772         return 0;
03773     }
03774 #endif /* CYASSL_SEP */
03775 
03776 
03777 static int DecodeCertExtensions(DecodedCert* cert)
03778 /*
03779  *  Processing the Certificate Extensions. This does not modify the current
03780  *  index. It is works starting with the recorded extensions pointer.
03781  */
03782 {
03783     word32 idx = 0;
03784     int sz = cert->extensionsSz;
03785     byte* input = cert->extensions;
03786     int length;
03787     word32 oid;
03788     byte critical = 0;
03789     byte criticalFail = 0;
03790 
03791     CYASSL_ENTER("DecodeCertExtensions");
03792 
03793     if (input == NULL || sz == 0)
03794         return BAD_FUNC_ARG;
03795 
03796     if (input[idx++] != ASN_EXTENSIONS)
03797         return ASN_PARSE_E;
03798 
03799     if (GetLength(input, &idx, &length, sz) < 0)
03800         return ASN_PARSE_E;
03801 
03802     if (GetSequence(input, &idx, &length, sz) < 0)
03803         return ASN_PARSE_E;
03804     
03805     while (idx < (word32)sz) {
03806         if (GetSequence(input, &idx, &length, sz) < 0) {
03807             CYASSL_MSG("\tfail: should be a SEQUENCE");
03808             return ASN_PARSE_E;
03809         }
03810 
03811         oid = 0;
03812         if (GetObjectId(input, &idx, &oid, sz) < 0) {
03813             CYASSL_MSG("\tfail: OBJECT ID");
03814             return ASN_PARSE_E;
03815         }
03816 
03817         /* check for critical flag */
03818         critical = 0;
03819         if (input[idx] == ASN_BOOLEAN) {
03820             int boolLength = 0;
03821             idx++;
03822             if (GetLength(input, &idx, &boolLength, sz) < 0) {
03823                 CYASSL_MSG("\tfail: critical boolean length");
03824                 return ASN_PARSE_E;
03825             }
03826             if (input[idx++])
03827                 critical = 1;
03828         }
03829 
03830         /* process the extension based on the OID */
03831         if (input[idx++] != ASN_OCTET_STRING) {
03832             CYASSL_MSG("\tfail: should be an OCTET STRING");
03833             return ASN_PARSE_E;
03834         }
03835 
03836         if (GetLength(input, &idx, &length, sz) < 0) {
03837             CYASSL_MSG("\tfail: extension data length");
03838             return ASN_PARSE_E;
03839         }
03840 
03841         switch (oid) {
03842             case BASIC_CA_OID:
03843                 #ifdef OPENSSL_EXTRA
03844                     cert->extBasicConstSet = 1;
03845                     cert->extBasicConstCrit = critical;
03846                 #endif
03847                 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
03848                     return ASN_PARSE_E;
03849                 break;
03850 
03851             case CRL_DIST_OID:
03852                 if (DecodeCrlDist(&input[idx], length, cert) < 0)
03853                     return ASN_PARSE_E;
03854                 break;
03855 
03856             case AUTH_INFO_OID:
03857                 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
03858                     return ASN_PARSE_E;
03859                 break;
03860 
03861             case ALT_NAMES_OID:
03862                 #ifdef OPENSSL_EXTRA
03863                     cert->extSubjAltNameSet = 1;
03864                     cert->extSubjAltNameCrit = critical;
03865                 #endif
03866                 if (DecodeAltNames(&input[idx], length, cert) < 0)
03867                     return ASN_PARSE_E;
03868                 break;
03869 
03870             case AUTH_KEY_OID:
03871                 cert->extAuthKeyIdSet = 1;
03872                 #ifdef OPENSSL_EXTRA
03873                     cert->extAuthKeyIdCrit = critical;
03874                 #endif
03875                 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
03876                     return ASN_PARSE_E;
03877                 break;
03878 
03879             case SUBJ_KEY_OID:
03880                 cert->extSubjKeyIdSet = 1;
03881                 #ifdef OPENSSL_EXTRA
03882                     cert->extSubjKeyIdCrit = critical;
03883                 #endif
03884                 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
03885                     return ASN_PARSE_E;
03886                 break;
03887 
03888             case CERT_POLICY_OID:
03889                 CYASSL_MSG("Certificate Policy extension not supported yet.");
03890                 #ifdef CYASSL_SEP
03891                     #ifdef OPENSSL_EXTRA
03892                         cert->extCertPolicySet = 1;
03893                         cert->extCertPolicyCrit = critical;
03894                     #endif
03895                     if (DecodeCertPolicy(&input[idx], length, cert) < 0)
03896                         return ASN_PARSE_E;
03897                 #endif
03898                 break;
03899 
03900             case KEY_USAGE_OID:
03901                 cert->extKeyUsageSet = 1;
03902                 #ifdef OPENSSL_EXTRA
03903                     cert->extKeyUsageCrit = critical;
03904                 #endif
03905                 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
03906                     return ASN_PARSE_E;
03907                 break;
03908 
03909             case EXT_KEY_USAGE_OID:
03910                 cert->extExtKeyUsageSet = 1;
03911                 #ifdef OPENSSL_EXTRA
03912                     cert->extExtKeyUsageCrit = critical;
03913                 #endif
03914                 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
03915                     return ASN_PARSE_E;
03916                 break;
03917 
03918             #ifndef IGNORE_NAME_CONSTRAINTS
03919             case NAME_CONS_OID:
03920                 cert->extNameConstraintSet = 1;
03921                 #ifdef OPENSSL_EXTRA
03922                     cert->extNameConstraintCrit = critical;
03923                 #endif
03924                 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
03925                     return ASN_PARSE_E;
03926                 break;
03927             #endif /* IGNORE_NAME_CONSTRAINTS */
03928 
03929             case INHIBIT_ANY_OID:
03930                 CYASSL_MSG("Inhibit anyPolicy extension not supported yet.");
03931                 break;
03932 
03933             default:
03934                 /* While it is a failure to not support critical extensions,
03935                  * still parse the certificate ignoring the unsupported
03936                  * extention to allow caller to accept it with the verify
03937                  * callback. */
03938                 if (critical)
03939                     criticalFail = 1;
03940                 break;
03941         }
03942         idx += length;
03943     }
03944 
03945     return criticalFail ? ASN_CRIT_EXT_E : 0;
03946 }
03947 
03948 
03949 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
03950 {
03951     int   ret;
03952     char* ptr;
03953 
03954     ret = ParseCertRelative(cert, type, verify, cm);
03955     if (ret < 0)
03956         return ret;
03957 
03958     if (cert->subjectCNLen > 0) {
03959         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
03960                               DYNAMIC_TYPE_SUBJECT_CN);
03961         if (ptr == NULL)
03962             return MEMORY_E;
03963         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
03964         ptr[cert->subjectCNLen] = '\0';
03965         cert->subjectCN = ptr;
03966         cert->subjectCNStored = 1;
03967     }
03968 
03969     if (cert->keyOID == RSAk &&
03970                           cert->publicKey != NULL  && cert->pubKeySize > 0) {
03971         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
03972                               DYNAMIC_TYPE_PUBLIC_KEY);
03973         if (ptr == NULL)
03974             return MEMORY_E;
03975         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
03976         cert->publicKey = (byte *)ptr;
03977         cert->pubKeyStored = 1;
03978     }
03979 
03980     return ret;
03981 }
03982 
03983 
03984 /* from SSL proper, for locking can't do find here anymore */
03985 #ifdef __cplusplus
03986     extern "C" {
03987 #endif
03988     CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
03989     #ifndef NO_SKID
03990         CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
03991     #endif
03992 #ifdef __cplusplus
03993     } 
03994 #endif
03995 
03996 
03997 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
03998 {
03999     word32 confirmOID;
04000     int    ret;
04001     int    badDate     = 0;
04002     int    criticalExt = 0;
04003 
04004     if ((ret = DecodeToKey(cert, verify)) < 0) {
04005         if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
04006             badDate = ret;
04007         else
04008             return ret;
04009     }
04010 
04011     CYASSL_MSG("Parsed Past Key");
04012 
04013     if (cert->srcIdx < cert->sigIndex) {
04014         #ifndef ALLOW_V1_EXTENSIONS
04015             if (cert->version < 2) {
04016                 CYASSL_MSG("    v1 and v2 certs not allowed extensions");
04017                 return ASN_VERSION_E;
04018             }
04019         #endif
04020         /* save extensions */
04021         cert->extensions    = &cert->source[cert->srcIdx];
04022         cert->extensionsSz  =  cert->sigIndex - cert->srcIdx;
04023         cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
04024 
04025         if ((ret = DecodeCertExtensions(cert)) < 0) {
04026             if (ret == ASN_CRIT_EXT_E)
04027                 criticalExt = ret;
04028             else
04029                 return ret;
04030         }
04031 
04032         /* advance past extensions */
04033         cert->srcIdx =  cert->sigIndex;
04034     }
04035 
04036     if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
04037                          cert->maxIdx)) < 0)
04038         return ret;
04039 
04040     if ((ret = GetSignature(cert)) < 0)
04041         return ret;
04042 
04043     if (confirmOID != cert->signatureOID)
04044         return ASN_SIG_OID_E;
04045 
04046     #ifndef NO_SKID
04047         if (cert->extSubjKeyIdSet == 0
04048                           && cert->publicKey != NULL && cert->pubKeySize > 0) {
04049             Sha sha;
04050             ret = InitSha(&sha);
04051             if (ret != 0)
04052                 return ret;
04053             ShaUpdate(&sha, cert->publicKey, cert->pubKeySize);
04054             ShaFinal(&sha, cert->extSubjKeyId);
04055         }
04056     #endif
04057 
04058     if (verify && type != CA_TYPE) {
04059         Signer* ca = NULL;
04060         #ifndef NO_SKID
04061             if (cert->extAuthKeyIdSet)
04062                 ca = GetCA(cm, cert->extAuthKeyId);
04063             if (ca == NULL)
04064                 ca = GetCAByName(cm, cert->issuerHash);
04065         #else /* NO_SKID */
04066             ca = GetCA(cm, cert->issuerHash);
04067         #endif /* NO SKID */
04068         CYASSL_MSG("About to verify certificate signature");
04069  
04070         if (ca) {
04071 #ifdef HAVE_OCSP
04072             /* Need the ca's public key hash for OCSP */
04073             {
04074                 Sha sha;
04075                 ret = InitSha(&sha);
04076                 if (ret != 0)
04077                     return ret;
04078                 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize);
04079                 ShaFinal(&sha, cert->issuerKeyHash);
04080             }
04081 #endif /* HAVE_OCSP */
04082             /* try to confirm/verify signature */
04083             if (!ConfirmSignature(cert->source + cert->certBegin,
04084                         cert->sigIndex - cert->certBegin,
04085                     ca->publicKey, ca->pubKeySize, ca->keyOID,
04086                     cert->signature, cert->sigLength, cert->signatureOID,
04087                     cert->heap)) {
04088                 CYASSL_MSG("Confirm signature failed");
04089                 return ASN_SIG_CONFIRM_E;
04090             }
04091 #ifndef IGNORE_NAME_CONSTRAINTS
04092             /* check that this cert's name is permitted by the signer's
04093              * name constraints */
04094             if (!ConfirmNameConstraints(ca, cert)) {
04095                 CYASSL_MSG("Confirm name constraint failed");
04096                 return ASN_NAME_INVALID_E;
04097             }
04098 #endif /* IGNORE_NAME_CONSTRAINTS */
04099         }
04100         else {
04101             /* no signer */
04102             CYASSL_MSG("No CA signer to verify with");
04103             return ASN_NO_SIGNER_E;
04104         }
04105     }
04106 
04107     if (badDate != 0)
04108         return badDate;
04109 
04110     if (criticalExt != 0)
04111         return criticalExt;
04112 
04113     return 0;
04114 }
04115 
04116 
04117 /* Create and init an new signer */
04118 Signer* MakeSigner(void* heap)
04119 {
04120     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
04121                                        DYNAMIC_TYPE_SIGNER);
04122     if (signer) {
04123         signer->pubKeySize = 0;
04124         signer->keyOID     = 0;
04125         signer->publicKey  = NULL;
04126         signer->nameLen    = 0;
04127         signer->name       = NULL;
04128         #ifndef IGNORE_NAME_CONSTRAINTS
04129             signer->permittedNames = NULL;
04130             signer->excludedNames = NULL;
04131         #endif /* IGNORE_NAME_CONSTRAINTS */
04132         signer->next       = NULL;
04133     }
04134     (void)heap;
04135 
04136     return signer;
04137 }
04138 
04139 
04140 /* Free an individual signer */
04141 void FreeSigner(Signer* signer, void* heap)
04142 {
04143     XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
04144     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
04145     #ifndef IGNORE_NAME_CONSTRAINTS
04146         if (signer->permittedNames)
04147             FreeNameSubtrees(signer->permittedNames, heap);
04148         if (signer->excludedNames)
04149             FreeNameSubtrees(signer->excludedNames, heap);
04150     #endif
04151     XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
04152 
04153     (void)heap;
04154 }
04155 
04156 
04157 /* Free the whole singer table with number of rows */
04158 void FreeSignerTable(Signer** table, int rows, void* heap)
04159 {
04160     int i;
04161 
04162     for (i = 0; i < rows; i++) {
04163         Signer* signer = table[i];
04164         while (signer) {
04165             Signer* next = signer->next;
04166             FreeSigner(signer, heap);
04167             signer = next;
04168         }
04169         table[i] = NULL;
04170     }
04171 }
04172 
04173 
04174 CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
04175 {
04176     int i = 0;
04177 
04178     if (header) {
04179         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
04180         output[i++] = ASN_BIT_STRING;
04181     }
04182     output[i++] = ASN_INTEGER;
04183     output[i++] = 0x01;
04184     output[i++] = (byte)version;
04185 
04186     return i;
04187 }
04188 
04189 
04190 CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
04191 {
04192     int result = 0;
04193 
04194     CYASSL_ENTER("SetSerialNumber");
04195 
04196     if (snSz <= EXTERNAL_SERIAL_SIZE) {
04197         output[0] = ASN_INTEGER;
04198         /* The serial number is always positive. When encoding the
04199          * INTEGER, if the MSB is 1, add a padding zero to keep the
04200          * number positive. */
04201         if (sn[0] & 0x80) {
04202             output[1] = (byte)snSz + 1;
04203             output[2] = 0;
04204             XMEMCPY(&output[3], sn, snSz);
04205             result = snSz + 3;
04206         }
04207         else {
04208             output[1] = (byte)snSz;
04209             XMEMCPY(&output[2], sn, snSz);
04210             result = snSz + 2;
04211         }
04212     }
04213     return result;
04214 }
04215 
04216 
04217 
04218 
04219 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
04220 
04221 /* convert der buffer to pem into output, can't do inplace, der and output
04222    need to be different */
04223 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
04224              int type)
04225 {
04226     char header[80];
04227     char footer[80];
04228 
04229     int headerLen;
04230     int footerLen;
04231     int i;
04232     int err;
04233     int outLen;   /* return length or error */
04234 
04235     if (der == output)      /* no in place conversion */
04236         return BAD_FUNC_ARG;
04237 
04238     if (type == CERT_TYPE) {
04239         XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header));
04240         XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer));
04241     }
04242     else if (type == PRIVATEKEY_TYPE) {
04243         XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header));
04244         XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer));
04245     }
04246     #ifdef HAVE_ECC
04247     else if (type == ECC_PRIVATEKEY_TYPE) {
04248         XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", sizeof(header));
04249         XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", sizeof(footer));
04250     }
04251     #endif
04252     #ifdef CYASSL_CERT_REQ
04253     else if (type == CERTREQ_TYPE)
04254     {
04255         XSTRNCPY(header,
04256                        "-----BEGIN CERTIFICATE REQUEST-----\n", sizeof(header));
04257         XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", sizeof(footer));
04258     }
04259     #endif
04260     else
04261         return BAD_FUNC_ARG;
04262 
04263     headerLen = (int)XSTRLEN(header);
04264     footerLen = (int)XSTRLEN(footer);
04265 
04266     if (!der || !output)
04267         return BAD_FUNC_ARG;
04268 
04269     /* don't even try if outSz too short */
04270     if (outSz < headerLen + footerLen + derSz)
04271         return BAD_FUNC_ARG;
04272 
04273     /* header */
04274     XMEMCPY(output, header, headerLen);
04275     i = headerLen;
04276 
04277     /* body */
04278     outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
04279     if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0)
04280         return err;
04281     i += outLen;
04282 
04283     /* footer */
04284     if ( (i + footerLen) > (int)outSz)
04285         return BAD_FUNC_ARG;
04286     XMEMCPY(output + i, footer, footerLen);
04287 
04288     return outLen + headerLen + footerLen;
04289 }
04290 
04291 
04292 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
04293 
04294 
04295 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA)
04296 
04297 
04298 static mp_int* GetRsaInt(RsaKey* key, int idx)
04299 {
04300     if (idx == 0)
04301         return &key->n;
04302     if (idx == 1)
04303         return &key->e;
04304     if (idx == 2)
04305         return &key->d;
04306     if (idx == 3)
04307         return &key->p;
04308     if (idx == 4)
04309         return &key->q;
04310     if (idx == 5)
04311         return &key->dP;
04312     if (idx == 6)
04313         return &key->dQ;
04314     if (idx == 7)
04315         return &key->u;
04316 
04317     return NULL;
04318 }
04319 
04320 
04321 /* Release Tmp RSA resources */
04322 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
04323 {
04324     int i;
04325 
04326     (void)heap;
04327 
04328     for (i = 0; i < RSA_INTS; i++) 
04329         XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
04330 }
04331 
04332 
04333 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
04334    written */
04335 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
04336 {
04337     word32 seqSz, verSz, rawLen, intTotalLen = 0;
04338     word32 sizes[RSA_INTS];
04339     int    i, j, outLen, ret = 0;
04340 
04341     byte  seq[MAX_SEQ_SZ];
04342     byte  ver[MAX_VERSION_SZ];
04343     byte* tmps[RSA_INTS];
04344 
04345     if (!key || !output)
04346         return BAD_FUNC_ARG;
04347 
04348     if (key->type != RSA_PRIVATE)
04349         return BAD_FUNC_ARG;
04350 
04351     for (i = 0; i < RSA_INTS; i++)
04352         tmps[i] = NULL;
04353 
04354     /* write all big ints from key to DER tmps */
04355     for (i = 0; i < RSA_INTS; i++) {
04356         mp_int* keyInt = GetRsaInt(key, i);
04357         rawLen = mp_unsigned_bin_size(keyInt);
04358         tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
04359                                  DYNAMIC_TYPE_RSA);
04360         if (tmps[i] == NULL) {
04361             ret = MEMORY_E;
04362             break;
04363         }
04364 
04365         tmps[i][0] = ASN_INTEGER;
04366         sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1;  /* int tag */
04367 
04368         if (sizes[i] <= MAX_SEQ_SZ) {
04369             int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
04370             if (err == MP_OKAY) {
04371                 sizes[i] += rawLen;
04372                 intTotalLen += sizes[i];
04373             }
04374             else {
04375                 ret = err;
04376                 break;
04377             }
04378         }
04379         else {
04380             ret = ASN_INPUT_E;
04381             break;
04382         }
04383     }
04384 
04385     if (ret != 0) {
04386         FreeTmpRsas(tmps, key->heap);
04387         return ret;
04388     }
04389 
04390     /* make headers */
04391     verSz = SetMyVersion(0, ver, FALSE);
04392     seqSz = SetSequence(verSz + intTotalLen, seq);
04393 
04394     outLen = seqSz + verSz + intTotalLen;
04395     if (outLen > (int)inLen)
04396         return BAD_FUNC_ARG;
04397 
04398     /* write to output */
04399     XMEMCPY(output, seq, seqSz);
04400     j = seqSz;
04401     XMEMCPY(output + j, ver, verSz);
04402     j += verSz;
04403 
04404     for (i = 0; i < RSA_INTS; i++) {
04405         XMEMCPY(output + j, tmps[i], sizes[i]);
04406         j += sizes[i];
04407     }
04408     FreeTmpRsas(tmps, key->heap);
04409 
04410     return outLen;
04411 }
04412 
04413 #endif /* CYASSL_KEY_GEN && !NO_RSA */
04414 
04415 
04416 #if defined(CYASSL_CERT_GEN) && !defined(NO_RSA)
04417 
04418 
04419 #ifndef min
04420 
04421     static INLINE word32 min(word32 a, word32 b)
04422     {
04423         return a > b ? b : a;
04424     }
04425 
04426 #endif /* min */
04427 
04428 
04429 /* Initialize and Set Certficate defaults:
04430    version    = 3 (0x2)
04431    serial     = 0
04432    sigType    = SHA_WITH_RSA
04433    issuer     = blank
04434    daysValid  = 500
04435    selfSigned = 1 (true) use subject as issuer
04436    subject    = blank
04437 */
04438 void InitCert(Cert* cert)
04439 {
04440     cert->version    = 2;   /* version 3 is hex 2 */
04441     cert->sigType    = CTC_SHAwRSA;
04442     cert->daysValid  = 500;
04443     cert->selfSigned = 1;
04444     cert->isCA       = 0;
04445     cert->bodySz     = 0;
04446 #ifdef CYASSL_ALT_NAMES
04447     cert->altNamesSz   = 0;
04448     cert->beforeDateSz = 0;
04449     cert->afterDateSz  = 0;
04450 #endif
04451     cert->keyType    = RSA_KEY;
04452     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
04453 
04454     cert->issuer.country[0] = '\0';
04455     cert->issuer.state[0] = '\0';
04456     cert->issuer.locality[0] = '\0';
04457     cert->issuer.sur[0] = '\0';
04458     cert->issuer.org[0] = '\0';
04459     cert->issuer.unit[0] = '\0';
04460     cert->issuer.commonName[0] = '\0';
04461     cert->issuer.email[0] = '\0';
04462 
04463     cert->subject.country[0] = '\0';
04464     cert->subject.state[0] = '\0';
04465     cert->subject.locality[0] = '\0';
04466     cert->subject.sur[0] = '\0';
04467     cert->subject.org[0] = '\0';
04468     cert->subject.unit[0] = '\0';
04469     cert->subject.commonName[0] = '\0';
04470     cert->subject.email[0] = '\0';
04471 
04472 #ifdef CYASSL_CERT_REQ
04473     cert->challengePw[0] ='\0';
04474 #endif
04475 }
04476 
04477 
04478 /* DER encoded x509 Certificate */
04479 typedef struct DerCert {
04480     byte size[MAX_LENGTH_SZ];          /* length encoded */
04481     byte version[MAX_VERSION_SZ];      /* version encoded */
04482     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
04483     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
04484     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
04485     byte subject[ASN_NAME_MAX];        /* subject encoded */
04486     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
04487     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
04488     byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
04489     byte extensions[MAX_EXTENSIONS_SZ];  /* all extensions */
04490 #ifdef CYASSL_CERT_REQ
04491     byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
04492 #endif
04493     int  sizeSz;                       /* encoded size length */
04494     int  versionSz;                    /* encoded version length */
04495     int  serialSz;                     /* encoded serial length */
04496     int  sigAlgoSz;                    /* enocded sig alog length */
04497     int  issuerSz;                     /* encoded issuer length */
04498     int  subjectSz;                    /* encoded subject length */
04499     int  validitySz;                   /* encoded validity length */
04500     int  publicKeySz;                  /* encoded public key length */
04501     int  caSz;                         /* encoded CA extension length */
04502     int  extensionsSz;                 /* encoded extensions total length */
04503     int  total;                        /* total encoded lengths */
04504 #ifdef CYASSL_CERT_REQ
04505     int  attribSz;
04506 #endif
04507 } DerCert;
04508 
04509 
04510 #ifdef CYASSL_CERT_REQ
04511 
04512 /* Write a set header to output */
04513 static word32 SetUTF8String(word32 len, byte* output)
04514 {
04515     output[0] = ASN_UTF8STRING;
04516     return SetLength(len, output + 1) + 1;
04517 }
04518 
04519 #endif /* CYASSL_CERT_REQ */
04520 
04521 
04522 /* Write a serial number to output */
04523 static int SetSerial(const byte* serial, byte* output)
04524 {
04525     int length = 0;
04526 
04527     output[length++] = ASN_INTEGER;
04528     length += SetLength(CTC_SERIAL_SIZE, &output[length]);
04529     XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
04530 
04531     return length + CTC_SERIAL_SIZE;
04532 }
04533 
04534 
04535 #ifdef HAVE_ECC 
04536 
04537 /* Write a public ECC key to output */
04538 static int SetEccPublicKey(byte* output, ecc_key* key)
04539 {
04540     byte algo[MAX_ALGO_SZ];
04541     byte curve[MAX_ALGO_SZ];
04542     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
04543     byte pub[ECC_BUFSIZE];
04544     int  algoSz;
04545     int  curveSz;
04546     int  lenSz;
04547     int  idx;
04548     word32 pubSz = sizeof(pub);
04549 
04550     int ret = ecc_export_x963(key, pub, &pubSz);
04551     if (ret != 0) return ret;
04552 
04553     /* headers */
04554     curveSz = SetCurve(key, curve);
04555     if (curveSz <= 0) return curveSz;
04556 
04557     algoSz  = SetAlgoID(ECDSAk, algo, keyType, curveSz);
04558     lenSz   = SetLength(pubSz + 1, len);
04559     len[lenSz++] = 0;   /* trailing 0 */
04560 
04561     /* write */
04562     idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output);
04563         /* 1 is for ASN_BIT_STRING */
04564     /* algo */
04565     XMEMCPY(output + idx, algo, algoSz);
04566     idx += algoSz;
04567     /* curve */
04568     XMEMCPY(output + idx, curve, curveSz);
04569     idx += curveSz;
04570     /* bit string */
04571     output[idx++] = ASN_BIT_STRING;
04572     /* length */
04573     XMEMCPY(output + idx, len, lenSz);
04574     idx += lenSz;
04575     /* pub */
04576     XMEMCPY(output + idx, pub, pubSz);
04577     idx += pubSz;
04578 
04579     return idx;
04580 }
04581 
04582 
04583 #endif /* HAVE_ECC */
04584 
04585 
04586 /* Write a public RSA key to output */
04587 static int SetRsaPublicKey(byte* output, RsaKey* key)
04588 {
04589     byte n[MAX_RSA_INT_SZ];
04590     byte e[MAX_RSA_E_SZ];
04591     byte algo[MAX_ALGO_SZ];
04592     byte seq[MAX_SEQ_SZ];
04593     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
04594     int  nSz;
04595     int  eSz;
04596     int  algoSz;
04597     int  seqSz;
04598     int  lenSz;
04599     int  idx;
04600     int  rawLen;
04601     int  leadingBit;
04602     int  err;
04603 
04604     /* n */
04605     leadingBit = mp_leading_bit(&key->n);
04606     rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
04607     n[0] = ASN_INTEGER;
04608     nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
04609 
04610     if ( (nSz + rawLen) < (int)sizeof(n)) {
04611         if (leadingBit)
04612             n[nSz] = 0;
04613         err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
04614         if (err == MP_OKAY)
04615             nSz += rawLen;
04616         else
04617             return MP_TO_E;
04618     }
04619     else
04620         return BUFFER_E;
04621 
04622     /* e */
04623     leadingBit = mp_leading_bit(&key->e);
04624     rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
04625     e[0] = ASN_INTEGER;
04626     eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
04627 
04628     if ( (eSz + rawLen) < (int)sizeof(e)) {
04629         if (leadingBit)
04630             e[eSz] = 0;
04631         err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
04632         if (err == MP_OKAY)
04633             eSz += rawLen;
04634         else
04635             return MP_TO_E;
04636     }
04637     else
04638         return BUFFER_E;
04639 
04640     /* headers */
04641     algoSz = SetAlgoID(RSAk, algo, keyType, 0);
04642     seqSz  = SetSequence(nSz + eSz, seq);
04643     lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
04644     len[lenSz++] = 0;   /* trailing 0 */
04645 
04646     /* write */
04647     idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
04648         /* 1 is for ASN_BIT_STRING */
04649     /* algo */
04650     XMEMCPY(output + idx, algo, algoSz);
04651     idx += algoSz;
04652     /* bit string */
04653     output[idx++] = ASN_BIT_STRING;
04654     /* length */
04655     XMEMCPY(output + idx, len, lenSz);
04656     idx += lenSz;
04657     /* seq */
04658     XMEMCPY(output + idx, seq, seqSz);
04659     idx += seqSz;
04660     /* n */
04661     XMEMCPY(output + idx, n, nSz);
04662     idx += nSz;
04663     /* e */
04664     XMEMCPY(output + idx, e, eSz);
04665     idx += eSz;
04666 
04667     return idx;
04668 }
04669 
04670 
04671 static INLINE byte itob(int number)
04672 {
04673     return (byte)number + 0x30;
04674 }
04675 
04676 
04677 /* write time to output, format */
04678 static void SetTime(struct tm* date, byte* output)
04679 {
04680     int i = 0;
04681 
04682     output[i++] = itob((date->tm_year % 10000) / 1000);
04683     output[i++] = itob((date->tm_year % 1000)  /  100);
04684     output[i++] = itob((date->tm_year % 100)   /   10);
04685     output[i++] = itob( date->tm_year % 10);
04686 
04687     output[i++] = itob(date->tm_mon / 10);
04688     output[i++] = itob(date->tm_mon % 10);
04689 
04690     output[i++] = itob(date->tm_mday / 10);
04691     output[i++] = itob(date->tm_mday % 10);
04692 
04693     output[i++] = itob(date->tm_hour / 10);
04694     output[i++] = itob(date->tm_hour % 10);
04695 
04696     output[i++] = itob(date->tm_min / 10);
04697     output[i++] = itob(date->tm_min % 10);
04698 
04699     output[i++] = itob(date->tm_sec / 10);
04700     output[i++] = itob(date->tm_sec % 10);
04701     
04702     output[i] = 'Z';  /* Zulu profile */
04703 }
04704 
04705 
04706 #ifdef CYASSL_ALT_NAMES
04707 
04708 /* Copy Dates from cert, return bytes written */
04709 static int CopyValidity(byte* output, Cert* cert)
04710 {
04711     int seqSz;
04712 
04713     CYASSL_ENTER("CopyValidity");
04714 
04715     /* headers and output */
04716     seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
04717     XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
04718     XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
04719                                                  cert->afterDateSz);
04720     return seqSz + cert->beforeDateSz + cert->afterDateSz;
04721 }
04722 
04723 #endif
04724 
04725 
04726 /* Set Date validity from now until now + daysValid */
04727 static int SetValidity(byte* output, int daysValid)
04728 {
04729     byte before[MAX_DATE_SIZE];
04730     byte  after[MAX_DATE_SIZE];
04731 
04732     int beforeSz;
04733     int afterSz;
04734     int seqSz;
04735 
04736     time_t     ticks;
04737     struct tm* now;
04738     struct tm  local;
04739 
04740     ticks = XTIME(0);
04741     now   = XGMTIME(&ticks);
04742 
04743     /* before now */
04744     local = *now;
04745     before[0] = ASN_GENERALIZED_TIME;
04746     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
04747 
04748     /* subtract 1 day for more compliance */
04749     local.tm_mday -= 1;
04750     mktime(&local);
04751 
04752     /* adjust */
04753     local.tm_year += 1900;
04754     local.tm_mon  +=    1;
04755 
04756     SetTime(&local, before + beforeSz);
04757     beforeSz += ASN_GEN_TIME_SZ;
04758     
04759     /* after now + daysValid */
04760     local = *now;
04761     after[0] = ASN_GENERALIZED_TIME;
04762     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
04763 
04764     /* add daysValid */
04765     local.tm_mday += daysValid;
04766     mktime(&local);
04767 
04768     /* adjust */
04769     local.tm_year += 1900;
04770     local.tm_mon  +=    1;
04771 
04772     SetTime(&local, after + afterSz);
04773     afterSz += ASN_GEN_TIME_SZ;
04774 
04775     /* headers and output */
04776     seqSz = SetSequence(beforeSz + afterSz, output);
04777     XMEMCPY(output + seqSz, before, beforeSz);
04778     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
04779 
04780     return seqSz + beforeSz + afterSz;
04781 }
04782 
04783 
04784 /* ASN Encoded Name field */
04785 typedef struct EncodedName {
04786     int  nameLen;                /* actual string value length */
04787     int  totalLen;               /* total encoded length */
04788     int  type;                   /* type of name */
04789     int  used;                   /* are we actually using this one */
04790     byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
04791 } EncodedName;
04792 
04793 
04794 /* Get Which Name from index */
04795 static const char* GetOneName(CertName* name, int idx)
04796 {
04797     switch (idx) {
04798     case 0:
04799        return name->country;
04800 
04801     case 1:
04802        return name->state;
04803 
04804     case 2:
04805        return name->locality;
04806 
04807     case 3:
04808        return name->sur;
04809 
04810     case 4:
04811        return name->org;
04812 
04813     case 5:
04814        return name->unit;
04815 
04816     case 6:
04817        return name->commonName;
04818 
04819     case 7:
04820        return name->email;
04821 
04822     default:
04823        return 0;
04824     }
04825 }
04826 
04827 
04828 /* Get ASN Name from index */
04829 static byte GetNameId(int idx)
04830 {
04831     switch (idx) {
04832     case 0:
04833        return ASN_COUNTRY_NAME;
04834 
04835     case 1:
04836        return ASN_STATE_NAME;
04837 
04838     case 2:
04839        return ASN_LOCALITY_NAME;
04840 
04841     case 3:
04842        return ASN_SUR_NAME;
04843 
04844     case 4:
04845        return ASN_ORG_NAME;
04846 
04847     case 5:
04848        return ASN_ORGUNIT_NAME;
04849 
04850     case 6:
04851        return ASN_COMMON_NAME;
04852 
04853     case 7:
04854        /* email uses different id type */
04855        return 0;
04856 
04857     default:
04858        return 0;
04859     }
04860 }
04861 
04862 
04863 /* encode all extensions, return total bytes written */
04864 static int SetExtensions(byte* output, const byte* ext, int extSz, int header)
04865 {
04866     byte sequence[MAX_SEQ_SZ];
04867     byte len[MAX_LENGTH_SZ];
04868 
04869     int sz = 0;
04870     int seqSz = SetSequence(extSz, sequence);
04871 
04872     if (header) {
04873         int lenSz = SetLength(seqSz + extSz, len);
04874         output[0] = ASN_EXTENSIONS; /* extensions id */
04875         sz++;
04876         XMEMCPY(&output[sz], len, lenSz);  /* length */
04877         sz += lenSz;
04878     }
04879     XMEMCPY(&output[sz], sequence, seqSz);  /* sequence */
04880     sz += seqSz;
04881     XMEMCPY(&output[sz], ext, extSz);  /* extensions */
04882     sz += extSz;
04883 
04884     return sz;
04885 }
04886 
04887 
04888 /* encode CA basic constraint true, return total bytes written */
04889 static int SetCa(byte* output)
04890 {
04891     static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
04892                                0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
04893     
04894     XMEMCPY(output, ca, sizeof(ca));
04895 
04896     return (int)sizeof(ca);
04897 }
04898 
04899 
04900 /* encode CertName into output, return total bytes written */
04901 static int SetName(byte* output, CertName* name)
04902 {
04903     int         totalBytes = 0, i, idx;
04904     EncodedName names[NAME_ENTRIES];
04905 
04906     for (i = 0; i < NAME_ENTRIES; i++) {
04907         const char* nameStr = GetOneName(name, i);
04908         if (nameStr) {
04909             /* bottom up */
04910             byte firstLen[MAX_LENGTH_SZ];
04911             byte secondLen[MAX_LENGTH_SZ];
04912             byte sequence[MAX_SEQ_SZ];
04913             byte set[MAX_SET_SZ];
04914 
04915             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
04916             int strLen  = (int)XSTRLEN(nameStr);
04917             int thisLen = strLen;
04918             int firstSz, secondSz, seqSz, setSz;
04919 
04920             if (strLen == 0) { /* no user data for this item */
04921                 names[i].used = 0;
04922                 continue;
04923             }
04924 
04925             secondSz = SetLength(strLen, secondLen);
04926             thisLen += secondSz;
04927             if (email) {
04928                 thisLen += EMAIL_JOINT_LEN;
04929                 thisLen ++;                               /* id type */
04930                 firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
04931             }
04932             else {
04933                 thisLen++;                                 /* str type */
04934                 thisLen++;                                 /* id  type */
04935                 thisLen += JOINT_LEN;    
04936                 firstSz = SetLength(JOINT_LEN + 1, firstLen);
04937             }
04938             thisLen += firstSz;
04939             thisLen++;                                /* object id */
04940 
04941             seqSz = SetSequence(thisLen, sequence);
04942             thisLen += seqSz;
04943             setSz = SetSet(thisLen, set);
04944             thisLen += setSz;
04945 
04946             if (thisLen > (int)sizeof(names[i].encoded))
04947                 return BUFFER_E;
04948 
04949             /* store it */
04950             idx = 0;
04951             /* set */
04952             XMEMCPY(names[i].encoded, set, setSz);
04953             idx += setSz;
04954             /* seq */
04955             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
04956             idx += seqSz;
04957             /* asn object id */
04958             names[i].encoded[idx++] = ASN_OBJECT_ID;
04959             /* first length */
04960             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
04961             idx += firstSz;
04962             if (email) {
04963                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
04964                                            0x01, 0x09, 0x01, 0x16 };
04965                 /* email joint id */
04966                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
04967                 idx += (int)sizeof(EMAIL_OID);
04968             }
04969             else {
04970                 /* joint id */
04971                 byte bType = GetNameId(i);
04972                 names[i].encoded[idx++] = 0x55;
04973                 names[i].encoded[idx++] = 0x04;
04974                 /* id type */
04975                 names[i].encoded[idx++] = bType; 
04976                 /* str type */
04977                 if (bType == ASN_COUNTRY_NAME)
04978                     names[i].encoded[idx++] = 0x13;   /* printable */
04979                 else
04980                     names[i].encoded[idx++] = 0x0c;   /* utf8 */
04981             }
04982             /* second length */
04983             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
04984             idx += secondSz;
04985             /* str value */
04986             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
04987             idx += strLen;
04988 
04989             totalBytes += idx;
04990             names[i].totalLen = idx;
04991             names[i].used = 1;
04992         }
04993         else
04994             names[i].used = 0;
04995     }
04996 
04997     /* header */
04998     idx = SetSequence(totalBytes, output);
04999     totalBytes += idx;
05000     if (totalBytes > ASN_NAME_MAX)
05001         return BUFFER_E;
05002 
05003     for (i = 0; i < NAME_ENTRIES; i++) {
05004         if (names[i].used) {
05005             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
05006             idx += names[i].totalLen;
05007         }
05008     }
05009     return totalBytes;
05010 }
05011 
05012 /* encode info from cert into DER encoded format */
05013 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
05014                       RNG* rng, const byte* ntruKey, word16 ntruSz)
05015 {
05016     int ret;
05017 
05018     (void)eccKey;
05019     (void)ntruKey;
05020     (void)ntruSz;
05021 
05022     /* init */
05023     XMEMSET(der, 0, sizeof(DerCert));
05024 
05025     /* version */
05026     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
05027 
05028     /* serial number */
05029     ret = RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
05030     if (ret != 0)
05031         return ret;
05032 
05033     cert->serial[0] = 0x01;   /* ensure positive */
05034     der->serialSz  = SetSerial(cert->serial, der->serial);
05035 
05036     /* signature algo */
05037     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0);
05038     if (der->sigAlgoSz == 0)
05039         return ALGO_ID_E;
05040 
05041     /* public key */
05042     if (cert->keyType == RSA_KEY) {
05043         if (rsaKey == NULL)
05044             return PUBLIC_KEY_E;
05045         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
05046         if (der->publicKeySz <= 0)
05047             return PUBLIC_KEY_E;
05048     }
05049 
05050 #ifdef HAVE_ECC
05051     if (cert->keyType == ECC_KEY) {
05052         if (eccKey == NULL)
05053             return PUBLIC_KEY_E;
05054         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
05055         if (der->publicKeySz <= 0)
05056             return PUBLIC_KEY_E;
05057     }
05058 #endif /* HAVE_ECC */
05059 
05060 #ifdef HAVE_NTRU
05061     if (cert->keyType == NTRU_KEY) {
05062         word32 rc;
05063         word16 encodedSz;
05064 
05065         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
05066                                               ntruKey, &encodedSz, NULL);
05067         if (rc != NTRU_OK)
05068             return PUBLIC_KEY_E;
05069         if (encodedSz > MAX_PUBLIC_KEY_SZ)
05070             return PUBLIC_KEY_E;
05071 
05072         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
05073                               ntruKey, &encodedSz, der->publicKey);
05074         if (rc != NTRU_OK)
05075             return PUBLIC_KEY_E;
05076 
05077         der->publicKeySz = encodedSz;
05078     }
05079 #endif /* HAVE_NTRU */
05080 
05081     der->validitySz = 0;
05082 #ifdef CYASSL_ALT_NAMES
05083     /* date validity copy ? */
05084     if (cert->beforeDateSz && cert->afterDateSz) {
05085         der->validitySz = CopyValidity(der->validity, cert);
05086         if (der->validitySz == 0)
05087             return DATE_E;
05088     }
05089 #endif
05090 
05091     /* date validity */
05092     if (der->validitySz == 0) {
05093         der->validitySz = SetValidity(der->validity, cert->daysValid);
05094         if (der->validitySz == 0)
05095             return DATE_E;
05096     }
05097 
05098     /* subject name */
05099     der->subjectSz = SetName(der->subject, &cert->subject);
05100     if (der->subjectSz == 0)
05101         return SUBJECT_E;
05102 
05103     /* issuer name */
05104     der->issuerSz = SetName(der->issuer, cert->selfSigned ?
05105              &cert->subject : &cert->issuer);
05106     if (der->issuerSz == 0)
05107         return ISSUER_E;
05108 
05109     /* CA */
05110     if (cert->isCA) {
05111         der->caSz = SetCa(der->ca);
05112         if (der->caSz == 0)
05113             return CA_TRUE_E;
05114     }
05115     else
05116         der->caSz = 0;
05117 
05118     /* extensions, just CA now */
05119     if (cert->isCA) {
05120         der->extensionsSz = SetExtensions(der->extensions,
05121                                           der->ca, der->caSz, TRUE);
05122         if (der->extensionsSz == 0)
05123             return EXTENSIONS_E;
05124     }
05125     else
05126         der->extensionsSz = 0;
05127 
05128 #ifdef CYASSL_ALT_NAMES
05129     if (der->extensionsSz == 0 && cert->altNamesSz) {
05130         der->extensionsSz = SetExtensions(der->extensions, cert->altNames,
05131                                           cert->altNamesSz, TRUE);
05132         if (der->extensionsSz == 0)
05133             return EXTENSIONS_E;
05134     }
05135 #endif
05136 
05137     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
05138         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
05139         der->extensionsSz;
05140 
05141     return 0;
05142 }
05143 
05144 
05145 /* write DER encoded cert to buffer, size already checked */
05146 static int WriteCertBody(DerCert* der, byte* buffer)
05147 {
05148     int idx;
05149 
05150     /* signed part header */
05151     idx = SetSequence(der->total, buffer);
05152     /* version */
05153     XMEMCPY(buffer + idx, der->version, der->versionSz);
05154     idx += der->versionSz;
05155     /* serial */
05156     XMEMCPY(buffer + idx, der->serial, der->serialSz);
05157     idx += der->serialSz;
05158     /* sig algo */
05159     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
05160     idx += der->sigAlgoSz;
05161     /* issuer */
05162     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
05163     idx += der->issuerSz;
05164     /* validity */
05165     XMEMCPY(buffer + idx, der->validity, der->validitySz);
05166     idx += der->validitySz;
05167     /* subject */
05168     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
05169     idx += der->subjectSz;
05170     /* public key */
05171     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
05172     idx += der->publicKeySz;
05173     if (der->extensionsSz) {
05174         /* extensions */
05175         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
05176                                                    sizeof(der->extensions)));
05177         idx += der->extensionsSz;
05178     }
05179 
05180     return idx;
05181 }
05182 
05183 
05184 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
05185 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
05186                          RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
05187                          int sigAlgoType)
05188 {
05189     byte    digest[SHA256_DIGEST_SIZE];     /* max size */
05190     byte    encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
05191     int     encSigSz, digestSz, typeH, ret = 0;
05192 
05193     (void)eccKey;
05194 
05195     if (sigAlgoType == CTC_MD5wRSA) {
05196         Md5 md5;
05197 
05198         InitMd5(&md5);
05199         Md5Update(&md5, buffer, sz);
05200         Md5Final(&md5, digest);
05201 
05202         digestSz = MD5_DIGEST_SIZE;
05203         typeH    = MD5h;
05204     }
05205     else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) {
05206         Sha sha;
05207 
05208         ret = InitSha(&sha);
05209         if (ret != 0)
05210             return ret;
05211 
05212         ShaUpdate(&sha, buffer, sz);
05213         ShaFinal(&sha, digest);
05214 
05215         digestSz = SHA_DIGEST_SIZE;
05216         typeH    = SHAh;
05217     }
05218     else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) {
05219         Sha256 sha256;
05220 
05221         ret = InitSha256(&sha256);
05222         if (ret != 0)
05223             return ret;
05224 
05225         ret = Sha256Update(&sha256, buffer, sz);
05226         if (ret != 0)
05227             return ret;
05228 
05229         ret = Sha256Final(&sha256, digest);
05230         if (ret != 0)
05231             return ret;
05232 
05233         digestSz = SHA256_DIGEST_SIZE;
05234         typeH    = SHA256h;
05235     }
05236     else
05237         return ALGO_ID_E;
05238 
05239     if (rsaKey) {
05240         /* signature */
05241         encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
05242         return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng);
05243     }
05244 #ifdef HAVE_ECC
05245     else if (eccKey) {
05246         word32 outSz = sigSz;
05247         ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey);
05248 
05249         if (ret != 0)
05250             return ret;
05251         return outSz;
05252     }
05253 #endif /* HAVE_ECC */
05254 
05255     return ALGO_ID_E;
05256 }
05257 
05258 
05259 /* add signature to end of buffer, size of buffer assumed checked, return
05260    new length */
05261 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
05262                         int sigAlgoType)
05263 {
05264     byte seq[MAX_SEQ_SZ];
05265     int  idx = bodySz, seqSz;
05266 
05267     /* algo */
05268     idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0);
05269     /* bit string */
05270     buffer[idx++] = ASN_BIT_STRING;
05271     /* length */
05272     idx += SetLength(sigSz + 1, buffer + idx);
05273     buffer[idx++] = 0;   /* trailing 0 */
05274     /* signature */
05275     XMEMCPY(buffer + idx, sig, sigSz);
05276     idx += sigSz;
05277 
05278     /* make room for overall header */
05279     seqSz = SetSequence(idx, seq);
05280     XMEMMOVE(buffer + seqSz, buffer, idx);
05281     XMEMCPY(buffer, seq, seqSz);
05282 
05283     return idx + seqSz;
05284 }
05285 
05286 
05287 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
05288 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
05289                        RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
05290                        const byte* ntruKey, word16 ntruSz)
05291 {
05292     DerCert der;
05293     int     ret;
05294 
05295     if (eccKey)
05296         cert->keyType = ECC_KEY;
05297     else
05298         cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY;
05299     ret = EncodeCert(cert, &der, rsaKey, eccKey, rng, ntruKey, ntruSz);
05300     if (ret != 0)
05301         return ret;
05302 
05303     if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
05304         return BUFFER_E;
05305 
05306     return cert->bodySz = WriteCertBody(&der, derBuffer);
05307 }
05308 
05309 
05310 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
05311 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
05312              ecc_key* eccKey, RNG* rng)
05313 {
05314     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0);
05315 }
05316 
05317 
05318 #ifdef HAVE_NTRU
05319 
05320 int  MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
05321                   const byte* ntruKey, word16 keySz, RNG* rng)
05322 {
05323     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
05324 }
05325 
05326 #endif /* HAVE_NTRU */
05327 
05328 
05329 #ifdef CYASSL_CERT_REQ
05330 
05331 static int SetReqAttrib(byte* output, char* pw, int extSz)
05332 {
05333     static const byte cpOid[] =
05334         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
05335                          0x09, 0x07 };
05336     static const byte erOid[] =
05337         { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
05338                          0x09, 0x0e };
05339 
05340     int sz      = 0; /* overall size */
05341     int cpSz    = 0; /* Challenge Password section size */
05342     int cpSeqSz = 0;
05343     int cpSetSz = 0;
05344     int cpStrSz = 0;
05345     int pwSz    = 0;
05346     int erSz    = 0; /* Extension Request section size */
05347     int erSeqSz = 0;
05348     int erSetSz = 0;
05349     byte cpSeq[MAX_SEQ_SZ];
05350     byte cpSet[MAX_SET_SZ];
05351     byte cpStr[MAX_PRSTR_SZ];
05352     byte erSeq[MAX_SEQ_SZ];
05353     byte erSet[MAX_SET_SZ];
05354 
05355     output[0] = 0xa0;
05356     sz++;
05357 
05358     if (pw && pw[0]) {
05359         pwSz = (int)XSTRLEN(pw);
05360         cpStrSz = SetUTF8String(pwSz, cpStr);
05361         cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
05362         cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
05363         cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
05364     }
05365 
05366     if (extSz) {
05367         erSetSz = SetSet(extSz, erSet);
05368         erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
05369         erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
05370     }
05371 
05372     /* Put the pieces together. */
05373     sz += SetLength(cpSz + erSz, &output[sz]);
05374 
05375     if (cpSz) {
05376         XMEMCPY(&output[sz], cpSeq, cpSeqSz);
05377         sz += cpSeqSz;
05378         XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
05379         sz += sizeof(cpOid);
05380         XMEMCPY(&output[sz], cpSet, cpSetSz);
05381         sz += cpSetSz;
05382         XMEMCPY(&output[sz], cpStr, cpStrSz);
05383         sz += cpStrSz;
05384         XMEMCPY(&output[sz], pw, pwSz);
05385         sz += pwSz;
05386     }
05387 
05388     if (erSz) {
05389         XMEMCPY(&output[sz], erSeq, erSeqSz);
05390         sz += erSeqSz;
05391         XMEMCPY(&output[sz], erOid, sizeof(erOid));
05392         sz += sizeof(erOid);
05393         XMEMCPY(&output[sz], erSet, erSetSz);
05394         sz += erSetSz;
05395         /* The actual extension data will be tacked onto the output later. */
05396     }
05397 
05398     return sz;
05399 }
05400 
05401 
05402 /* encode info from cert into DER encoded format */
05403 static int EncodeCertReq(Cert* cert, DerCert* der,
05404                          RsaKey* rsaKey, ecc_key* eccKey)
05405 {
05406     (void)eccKey;
05407 
05408     /* init */
05409     XMEMSET(der, 0, sizeof(DerCert));
05410 
05411     /* version */
05412     der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
05413 
05414     /* subject name */
05415     der->subjectSz = SetName(der->subject, &cert->subject);
05416     if (der->subjectSz == 0)
05417         return SUBJECT_E;
05418 
05419     /* public key */
05420     if (cert->keyType == RSA_KEY) {
05421         if (rsaKey == NULL)
05422             return PUBLIC_KEY_E;
05423         der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
05424         if (der->publicKeySz <= 0)
05425             return PUBLIC_KEY_E;
05426     }
05427 
05428 #ifdef HAVE_ECC
05429     if (cert->keyType == ECC_KEY) {
05430         if (eccKey == NULL)
05431             return PUBLIC_KEY_E;
05432         der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
05433         if (der->publicKeySz <= 0)
05434             return PUBLIC_KEY_E;
05435     }
05436 #endif /* HAVE_ECC */
05437 
05438     /* CA */
05439     if (cert->isCA) {
05440         der->caSz = SetCa(der->ca);
05441         if (der->caSz == 0)
05442             return CA_TRUE_E;
05443     }
05444     else
05445         der->caSz = 0;
05446 
05447     /* extensions, just CA now */
05448     if (cert->isCA) {
05449         der->extensionsSz = SetExtensions(der->extensions,
05450                                           der->ca, der->caSz, FALSE);
05451         if (der->extensionsSz == 0)
05452             return EXTENSIONS_E;
05453     }
05454     else
05455         der->extensionsSz = 0;
05456 
05457     der->attribSz = SetReqAttrib(der->attrib,
05458                                  cert->challengePw, der->extensionsSz);
05459     if (der->attribSz == 0)
05460         return REQ_ATTRIBUTE_E;
05461 
05462     der->total = der->versionSz + der->subjectSz + der->publicKeySz +
05463         der->extensionsSz + der->attribSz;
05464 
05465     return 0;
05466 }
05467 
05468 
05469 /* write DER encoded cert req to buffer, size already checked */
05470 static int WriteCertReqBody(DerCert* der, byte* buffer)
05471 {
05472     int idx;
05473 
05474     /* signed part header */
05475     idx = SetSequence(der->total, buffer);
05476     /* version */
05477     XMEMCPY(buffer + idx, der->version, der->versionSz);
05478     idx += der->versionSz;
05479     /* subject */
05480     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
05481     idx += der->subjectSz;
05482     /* public key */
05483     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
05484     idx += der->publicKeySz;
05485     /* attributes */
05486     XMEMCPY(buffer + idx, der->attrib, der->attribSz);
05487     idx += der->attribSz;
05488     /* extensions */
05489     if (der->extensionsSz) {
05490         XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
05491                                                    sizeof(der->extensions)));
05492         idx += der->extensionsSz;
05493     }
05494 
05495     return idx;
05496 }
05497 
05498 
05499 int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
05500                 RsaKey* rsaKey, ecc_key* eccKey)
05501 {
05502     DerCert der;
05503     int     ret;
05504 
05505     cert->keyType = (eccKey != NULL) ? ECC_KEY : RSA_KEY;
05506     ret = EncodeCertReq(cert, &der, rsaKey, eccKey);
05507     if (ret != 0)
05508         return ret;
05509 
05510     if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
05511         return BUFFER_E;
05512 
05513     return cert->bodySz = WriteCertReqBody(&der, derBuffer);
05514 }
05515 
05516 #endif /* CYASSL_CERT_REQ */
05517 
05518 
05519 int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
05520              RsaKey* rsaKey, ecc_key* eccKey, RNG* rng)
05521 {
05522     byte    sig[MAX_ENCODED_SIG_SZ];
05523     int     sigSz;
05524 
05525     if (requestSz < 0)
05526         return requestSz;
05527 
05528     sigSz = MakeSignature(buffer, requestSz, sig, sizeof(sig), rsaKey, eccKey,
05529                           rng, sType);
05530     if (sigSz < 0)
05531         return sigSz; 
05532 
05533     if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
05534         return BUFFER_E; 
05535 
05536     return AddSignature(buffer, requestSz, sig, sigSz, sType);
05537 }
05538 
05539 
05540 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
05541 {
05542     int ret = MakeCert(cert, buffer, buffSz, key, NULL, rng);
05543 
05544     if (ret < 0)
05545         return ret;
05546 
05547     return SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng);
05548 }
05549 
05550 
05551 #ifdef CYASSL_ALT_NAMES 
05552 
05553 /* Set Alt Names from der cert, return 0 on success */
05554 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
05555 {
05556     DecodedCert decoded;
05557     int         ret;
05558 
05559     if (derSz < 0)
05560         return derSz;
05561 
05562     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
05563     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
05564 
05565     if (ret < 0) {
05566         FreeDecodedCert(&decoded);
05567         return ret;
05568     }
05569 
05570     if (decoded.extensions) {
05571         byte   b;
05572         int    length;
05573         word32 maxExtensionsIdx;
05574 
05575         decoded.srcIdx = decoded.extensionsIdx;
05576         b = decoded.source[decoded.srcIdx++];
05577         if (b != ASN_EXTENSIONS) {
05578             FreeDecodedCert(&decoded);
05579             return ASN_PARSE_E;
05580         }
05581 
05582         if (GetLength(decoded.source, &decoded.srcIdx, &length,
05583                       decoded.maxIdx) < 0) {
05584             FreeDecodedCert(&decoded);
05585             return ASN_PARSE_E;
05586         }
05587 
05588         if (GetSequence(decoded.source, &decoded.srcIdx, &length,
05589                         decoded.maxIdx) < 0) {
05590             FreeDecodedCert(&decoded);
05591             return ASN_PARSE_E;
05592         }
05593 
05594         maxExtensionsIdx = decoded.srcIdx + length;
05595 
05596         while (decoded.srcIdx < maxExtensionsIdx) {
05597             word32 oid;
05598             word32 startIdx = decoded.srcIdx;
05599             word32 tmpIdx;
05600 
05601             if (GetSequence(decoded.source, &decoded.srcIdx, &length,
05602                         decoded.maxIdx) < 0) {
05603                 FreeDecodedCert(&decoded);
05604                 return ASN_PARSE_E;
05605             }
05606 
05607             tmpIdx = decoded.srcIdx;
05608             decoded.srcIdx = startIdx;
05609 
05610             if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid,
05611                           decoded.maxIdx) < 0) {
05612                 FreeDecodedCert(&decoded);
05613                 return ASN_PARSE_E;
05614             }
05615 
05616             if (oid == ALT_NAMES_OID) {
05617                 cert->altNamesSz = length + (tmpIdx - startIdx);
05618 
05619                 if (cert->altNamesSz < (int)sizeof(cert->altNames))
05620                     XMEMCPY(cert->altNames, &decoded.source[startIdx],
05621                         cert->altNamesSz);
05622                 else {
05623                     cert->altNamesSz = 0;
05624                     CYASSL_MSG("AltNames extensions too big");
05625                     FreeDecodedCert(&decoded);
05626                     return ALT_NAME_E;
05627                 }
05628             }
05629             decoded.srcIdx = tmpIdx + length;
05630         }
05631     }
05632     FreeDecodedCert(&decoded);
05633 
05634     return 0;
05635 }
05636 
05637 
05638 /* Set Dates from der cert, return 0 on success */
05639 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
05640 {
05641     DecodedCert decoded;
05642     int         ret;
05643 
05644     CYASSL_ENTER("SetDatesFromCert");
05645     if (derSz < 0)
05646         return derSz;
05647 
05648     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
05649     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
05650 
05651     if (ret < 0) {
05652         CYASSL_MSG("ParseCertRelative error");
05653         FreeDecodedCert(&decoded);
05654         return ret;
05655     }
05656 
05657     if (decoded.beforeDate == NULL || decoded.afterDate == NULL) {
05658         CYASSL_MSG("Couldn't extract dates");
05659         FreeDecodedCert(&decoded);
05660         return -1;
05661     }
05662 
05663     if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen >
05664                                                  MAX_DATE_SIZE) {
05665         CYASSL_MSG("Bad date size");
05666         FreeDecodedCert(&decoded);
05667         return -1;
05668     }
05669 
05670     XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen);
05671     XMEMCPY(cert->afterDate,  decoded.afterDate,  decoded.afterDateLen);
05672 
05673     cert->beforeDateSz = decoded.beforeDateLen;
05674     cert->afterDateSz  = decoded.afterDateLen;
05675 
05676     return 0;
05677 }
05678 
05679 
05680 #endif /* CYASSL_ALT_NAMES && !NO_RSA */
05681 
05682 
05683 /* Set cn name from der buffer, return 0 on success */
05684 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
05685 {
05686     DecodedCert decoded;
05687     int         ret;
05688     int         sz;
05689 
05690     if (derSz < 0)
05691         return derSz;
05692 
05693     InitDecodedCert(&decoded, (byte*)der, derSz, 0);
05694     ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0);
05695 
05696     if (ret < 0)
05697         return ret;
05698 
05699     if (decoded.subjectCN) {
05700         sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen :
05701                                                   CTC_NAME_SIZE - 1;
05702         strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE);
05703         cn->commonName[sz] = 0;
05704     }
05705     if (decoded.subjectC) {
05706         sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen :
05707                                                  CTC_NAME_SIZE - 1;
05708         strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE);
05709         cn->country[sz] = 0;
05710     }
05711     if (decoded.subjectST) {
05712         sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen :
05713                                                   CTC_NAME_SIZE - 1;
05714         strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE);
05715         cn->state[sz] = 0;
05716     }
05717     if (decoded.subjectL) {
05718         sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen :
05719                                                  CTC_NAME_SIZE - 1;
05720         strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE);
05721         cn->locality[sz] = 0;
05722     }
05723     if (decoded.subjectO) {
05724         sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen :
05725                                                  CTC_NAME_SIZE - 1;
05726         strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE);
05727         cn->org[sz] = 0;
05728     }
05729     if (decoded.subjectOU) {
05730         sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen :
05731                                                   CTC_NAME_SIZE - 1;
05732         strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE);
05733         cn->unit[sz] = 0;
05734     }
05735     if (decoded.subjectSN) {
05736         sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen :
05737                                                   CTC_NAME_SIZE - 1;
05738         strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE);
05739         cn->sur[sz] = 0;
05740     }
05741     if (decoded.subjectEmail) {
05742         sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ?
05743                               decoded.subjectEmailLen : CTC_NAME_SIZE - 1;
05744         strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE);
05745         cn->email[sz] = 0;
05746     }
05747 
05748     FreeDecodedCert(&decoded);
05749 
05750     return 0;
05751 }
05752 
05753 
05754 #ifndef NO_FILESYSTEM
05755 
05756 /* forward from CyaSSL */
05757 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
05758 
05759 /* Set cert issuer from issuerFile in PEM */
05760 int SetIssuer(Cert* cert, const char* issuerFile)
05761 {
05762     int         ret;
05763     int         derSz;
05764     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
05765 
05766     if (der == NULL) {
05767         CYASSL_MSG("SetIssuer OOF Problem");
05768         return MEMORY_E;
05769     }
05770     derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
05771     cert->selfSigned = 0;
05772     ret = SetNameFromCert(&cert->issuer, der, derSz);
05773     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
05774 
05775     return ret;
05776 }
05777 
05778 
05779 /* Set cert subject from subjectFile in PEM */
05780 int SetSubject(Cert* cert, const char* subjectFile)
05781 {
05782     int         ret;
05783     int         derSz;
05784     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
05785 
05786     if (der == NULL) {
05787         CYASSL_MSG("SetSubject OOF Problem");
05788         return MEMORY_E;
05789     }
05790     derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
05791     ret = SetNameFromCert(&cert->subject, der, derSz);
05792     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
05793 
05794     return ret;
05795 }
05796 
05797 
05798 #ifdef CYASSL_ALT_NAMES
05799 
05800 /* Set atl names from file in PEM */
05801 int SetAltNames(Cert* cert, const char* file)
05802 {
05803     int         ret;
05804     int         derSz;
05805     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
05806 
05807     if (der == NULL) {
05808         CYASSL_MSG("SetAltNames OOF Problem");
05809         return MEMORY_E;
05810     }
05811     derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF);
05812     ret = SetAltNamesFromCert(cert, der, derSz);
05813     XFREE(der, NULL, DYNAMIC_TYPE_CERT);
05814 
05815     return ret;
05816 }
05817 
05818 #endif /* CYASSL_ALT_NAMES */
05819 
05820 #endif /* NO_FILESYSTEM */
05821 
05822 /* Set cert issuer from DER buffer */
05823 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
05824 {
05825     cert->selfSigned = 0;
05826     return SetNameFromCert(&cert->issuer, der, derSz);
05827 }
05828 
05829 
05830 /* Set cert subject from DER buffer */
05831 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
05832 {
05833     return SetNameFromCert(&cert->subject, der, derSz);
05834 }
05835 
05836 
05837 #ifdef CYASSL_ALT_NAMES
05838 
05839 /* Set cert alt names from DER buffer */
05840 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
05841 {
05842     return SetAltNamesFromCert(cert, der, derSz);
05843 }
05844 
05845 /* Set cert dates from DER buffer */
05846 int SetDatesBuffer(Cert* cert, const byte* der, int derSz)
05847 {
05848     return SetDatesFromCert(cert, der, derSz);
05849 }
05850 
05851 #endif /* CYASSL_ALT_NAMES */
05852 
05853 #endif /* CYASSL_CERT_GEN */
05854 
05855 
05856 #ifdef HAVE_ECC
05857 
05858 /* Der Encode r & s ints into out, outLen is (in/out) size */
05859 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
05860 {
05861     word32 idx = 0;
05862     word32 rSz;                           /* encoding size */
05863     word32 sSz;
05864     word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
05865 
05866     /* If the leading bit on the INTEGER is a 1, add a leading zero */
05867     int rLeadingZero = mp_leading_bit(r);
05868     int sLeadingZero = mp_leading_bit(s);
05869     int rLen = mp_unsigned_bin_size(r);   /* big int size */
05870     int sLen = mp_unsigned_bin_size(s);
05871     int err;
05872 
05873     if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
05874                    headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
05875         return BAD_FUNC_ARG;
05876 
05877     idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
05878 
05879     /* store r */
05880     out[idx++] = ASN_INTEGER;
05881     rSz = SetLength(rLen + rLeadingZero, &out[idx]);
05882     idx += rSz;
05883     if (rLeadingZero)
05884         out[idx++] = 0;
05885     err = mp_to_unsigned_bin(r, &out[idx]);
05886     if (err != MP_OKAY) return err;
05887     idx += rLen;
05888 
05889     /* store s */
05890     out[idx++] = ASN_INTEGER;
05891     sSz = SetLength(sLen + sLeadingZero, &out[idx]);
05892     idx += sSz;
05893     if (sLeadingZero)
05894         out[idx++] = 0;
05895     err = mp_to_unsigned_bin(s, &out[idx]);
05896     if (err != MP_OKAY) return err;
05897     idx += sLen;
05898 
05899     *outLen = idx;
05900 
05901     return 0;
05902 }
05903 
05904 
05905 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */
05906 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
05907 {
05908     word32 idx = 0;
05909     int    len = 0;
05910 
05911     if (GetSequence(sig, &idx, &len, sigLen) < 0)
05912         return ASN_ECC_KEY_E;
05913 
05914     if ((word32)len > (sigLen - idx))
05915         return ASN_ECC_KEY_E;
05916 
05917     if (GetInt(r, sig, &idx, sigLen) < 0)
05918         return ASN_ECC_KEY_E;
05919 
05920     if (GetInt(s, sig, &idx, sigLen) < 0)
05921         return ASN_ECC_KEY_E;
05922 
05923     return 0;
05924 }
05925 
05926 
05927 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
05928                         word32 inSz)
05929 {
05930     word32 oid = 0;
05931     int    version, length;
05932     int    privSz, pubSz;
05933     byte   b;
05934     byte   priv[ECC_MAXSIZE];
05935     byte   pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */
05936 
05937     if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
05938         return BAD_FUNC_ARG;
05939 
05940     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
05941         return ASN_PARSE_E;
05942 
05943     if (GetMyVersion(input, inOutIdx, &version) < 0)
05944         return ASN_PARSE_E;
05945 
05946     b = input[*inOutIdx];
05947     *inOutIdx += 1;
05948 
05949     /* priv type */
05950     if (b != 4 && b != 6 && b != 7) 
05951         return ASN_PARSE_E;
05952 
05953     if (GetLength(input, inOutIdx, &length, inSz) < 0)
05954         return ASN_PARSE_E;
05955 
05956     /* priv key */
05957     privSz = length;
05958     XMEMCPY(priv, &input[*inOutIdx], privSz);
05959     *inOutIdx += length;
05960 
05961     /* prefix 0, may have */
05962     b = input[*inOutIdx];
05963     if (b == ECC_PREFIX_0) {
05964         *inOutIdx += 1;
05965 
05966         if (GetLength(input, inOutIdx, &length, inSz) < 0)
05967             return ASN_PARSE_E;
05968 
05969         /* object id */
05970         b = input[*inOutIdx];
05971         *inOutIdx += 1;
05972     
05973         if (b != ASN_OBJECT_ID) 
05974             return ASN_OBJECT_ID_E;
05975 
05976         if (GetLength(input, inOutIdx, &length, inSz) < 0)
05977             return ASN_PARSE_E;
05978 
05979         while(length--) {
05980             oid += input[*inOutIdx];
05981             *inOutIdx += 1;
05982         }
05983         if (CheckCurve(oid) < 0)
05984             return ECC_CURVE_OID_E;
05985     }
05986     
05987     /* prefix 1 */
05988     b = input[*inOutIdx];
05989     *inOutIdx += 1;
05990     if (b != ECC_PREFIX_1)
05991         return ASN_ECC_KEY_E;
05992 
05993     if (GetLength(input, inOutIdx, &length, inSz) < 0)
05994         return ASN_PARSE_E;
05995 
05996     /* key header */
05997     b = input[*inOutIdx];
05998     *inOutIdx += 1;
05999     if (b != ASN_BIT_STRING)
06000         return ASN_BITSTR_E;
06001 
06002     if (GetLength(input, inOutIdx, &length, inSz) < 0)
06003         return ASN_PARSE_E;
06004     b = input[*inOutIdx];
06005     *inOutIdx += 1;
06006     if (b != 0x00)
06007         return ASN_EXPECT_0_E;
06008 
06009     pubSz = length - 1;  /* null prefix */
06010     XMEMCPY(pub, &input[*inOutIdx], pubSz);
06011 
06012     *inOutIdx += length;
06013     
06014     return ecc_import_private_key(priv, privSz, pub, pubSz, key);
06015 }
06016 
06017 #endif  /* HAVE_ECC */
06018 
06019 
06020 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
06021 
06022 /* Get raw Date only, no processing, 0 on success */
06023 static int GetBasicDate(const byte* source, word32* idx, byte* date,
06024                         byte* format, int maxIdx)
06025 {
06026     int    length;
06027 
06028     CYASSL_ENTER("GetBasicDate");
06029 
06030     *format = source[*idx];
06031     *idx += 1;
06032     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
06033         return ASN_TIME_E;
06034 
06035     if (GetLength(source, idx, &length, maxIdx) < 0)
06036         return ASN_PARSE_E;
06037 
06038     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
06039         return ASN_DATE_SZ_E;
06040 
06041     XMEMCPY(date, &source[*idx], length);
06042     *idx += length;
06043 
06044     return 0;
06045 }
06046 
06047 #endif
06048 
06049 
06050 #ifdef HAVE_OCSP
06051 
06052 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
06053 {
06054     word32 idx = *inOutIdx;
06055     word32 len;
06056 
06057     CYASSL_ENTER("GetEnumerated");
06058 
06059     *value = 0;
06060 
06061     if (input[idx++] != ASN_ENUMERATED)
06062         return ASN_PARSE_E;
06063 
06064     len = input[idx++];
06065     if (len > 4)
06066         return ASN_PARSE_E;
06067 
06068     while (len--) {
06069         *value  = *value << 8 | input[idx++];
06070     }
06071 
06072     *inOutIdx = idx;
06073 
06074     return *value;
06075 }
06076 
06077 
06078 static int DecodeSingleResponse(byte* source,
06079                             word32* ioIndex, OcspResponse* resp, word32 size)
06080 {
06081     word32 idx = *ioIndex, prevIndex, oid;
06082     int length, wrapperSz;
06083     CertStatus* cs = resp->status;
06084 
06085     CYASSL_ENTER("DecodeSingleResponse");
06086 
06087     /* Outer wrapper of the SEQUENCE OF Single Responses. */
06088     if (GetSequence(source, &idx, &wrapperSz, size) < 0)
06089         return ASN_PARSE_E;
06090 
06091     prevIndex = idx;
06092 
06093     /* When making a request, we only request one status on one certificate
06094      * at a time. There should only be one SingleResponse */
06095 
06096     /* Wrapper around the Single Response */
06097     if (GetSequence(source, &idx, &length, size) < 0)
06098         return ASN_PARSE_E;
06099 
06100     /* Wrapper around the CertID */
06101     if (GetSequence(source, &idx, &length, size) < 0)
06102         return ASN_PARSE_E;
06103     /* Skip the hash algorithm */
06104     if (GetAlgoId(source, &idx, &oid, size) < 0)
06105         return ASN_PARSE_E;
06106     /* Save reference to the hash of CN */
06107     if (source[idx++] != ASN_OCTET_STRING)
06108         return ASN_PARSE_E;
06109     if (GetLength(source, &idx, &length, size) < 0)
06110         return ASN_PARSE_E;
06111     resp->issuerHash = source + idx;
06112     idx += length;
06113     /* Save reference to the hash of the issuer public key */
06114     if (source[idx++] != ASN_OCTET_STRING)
06115         return ASN_PARSE_E;
06116     if (GetLength(source, &idx, &length, size) < 0)
06117         return ASN_PARSE_E;
06118     resp->issuerKeyHash = source + idx;
06119     idx += length;
06120 
06121     /* Read the serial number, it is handled as a string, not as a 
06122      * proper number. Just XMEMCPY the data over, rather than load it
06123      * as an mp_int. */
06124     if (source[idx++] != ASN_INTEGER)
06125         return ASN_PARSE_E;
06126     if (GetLength(source, &idx, &length, size) < 0)
06127         return ASN_PARSE_E;
06128     if (length <= EXTERNAL_SERIAL_SIZE)
06129     {
06130         if (source[idx] == 0)
06131         {
06132             idx++;
06133             length--;
06134         }
06135         XMEMCPY(cs->serial, source + idx, length);
06136         cs->serialSz = length;
06137     }
06138     else
06139     {
06140         return ASN_GETINT_E;
06141     }
06142     idx += length;
06143 
06144     /* CertStatus */
06145     switch (source[idx++])
06146     {
06147         case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
06148             cs->status = CERT_GOOD;
06149             idx++;
06150             break;
06151         case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
06152             cs->status = CERT_REVOKED;
06153             if (GetLength(source, &idx, &length, size) < 0)
06154                 return ASN_PARSE_E;
06155             idx += length;
06156             break;
06157         case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
06158             cs->status = CERT_UNKNOWN;
06159             idx++;
06160             break;
06161         default:
06162             return ASN_PARSE_E;
06163     }
06164 
06165     if (GetBasicDate(source, &idx, cs->thisDate,
06166                                                 &cs->thisDateFormat, size) < 0)
06167         return ASN_PARSE_E;
06168     if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
06169         return ASN_BEFORE_DATE_E;
06170     
06171     /* The following items are optional. Only check for them if there is more
06172      * unprocessed data in the singleResponse wrapper. */
06173     
06174     if (((int)(idx - prevIndex) < wrapperSz) &&
06175         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
06176     {
06177         idx++;
06178         if (GetLength(source, &idx, &length, size) < 0)
06179             return ASN_PARSE_E;
06180         if (GetBasicDate(source, &idx, cs->nextDate,
06181                                                 &cs->nextDateFormat, size) < 0)
06182             return ASN_PARSE_E;
06183     }
06184     if (((int)(idx - prevIndex) < wrapperSz) &&
06185         (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
06186     {
06187         idx++;
06188         if (GetLength(source, &idx, &length, size) < 0)
06189             return ASN_PARSE_E;
06190         idx += length;
06191     }
06192 
06193     *ioIndex = idx;
06194 
06195     return 0;
06196 }
06197 
06198 static int DecodeOcspRespExtensions(byte* source,
06199                             word32* ioIndex, OcspResponse* resp, word32 sz)
06200 {
06201     word32 idx = *ioIndex;
06202     int length;
06203     int ext_bound; /* boundary index for the sequence of extensions */
06204     word32 oid;
06205 
06206     CYASSL_ENTER("DecodeOcspRespExtensions");
06207 
06208     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
06209         return ASN_PARSE_E;
06210 
06211     if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
06212 
06213     if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
06214    
06215     ext_bound = idx + length;
06216 
06217     while (idx < (word32)ext_bound) {
06218         if (GetSequence(source, &idx, &length, sz) < 0) {
06219             CYASSL_MSG("\tfail: should be a SEQUENCE");
06220             return ASN_PARSE_E;
06221         }
06222 
06223         oid = 0;
06224         if (GetObjectId(source, &idx, &oid, sz) < 0) {
06225             CYASSL_MSG("\tfail: OBJECT ID");
06226             return ASN_PARSE_E;
06227         }
06228 
06229         /* check for critical flag */
06230         if (source[idx] == ASN_BOOLEAN) {
06231             CYASSL_MSG("\tfound optional critical flag, moving past");
06232             idx += (ASN_BOOL_SIZE + 1);
06233         }
06234 
06235         /* process the extension based on the OID */
06236         if (source[idx++] != ASN_OCTET_STRING) {
06237             CYASSL_MSG("\tfail: should be an OCTET STRING");
06238             return ASN_PARSE_E;
06239         }
06240 
06241         if (GetLength(source, &idx, &length, sz) < 0) {
06242             CYASSL_MSG("\tfail: extension data length");
06243             return ASN_PARSE_E;
06244         }
06245 
06246         if (oid == OCSP_NONCE_OID) {
06247             resp->nonce = source + idx;
06248             resp->nonceSz = length;
06249         }
06250 
06251         idx += length;
06252     }
06253 
06254     *ioIndex = idx;
06255     return 0;
06256 }
06257 
06258 
06259 static int DecodeResponseData(byte* source,
06260                             word32* ioIndex, OcspResponse* resp, word32 size)
06261 {
06262     word32 idx = *ioIndex, prev_idx;
06263     int length;
06264     int version;
06265     word32 responderId = 0;
06266 
06267     CYASSL_ENTER("DecodeResponseData");
06268 
06269     resp->response = source + idx;
06270     prev_idx = idx;
06271     if (GetSequence(source, &idx, &length, size) < 0)
06272         return ASN_PARSE_E;
06273     resp->responseSz = length + idx - prev_idx;
06274 
06275     /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
06276      * item isn't an EXPLICIT[0], then set version to zero and move
06277      * onto the next item.
06278      */
06279     if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
06280     {    
06281         idx += 2; /* Eat the value and length */
06282         if (GetMyVersion(source, &idx, &version) < 0)
06283             return ASN_PARSE_E;
06284     } else
06285         version = 0;
06286 
06287     responderId = source[idx++];
06288     if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
06289         (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
06290     {
06291         if (GetLength(source, &idx, &length, size) < 0)
06292             return ASN_PARSE_E;
06293         idx += length;
06294     }
06295     else
06296         return ASN_PARSE_E;
06297     
06298     /* save pointer to the producedAt time */
06299     if (GetBasicDate(source, &idx, resp->producedDate,
06300                                         &resp->producedDateFormat, size) < 0)
06301         return ASN_PARSE_E;
06302 
06303     if (DecodeSingleResponse(source, &idx, resp, size) < 0)
06304         return ASN_PARSE_E;
06305 
06306     if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
06307         return ASN_PARSE_E;
06308 
06309     *ioIndex = idx;
06310     return 0;
06311 }
06312 
06313 
06314 static int DecodeCerts(byte* source,
06315                             word32* ioIndex, OcspResponse* resp, word32 size)
06316 {
06317     word32 idx = *ioIndex;
06318 
06319     CYASSL_ENTER("DecodeCerts");
06320 
06321     if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
06322     {
06323         int length;
06324 
06325         if (GetLength(source, &idx, &length, size) < 0)
06326             return ASN_PARSE_E;
06327 
06328         if (GetSequence(source, &idx, &length, size) < 0)
06329             return ASN_PARSE_E;
06330 
06331         resp->cert = source + idx;
06332         resp->certSz = length;
06333 
06334         idx += length;
06335     }
06336     *ioIndex = idx;
06337     return 0;
06338 }
06339 
06340 static int DecodeBasicOcspResponse(byte* source,
06341                             word32* ioIndex, OcspResponse* resp, word32 size)
06342 {
06343     int length;
06344     word32 idx = *ioIndex;
06345     word32 end_index;
06346 
06347     CYASSL_ENTER("DecodeBasicOcspResponse");
06348 
06349     if (GetSequence(source, &idx, &length, size) < 0)
06350         return ASN_PARSE_E;
06351 
06352     if (idx + length > size)
06353         return ASN_INPUT_E;
06354     end_index = idx + length;
06355 
06356     if (DecodeResponseData(source, &idx, resp, size) < 0)
06357         return ASN_PARSE_E;
06358     
06359     /* Get the signature algorithm */
06360     if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
06361         return ASN_PARSE_E;
06362 
06363     /* Obtain pointer to the start of the signature, and save the size */
06364     if (source[idx++] == ASN_BIT_STRING)
06365     {
06366         int sigLength = 0;
06367         if (GetLength(source, &idx, &sigLength, size) < 0)
06368             return ASN_PARSE_E;
06369         resp->sigSz = sigLength;
06370         resp->sig = source + idx;
06371         idx += sigLength;
06372     }
06373 
06374     /*
06375      * Check the length of the BasicOcspResponse against the current index to
06376      * see if there are certificates, they are optional.
06377      */
06378     if (idx < end_index)
06379     {
06380         DecodedCert cert;
06381         int ret;
06382 
06383         if (DecodeCerts(source, &idx, resp, size) < 0)
06384             return ASN_PARSE_E;
06385 
06386         InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
06387         ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
06388         if (ret < 0)
06389             return ret;
06390 
06391         ret = ConfirmSignature(resp->response, resp->responseSz,
06392                             cert.publicKey, cert.pubKeySize, cert.keyOID,
06393                             resp->sig, resp->sigSz, resp->sigOID, NULL);
06394         FreeDecodedCert(&cert);
06395 
06396         if (ret == 0)
06397         {
06398             CYASSL_MSG("\tOCSP Confirm signature failed");
06399             return ASN_OCSP_CONFIRM_E;
06400         }
06401     }
06402 
06403     *ioIndex = idx;
06404     return 0;
06405 }
06406 
06407 
06408 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
06409                                                     byte* source, word32 inSz)
06410 {
06411     CYASSL_ENTER("InitOcspResponse");
06412 
06413     resp->responseStatus = -1;
06414     resp->response = NULL;
06415     resp->responseSz = 0;
06416     resp->producedDateFormat = 0;
06417     resp->issuerHash = NULL;
06418     resp->issuerKeyHash = NULL;
06419     resp->sig = NULL;
06420     resp->sigSz = 0;
06421     resp->sigOID = 0;
06422     resp->status = status;
06423     resp->nonce = NULL;
06424     resp->nonceSz = 0;
06425     resp->source = source;
06426     resp->maxIdx = inSz;
06427 }
06428 
06429 
06430 int OcspResponseDecode(OcspResponse* resp)
06431 {
06432     int length = 0;
06433     word32 idx = 0;
06434     byte* source = resp->source;
06435     word32 size = resp->maxIdx;
06436     word32 oid;
06437 
06438     CYASSL_ENTER("OcspResponseDecode");
06439 
06440     /* peel the outer SEQUENCE wrapper */
06441     if (GetSequence(source, &idx, &length, size) < 0)
06442         return ASN_PARSE_E;
06443     
06444     /* First get the responseStatus, an ENUMERATED */
06445     if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
06446         return ASN_PARSE_E;
06447 
06448     if (resp->responseStatus != OCSP_SUCCESSFUL)
06449         return 0;
06450 
06451     /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
06452     if (idx >= size)
06453         return ASN_INPUT_E;
06454     if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
06455         return ASN_PARSE_E;
06456     if (GetLength(source, &idx, &length, size) < 0)
06457         return ASN_PARSE_E;
06458 
06459     /* Get the responseBytes SEQUENCE */
06460     if (GetSequence(source, &idx, &length, size) < 0)
06461         return ASN_PARSE_E;
06462 
06463     /* Check ObjectID for the resposeBytes */
06464     if (GetObjectId(source, &idx, &oid, size) < 0)
06465         return ASN_PARSE_E;
06466     if (oid != OCSP_BASIC_OID)
06467         return ASN_PARSE_E;
06468     if (source[idx++] != ASN_OCTET_STRING)
06469         return ASN_PARSE_E;
06470 
06471     if (GetLength(source, &idx, &length, size) < 0)
06472         return ASN_PARSE_E;
06473 
06474     if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
06475         return ASN_PARSE_E;
06476     
06477     return 0;
06478 }
06479 
06480 
06481 static word32 SetOcspReqExtensions(word32 extSz, byte* output,
06482                                             const byte* nonce, word32 nonceSz)
06483 {
06484     static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
06485                                        0x30, 0x01, 0x02 };
06486     byte seqArray[5][MAX_SEQ_SZ];
06487     word32 seqSz[5], totalSz;
06488 
06489     CYASSL_ENTER("SetOcspReqExtensions");
06490 
06491     if (nonce == NULL || nonceSz == 0) return 0;
06492     
06493     seqArray[0][0] = ASN_OCTET_STRING;
06494     seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
06495 
06496     seqArray[1][0] = ASN_OBJECT_ID;
06497     seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
06498 
06499     totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
06500 
06501     seqSz[2] = SetSequence(totalSz, seqArray[2]);
06502     totalSz += seqSz[2];
06503 
06504     seqSz[3] = SetSequence(totalSz, seqArray[3]);
06505     totalSz += seqSz[3];
06506 
06507     seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
06508     seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
06509     totalSz += seqSz[4];
06510 
06511     if (totalSz < extSz)
06512     {
06513         totalSz = 0;
06514         XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
06515         totalSz += seqSz[4];
06516         XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
06517         totalSz += seqSz[3];
06518         XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
06519         totalSz += seqSz[2];
06520         XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
06521         totalSz += seqSz[1];
06522         XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
06523         totalSz += (word32)sizeof(NonceObjId);
06524         XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
06525         totalSz += seqSz[0];
06526         XMEMCPY(output + totalSz, nonce, nonceSz);
06527         totalSz += nonceSz;
06528     }
06529 
06530     return totalSz;
06531 }
06532 
06533 
06534 int EncodeOcspRequest(OcspRequest* req)
06535 {
06536     byte seqArray[5][MAX_SEQ_SZ];
06537     /* The ASN.1 of the OCSP Request is an onion of sequences */
06538     byte algoArray[MAX_ALGO_SZ];
06539     byte issuerArray[MAX_ENCODED_DIG_SZ];
06540     byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
06541     byte snArray[MAX_SN_SZ];
06542     byte extArray[MAX_OCSP_EXT_SZ];
06543     byte* output = req->dest;
06544     word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
06545     int i;
06546 
06547     CYASSL_ENTER("EncodeOcspRequest");
06548 
06549     algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
06550 
06551     req->issuerHash = req->cert->issuerHash;
06552     issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray);
06553     
06554     req->issuerKeyHash = req->cert->issuerKeyHash;
06555     issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray);
06556 
06557     req->serial = req->cert->serial;
06558     req->serialSz = req->cert->serialSz;
06559     snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
06560 
06561     extSz = 0;
06562     if (req->useNonce) {
06563         RNG rng;
06564         if (InitRng(&rng) != 0) {
06565             CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
06566         } else {
06567             if (RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
06568                 CYASSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
06569             else {
06570                 req->nonceSz = MAX_OCSP_NONCE_SZ;
06571                 extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
06572                                                       req->nonce, req->nonceSz);
06573             }
06574         }
06575     }
06576 
06577     totalSz = algoSz + issuerSz + issuerKeySz + snSz;
06578 
06579     for (i = 4; i >= 0; i--) {
06580         seqSz[i] = SetSequence(totalSz, seqArray[i]);
06581         totalSz += seqSz[i];
06582         if (i == 2) totalSz += extSz;
06583     }
06584     totalSz = 0;
06585     for (i = 0; i < 5; i++) {
06586         XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
06587         totalSz += seqSz[i];
06588     }
06589     XMEMCPY(output + totalSz, algoArray, algoSz);
06590     totalSz += algoSz;
06591     XMEMCPY(output + totalSz, issuerArray, issuerSz);
06592     totalSz += issuerSz;
06593     XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
06594     totalSz += issuerKeySz;
06595     XMEMCPY(output + totalSz, snArray, snSz);
06596     totalSz += snSz;
06597     if (extSz != 0) {
06598         XMEMCPY(output + totalSz, extArray, extSz);
06599         totalSz += extSz;
06600     }
06601 
06602     return totalSz;
06603 }
06604 
06605 
06606 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
06607                                                     byte* dest, word32 destSz)
06608 {
06609     CYASSL_ENTER("InitOcspRequest");
06610 
06611     req->cert = cert;
06612     req->useNonce = useNonce;
06613     req->nonceSz = 0;
06614     req->issuerHash = NULL;
06615     req->issuerKeyHash = NULL;
06616     req->serial = NULL;
06617     req->dest = dest;
06618     req->destSz = destSz;
06619 }
06620 
06621 
06622 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
06623 {
06624     int cmp;
06625 
06626     CYASSL_ENTER("CompareOcspReqResp");
06627 
06628     if (req == NULL)
06629     {
06630         CYASSL_MSG("\tReq missing");
06631         return -1;
06632     }
06633 
06634     if (resp == NULL)
06635     {
06636         CYASSL_MSG("\tResp missing");
06637         return 1;
06638     }
06639 
06640     /* Nonces are not critical. The responder may not necessarily add
06641      * the nonce to the response. */
06642     if (req->useNonce && resp->nonceSz != 0) {
06643         cmp = req->nonceSz - resp->nonceSz;
06644         if (cmp != 0)
06645         {
06646             CYASSL_MSG("\tnonceSz mismatch");
06647             return cmp;
06648         }
06649     
06650         cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
06651         if (cmp != 0)
06652         {
06653             CYASSL_MSG("\tnonce mismatch");
06654             return cmp;
06655         }
06656     }
06657 
06658     cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE);
06659     if (cmp != 0)
06660     {
06661         CYASSL_MSG("\tissuerHash mismatch");
06662         return cmp;
06663     }
06664 
06665     cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE);
06666     if (cmp != 0)
06667     {
06668         CYASSL_MSG("\tissuerKeyHash mismatch");
06669         return cmp;
06670     }
06671 
06672     cmp = req->serialSz - resp->status->serialSz;
06673     if (cmp != 0)
06674     {
06675         CYASSL_MSG("\tserialSz mismatch");
06676         return cmp;
06677     }
06678 
06679     cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
06680     if (cmp != 0)
06681     {
06682         CYASSL_MSG("\tserial mismatch");
06683         return cmp;
06684     }
06685 
06686     return 0;
06687 }
06688 
06689 #endif
06690 
06691 
06692 /* store SHA1 hash of NAME */
06693 CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
06694                              int maxIdx)
06695 {
06696     Sha    sha;
06697     int    length;  /* length of all distinguished names */
06698     int    ret = 0;
06699     word32 dummy;
06700 
06701     CYASSL_ENTER("GetNameHash");
06702 
06703     if (source[*idx] == ASN_OBJECT_ID) {
06704         CYASSL_MSG("Trying optional prefix...");
06705 
06706         if (GetLength(source, idx, &length, maxIdx) < 0)
06707             return ASN_PARSE_E;
06708 
06709         *idx += length;
06710         CYASSL_MSG("Got optional prefix");
06711     }
06712 
06713     /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
06714      * calculated over the entire DER encoding of the Name field, including
06715      * the tag and length. */
06716     dummy = *idx;
06717     if (GetSequence(source, idx, &length, maxIdx) < 0)
06718         return ASN_PARSE_E;
06719 
06720     ret = InitSha(&sha);
06721     if (ret != 0)
06722         return ret;
06723     ShaUpdate(&sha, source + dummy, length + *idx - dummy);
06724     ShaFinal(&sha, hash);
06725 
06726     *idx += length;
06727 
06728     return 0;
06729 }
06730 
06731 
06732 #ifdef HAVE_CRL
06733 
06734 /* initialize decoded CRL */
06735 void InitDecodedCRL(DecodedCRL* dcrl)
06736 {
06737     CYASSL_MSG("InitDecodedCRL");
06738 
06739     dcrl->certBegin    = 0;
06740     dcrl->sigIndex     = 0;
06741     dcrl->sigLength    = 0;
06742     dcrl->signatureOID = 0;
06743     dcrl->certs        = NULL;
06744     dcrl->totalCerts   = 0;
06745 }
06746 
06747 
06748 /* free decoded CRL resources */
06749 void FreeDecodedCRL(DecodedCRL* dcrl)
06750 {
06751     RevokedCert* tmp = dcrl->certs;
06752 
06753     CYASSL_MSG("FreeDecodedCRL");
06754 
06755     while(tmp) {
06756         RevokedCert* next = tmp->next;
06757         XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
06758         tmp = next;
06759     }
06760 }
06761 
06762 
06763 /* Get Revoked Cert list, 0 on success */
06764 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
06765                       int maxIdx)
06766 {
06767     int    len;
06768     word32 end;
06769     byte   b;
06770     RevokedCert* rc;
06771 
06772     CYASSL_ENTER("GetRevoked");
06773 
06774     if (GetSequence(buff, idx, &len, maxIdx) < 0)
06775         return ASN_PARSE_E;
06776 
06777     end = *idx + len;
06778 
06779     /* get serial number */
06780     b = buff[*idx];
06781     *idx += 1;
06782 
06783     if (b != ASN_INTEGER) {
06784         CYASSL_MSG("Expecting Integer");
06785         return ASN_PARSE_E;
06786     }
06787 
06788     if (GetLength(buff, idx, &len, maxIdx) < 0)
06789         return ASN_PARSE_E;
06790 
06791     if (len > EXTERNAL_SERIAL_SIZE) {
06792         CYASSL_MSG("Serial Size too big");
06793         return ASN_PARSE_E;
06794     }
06795 
06796     rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
06797     if (rc == NULL) {
06798         CYASSL_MSG("Alloc Revoked Cert failed");
06799         return MEMORY_E;
06800     }
06801 
06802     XMEMCPY(rc->serialNumber, &buff[*idx], len);
06803     rc->serialSz = len;
06804 
06805     /* add to list */
06806     rc->next = dcrl->certs;
06807     dcrl->certs = rc;
06808     dcrl->totalCerts++;
06809 
06810     *idx += len;
06811 
06812     /* get date */
06813     b = buff[*idx];
06814     *idx += 1;
06815 
06816     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
06817         CYASSL_MSG("Expecting Date");
06818         return ASN_PARSE_E;
06819     }
06820 
06821     if (GetLength(buff, idx, &len, maxIdx) < 0)
06822         return ASN_PARSE_E;
06823 
06824     /* skip for now */
06825     *idx += len;
06826 
06827     if (*idx != end)  /* skip extensions */
06828         *idx = end;
06829 
06830     return 0;
06831 }
06832 
06833 
06834 /* Get CRL Signature, 0 on success */
06835 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
06836                             int maxIdx)
06837 {
06838     int    length;
06839     byte   b;
06840 
06841     CYASSL_ENTER("GetCRL_Signature");
06842 
06843     b = source[*idx];
06844     *idx += 1;
06845     if (b != ASN_BIT_STRING)
06846         return ASN_BITSTR_E;
06847 
06848     if (GetLength(source, idx, &length, maxIdx) < 0)
06849         return ASN_PARSE_E;
06850 
06851     dcrl->sigLength = length;
06852 
06853     b = source[*idx];
06854     *idx += 1;
06855     if (b != 0x00)
06856         return ASN_EXPECT_0_E;
06857 
06858     dcrl->sigLength--;
06859     dcrl->signature = (byte*)&source[*idx];
06860 
06861     *idx += dcrl->sigLength;
06862 
06863     return 0;
06864 }
06865 
06866 
06867 /* prase crl buffer into decoded state, 0 on success */
06868 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
06869 {
06870     int     version, len;
06871     word32  oid, idx = 0;
06872     Signer* ca = NULL;
06873 
06874     CYASSL_MSG("ParseCRL");
06875 
06876     /* raw crl hash */
06877     /* hash here if needed for optimized comparisons
06878      * Sha     sha;
06879      * InitSha(&sha);
06880      * ShaUpdate(&sha, buff, sz);
06881      * ShaFinal(&sha, dcrl->crlHash); */
06882 
06883     if (GetSequence(buff, &idx, &len, sz) < 0)
06884         return ASN_PARSE_E;
06885 
06886     dcrl->certBegin = idx;
06887 
06888     if (GetSequence(buff, &idx, &len, sz) < 0)
06889         return ASN_PARSE_E;
06890     dcrl->sigIndex = len + idx;
06891 
06892     /* may have version */
06893     if (buff[idx] == ASN_INTEGER) {
06894         if (GetMyVersion(buff, &idx, &version) < 0)
06895             return ASN_PARSE_E;
06896     }
06897 
06898     if (GetAlgoId(buff, &idx, &oid, sz) < 0)
06899         return ASN_PARSE_E;
06900 
06901     if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
06902         return ASN_PARSE_E;
06903 
06904     if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
06905         return ASN_PARSE_E;
06906 
06907     if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
06908         return ASN_PARSE_E;
06909 
06910     if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
06911         CYASSL_MSG("CRL after date is no longer valid");
06912         return ASN_AFTER_DATE_E;
06913     }
06914 
06915     if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
06916         if (GetSequence(buff, &idx, &len, sz) < 0)
06917             return ASN_PARSE_E;
06918 
06919         len += idx;
06920 
06921         while (idx < (word32)len) {
06922             if (GetRevoked(buff, &idx, dcrl, sz) < 0)
06923                 return ASN_PARSE_E;
06924         }
06925     }
06926 
06927     if (idx != dcrl->sigIndex)
06928         idx = dcrl->sigIndex;   /* skip extensions */
06929 
06930     if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
06931         return ASN_PARSE_E;
06932 
06933     if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
06934         return ASN_PARSE_E;
06935 
06936     /* openssl doesn't add skid by default for CRLs cause firefox chokes
06937        we're not assuming it's available yet */
06938     #if !defined(NO_SKID) && defined(CRL_SKID_READY)
06939         if (dcrl->extAuthKeyIdSet)
06940             ca = GetCA(cm, dcrl->extAuthKeyId);
06941         if (ca == NULL)
06942             ca = GetCAByName(cm, dcrl->issuerHash);
06943     #else /* NO_SKID */
06944         ca = GetCA(cm, dcrl->issuerHash);
06945     #endif /* NO_SKID */
06946     CYASSL_MSG("About to verify CRL signature");
06947 
06948     if (ca) {
06949         CYASSL_MSG("Found CRL issuer CA");
06950         /* try to confirm/verify signature */
06951         #ifndef IGNORE_KEY_EXTENSIONS
06952             if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
06953                 CYASSL_MSG("CA cannot sign CRLs");
06954                 return ASN_CRL_NO_SIGNER_E;
06955             }
06956         #endif /* IGNORE_KEY_EXTENSIONS */
06957         if (!ConfirmSignature(buff + dcrl->certBegin,
06958                 dcrl->sigIndex - dcrl->certBegin,
06959                 ca->publicKey, ca->pubKeySize, ca->keyOID,
06960                 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
06961             CYASSL_MSG("CRL Confirm signature failed");
06962             return ASN_CRL_CONFIRM_E;
06963         }
06964     }
06965     else {
06966         CYASSL_MSG("Did NOT find CRL issuer CA");
06967         return ASN_CRL_NO_SIGNER_E;
06968     }
06969 
06970     return 0;
06971 }
06972 
06973 #endif /* HAVE_CRL */
06974 #endif
06975 
06976 #ifdef CYASSL_SEP
06977 
06978 
06979 
06980 #endif /* CYASSL_SEP */
06981 
06982