Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CyaSSL by
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(<ime); 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 */
Generated on Sat Jul 16 2022 04:51:03 by
1.7.2
