Todd Ouska / CyaSSL

Dependents:   cyassl-client Sync

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-2009 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 
00023 #ifdef THREADX
00024     #include "os.h"           /* dc_rtc_api needs    */
00025     #include "dc_rtc_api.h"   /* to get current time */
00026 #endif
00027 #include "asn.h"
00028 #include "coding.h"
00029 #include "ctc_sha.h"
00030 #include "ctc_md5.h"
00031 #include "error.h"
00032 
00033 #ifdef HAVE_NTRU
00034     #include "crypto_ntru.h"
00035 #endif
00036 
00037 
00038 #ifdef _MSC_VER
00039     /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
00040     #pragma warning(disable: 4996)
00041 #endif
00042 
00043 
00044 #ifndef TRUE
00045 enum {
00046     FALSE = 0,
00047     TRUE  = 1
00048 };
00049 #endif
00050 
00051 enum {
00052     ISSUER  = 0,
00053     SUBJECT = 1,
00054 
00055     BEFORE  = 0,
00056     AFTER   = 1
00057 };
00058 
00059 
00060 #ifdef THREADX
00061     /* uses parital <time.h> structures */
00062     #define XTIME(tl)  (0)
00063     #define XGMTIME(c) my_gmtime((c))
00064     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00065 #elif defined(MICRIUM)
00066     #include <clk.h>
00067     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
00068         #define XVALIDATE_DATE(d, f, t) NetSecure_ValidDate((d), (f), (t))
00069     #else
00070         #define XVALIDATE_DATE(d, f, t) (0)
00071     #endif
00072     #define NO_TIME_H
00073     /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
00074 #elif defined(USER_TIME)
00075     /* no <time.h> strucutres used */
00076     #define NO_TIME_H
00077     /* user time, and gmtime compatible functions, there is a gmtime 
00078        implementation here that WINCE uses, so really just need some ticks
00079        since the EPOCH 
00080     */
00081 #else
00082     /* default */
00083     /* uses complete <time.h> facility */
00084     #include <time.h> 
00085     #define XTIME(tl)  time((tl))
00086     #define XGMTIME(c) gmtime((c))
00087     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
00088 #endif
00089 
00090 
00091 #ifdef _WIN32_WCE
00092 /* no time() or gmtime() even though in time.h header?? */
00093 
00094 #include <windows.h>
00095 
00096 
00097 time_t time(time_t* timer)
00098 {
00099     SYSTEMTIME     sysTime;
00100     FILETIME       fTime;
00101     ULARGE_INTEGER intTime;
00102     time_t         localTime;
00103 
00104     if (timer == NULL)
00105         timer = &localTime;
00106 
00107     GetSystemTime(&sysTime);
00108     SystemTimeToFileTime(&sysTime, &fTime);
00109     
00110     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
00111     /* subtract EPOCH */
00112     intTime.QuadPart -= 0x19db1ded53e8000;
00113     /* to secs */
00114     intTime.QuadPart /= 10000000;
00115     *timer = (time_t)intTime.QuadPart;
00116 
00117     return *timer;
00118 }
00119 
00120 
00121 
00122 struct tm* gmtime(const time_t* timer)
00123 {
00124     #define YEAR0          1900
00125     #define EPOCH_YEAR     1970
00126     #define SECS_DAY       (24L * 60L * 60L)
00127     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
00128     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
00129 
00130     static const int _ytab[2][12] =
00131     {
00132         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
00133         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
00134     };
00135 
00136     static struct tm st_time;
00137     struct tm* ret = &st_time;
00138     time_t time = *timer;
00139     unsigned long dayclock, dayno;
00140     int year = EPOCH_YEAR;
00141 
00142     dayclock = (unsigned long)time % SECS_DAY;
00143     dayno    = (unsigned long)time / SECS_DAY;
00144 
00145     ret->tm_sec  =  dayclock % 60;
00146     ret->tm_min  = (dayclock % 3600) / 60;
00147     ret->tm_hour =  dayclock / 3600;
00148     ret->tm_wday = (dayno + 4) % 7;        /* day 0 a Thursday */
00149 
00150     while(dayno >= (unsigned long)YEARSIZE(year)) {
00151         dayno -= YEARSIZE(year);
00152         year++;
00153     }
00154 
00155     ret->tm_year = year - YEAR0;
00156     ret->tm_yday = dayno;
00157     ret->tm_mon  = 0;
00158 
00159     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
00160         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
00161         ret->tm_mon++;
00162     }
00163 
00164     ret->tm_mday  = ++dayno;
00165     ret->tm_isdst = 0;
00166 
00167     return ret;
00168 }
00169 
00170 #endif /* _WIN32_WCE */
00171 
00172 
00173 
00174 #ifdef  THREADX
00175 
00176 #define YEAR0          1900
00177 
00178 struct tm* my_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
00179 {
00180     static struct tm st_time;
00181     struct tm* ret = &st_time;
00182 
00183     DC_RTC_CALENDAR cal;
00184     dc_rtc_time_get(&cal, TRUE);
00185 
00186     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
00187     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
00188     ret->tm_mday  = cal.day;
00189     ret->tm_hour  = cal.hour;
00190     ret->tm_min   = cal.minute;
00191     ret->tm_sec   = cal.second;
00192 
00193     return ret;
00194 }
00195 
00196 #endif /* THREADX */
00197 
00198 
00199 static INLINE word32 btoi(byte b)
00200 {
00201     return b - 0x30;
00202 }
00203 
00204 
00205 /* two byte date/time, add to value */
00206 static INLINE void GetTime(int* value, const byte* date, int* idx)
00207 {
00208     int i = *idx;
00209 
00210     *value += btoi(date[i++]) * 10;
00211     *value += btoi(date[i++]);
00212 
00213     *idx = i;
00214 }
00215 
00216 
00217 #if defined(MICRIUM)
00218 
00219 static int NetSecure_ValidDate(CPU_INT08U *date, CPU_INT08U format,
00220                                CPU_INT08U dateType)
00221 {
00222     CLK_DATE_TIME   cert_date_time;
00223     CLK_TS_SEC      cert_ts_sec;
00224     CLK_TS_SEC      local_ts_sec;
00225     CPU_INT32S      i;
00226     CPU_INT32S      val;
00227 
00228     local_ts_sec = Clk_GetTS();
00229     XMEMSET(&cert_date_time, 0, sizeof(cert_date_time));
00230 
00231     i = 0;
00232     if (format == ASN_UTC_TIME) {
00233         if (btoi(date[0]) >= 5)
00234             cert_date_time.Yr = 1900;
00235         else
00236             cert_date_time.Yr = 2000;
00237     }
00238     else  { /* format == GENERALIZED_TIME */
00239         cert_date_time.Yr += btoi(date[i++]) * 1000;
00240         cert_date_time.Yr += btoi(date[i++]) * 100;
00241     }
00242 
00243     val = cert_date_time.Yr;
00244     GetTime(&val,   date, &i);
00245     cert_date_time.Yr =    (CLK_YR)val;
00246 
00247     val = 0;
00248     GetTime(&val, date, &i);   
00249     cert_date_time.Month = (CLK_MONTH)val;
00250   
00251     val = 0;
00252     GetTime(&val, date, &i);  
00253     cert_date_time.Day =   (CLK_DAY)val;
00254 
00255     val = 0;
00256     GetTime(&val, date, &i);  
00257     cert_date_time.Hr =    (CLK_HR)val;
00258     
00259     val = 0;
00260     GetTime(&val, date, &i);  
00261     cert_date_time.Min =   (CLK_MIN)val;
00262     
00263     val = 0;
00264     GetTime(&val, date, &i);  
00265     cert_date_time.Sec =   (CLK_SEC)val;
00266 
00267     if (date[i] != 'Z')     /* only Zulu supported for this profile */
00268         return 0;
00269 
00270     cert_date_time.DayOfWk = 1;
00271     cert_date_time.DayOfYr = 1;
00272     Clk_DateTimeToTS(&cert_ts_sec, &cert_date_time);
00273 
00274 
00275     if (dateType == BEFORE) {
00276         if (local_ts_sec < cert_ts_sec)  /* If cert creation date after
00277                                              current date...  */
00278             return (DEF_FAIL);           /* ... report an error. */
00279    } else {
00280         if (local_ts_sec > cert_ts_sec)  /* If cert expiration date before
00281                                            current date...  */
00282             return (DEF_FAIL);           /* ... report an error. */
00283    }
00284 
00285     return (DEF_OK);
00286 }
00287 
00288 #endif /* MICRIUM */
00289 
00290 
00291 int GetLength(const byte* input, word32* inOutIdx, int* len)
00292 {
00293     int     length = 0;
00294     word32  i = *inOutIdx;
00295 
00296     byte b = input[i++];
00297     if (b >= ASN_LONG_LENGTH) {        
00298         word32 bytes = b & 0x7F;
00299 
00300         while (bytes--) {
00301             b = input[i++];
00302             length = (length << 8) | b;
00303         }
00304     }
00305     else
00306         length = b;
00307     
00308     *inOutIdx = i;
00309     *len      = length;
00310 
00311     return length;
00312 }
00313 
00314 
00315 int GetSequence(const byte* input, word32* inOutIdx, int* len)
00316 {
00317     int    length = -1;
00318     word32 idx    = *inOutIdx;
00319 
00320     if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
00321             GetLength(input, &idx, &length) < 0)
00322         return ASN_PARSE_E;
00323 
00324     *len      = length;
00325     *inOutIdx = idx;
00326 
00327     return length;
00328 }
00329 
00330 
00331 int GetSet(const byte* input, word32* inOutIdx, int* len)
00332 {
00333     int    length = -1;
00334     word32 idx    = *inOutIdx;
00335 
00336     if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
00337             GetLength(input, &idx, &length) < 0)
00338         return ASN_PARSE_E;
00339 
00340     *len      = length;
00341     *inOutIdx = idx;
00342 
00343     return length;
00344 }
00345 
00346 
00347 /* winodws header clash for WinCE using GetVersion */
00348 int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
00349 {
00350     word32 idx = *inOutIdx;
00351 
00352     if (input[idx++] != ASN_INTEGER)
00353         return ASN_PARSE_E;
00354 
00355     if (input[idx++] != 0x01)
00356         return ASN_VERSION_E;
00357 
00358     *version  = input[idx++];
00359     *inOutIdx = idx;
00360 
00361     return *version;
00362 }
00363 
00364 
00365 /* May not have one, not an error */
00366 int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
00367 {
00368     word32 idx = *inOutIdx;
00369 
00370     if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
00371         *inOutIdx = ++idx;  /* eat header */
00372         return GetMyVersion(input, inOutIdx, version);
00373     }
00374 
00375     /* go back as is */
00376     *version = 0;
00377 
00378     return 0;
00379 }
00380 
00381 
00382 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx )
00383 {
00384     word32 i = *inOutIdx;
00385     byte   b = input[i++];
00386     int    length;
00387 
00388     if (b != ASN_INTEGER)
00389         return ASN_PARSE_E;
00390 
00391     if (GetLength(input, &i, &length) < 0)
00392         return ASN_PARSE_E;
00393 
00394     if ( (b = input[i++]) == 0x00)
00395         length--;
00396     else
00397         i--;
00398 
00399     mp_init(mpi); 
00400     if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
00401         mp_clear(mpi);
00402         return ASN_GETINT_E;
00403     }
00404 
00405     *inOutIdx = i + length;
00406     return 0;
00407 }
00408 
00409 
00410 static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid)
00411 {
00412     int    length;
00413     word32 i = *inOutIdx;
00414     byte   b;
00415     *oid = 0;
00416     
00417     if (GetSequence(input, &i, &length) < 0)
00418         return ASN_PARSE_E;
00419     
00420     b = input[i++];
00421     if (b != ASN_OBJECT_ID) 
00422         return ASN_OBJECT_ID_E;
00423     
00424     if (GetLength(input, &i, &length) < 0)
00425         return ASN_PARSE_E;
00426     
00427     while(length--)
00428         *oid += input[i++];
00429     /* just sum it up for now */
00430     
00431     /* could have NULL tag and 0 terminator, but may not */
00432     b = input[i++];
00433     
00434     if (b == ASN_TAG_NULL) {
00435         b = input[i++];
00436         if (b != 0) 
00437             return ASN_EXPECT_0_E;
00438     }
00439     else
00440     /* go back, didn't have it */
00441         i--;
00442     
00443     *inOutIdx = i;
00444     
00445     return 0;
00446 }
00447 
00448 
00449 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
00450                         word32 inSz)
00451 {
00452     word32 begin = *inOutIdx;
00453     int    version, length;
00454 
00455     if (GetSequence(input, inOutIdx, &length) < 0)
00456         return ASN_PARSE_E;
00457 
00458     if ((word32)length > (inSz - (*inOutIdx - begin)))
00459         return ASN_INPUT_E;
00460 
00461     if (GetMyVersion(input, inOutIdx, &version) < 0)
00462         return ASN_PARSE_E;
00463 
00464     key->type = RSA_PRIVATE;
00465 
00466     if (GetInt(&key->n,  input, inOutIdx) < 0 ||
00467         GetInt(&key->e,  input, inOutIdx) < 0 ||
00468         GetInt(&key->d,  input, inOutIdx) < 0 ||
00469         GetInt(&key->p,  input, inOutIdx) < 0 ||
00470         GetInt(&key->q,  input, inOutIdx) < 0 ||
00471         GetInt(&key->dP, input, inOutIdx) < 0 ||
00472         GetInt(&key->dQ, input, inOutIdx) < 0 ||
00473         GetInt(&key->u,  input, inOutIdx) < 0 )  return ASN_RSA_KEY_E;
00474 
00475     return 0;
00476 }
00477 
00478 
00479 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
00480 int ToTraditional(byte* input, word32 sz)
00481 {
00482     word32 inOutIdx = 0, oid;
00483     int    version, length;
00484 
00485     if (GetSequence(input, &inOutIdx, &length) < 0)
00486         return ASN_PARSE_E;
00487 
00488     if ((word32)length > (sz - inOutIdx))
00489         return ASN_INPUT_E;
00490 
00491     if (GetMyVersion(input, &inOutIdx, &version) < 0)
00492         return ASN_PARSE_E;
00493     
00494     if (GetAlgoId(input, &inOutIdx, &oid) < 0)
00495         return ASN_PARSE_E;
00496     
00497     if (input[inOutIdx++] != ASN_OCTET_STRING)
00498         return ASN_PARSE_E;
00499     
00500     if (GetLength(input, &inOutIdx, &length) < 0)
00501         return ASN_PARSE_E;
00502     
00503     if ((word32)length > (sz - inOutIdx))
00504         return ASN_INPUT_E;
00505     
00506     XMEMMOVE(input, input + inOutIdx, length);
00507 
00508     return 0;
00509 }
00510 
00511 
00512 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
00513                        word32 inSz)
00514 {
00515     word32 begin = *inOutIdx;
00516     int    length;
00517     byte   b;
00518 
00519     if (GetSequence(input, inOutIdx, &length) < 0)
00520         return ASN_PARSE_E;
00521 
00522     if ((word32)length > (inSz - (*inOutIdx - begin)))
00523         return ASN_INPUT_E;
00524 
00525     key->type = RSA_PUBLIC;
00526     b = input[*inOutIdx];
00527 
00528 #ifdef OPENSSL_EXTRA    
00529     if (b != ASN_INTEGER) {
00530         /* not from decoded cert, will have algo id, skip past */
00531         if (GetSequence(input, inOutIdx, &length) < 0)
00532             return ASN_PARSE_E;
00533         
00534         b = input[(*inOutIdx)++];
00535         if (b != ASN_OBJECT_ID) 
00536             return ASN_OBJECT_ID_E;
00537         
00538         if (GetLength(input, inOutIdx, &length) < 0)
00539             return ASN_PARSE_E;
00540         
00541         *inOutIdx += length;   /* skip past */
00542         
00543         /* could have NULL tag and 0 terminator, but may not */
00544         b = input[(*inOutIdx)++];
00545         
00546         if (b == ASN_TAG_NULL) {
00547             b = input[(*inOutIdx)++];
00548             if (b != 0) 
00549                 return ASN_EXPECT_0_E;
00550         }
00551         else
00552         /* go back, didn't have it */
00553             (*inOutIdx)--;
00554         
00555         /* should have bit tag length and seq next */
00556         b = input[(*inOutIdx)++];
00557         if (b != ASN_BIT_STRING)
00558             return ASN_BITSTR_E;
00559         
00560         if (GetLength(input, inOutIdx, &length) < 0)
00561             return ASN_PARSE_E;
00562         
00563         /* could have 0 */
00564         b = input[(*inOutIdx)++];
00565         if (b != 0)
00566             (*inOutIdx)--;
00567         
00568         if (GetSequence(input, inOutIdx, &length) < 0)
00569             return ASN_PARSE_E;
00570     }
00571 #endif /* OPENSSL_EXTRA */
00572 
00573     if (GetInt(&key->n,  input, inOutIdx) < 0 ||
00574         GetInt(&key->e,  input, inOutIdx) < 0 )  return ASN_RSA_KEY_E;
00575 
00576     return 0;
00577 }
00578 
00579 
00580 #ifndef NO_DH
00581 
00582 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
00583 {
00584     word32 begin = *inOutIdx;
00585     int    length;
00586 
00587     if (GetSequence(input, inOutIdx, &length) < 0)
00588         return ASN_PARSE_E;
00589 
00590     if ((word32)length > (inSz - (*inOutIdx - begin)))
00591         return ASN_INPUT_E;
00592 
00593     if (GetInt(&key->p,  input, inOutIdx) < 0 ||
00594         GetInt(&key->g,  input, inOutIdx) < 0 )  return ASN_DH_KEY_E;
00595 
00596     return 0;
00597 }
00598 
00599 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
00600 {
00601     /* may have leading 0 */
00602     if (p[0] == 0) {
00603         pSz--; p++;
00604     }
00605 
00606     if (g[0] == 0) {
00607         gSz--; g++;
00608     }
00609 
00610     mp_init(&key->p);
00611     if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
00612         mp_clear(&key->p);
00613         return ASN_DH_KEY_E;
00614     }
00615 
00616     mp_init(&key->g);
00617     if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
00618         mp_clear(&key->p);
00619         return ASN_DH_KEY_E;
00620     }
00621 
00622     return 0;
00623 }
00624 
00625 
00626 #endif /* NO_DH */
00627 
00628 
00629 #ifndef NO_DSA
00630 
00631 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
00632                         word32 inSz)
00633 {
00634     word32 begin = *inOutIdx;
00635     int    length;
00636 
00637     if (GetSequence(input, inOutIdx, &length) < 0)
00638         return ASN_PARSE_E;
00639 
00640     if ((word32)length > (inSz - (*inOutIdx - begin)))
00641         return ASN_INPUT_E;
00642 
00643     if (GetInt(&key->p,  input, inOutIdx) < 0 ||
00644         GetInt(&key->q,  input, inOutIdx) < 0 ||
00645         GetInt(&key->g,  input, inOutIdx) < 0 ||
00646         GetInt(&key->y,  input, inOutIdx) < 0 )  return ASN_DH_KEY_E;
00647 
00648     key->type = DSA_PUBLIC;
00649     return 0;
00650 }
00651 
00652 
00653 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
00654                         word32 inSz)
00655 {
00656     word32 begin = *inOutIdx;
00657     int    length, version;
00658 
00659     if (GetSequence(input, inOutIdx, &length) < 0)
00660         return ASN_PARSE_E;
00661 
00662     if ((word32)length > (inSz - (*inOutIdx - begin)))
00663         return ASN_INPUT_E;
00664 
00665     if (GetMyVersion(input, inOutIdx, &version) < 0)
00666         return ASN_PARSE_E;
00667 
00668     if (GetInt(&key->p,  input, inOutIdx) < 0 ||
00669         GetInt(&key->q,  input, inOutIdx) < 0 ||
00670         GetInt(&key->g,  input, inOutIdx) < 0 ||
00671         GetInt(&key->y,  input, inOutIdx) < 0 ||
00672         GetInt(&key->x,  input, inOutIdx) < 0 )  return ASN_DH_KEY_E;
00673 
00674     key->type = DSA_PRIVATE;
00675     return 0;
00676 }
00677 
00678 #endif /* NO_DSA */
00679 
00680 
00681 void InitDecodedCert(DecodedCert* cert, byte* source, void* heap)
00682 {
00683     cert->publicKey       = 0;
00684     cert->pubKeyStored    = 0;
00685     cert->signature       = 0;
00686     cert->subjectCN       = 0;
00687     cert->subjectCNLen    = 0;
00688     cert->source          = source;  /* don't own */
00689     cert->srcIdx          = 0;
00690     cert->heap            = heap;
00691 #ifdef CYASSL_CERT_GEN
00692     cert->subjectSN       = 0;
00693     cert->subjectSNLen    = 0;
00694     cert->subjectC        = 0;
00695     cert->subjectCLen     = 0;
00696     cert->subjectL        = 0;
00697     cert->subjectLLen     = 0;
00698     cert->subjectST       = 0;
00699     cert->subjectSTLen    = 0;
00700     cert->subjectO        = 0;
00701     cert->subjectOLen     = 0;
00702     cert->subjectOU       = 0;
00703     cert->subjectOULen    = 0;
00704     cert->subjectEmail    = 0;
00705     cert->subjectEmailLen = 0;
00706 #endif /* CYASSL_CERT_GEN */
00707 }
00708 
00709 
00710 void FreeDecodedCert(DecodedCert* cert)
00711 {
00712     if (cert->subjectCNLen == 0)  /* 0 means no longer pointer to raw, we own */
00713         XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
00714     if (cert->pubKeyStored == 1)
00715         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
00716 }
00717 
00718 
00719 static int GetCertHeader(DecodedCert* cert, word32 inSz)
00720 {
00721     int    ret = 0, version, len;
00722     word32 begin = cert->srcIdx;
00723     mp_int mpi;
00724 
00725     if (GetSequence(cert->source, &cert->srcIdx, &len) < 0)
00726         return ASN_PARSE_E;
00727 
00728     if ((word32)len > (inSz - (cert->srcIdx - begin))) return ASN_INPUT_E;
00729 
00730     cert->certBegin = cert->srcIdx;
00731 
00732     GetSequence(cert->source, &cert->srcIdx, &len);
00733     cert->sigIndex = len + cert->srcIdx;
00734 
00735     if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
00736         return ASN_PARSE_E;
00737 
00738     if (GetInt(&mpi, cert->source, &cert->srcIdx) < 0) 
00739         ret = ASN_PARSE_E;
00740 
00741     mp_clear(&mpi);
00742     return ret;
00743 }
00744 
00745 
00746 static int StoreKey(DecodedCert* cert)
00747 {
00748     int    length;
00749     word32 read = cert->srcIdx;
00750 
00751     if (cert->keyOID == NTRUk)
00752         return 0;                /* already stored */
00753 
00754     if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
00755         return ASN_PARSE_E;
00756    
00757     read = cert->srcIdx - read;
00758     length += read;
00759 
00760     while (read--)
00761        cert->srcIdx--;
00762 
00763     cert->pubKeySize = length;
00764     cert->publicKey = cert->source + cert->srcIdx;
00765     cert->srcIdx += length;
00766 
00767     return 0;
00768 }
00769 
00770 
00771 static int GetKey(DecodedCert* cert)
00772 {
00773     int length;
00774 #ifdef HAVE_NTRU
00775     int tmpIdx = cert->srcIdx;
00776 #endif
00777 
00778     if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
00779         return ASN_PARSE_E;
00780     
00781     if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID) < 0)
00782         return ASN_PARSE_E;
00783 
00784     if (cert->keyOID == RSAk) {
00785         byte b = cert->source[cert->srcIdx++];
00786         if (b != ASN_BIT_STRING)
00787             return ASN_BITSTR_E;
00788 
00789         if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
00790             return ASN_PARSE_E;
00791         b = cert->source[cert->srcIdx++];
00792         if (b != 0x00)
00793             return ASN_EXPECT_0_E;
00794     }
00795     else if (cert->keyOID == DSAk )
00796         ;   /* do nothing */
00797 #ifdef HAVE_NTRU
00798     else if (cert->keyOID == NTRUk ) {
00799         const byte* key = &cert->source[tmpIdx];
00800         byte*       next = (byte*)key;
00801         word16      keyLen;
00802         byte        keyBlob[MAX_NTRU_KEY_SZ];
00803 
00804         word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
00805                             &keyLen, NULL, &next);
00806 
00807         if (rc != NTRU_OK)
00808             return ASN_NTRU_KEY_E;
00809         if (keyLen > sizeof(keyBlob))
00810             return ASN_NTRU_KEY_E;
00811 
00812         rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, &keyLen,
00813                                                                 keyBlob, &next);
00814         if (rc != NTRU_OK)
00815             return ASN_NTRU_KEY_E;
00816 
00817         if ( (next - key) < 0)
00818             return ASN_NTRU_KEY_E;
00819 
00820         cert->srcIdx = tmpIdx + (next - key);
00821 
00822         cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
00823                                           DYNAMIC_TYPE_PUBLIC_KEY);
00824         if (cert->publicKey == NULL)
00825             return MEMORY_E;
00826         memcpy(cert->publicKey, keyBlob, keyLen);
00827         cert->pubKeyStored = 1;
00828         cert->pubKeySize   = keyLen;
00829     }
00830 #endif
00831     else
00832         return ASN_UNKNOWN_OID_E;
00833     
00834     return StoreKey(cert);
00835 }
00836 
00837 
00838 /* process NAME, either issuer or subject */
00839 static int GetName(DecodedCert* cert, int nameType)
00840 {
00841     Sha    sha;
00842     int    length;  /* length of all distinguished names */
00843     int    dummy;
00844     char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
00845     word32 idx = 0;
00846 
00847     InitSha(&sha);
00848 
00849     if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
00850         return ASN_PARSE_E;
00851 
00852     length += cert->srcIdx;
00853 
00854     while (cert->srcIdx < (word32)length) {
00855         byte   b;
00856         byte   joint[2];
00857         int    oidSz;
00858 
00859         if (GetSet(cert->source, &cert->srcIdx, &dummy) < 0)
00860             return ASN_PARSE_E;
00861 
00862         if (GetSequence(cert->source, &cert->srcIdx, &dummy) < 0)
00863             return ASN_PARSE_E;
00864 
00865         b = cert->source[cert->srcIdx++];
00866         if (b != ASN_OBJECT_ID) 
00867             return ASN_OBJECT_ID_E;
00868 
00869         if (GetLength(cert->source, &cert->srcIdx, &oidSz) < 0)
00870             return ASN_PARSE_E;
00871 
00872         XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
00873 
00874         /* v1 name types */
00875         if (joint[0] == 0x55 && joint[1] == 0x04) {
00876             byte   id;
00877             byte   copy = FALSE;
00878             int    strLen;
00879 
00880             cert->srcIdx += 2;
00881             id = cert->source[cert->srcIdx++]; 
00882             b  = cert->source[cert->srcIdx++];    /* strType */
00883 
00884             if (GetLength(cert->source, &cert->srcIdx, &strLen) < 0)
00885                 return ASN_PARSE_E;
00886 
00887             if (strLen > (int)(ASN_NAME_MAX - idx))
00888                 return ASN_PARSE_E; 
00889 
00890             if (4  > (ASN_NAME_MAX - idx))  /* make sure room for biggest */
00891                 return ASN_PARSE_E;         /* pre fix header too "/CN=" */
00892 
00893             if (id == ASN_COMMON_NAME) {
00894                 if (nameType == SUBJECT) {
00895                     cert->subjectCN = (char *)&cert->source[cert->srcIdx];
00896                     cert->subjectCNLen = strLen;
00897                 }
00898 
00899                 XMEMCPY(&full[idx], "/CN=", 4);
00900                 idx += 4;
00901                 copy = TRUE;
00902             }
00903             else if (id == ASN_SUR_NAME) {
00904                 XMEMCPY(&full[idx], "/SN=", 4);
00905                 idx += 4;
00906                 copy = TRUE;
00907 #ifdef CYASSL_CERT_GEN
00908                 if (nameType == SUBJECT) {
00909                     cert->subjectSN = (char*)&cert->source[cert->srcIdx];
00910                     cert->subjectSNLen = strLen;
00911                 }
00912 #endif /* CYASSL_CERT_GEN */
00913             }
00914             else if (id == ASN_COUNTRY_NAME) {
00915                 XMEMCPY(&full[idx], "/C=", 3);
00916                 idx += 3;
00917                 copy = TRUE;
00918 #ifdef CYASSL_CERT_GEN
00919                 if (nameType == SUBJECT) {
00920                     cert->subjectC = (char*)&cert->source[cert->srcIdx];
00921                     cert->subjectCLen = strLen;
00922                 }
00923 #endif /* CYASSL_CERT_GEN */
00924             }
00925             else if (id == ASN_LOCALITY_NAME) {
00926                 XMEMCPY(&full[idx], "/L=", 3);
00927                 idx += 3;
00928                 copy = TRUE;
00929 #ifdef CYASSL_CERT_GEN
00930                 if (nameType == SUBJECT) {
00931                     cert->subjectL = (char*)&cert->source[cert->srcIdx];
00932                     cert->subjectLLen = strLen;
00933                 }
00934 #endif /* CYASSL_CERT_GEN */
00935             }
00936             else if (id == ASN_STATE_NAME) {
00937                 XMEMCPY(&full[idx], "/ST=", 4);
00938                 idx += 4;
00939                 copy = TRUE;
00940 #ifdef CYASSL_CERT_GEN
00941                 if (nameType == SUBJECT) {
00942                     cert->subjectST = (char*)&cert->source[cert->srcIdx];
00943                     cert->subjectSTLen = strLen;
00944                 }
00945 #endif /* CYASSL_CERT_GEN */
00946             }
00947             else if (id == ASN_ORG_NAME) {
00948                 XMEMCPY(&full[idx], "/O=", 3);
00949                 idx += 3;
00950                 copy = TRUE;
00951 #ifdef CYASSL_CERT_GEN
00952                 if (nameType == SUBJECT) {
00953                     cert->subjectO = (char*)&cert->source[cert->srcIdx];
00954                     cert->subjectOLen = strLen;
00955                 }
00956 #endif /* CYASSL_CERT_GEN */
00957             }
00958             else if (id == ASN_ORGUNIT_NAME) {
00959                 XMEMCPY(&full[idx], "/OU=", 4);
00960                 idx += 4;
00961                 copy = TRUE;
00962 #ifdef CYASSL_CERT_GEN
00963                 if (nameType == SUBJECT) {
00964                     cert->subjectOU = (char*)&cert->source[cert->srcIdx];
00965                     cert->subjectOULen = strLen;
00966                 }
00967 #endif /* CYASSL_CERT_GEN */
00968             }
00969 
00970             if (copy) {
00971                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
00972                 idx += strLen;
00973             }
00974 
00975             ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen);
00976             cert->srcIdx += strLen;
00977         }
00978         else {
00979             /* skip */
00980             byte email = FALSE;
00981             int  adv;
00982 
00983             if (joint[0] == 0x2a && joint[1] == 0x86)  /* email id hdr */
00984                 email = TRUE;
00985 
00986             cert->srcIdx += oidSz + 1;
00987 
00988             if (GetLength(cert->source, &cert->srcIdx, &adv) < 0)
00989                 return ASN_PARSE_E;
00990 
00991             if (adv > (int)(ASN_NAME_MAX - idx))
00992                 return ASN_PARSE_E; 
00993 
00994             if (email) {
00995                 if (14 > (ASN_NAME_MAX - idx))
00996                     return ASN_PARSE_E; 
00997                 XMEMCPY(&full[idx], "/emailAddress=", 14);
00998                 idx += 14;
00999 
01000 #ifdef CYASSL_CERT_GEN
01001                 if (nameType == SUBJECT) {
01002                     cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
01003                     cert->subjectEmailLen = adv;
01004                 }
01005 #endif /* CYASSL_CERT_GEN */
01006 
01007                 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
01008                 idx += adv;
01009             }
01010 
01011             cert->srcIdx += adv;
01012         }
01013     }
01014     full[idx++] = 0;
01015 
01016     if (nameType == ISSUER)
01017         ShaFinal(&sha, cert->issuerHash);
01018     else
01019         ShaFinal(&sha, cert->subjectHash);
01020 
01021     return 0;
01022 }
01023 
01024 
01025 #ifndef NO_TIME_H
01026 
01027 /* to the second */
01028 static int DateGreaterThan(const struct tm* a, const struct tm* b)
01029 {
01030     if (a->tm_year > b->tm_year)
01031         return 1;
01032 
01033     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
01034         return 1;
01035     
01036     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01037            a->tm_mday > b->tm_mday)
01038         return 1;
01039 
01040     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01041         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
01042         return 1;
01043 
01044     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01045         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
01046         a->tm_min > b->tm_min)
01047         return 1;
01048 
01049     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
01050         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
01051         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
01052         return 1;
01053 
01054     return 0; /* false */
01055 }
01056 
01057 
01058 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
01059 {
01060     return !DateGreaterThan(a,b);
01061 }
01062 
01063 
01064 /* like atoi but only use first byte */
01065 /* Make sure before and after dates are valid */
01066 static int ValidateDate(const byte* date, byte format, int dateType)
01067 {
01068     time_t ltime;
01069     struct tm  certTime;
01070     struct tm* localTime;
01071     int    i = 0;
01072 
01073     ltime = XTIME(0);
01074     XMEMSET(&certTime, 0, sizeof(certTime));
01075 
01076     if (format == ASN_UTC_TIME) {
01077         if (btoi(date[0]) >= 5)
01078             certTime.tm_year = 1900;
01079         else
01080             certTime.tm_year = 2000;
01081     }
01082     else  { /* format == GENERALIZED_TIME */
01083         certTime.tm_year += btoi(date[i++]) * 1000;
01084         certTime.tm_year += btoi(date[i++]) * 100;
01085     }
01086 
01087     GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
01088     GetTime(&certTime.tm_mon,  date, &i); certTime.tm_mon  -= 1;    /* adjust */
01089     GetTime(&certTime.tm_mday, date, &i);
01090     GetTime(&certTime.tm_hour, date, &i); 
01091     GetTime(&certTime.tm_min,  date, &i); 
01092     GetTime(&certTime.tm_sec,  date, &i); 
01093 
01094     if (date[i] != 'Z')     /* only Zulu supported for this profile */
01095         return 0;
01096 
01097     localTime = XGMTIME(&ltime);
01098 
01099     if (dateType == BEFORE) {
01100         if (DateLessThan(localTime, &certTime))
01101             return 0;
01102     }
01103     else
01104         if (DateGreaterThan(localTime, &certTime))
01105             return 0;
01106 
01107     return 1;
01108 }
01109 
01110 #endif /* NO_TIME_H */
01111 
01112 
01113 static int GetDate(DecodedCert* cert, int dateType)
01114 {
01115     int    length;
01116     byte   date[MAX_DATE_SIZE];
01117     byte   b = cert->source[cert->srcIdx++];
01118 
01119     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
01120         return ASN_TIME_E;
01121 
01122     if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
01123         return ASN_PARSE_E;
01124 
01125     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
01126         return ASN_DATE_SZ_E;
01127 
01128     XMEMCPY(date, &cert->source[cert->srcIdx], length);
01129     cert->srcIdx += length;
01130 
01131     if (!XVALIDATE_DATE(date, b, dateType)) {
01132         if (dateType == BEFORE)
01133             return ASN_BEFORE_DATE_E;
01134         else
01135             return ASN_AFTER_DATE_E;
01136     }
01137 
01138     return 0;
01139 }
01140 
01141 
01142 static int GetValidity(DecodedCert* cert, int verify)
01143 {
01144     int length;
01145     int badDate = 0;
01146 
01147     if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
01148         return ASN_PARSE_E;
01149 
01150     if (GetDate(cert, BEFORE) < 0 && verify)
01151         badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
01152     
01153     if (GetDate(cert, AFTER) < 0 && verify)
01154         return ASN_AFTER_DATE_E;
01155    
01156     if (badDate != 0)
01157         return badDate;
01158 
01159     return 0;
01160 }
01161 
01162 
01163 static int DecodeToKey(DecodedCert* cert, word32 inSz, int verify)
01164 {
01165     int badDate = 0;
01166     int ret;
01167 
01168     if ( (ret = GetCertHeader(cert, inSz)) < 0)
01169         return ret;
01170 
01171     if ( (ret = GetAlgoId(cert->source, &cert->srcIdx,&cert->signatureOID)) < 0)
01172         return ret;
01173 
01174     if ( (ret = GetName(cert, ISSUER)) < 0)
01175         return ret;
01176 
01177     if ( (ret = GetValidity(cert, verify)) < 0)
01178         badDate = ret;
01179 
01180     if ( (ret = GetName(cert, SUBJECT)) < 0)
01181         return ret;
01182 
01183     if ( (ret = GetKey(cert)) < 0)
01184         return ret;
01185 
01186     if (badDate != 0)
01187         return badDate;
01188 
01189     return ret;
01190 }
01191 
01192 
01193 static int GetSignature(DecodedCert* cert)
01194 {
01195     int    length;
01196     byte   b = cert->source[cert->srcIdx++];
01197 
01198     if (b != ASN_BIT_STRING)
01199         return ASN_BITSTR_E;
01200 
01201     if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
01202         return ASN_PARSE_E;
01203 
01204     cert->sigLength = length;
01205 
01206     b = cert->source[cert->srcIdx++];
01207     if (b != 0x00)
01208         return ASN_EXPECT_0_E;
01209 
01210     cert->sigLength--;
01211     cert->signature = &cert->source[cert->srcIdx];
01212     cert->srcIdx += cert->sigLength;
01213 
01214     return 0;
01215 }
01216 
01217 
01218 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
01219 {
01220     output[0] = ASN_OCTET_STRING;
01221     output[1] = digSz;
01222     XMEMCPY(&output[2], digest, digSz);
01223 
01224     return digSz + 2;
01225 } 
01226 
01227 
01228 static word32 BytePrecision(word32 value)
01229 {
01230     word32 i;
01231     for (i = sizeof(value); i; --i)
01232         if (value >> (i - 1) * 8)
01233             break;
01234 
01235     return i;
01236 }
01237 
01238 
01239 static word32 SetLength(word32 length, byte* output)
01240 {
01241     word32 i = 0, j;
01242 
01243     if (length < ASN_LONG_LENGTH)
01244         output[i++] = length;
01245     else {
01246         output[i++] = BytePrecision(length) | ASN_LONG_LENGTH;
01247       
01248         for (j = BytePrecision(length); j; --j) {
01249             output[i] = length >> (j - 1) * 8;
01250             i++;
01251         }
01252     }
01253 
01254     return i;
01255 }
01256 
01257 
01258 static word32 SetSequence(word32 len, byte* output)
01259 {
01260     output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
01261     return SetLength(len, output + 1) + 1;
01262 }
01263 
01264 
01265 static word32 SetAlgoID(int algoOID, byte* output, int type)
01266 {
01267     /* adding TAG_NULL and 0 to end */
01268     
01269     /* hashTypes */
01270     static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
01271                                       0x05, 0x00 };
01272     static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
01273                                       0x02, 0x05, 0x05, 0x00  };
01274     static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
01275                                       0x02, 0x02, 0x05, 0x00};
01276 
01277     /* sigTypes */
01278     static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
01279                                       0x01, 0x01, 0x04, 0x05, 0x00};
01280 
01281     /* keyTypes */
01282     static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
01283                                       0x01, 0x01, 0x01, 0x05, 0x00};
01284 
01285     int    algoSz = 0;
01286     word32 idSz, seqSz;
01287     const  byte* algoName = 0;
01288     byte ID_Length[MAX_LENGTH_SZ];
01289     byte seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
01290 
01291     if (type == hashType) {
01292         switch (algoOID) {
01293         case SHAh:
01294             algoSz = sizeof(shaAlgoID);
01295             algoName = shaAlgoID;
01296             break;
01297 
01298         case MD2h:
01299             algoSz = sizeof(md2AlgoID);
01300             algoName = md2AlgoID;
01301             break;
01302 
01303         case MD5h:
01304             algoSz = sizeof(md5AlgoID);
01305             algoName = md5AlgoID;
01306             break;
01307 
01308         default:
01309             return 0;  /* UNKOWN_HASH_E; */
01310         }
01311     }
01312     else if (type == sigType) {    /* sigType */
01313         switch (algoOID) {
01314         case MD5wRSA:
01315             algoSz = sizeof(md5wRSA_AlgoID);
01316             algoName = md5wRSA_AlgoID;
01317             break;
01318 
01319         default:
01320             return 0;  /* UNKOWN_HASH_E; */
01321         }
01322     }
01323     else if (type == keyType) {    /* keyType */
01324         switch (algoOID) {
01325         case RSAk:
01326             algoSz = sizeof(RSA_AlgoID);
01327             algoName = RSA_AlgoID;
01328             break;
01329 
01330         default:
01331             return 0;  /* UNKOWN_HASH_E; */
01332         }
01333     }
01334     else
01335         return 0;  /* UNKNOWN_TYPE */
01336 
01337 
01338     idSz  = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */
01339     seqSz = SetSequence(idSz + algoSz + 1, seqArray);
01340     seqArray[seqSz++] = ASN_OBJECT_ID;
01341 
01342     XMEMCPY(output, seqArray, seqSz);
01343     XMEMCPY(output + seqSz, ID_Length, idSz);
01344     XMEMCPY(output + seqSz + idSz, algoName, algoSz);
01345 
01346     return seqSz + idSz + algoSz;
01347 
01348 }
01349 
01350 
01351 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
01352 {
01353     byte digArray[MAX_ENCODED_DIG_SZ];
01354     byte algoArray[MAX_ALGO_SZ];
01355     byte seqArray[MAX_SEQ_SZ];
01356     word32 encDigSz, algoSz, seqSz; 
01357 
01358     encDigSz = SetDigest(digest, digSz, digArray);
01359     algoSz   = SetAlgoID(hashOID, algoArray, hashType);
01360     seqSz    = SetSequence(encDigSz + algoSz, seqArray);
01361 
01362     XMEMCPY(out, seqArray, seqSz);
01363     XMEMCPY(out + seqSz, algoArray, algoSz);
01364     XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
01365 
01366     return encDigSz + algoSz + seqSz;
01367 }
01368                            
01369 
01370 /* return true (1) for Confirmation */
01371 static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
01372                             word32 keyOID)
01373 {
01374     byte digest[SHA_DIGEST_SIZE]; /* max size */
01375     int  hashType, digestSz, ret;
01376 
01377     if (cert->signatureOID == MD5wRSA) {
01378         Md5 md5;
01379         InitMd5(&md5);
01380         Md5Update(&md5, cert->source + cert->certBegin,
01381                   cert->sigIndex - cert->certBegin);
01382         Md5Final(&md5, digest);
01383         hashType = MD5h;
01384         digestSz = MD5_DIGEST_SIZE;
01385     }
01386     else if (cert->signatureOID == SHAwRSA || cert->signatureOID == SHAwDSA) {
01387         Sha sha;
01388         InitSha(&sha);
01389         ShaUpdate(&sha, cert->source + cert->certBegin,
01390                   cert->sigIndex - cert->certBegin);
01391         ShaFinal(&sha, digest);
01392         hashType = SHAh;
01393         digestSz = SHA_DIGEST_SIZE;
01394     }
01395     else
01396         return 0; /* ASN_SIG_HASH_E; */
01397 
01398     if (keyOID == RSAk) {
01399         RsaKey pubKey;
01400         byte   encodedSig[MAX_ENCODED_SIG_SZ];
01401         byte   plain[MAX_ENCODED_SIG_SZ];
01402         word32 idx = 0;
01403         int    sigSz, verifySz;
01404         byte*  out;
01405 
01406         if (cert->sigLength > MAX_ENCODED_SIG_SZ)
01407             return 0; /* the key is too big */
01408             
01409         InitRsaKey(&pubKey, cert->heap);
01410         if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0)
01411             ret = 0; /* ASN_KEY_DECODE_E; */
01412 
01413         else {
01414             XMEMCPY(plain, cert->signature, cert->sigLength);
01415             if ( (verifySz = RsaSSL_VerifyInline(plain, cert->sigLength, &out,
01416                                            &pubKey)) < 0)
01417                 ret = 0; /* ASN_VERIFY_E; */
01418             else {
01419                 /* make sure we're right justified */
01420                 sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
01421                 if (sigSz != verifySz || XMEMCMP(out, encodedSig, sigSz) != 0)
01422                     ret = 0; /* ASN_VERIFY_MATCH_E; */
01423                 else
01424                     ret = 1; /* match */
01425             }
01426         }
01427         FreeRsaKey(&pubKey);
01428         return ret;
01429     }
01430     else
01431         return 0; /* ASN_SIG_KEY_E; */
01432 }
01433 
01434 
01435 int ParseCert(DecodedCert* cert, word32 inSz, int type, int verify,
01436               Signer* signers)
01437 {
01438     int   ret;
01439     char* ptr;
01440 
01441     ret = ParseCertRelative(cert, inSz, type, verify, signers);
01442     if (ret < 0)
01443         return ret;
01444 
01445     if (cert->subjectCNLen > 0) {
01446         ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
01447                               DYNAMIC_TYPE_SUBJECT_CN);
01448         if (ptr == NULL)
01449             return MEMORY_E;
01450         XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
01451         ptr[cert->subjectCNLen] = '\0';
01452         cert->subjectCN = ptr;
01453         cert->subjectCNLen = 0;
01454     }
01455 
01456     if (cert->keyOID == RSAk && cert->pubKeySize > 0) {
01457         ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
01458                               DYNAMIC_TYPE_PUBLIC_KEY);
01459         if (ptr == NULL)
01460             return MEMORY_E;
01461         XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
01462         cert->publicKey = (byte *)ptr;
01463         cert->pubKeyStored = 1;
01464     }
01465 
01466     return ret;
01467 }
01468 
01469 
01470 int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify,
01471               Signer* signers)
01472 {
01473     word32 confirmOID;
01474     int    ret;
01475     int    badDate = 0;
01476     int    confirm = 0;
01477 
01478     if ((ret = DecodeToKey(cert, inSz, verify)) < 0) {
01479         if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
01480             badDate = ret;
01481         else
01482             return ret;
01483     }
01484 
01485     if (cert->srcIdx != cert->sigIndex)
01486         cert->srcIdx =  cert->sigIndex;
01487 
01488     if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID)) < 0)
01489         return ret;
01490 
01491     if ((ret = GetSignature(cert)) < 0)
01492         return ret;
01493 
01494     if (confirmOID != cert->signatureOID)
01495         return ASN_SIG_OID_E;
01496 
01497     if (verify && type != CA_TYPE) {
01498         while (signers) {
01499             if (XMEMCMP(cert->issuerHash, signers->hash, SHA_DIGEST_SIZE)
01500                        == 0) {
01501                 /* other confirm */
01502                 if (!ConfirmSignature(cert, signers->publicKey,
01503                                       signers->pubKeySize, signers->keyOID))
01504                     return ASN_SIG_CONFIRM_E;
01505                 else {
01506                     confirm = 1;
01507                     break;
01508                 }
01509             }
01510             signers = signers->next;
01511         }
01512         if (!confirm)
01513             return ASN_SIG_CONFIRM_E;
01514     }
01515     if (badDate != 0)
01516         return badDate;
01517 
01518     return 0;
01519 }
01520 
01521 
01522 Signer* MakeSigner(void* heap)
01523 {
01524     Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
01525                                        DYNAMIC_TYPE_SIGNER);
01526     if (signer) {
01527         signer->name      = 0;
01528         signer->publicKey = 0;
01529         signer->next      = 0;
01530     }
01531 
01532     return signer;
01533 }
01534 
01535 
01536 void FreeSigners(Signer* signer, void* heap)
01537 {
01538     Signer* next = signer;
01539 
01540     while( (signer = next) ) {
01541         next = signer->next;
01542         XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
01543         XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
01544         XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
01545     }
01546 }
01547 
01548 
01549 void CTaoCryptErrorString(int error, char* buffer)
01550 {
01551     const int max = MAX_ERROR_SZ;   /* shorthand */
01552 
01553 #ifdef NO_ERROR_STRINGS
01554 
01555     XSTRNCPY(buffer, "no support for error strings built in", max);
01556 
01557 #else
01558 
01559     switch (error) {
01560 
01561     case OPEN_RAN_E :        
01562         XSTRNCPY(buffer, "opening random device error", max);
01563         break;
01564 
01565     case READ_RAN_E :
01566         XSTRNCPY(buffer, "reading random device error", max);
01567         break;
01568 
01569     case WINCRYPT_E :
01570         XSTRNCPY(buffer, "windows crypt init error", max);
01571         break;
01572 
01573     case CRYPTGEN_E : 
01574         XSTRNCPY(buffer, "windows crypt generation error", max);
01575         break;
01576 
01577     case RAN_BLOCK_E : 
01578         XSTRNCPY(buffer, "random device read would block error", max);
01579         break;
01580 
01581     case MP_INIT_E :
01582         XSTRNCPY(buffer, "mp_init error state", max);
01583         break;
01584 
01585     case MP_READ_E :
01586         XSTRNCPY(buffer, "mp_read error state", max);
01587         break;
01588 
01589     case MP_EXPTMOD_E :
01590         XSTRNCPY(buffer, "mp_exptmod error state", max);
01591         break;
01592 
01593     case MP_TO_E :
01594         XSTRNCPY(buffer, "mp_to_xxx error state, can't convert", max);
01595         break;
01596 
01597     case MP_SUB_E :
01598         XSTRNCPY(buffer, "mp_sub error state, can't subtract", max);
01599         break;
01600 
01601     case MP_ADD_E :
01602         XSTRNCPY(buffer, "mp_add error state, can't add", max);
01603         break;
01604 
01605     case MP_MUL_E :
01606         XSTRNCPY(buffer, "mp_mul error state, can't multiply", max);
01607         break;
01608 
01609     case MP_MULMOD_E :
01610         XSTRNCPY(buffer, "mp_mulmod error state, can't multiply mod", max);
01611         break;
01612 
01613     case MP_MOD_E :
01614         XSTRNCPY(buffer, "mp_mod error state, can't mod", max);
01615         break;
01616 
01617     case MP_INVMOD_E :
01618         XSTRNCPY(buffer, "mp_invmod error state, can't inv mod", max);
01619         break; 
01620         
01621     case MP_CMP_E :
01622         XSTRNCPY(buffer, "mp_cmp error state", max);
01623         break; 
01624         
01625     case MEMORY_E :
01626         XSTRNCPY(buffer, "out of memory error", max);
01627         break;
01628 
01629     case RSA_WRONG_TYPE_E :
01630         XSTRNCPY(buffer, "RSA wrong block type for RSA function", max);
01631         break; 
01632 
01633     case RSA_BUFFER_E :
01634         XSTRNCPY(buffer, "RSA buffer error, output too small or input too big",
01635                 max);
01636         break; 
01637 
01638     case BUFFER_E :
01639         XSTRNCPY(buffer, "Buffer error, output too small or input too big", max);
01640         break; 
01641 
01642     case ALGO_ID_E :
01643         XSTRNCPY(buffer, "Setting Cert AlogID error", max);
01644         break; 
01645 
01646     case PUBLIC_KEY_E :
01647         XSTRNCPY(buffer, "Setting Cert Public Key error", max);
01648         break; 
01649 
01650     case DATE_E :
01651         XSTRNCPY(buffer, "Setting Cert Date validity error", max);
01652         break; 
01653 
01654     case SUBJECT_E :
01655         XSTRNCPY(buffer, "Setting Cert Subject name error", max);
01656         break; 
01657 
01658     case ISSUER_E :
01659         XSTRNCPY(buffer, "Setting Cert Issuer name error", max);
01660         break; 
01661 
01662     case ASN_PARSE_E :
01663         XSTRNCPY(buffer, "ASN parsing error, invalid input", max);
01664         break;
01665 
01666     case ASN_VERSION_E :
01667         XSTRNCPY(buffer, "ASN version error, invalid number", max);
01668         break;
01669 
01670     case ASN_GETINT_E :
01671         XSTRNCPY(buffer, "ASN get big int error, invalid data", max);
01672         break;
01673 
01674     case ASN_RSA_KEY_E :
01675         XSTRNCPY(buffer, "ASN key init error, invalid input", max);
01676         break;
01677 
01678     case ASN_OBJECT_ID_E :
01679         XSTRNCPY(buffer, "ASN object id error, invalid id", max);
01680         break;
01681 
01682     case ASN_TAG_NULL_E :
01683         XSTRNCPY(buffer, "ASN tag error, not null", max);
01684         break;
01685 
01686     case ASN_EXPECT_0_E :
01687         XSTRNCPY(buffer, "ASN expect error, not zero", max);
01688         break;
01689 
01690     case ASN_BITSTR_E :
01691         XSTRNCPY(buffer, "ASN bit string error, wrong id", max);
01692         break;
01693 
01694     case ASN_UNKNOWN_OID_E :
01695         XSTRNCPY(buffer, "ASN oid error, unknown sum id", max);
01696         break;
01697 
01698     case ASN_DATE_SZ_E :
01699         XSTRNCPY(buffer, "ASN date error, bad size", max);
01700         break;
01701 
01702     case ASN_BEFORE_DATE_E :
01703         XSTRNCPY(buffer, "ASN date error, current date before", max);
01704         break;
01705 
01706     case ASN_AFTER_DATE_E :
01707         XSTRNCPY(buffer, "ASN date error, current date after", max);
01708         break;
01709 
01710     case ASN_SIG_OID_E :
01711         XSTRNCPY(buffer, "ASN signature error, mismatched oid", max);
01712         break;
01713 
01714     case ASN_TIME_E :
01715         XSTRNCPY(buffer, "ASN time error, unkown time type", max);
01716         break;
01717 
01718     case ASN_INPUT_E :
01719         XSTRNCPY(buffer, "ASN input error, not enough data", max);
01720         break;
01721 
01722     case ASN_SIG_CONFIRM_E :
01723         XSTRNCPY(buffer, "ASN sig error, confirm failure", max);
01724         break;
01725 
01726     case ASN_SIG_HASH_E :
01727         XSTRNCPY(buffer, "ASN sig error, unsupported hash type", max);
01728         break;
01729 
01730     case ASN_SIG_KEY_E :
01731         XSTRNCPY(buffer, "ASN sig error, unsupported key type", max);
01732         break;
01733 
01734     case ASN_DH_KEY_E :
01735         XSTRNCPY(buffer, "ASN key init error, invalid input", max);
01736         break;
01737 
01738     case ASN_NTRU_KEY_E :
01739         XSTRNCPY(buffer, "ASN NTRU key decode error, invalid input", max);
01740         break;
01741 
01742     default:
01743         XSTRNCPY(buffer, "unknown error number", max);
01744 
01745     }
01746 
01747 #endif /* NO_ERROR_STRINGS */
01748 
01749 }
01750 
01751 
01752 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
01753 
01754 static int SetMyVersion(word32 version, byte* output, int header)
01755 {
01756     int i = 0;
01757 
01758     if (header) {
01759         output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
01760         output[i++] = ASN_BIT_STRING;
01761     }
01762     output[i++] = ASN_INTEGER;
01763     output[i++] = 0x01;
01764     output[i++] = version;
01765 
01766     return i;
01767 }
01768 
01769 
01770 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
01771              int type)
01772 {
01773     char header[80];
01774     char footer[80];
01775 
01776     int headerLen;
01777     int footerLen;
01778     int i;
01779     int outLen;   /* return length or error */
01780 
01781     if (type == CERT_TYPE) {
01782         XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header));
01783         XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer));
01784     } else {
01785         XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header));
01786         XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer));
01787     }
01788 
01789     headerLen = XSTRLEN(header);
01790     footerLen = XSTRLEN(footer);
01791 
01792     if (!der || !output)
01793         return -1;
01794 
01795     /* don't even try if outSz too short */
01796     if (outSz < headerLen + footerLen + derSz)
01797         return -1;
01798 
01799     /* header */
01800     XMEMCPY(output, header, headerLen);
01801     i = headerLen;
01802 
01803     /* body */
01804     outLen = outSz;  /* input to Base64Encode */
01805     if (Base64Encode(der, derSz, output + i, (word32*)&outLen) < 0)
01806         return -1;
01807     i += outLen;
01808 
01809     /* footer */
01810     if ( (i + footerLen) > (int)outSz)
01811         return -1;
01812     XMEMCPY(output + i, footer, footerLen);
01813 
01814     return outLen + headerLen + footerLen;
01815 }
01816 
01817 
01818 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
01819 
01820 
01821 #ifdef CYASSL_KEY_GEN
01822 
01823 
01824 static mp_int* GetRsaInt(RsaKey* key, int index)
01825 {
01826     if (index == 0)
01827         return &key->n;
01828     if (index == 1)
01829         return &key->e;
01830     if (index == 2)
01831         return &key->d;
01832     if (index == 3)
01833         return &key->p;
01834     if (index == 4)
01835         return &key->q;
01836     if (index == 5)
01837         return &key->dP;
01838     if (index == 6)
01839         return &key->dQ;
01840     if (index == 7)
01841         return &key->u;
01842 
01843     return NULL;
01844 }
01845 
01846 
01847 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
01848    written */
01849 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
01850 {
01851     word32 seqSz, verSz, rawLen, intTotalLen = 0;
01852     word32 sizes[RSA_INTS];
01853     int    i, j, outLen;
01854 
01855     byte seq[MAX_SEQ_SZ];
01856     byte ver[MAX_VERSION_SZ];
01857     byte tmps[RSA_INTS][MAX_RSA_INT_SZ];
01858 
01859     if (!key || !output)
01860         return -1;
01861 
01862     if (key->type != RSA_PRIVATE)
01863         return -1;
01864 
01865     /* write all big ints from key to DER tmps */
01866     for (i = 0; i < RSA_INTS; i++) {
01867         mp_int* keyInt = GetRsaInt(key, i);
01868         rawLen = mp_unsigned_bin_size(keyInt);
01869 
01870         tmps[i][0] = ASN_INTEGER;
01871         sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1;  /* int tag */
01872 
01873         if ( (sizes[i] + rawLen) < sizeof(tmps[i])) {
01874             int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
01875             if (err == MP_OKAY) {
01876                 sizes[i] += rawLen;
01877                 intTotalLen += sizes[i];
01878             }
01879             else
01880                 return err;
01881         }
01882         else
01883             return -1;
01884     }
01885 
01886     /* make headers */
01887     verSz = SetMyVersion(0, ver, FALSE);
01888     seqSz = SetSequence(verSz + intTotalLen, seq);
01889 
01890     outLen = seqSz + verSz + intTotalLen;
01891     if (outLen > (int)inLen)
01892         return -1;
01893 
01894     /* write to output */
01895     XMEMCPY(output, seq, seqSz);
01896     j = seqSz;
01897     XMEMCPY(output + j, ver, verSz);
01898     j += verSz;
01899 
01900     for (i = 0; i < RSA_INTS; i++) {
01901         XMEMCPY(output + j, tmps[i], sizes[i]);
01902         j += sizes[i];
01903     }
01904 
01905     return outLen;
01906 }
01907 
01908 #endif /* CYASSL_KEY_GEN */
01909 
01910 
01911 #ifdef CYASSL_CERT_GEN
01912 
01913 /* Initialize and Set Certficate defaults:
01914    version    = 3 (0x2)
01915    serial     = 0
01916    sigType    = MD5_WITH_RSA
01917    issuer     = blank
01918    daysValid  = 500
01919    selfSigned = 1 (true) use subject as issuer
01920    subject    = blank
01921 */
01922 void InitCert(Cert* cert)
01923 {
01924     cert->version    = 2;   /* version 3 is hex 2 */
01925     cert->sigType    = MD5wRSA;
01926     cert->daysValid  = 500;
01927     cert->selfSigned = 1;
01928     cert->bodySz     = 0;
01929     cert->keyType    = RSA_KEY;
01930     XMEMSET(cert->serial, 0, SERIAL_SIZE);
01931 
01932     cert->issuer.country[0] = '\0';
01933     cert->issuer.state[0] = '\0';
01934     cert->issuer.locality[0] = '\0';
01935     cert->issuer.sur[0] = '\0';
01936     cert->issuer.org[0] = '\0';
01937     cert->issuer.unit[0] = '\0';
01938     cert->issuer.commonName[0] = '\0';
01939     cert->issuer.email[0] = '\0';
01940 
01941     cert->subject.country[0] = '\0';
01942     cert->subject.state[0] = '\0';
01943     cert->subject.locality[0] = '\0';
01944     cert->subject.sur[0] = '\0';
01945     cert->subject.org[0] = '\0';
01946     cert->subject.unit[0] = '\0';
01947     cert->subject.commonName[0] = '\0';
01948     cert->subject.email[0] = '\0';
01949 }
01950 
01951 
01952 /* DER encoded x509 Certificate */
01953 typedef struct DerCert {
01954     byte size[MAX_LENGTH_SZ];          /* length encoded */
01955     byte version[MAX_VERSION_SZ];      /* version encoded */
01956     byte serial[SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
01957     byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
01958     byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
01959     byte subject[ASN_NAME_MAX];        /* subject encoded */
01960     byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
01961     byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
01962     int  sizeSz;                       /* encoded size length */
01963     int  versionSz;                    /* encoded version length */
01964     int  serialSz;                     /* encoded serial length */
01965     int  sigAlgoSz;                    /* enocded sig alog length */
01966     int  issuerSz;                     /* encoded issuer length */
01967     int  subjectSz;                    /* encoded subject length */
01968     int  validitySz;                   /* encoded validity length */
01969     int  publicKeySz;                  /* encoded public key length */
01970     int  total;                        /* total encoded lengths */
01971 } DerCert;
01972 
01973 
01974 /* Write a set header to output */
01975 static word32 SetSet(word32 len, byte* output)
01976 {
01977     output[0] = ASN_SET | ASN_CONSTRUCTED;
01978     return SetLength(len, output + 1) + 1;
01979 }
01980 
01981 
01982 /* Write a serial number to output */
01983 static int SetSerial(const byte* serial, byte* output)
01984 {
01985     int length = 0;
01986 
01987     output[length++] = ASN_INTEGER;
01988     length += SetLength(SERIAL_SIZE, &output[length]);
01989     XMEMCPY(&output[length], serial, SERIAL_SIZE);
01990 
01991     return length + SERIAL_SIZE;
01992 }
01993 
01994 
01995 /* Write a public RSA key to output */
01996 static int SetPublicKey(byte* output, RsaKey* key)
01997 {
01998     byte n[MAX_RSA_INT_SZ];
01999     byte e[MAX_RSA_E_SZ];
02000     byte algo[MAX_ALGO_SZ];
02001     byte seq[MAX_SEQ_SZ];
02002     byte len[MAX_LENGTH_SZ + 1];  /* trailing 0 */
02003     int  nSz;
02004     int  eSz;
02005     int  algoSz;
02006     int  seqSz;
02007     int  lenSz;
02008     int  idx;
02009     int  rawLen;
02010 
02011     /* n */
02012     rawLen = mp_unsigned_bin_size(&key->n);
02013     n[0] = ASN_INTEGER;
02014     nSz  = SetLength(rawLen, n + 1) + 1;  /* int tag */
02015 
02016     if ( (nSz + rawLen) < sizeof(n)) {
02017         int err = mp_to_unsigned_bin(&key->n, n + nSz);
02018         if (err == MP_OKAY)
02019             nSz += rawLen;
02020         else
02021             return MP_TO_E;
02022     }
02023     else
02024         return BUFFER_E;
02025 
02026     /* e */
02027     rawLen = mp_unsigned_bin_size(&key->e);
02028     e[0] = ASN_INTEGER;
02029     eSz  = SetLength(rawLen, e + 1) + 1;  /* int tag */
02030 
02031     if ( (eSz + rawLen) < sizeof(e)) {
02032         int err = mp_to_unsigned_bin(&key->e, e + eSz);
02033         if (err == MP_OKAY)
02034             eSz += rawLen;
02035         else
02036             return MP_TO_E;
02037     }
02038     else
02039         return BUFFER_E;
02040 
02041     /* headers */
02042     algoSz = SetAlgoID(RSAk, algo, keyType);
02043     seqSz  = SetSequence(nSz + eSz, seq);
02044     lenSz  = SetLength(seqSz + nSz + eSz + 1, len);
02045     len[lenSz++] = 0;   /* trailing 0 */
02046 
02047     /* write */
02048     idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
02049         /* 1 is for ASN_BIT_STRING */
02050     /* algo */
02051     XMEMCPY(output + idx, algo, algoSz);
02052     idx += algoSz;
02053     /* bit string */
02054     output[idx++] = ASN_BIT_STRING;
02055     /* length */
02056     XMEMCPY(output + idx, len, lenSz);
02057     idx += lenSz;
02058     /* seq */
02059     XMEMCPY(output + idx, seq, seqSz);
02060     idx += seqSz;
02061     /* n */
02062     XMEMCPY(output + idx, n, nSz);
02063     idx += nSz;
02064     /* e */
02065     XMEMCPY(output + idx, e, eSz);
02066     idx += eSz;
02067 
02068     return idx;
02069 }
02070 
02071 
02072 static INLINE byte itob(int number)
02073 {
02074     return (byte)number + 0x30;
02075 }
02076 
02077 
02078 /* write time to output, format */
02079 static void SetTime(struct tm* date, byte* output)
02080 {
02081     int i = 0;
02082 
02083     output[i++] = itob((date->tm_year % 10000) / 1000);
02084     output[i++] = itob((date->tm_year % 1000)  /  100);
02085     output[i++] = itob((date->tm_year % 100)   /   10);
02086     output[i++] = itob( date->tm_year % 10);
02087 
02088     output[i++] = itob(date->tm_mon / 10);
02089     output[i++] = itob(date->tm_mon % 10);
02090 
02091     output[i++] = itob(date->tm_mday / 10);
02092     output[i++] = itob(date->tm_mday % 10);
02093 
02094     output[i++] = itob(date->tm_hour / 10);
02095     output[i++] = itob(date->tm_hour % 10);
02096 
02097     output[i++] = itob(date->tm_min / 10);
02098     output[i++] = itob(date->tm_min % 10);
02099 
02100     output[i++] = itob(date->tm_sec / 10);
02101     output[i++] = itob(date->tm_sec % 10);
02102     
02103     output[i] = 'Z';  /* Zulu profiel */
02104 }
02105 
02106 
02107 /* Set Date validity from now until now + daysValid */
02108 static int SetValidity(byte* output, int daysValid)
02109 {
02110     byte before[MAX_DATE_SIZE];
02111     byte  after[MAX_DATE_SIZE];
02112 
02113     int beforeSz;
02114     int afterSz;
02115     int seqSz;
02116 
02117     time_t     ticks;
02118     struct tm* now;
02119     struct tm  local;
02120 
02121     ticks = XTIME(0);
02122     now   = XGMTIME(&ticks);
02123 
02124     /* before now */
02125     local = *now;
02126     before[0] = ASN_GENERALIZED_TIME;
02127     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
02128 
02129     /* adjust */
02130     local.tm_year += 1900;
02131     local.tm_mon  +=    1;
02132 
02133     SetTime(&local, before + beforeSz);
02134     beforeSz += ASN_GEN_TIME_SZ;
02135     
02136     /* after now + daysValid */
02137     local = *now;
02138     after[0] = ASN_GENERALIZED_TIME;
02139     afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
02140 
02141     /* add daysValid */
02142     local.tm_mday += daysValid;
02143     mktime(&local);
02144 
02145     /* adjust */
02146     local.tm_year += 1900;
02147     local.tm_mon  +=    1;
02148 
02149     SetTime(&local, after + afterSz);
02150     afterSz += ASN_GEN_TIME_SZ;
02151 
02152     /* headers and output */
02153     seqSz = SetSequence(beforeSz + afterSz, output);
02154     XMEMCPY(output + seqSz, before, beforeSz);
02155     XMEMCPY(output + seqSz + beforeSz, after, afterSz);
02156 
02157     return seqSz + beforeSz + afterSz;
02158 }
02159 
02160 
02161 /* ASN Encoded Name field */
02162 typedef struct EncodedName {
02163     int  nameLen;                /* actual string value length */
02164     int  totalLen;               /* total encodeding length */
02165     int  type;                   /* type of name */
02166     int  used;                   /* are we actually using this one */
02167     byte encoded[NAME_SIZE * 2]; /* encoding */
02168 } EncodedName;
02169 
02170 
02171 /* Get Which Name from index */
02172 static const char* GetOneName(CertName* name, int index)
02173 {
02174     switch (index) {
02175     case 0:
02176        return name->country;
02177        break;
02178     case 1:
02179        return name->state;
02180        break;
02181     case 2:
02182        return name->locality;
02183        break;
02184     case 3:
02185        return name->sur;
02186        break;
02187     case 4:
02188        return name->org;
02189        break;
02190     case 5:
02191        return name->unit;
02192        break;
02193     case 6:
02194        return name->commonName;
02195        break;
02196     case 7:
02197        return name->email;
02198        break;
02199     default:
02200        return 0;
02201     }
02202 
02203     return 0;
02204 }
02205 
02206 
02207 /* Get ASN Name from index */
02208 static byte GetNameId(int index)
02209 {
02210     switch (index) {
02211     case 0:
02212        return ASN_COUNTRY_NAME;
02213        break;
02214     case 1:
02215        return ASN_STATE_NAME;
02216        break;
02217     case 2:
02218        return ASN_LOCALITY_NAME;
02219        break;
02220     case 3:
02221        return ASN_SUR_NAME;
02222        break;
02223     case 4:
02224        return ASN_ORG_NAME;
02225        break;
02226     case 5:
02227        return ASN_ORGUNIT_NAME;
02228        break;
02229     case 6:
02230        return ASN_COMMON_NAME;
02231        break;
02232     case 7:
02233        /* email uses different id type */
02234        return 0;
02235        break;
02236     default:
02237        return 0;
02238     }
02239 
02240     return 0;
02241 }
02242 
02243 
02244 /* encode CertName into output, return total bytes written */
02245 static int SetName(byte* output, CertName* name)
02246 {
02247     int         totalBytes = 0, i, idx;
02248     EncodedName names[NAME_ENTRIES];
02249 
02250     for (i = 0; i < NAME_ENTRIES; i++) {
02251         const char* nameStr = GetOneName(name, i);
02252         if (nameStr) {
02253             /* bottom up */
02254             byte firstLen[MAX_LENGTH_SZ];
02255             byte secondLen[MAX_LENGTH_SZ];
02256             byte sequence[MAX_SEQ_SZ];
02257             byte set[MAX_SET_SZ];
02258 
02259             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
02260             int strLen  = XSTRLEN(nameStr);
02261             int thisLen = strLen;
02262             int firstSz, secondSz, seqSz, setSz;
02263 
02264             if (strLen == 0) { /* no user data for this item */
02265                 names[i].used = 0;
02266                 continue;
02267             }
02268 
02269             secondSz = SetLength(strLen, secondLen);
02270             thisLen += secondSz;
02271             if (email) {
02272                 thisLen += EMAIL_JOINT_LEN;
02273                 thisLen ++;                               /* id type */
02274                 firstSz  = SetLength(EMAIL_JOINT_LEN, firstLen);
02275             }
02276             else {
02277                 thisLen++;                                 /* str type */
02278                 thisLen++;                                 /* id  type */
02279                 thisLen += JOINT_LEN;    
02280                 firstSz = SetLength(JOINT_LEN + 1, firstLen);
02281             }
02282             thisLen += firstSz;
02283             thisLen++;                                /* object id */
02284 
02285             seqSz = SetSequence(thisLen, sequence);
02286             thisLen += seqSz;
02287             setSz = SetSet(thisLen, set);
02288             thisLen += setSz;
02289 
02290             if (thisLen > sizeof(names[i].encoded))
02291                 return BUFFER_E;
02292 
02293             /* store it */
02294             idx = 0;
02295             /* set */
02296             XMEMCPY(names[i].encoded, set, setSz);
02297             idx += setSz;
02298             /* seq */
02299             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
02300             idx += seqSz;
02301             /* asn object id */
02302             names[i].encoded[idx++] = ASN_OBJECT_ID;
02303             /* first length */
02304             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
02305             idx += firstSz;
02306             if (email) {
02307                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
02308                                            0x01, 0x09, 0x01, 0x16 };
02309                 /* email joint id */
02310                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
02311                 idx += sizeof(EMAIL_OID);
02312             }
02313             else {
02314                 /* joint id */
02315                 names[i].encoded[idx++] = 0x55;
02316                 names[i].encoded[idx++] = 0x04;
02317                 /* id type */
02318                 names[i].encoded[idx++] = GetNameId(i);
02319                 /* str type */
02320                 names[i].encoded[idx++] = 0x13;
02321             }
02322             /* second length */
02323             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
02324             idx += secondSz;
02325             /* str value */
02326             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
02327             idx += strLen;
02328 
02329             totalBytes += idx;
02330             names[i].totalLen = idx;
02331             names[i].used = 1;
02332         }
02333         else
02334             names[i].used = 0;
02335     }
02336 
02337     /* header */
02338     idx = SetSequence(totalBytes, output);
02339     totalBytes += idx;
02340     if (totalBytes > ASN_NAME_MAX)
02341         return BUFFER_E;
02342 
02343     for (i = 0; i < NAME_ENTRIES; i++) {
02344         if (names[i].used) {
02345             XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
02346             idx += names[i].totalLen;
02347         }
02348     }
02349     return totalBytes;
02350 }
02351 
02352 
02353 /* encode info from cert into DER enocder format */
02354 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng,
02355                       const byte* ntruKey, word16 ntruSz)
02356 {
02357     /* version */
02358     der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
02359 
02360     /* serial number */
02361     RNG_GenerateBlock(rng, cert->serial, SERIAL_SIZE);
02362     cert->serial[0] = 0x01;   /* ensure positive */
02363     der->serialSz  = SetSerial(cert->serial, der->serial);
02364 
02365     /* signature algo */
02366     der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType);
02367     if (der->sigAlgoSz == 0)
02368         return ALGO_ID_E;
02369 
02370     /* public key */
02371     if (cert->keyType == RSA_KEY) {
02372         der->publicKeySz = SetPublicKey(der->publicKey, rsaKey);
02373         if (der->publicKeySz == 0)
02374             return PUBLIC_KEY_E;
02375     }
02376     else {
02377 #ifdef HAVE_NTRU
02378         word32 rc;
02379         word16 encodedSz;
02380 
02381         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
02382                                               ntruKey, &encodedSz, NULL);
02383         if (rc != NTRU_OK)
02384             return PUBLIC_KEY_E;
02385         if (encodedSz > MAX_PUBLIC_KEY_SZ)
02386             return PUBLIC_KEY_E;
02387 
02388         rc  = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
02389                               ntruKey, &encodedSz, der->publicKey);
02390         if (rc != NTRU_OK)
02391             return PUBLIC_KEY_E;
02392 
02393         der->publicKeySz = encodedSz;
02394 #endif
02395     }
02396 
02397     /* date validity */
02398     der->validitySz = SetValidity(der->validity, cert->daysValid);
02399     if (der->validitySz == 0)
02400         return DATE_E;
02401 
02402     /* subject name */
02403     der->subjectSz = SetName(der->subject, &cert->subject);
02404     if (der->subjectSz == 0)
02405         return SUBJECT_E;
02406 
02407     /* issuer name */
02408     der->issuerSz = SetName(der->issuer, cert->selfSigned ?
02409              &cert->subject : &cert->issuer);
02410     if (der->issuerSz == 0)
02411         return ISSUER_E;
02412 
02413     der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
02414         der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz;
02415 
02416     return 0;
02417 }
02418 
02419 
02420 /* write DER encoded cert to buffer, size already checked */
02421 static int WriteCertBody(DerCert* der, byte* buffer)
02422 {
02423     int idx;
02424 
02425     /* signed part header */
02426     idx = SetSequence(der->total, buffer);
02427     /* version */
02428     XMEMCPY(buffer + idx, der->version, der->versionSz);
02429     idx += der->versionSz;
02430     /* serial */
02431     XMEMCPY(buffer + idx, der->serial, der->serialSz);
02432     idx += der->serialSz;
02433     /* sig algo */
02434     XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
02435     idx += der->sigAlgoSz;
02436     /* issuer */
02437     XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
02438     idx += der->issuerSz;
02439     /* validity */
02440     XMEMCPY(buffer + idx, der->validity, der->validitySz);
02441     idx += der->validitySz;
02442     /* subject */
02443     XMEMCPY(buffer + idx, der->subject, der->subjectSz);
02444     idx += der->subjectSz;
02445     /* public key */
02446     XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
02447     idx += der->publicKeySz;
02448 
02449     return idx;
02450 }
02451 
02452 
02453 /* Make MD5wRSA signature from buffer (sz), write to sig (sigSz) */
02454 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
02455                          RsaKey* key, RNG* rng)
02456 {
02457     byte    digest[SHA_DIGEST_SIZE];     /* max size */
02458     byte    encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
02459     int     encSigSz, digestSz, hashType;
02460     Md5     md5;                         /* md5 for now */
02461 
02462     InitMd5(&md5);
02463     Md5Update(&md5, buffer, sz);
02464     Md5Final(&md5, digest);
02465     digestSz = MD5_DIGEST_SIZE;
02466     hashType = MD5h;
02467 
02468     /* signature */
02469     encSigSz = EncodeSignature(encSig, digest, digestSz, hashType);
02470     return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng);
02471 }
02472 
02473 
02474 /* add signature to end of buffer, size of buffer assumed checked, return
02475    new length */
02476 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz)
02477 {
02478     byte seq[MAX_SEQ_SZ];
02479     int  idx = bodySz, seqSz;
02480 
02481     /* algo */
02482     idx += SetAlgoID(MD5wRSA, buffer + idx, sigType);
02483     /* bit string */
02484     buffer[idx++] = ASN_BIT_STRING;
02485     /* length */
02486     idx += SetLength(sigSz + 1, buffer + idx);
02487     buffer[idx++] = 0;   /* trailing 0 */
02488     /* signature */
02489     XMEMCPY(buffer + idx, sig, sigSz);
02490     idx += sigSz;
02491 
02492     /* make room for overall header */
02493     seqSz = SetSequence(idx, seq);
02494     XMEMMOVE(buffer + seqSz, buffer, idx);
02495     XMEMCPY(buffer, seq, seqSz);
02496 
02497     return idx + seqSz;
02498 }
02499 
02500 
02501 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
02502 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
02503                    RsaKey* rsaKey, RNG* rng, const byte* ntruKey, word16 ntruSz)
02504 {
02505     DerCert der;
02506     int     ret;
02507 
02508     cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY;
02509     ret = EncodeCert(cert, &der, rsaKey, rng, ntruKey, ntruSz);
02510     if (ret != 0)
02511         return ret;
02512 
02513     if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
02514         return BUFFER_E;
02515 
02516     return cert->bodySz = WriteCertBody(&der, derBuffer);
02517 }
02518 
02519 
02520 /* Make an x509 Certificate v3 RSA from cert input, write to buffer */
02521 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,RNG* rng)
02522 {
02523     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, rng, NULL, 0);
02524 }
02525 
02526 
02527 #ifdef HAVE_NTRU
02528 
02529 int  MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
02530                   const byte* ntruKey, word16 keySz, RNG* rng)
02531 {
02532     return MakeAnyCert(cert, derBuffer, derSz, NULL, rng, ntruKey, keySz);
02533 }
02534 
02535 #endif /* HAVE_NTRU */
02536 
02537 
02538 int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
02539 {
02540     byte    sig[MAX_ENCODED_SIG_SZ];
02541     int     sigSz;
02542     int     bodySz = cert->bodySz;
02543 
02544     if (bodySz < 0)
02545         return bodySz;
02546 
02547     sigSz  = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng);
02548     if (sigSz < 0)
02549         return sigSz; 
02550 
02551     if (bodySz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
02552         return BUFFER_E; 
02553 
02554     return AddSignature(buffer, bodySz, sig, sigSz);
02555 }
02556 
02557 
02558 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
02559 {
02560     int ret = MakeCert(cert, buffer, buffSz, key, rng);
02561 
02562     if (ret < 0)
02563         return ret;
02564 
02565     return SignCert(cert, buffer, buffSz, key, rng);
02566 }
02567 
02568 
02569 /* forward from CyaSSL */
02570 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
02571 
02572 #ifndef NO_FILESYSTEM
02573 
02574 int SetIssuer(Cert* cert, const char* issuerCertFile)
02575 {
02576     DecodedCert decoded;
02577     byte        der[8192];
02578     int         derSz = CyaSSL_PemCertToDer(issuerCertFile, der, sizeof(der));
02579     int         ret;
02580     int         sz;
02581 
02582     if (derSz < 0)
02583         return derSz;
02584 
02585     cert->selfSigned = 0;
02586 
02587     InitDecodedCert(&decoded, der, 0);
02588     ret = ParseCertRelative(&decoded, derSz, CA_TYPE, NO_VERIFY, 0);
02589 
02590     if (ret < 0)
02591         return ret;
02592 
02593     if (decoded.subjectCN) {
02594         sz = (decoded.subjectCNLen < NAME_SIZE) ? decoded.subjectCNLen :
02595                                                   NAME_SIZE - 1;
02596         strncpy(cert->issuer.commonName, decoded.subjectCN, NAME_SIZE);
02597         cert->issuer.commonName[sz] = 0;
02598     }
02599     if (decoded.subjectC) {
02600         sz = (decoded.subjectCLen < NAME_SIZE) ? decoded.subjectCLen :
02601                                                  NAME_SIZE - 1;
02602         strncpy(cert->issuer.country, decoded.subjectC, NAME_SIZE);
02603         cert->issuer.country[sz] = 0;
02604     }
02605     if (decoded.subjectST) {
02606         sz = (decoded.subjectSTLen < NAME_SIZE) ? decoded.subjectSTLen :
02607                                                   NAME_SIZE - 1;
02608         strncpy(cert->issuer.state, decoded.subjectST, NAME_SIZE);
02609         cert->issuer.state[sz] = 0;
02610     }
02611     if (decoded.subjectL) {
02612         sz = (decoded.subjectLLen < NAME_SIZE) ? decoded.subjectLLen :
02613                                                  NAME_SIZE - 1;
02614         strncpy(cert->issuer.locality, decoded.subjectL, NAME_SIZE);
02615         cert->issuer.locality[sz] = 0;
02616     }
02617     if (decoded.subjectO) {
02618         sz = (decoded.subjectOLen < NAME_SIZE) ? decoded.subjectOLen :
02619                                                  NAME_SIZE - 1;
02620         strncpy(cert->issuer.org, decoded.subjectO, NAME_SIZE);
02621         cert->issuer.org[sz] = 0;
02622     }
02623     if (decoded.subjectOU) {
02624         sz = (decoded.subjectOULen < NAME_SIZE) ? decoded.subjectOULen :
02625                                                   NAME_SIZE - 1;
02626         strncpy(cert->issuer.unit, decoded.subjectOU, NAME_SIZE);
02627         cert->issuer.unit[sz] = 0;
02628     }
02629     if (decoded.subjectSN) {
02630         sz = (decoded.subjectSNLen < NAME_SIZE) ? decoded.subjectSNLen :
02631                                                   NAME_SIZE - 1;
02632         strncpy(cert->issuer.sur, decoded.subjectSN, NAME_SIZE);
02633         cert->issuer.sur[sz] = 0;
02634     }
02635     if (decoded.subjectEmail) {
02636         sz = (decoded.subjectEmailLen < NAME_SIZE) ? decoded.subjectEmailLen :
02637                                                      NAME_SIZE - 1;
02638         strncpy(cert->issuer.email, decoded.subjectEmail, NAME_SIZE);
02639         cert->issuer.email[sz] = 0;
02640     }
02641 
02642     FreeDecodedCert(&decoded);
02643 
02644     return 0;
02645 }
02646 
02647 #endif /* NO_FILESYSTEM */
02648 #endif /* CYASSL_CERT_GEN */