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