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