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.
Dependents: cyassl-client Sync
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 Tue Jul 12 2022 18:43:19 by
