cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

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