Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CyaSSL by
asn.c
00001 /* asn.c 00002 * 00003 * Copyright (C) 2006-2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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/error-crypt.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(FREESCALE_MQX) 00104 #include <time.h> 00105 #define XTIME(t1) mqx_time((t1)) 00106 #define XGMTIME(c) gmtime((c)) 00107 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) 00108 #elif defined(CYASSL_MDK_ARM) 00109 #if defined(CYASSL_MDK5) 00110 #include "cmsis_os.h" 00111 #else 00112 #include <rtl.h> 00113 #endif 00114 #undef RNG 00115 #include "cyassl_MDK_ARM.h" 00116 #undef RNG 00117 #define RNG CyaSSL_RNG /*for avoiding name conflict in "stm32f2xx.h" */ 00118 #define XTIME(tl) (0) 00119 #define XGMTIME(c) Cyassl_MDK_gmtime((c)) 00120 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) 00121 #elif defined(USER_TIME) 00122 /* user time, and gmtime compatible functions, there is a gmtime 00123 implementation here that WINCE uses, so really just need some ticks 00124 since the EPOCH 00125 */ 00126 00127 struct tm { 00128 int tm_sec; /* seconds after the minute [0-60] */ 00129 int tm_min; /* minutes after the hour [0-59] */ 00130 int tm_hour; /* hours since midnight [0-23] */ 00131 int tm_mday; /* day of the month [1-31] */ 00132 int tm_mon; /* months since January [0-11] */ 00133 int tm_year; /* years since 1900 */ 00134 int tm_wday; /* days since Sunday [0-6] */ 00135 int tm_yday; /* days since January 1 [0-365] */ 00136 int tm_isdst; /* Daylight Savings Time flag */ 00137 long tm_gmtoff; /* offset from CUT in seconds */ 00138 char *tm_zone; /* timezone abbreviation */ 00139 }; 00140 typedef long time_t; 00141 00142 /* forward declaration */ 00143 struct tm* gmtime(const time_t* timer); 00144 extern time_t XTIME(time_t * timer); 00145 00146 #define XGMTIME(c) gmtime((c)) 00147 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) 00148 00149 #ifdef STACK_TRAP 00150 /* for stack trap tracking, don't call os gmtime on OS X/linux, 00151 uses a lot of stack spce */ 00152 extern time_t time(time_t * timer); 00153 #define XTIME(tl) time((tl)) 00154 #endif /* STACK_TRAP */ 00155 00156 #else 00157 /* default */ 00158 /* uses complete <time.h> facility */ 00159 #include <time.h> 00160 #define XTIME(tl) time((tl)) 00161 #define XGMTIME(c) gmtime((c)) 00162 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) 00163 #endif 00164 00165 00166 #ifdef _WIN32_WCE 00167 /* no time() or gmtime() even though in time.h header?? */ 00168 00169 #include <windows.h> 00170 00171 00172 time_t time(time_t* timer) 00173 { 00174 SYSTEMTIME sysTime; 00175 FILETIME fTime; 00176 ULARGE_INTEGER intTime; 00177 time_t localTime; 00178 00179 if (timer == NULL) 00180 timer = &localTime; 00181 00182 GetSystemTime(&sysTime); 00183 SystemTimeToFileTime(&sysTime, &fTime); 00184 00185 XMEMCPY(&intTime, &fTime, sizeof(FILETIME)); 00186 /* subtract EPOCH */ 00187 intTime.QuadPart -= 0x19db1ded53e8000; 00188 /* to secs */ 00189 intTime.QuadPart /= 10000000; 00190 *timer = (time_t)intTime.QuadPart; 00191 00192 return *timer; 00193 } 00194 00195 #endif /* _WIN32_WCE */ 00196 #if defined( _WIN32_WCE ) || defined( USER_TIME ) 00197 00198 struct tm* gmtime(const time_t* timer) 00199 { 00200 #define YEAR0 1900 00201 #define EPOCH_YEAR 1970 00202 #define SECS_DAY (24L * 60L * 60L) 00203 #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400))) 00204 #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) 00205 00206 static const int _ytab[2][12] = 00207 { 00208 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 00209 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 00210 }; 00211 00212 static struct tm st_time; 00213 struct tm* ret = &st_time; 00214 time_t secs = *timer; 00215 unsigned long dayclock, dayno; 00216 int year = EPOCH_YEAR; 00217 00218 dayclock = (unsigned long)secs % SECS_DAY; 00219 dayno = (unsigned long)secs / SECS_DAY; 00220 00221 ret->tm_sec = (int) dayclock % 60; 00222 ret->tm_min = (int)(dayclock % 3600) / 60; 00223 ret->tm_hour = (int) dayclock / 3600; 00224 ret->tm_wday = (int) (dayno + 4) % 7; /* day 0 a Thursday */ 00225 00226 while(dayno >= (unsigned long)YEARSIZE(year)) { 00227 dayno -= YEARSIZE(year); 00228 year++; 00229 } 00230 00231 ret->tm_year = year - YEAR0; 00232 ret->tm_yday = (int)dayno; 00233 ret->tm_mon = 0; 00234 00235 while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) { 00236 dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon]; 00237 ret->tm_mon++; 00238 } 00239 00240 ret->tm_mday = (int)++dayno; 00241 ret->tm_isdst = 0; 00242 00243 return ret; 00244 } 00245 00246 #endif /* _WIN32_WCE || USER_TIME */ 00247 00248 00249 #ifdef HAVE_RTP_SYS 00250 00251 #define YEAR0 1900 00252 00253 struct tm* my_gmtime(const time_t* timer) /* has a gmtime() but hangs */ 00254 { 00255 static struct tm st_time; 00256 struct tm* ret = &st_time; 00257 00258 DC_RTC_CALENDAR cal; 00259 dc_rtc_time_get(&cal, TRUE); 00260 00261 ret->tm_year = cal.year - YEAR0; /* gm starts at 1900 */ 00262 ret->tm_mon = cal.month - 1; /* gm starts at 0 */ 00263 ret->tm_mday = cal.day; 00264 ret->tm_hour = cal.hour; 00265 ret->tm_min = cal.minute; 00266 ret->tm_sec = cal.second; 00267 00268 return ret; 00269 } 00270 00271 #endif /* HAVE_RTP_SYS */ 00272 00273 00274 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP) 00275 00276 /* 00277 * time() is just a stub in Microchip libraries. We need our own 00278 * implementation. Use SNTP client to get seconds since epoch. 00279 */ 00280 time_t pic32_time(time_t* timer) 00281 { 00282 #ifdef MICROCHIP_TCPIP_V5 00283 DWORD sec = 0; 00284 #else 00285 uint32_t sec = 0; 00286 #endif 00287 time_t localTime; 00288 00289 if (timer == NULL) 00290 timer = &localTime; 00291 00292 #ifdef MICROCHIP_MPLAB_HARMONY 00293 sec = TCPIP_SNTP_UTCSecondsGet(); 00294 #else 00295 sec = SNTPGetUTCSeconds(); 00296 #endif 00297 *timer = (time_t) sec; 00298 00299 return *timer; 00300 } 00301 00302 #endif /* MICROCHIP_TCPIP */ 00303 00304 00305 #ifdef FREESCALE_MQX 00306 00307 time_t mqx_time(time_t* timer) 00308 { 00309 time_t localTime; 00310 TIME_STRUCT time_s; 00311 00312 if (timer == NULL) 00313 timer = &localTime; 00314 00315 _time_get(&time_s); 00316 *timer = (time_t) time_s.SECONDS; 00317 00318 return *timer; 00319 } 00320 00321 #endif /* FREESCALE_MQX */ 00322 00323 00324 static INLINE word32 btoi(byte b) 00325 { 00326 return b - 0x30; 00327 } 00328 00329 00330 /* two byte date/time, add to value */ 00331 static INLINE void GetTime(int* value, const byte* date, int* idx) 00332 { 00333 int i = *idx; 00334 00335 *value += btoi(date[i++]) * 10; 00336 *value += btoi(date[i++]); 00337 00338 *idx = i; 00339 } 00340 00341 00342 #if defined(MICRIUM) 00343 00344 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format, 00345 CPU_INT08U dateType) 00346 { 00347 CPU_BOOLEAN rtn_code; 00348 CPU_INT32S i; 00349 CPU_INT32S val; 00350 CPU_INT16U year; 00351 CPU_INT08U month; 00352 CPU_INT16U day; 00353 CPU_INT08U hour; 00354 CPU_INT08U min; 00355 CPU_INT08U sec; 00356 00357 i = 0; 00358 year = 0u; 00359 00360 if (format == ASN_UTC_TIME) { 00361 if (btoi(date[0]) >= 5) 00362 year = 1900; 00363 else 00364 year = 2000; 00365 } 00366 else { /* format == GENERALIZED_TIME */ 00367 year += btoi(date[i++]) * 1000; 00368 year += btoi(date[i++]) * 100; 00369 } 00370 00371 val = year; 00372 GetTime(&val, date, &i); 00373 year = (CPU_INT16U)val; 00374 00375 val = 0; 00376 GetTime(&val, date, &i); 00377 month = (CPU_INT08U)val; 00378 00379 val = 0; 00380 GetTime(&val, date, &i); 00381 day = (CPU_INT16U)val; 00382 00383 val = 0; 00384 GetTime(&val, date, &i); 00385 hour = (CPU_INT08U)val; 00386 00387 val = 0; 00388 GetTime(&val, date, &i); 00389 min = (CPU_INT08U)val; 00390 00391 val = 0; 00392 GetTime(&val, date, &i); 00393 sec = (CPU_INT08U)val; 00394 00395 return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); 00396 } 00397 00398 #endif /* MICRIUM */ 00399 00400 00401 CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, 00402 word32 maxIdx) 00403 { 00404 int length = 0; 00405 word32 i = *inOutIdx; 00406 byte b; 00407 00408 if ( (i+1) > maxIdx) { /* for first read */ 00409 CYASSL_MSG("GetLength bad index on input"); 00410 return BUFFER_E; 00411 } 00412 00413 b = input[i++]; 00414 if (b >= ASN_LONG_LENGTH) { 00415 word32 bytes = b & 0x7F; 00416 00417 if ( (i+bytes) > maxIdx) { /* for reading bytes */ 00418 CYASSL_MSG("GetLength bad long length"); 00419 return BUFFER_E; 00420 } 00421 00422 while (bytes--) { 00423 b = input[i++]; 00424 length = (length << 8) | b; 00425 } 00426 } 00427 else 00428 length = b; 00429 00430 if ( (i+length) > maxIdx) { /* for user of length */ 00431 CYASSL_MSG("GetLength value exceeds buffer length"); 00432 return BUFFER_E; 00433 } 00434 00435 *inOutIdx = i; 00436 *len = length; 00437 00438 return length; 00439 } 00440 00441 00442 CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, 00443 word32 maxIdx) 00444 { 00445 int length = -1; 00446 word32 idx = *inOutIdx; 00447 00448 if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) || 00449 GetLength(input, &idx, &length, maxIdx) < 0) 00450 return ASN_PARSE_E; 00451 00452 *len = length; 00453 *inOutIdx = idx; 00454 00455 return length; 00456 } 00457 00458 00459 CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len, 00460 word32 maxIdx) 00461 { 00462 int length = -1; 00463 word32 idx = *inOutIdx; 00464 00465 if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) || 00466 GetLength(input, &idx, &length, maxIdx) < 0) 00467 return ASN_PARSE_E; 00468 00469 *len = length; 00470 *inOutIdx = idx; 00471 00472 return length; 00473 } 00474 00475 00476 /* winodws header clash for WinCE using GetVersion */ 00477 CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version) 00478 { 00479 word32 idx = *inOutIdx; 00480 00481 CYASSL_ENTER("GetMyVersion"); 00482 00483 if (input[idx++] != ASN_INTEGER) 00484 return ASN_PARSE_E; 00485 00486 if (input[idx++] != 0x01) 00487 return ASN_VERSION_E; 00488 00489 *version = input[idx++]; 00490 *inOutIdx = idx; 00491 00492 return *version; 00493 } 00494 00495 00496 #ifndef NO_PWDBASED 00497 /* Get small count integer, 32 bits or less */ 00498 static int GetShortInt(const byte* input, word32* inOutIdx, int* number) 00499 { 00500 word32 idx = *inOutIdx; 00501 word32 len; 00502 00503 *number = 0; 00504 00505 if (input[idx++] != ASN_INTEGER) 00506 return ASN_PARSE_E; 00507 00508 len = input[idx++]; 00509 if (len > 4) 00510 return ASN_PARSE_E; 00511 00512 while (len--) { 00513 *number = *number << 8 | input[idx++]; 00514 } 00515 00516 *inOutIdx = idx; 00517 00518 return *number; 00519 } 00520 #endif /* !NO_PWDBASED */ 00521 00522 00523 /* May not have one, not an error */ 00524 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version) 00525 { 00526 word32 idx = *inOutIdx; 00527 00528 CYASSL_ENTER("GetExplicitVersion"); 00529 if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { 00530 *inOutIdx = ++idx; /* eat header */ 00531 return GetMyVersion(input, inOutIdx, version); 00532 } 00533 00534 /* go back as is */ 00535 *version = 0; 00536 00537 return 0; 00538 } 00539 00540 00541 CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, 00542 word32 maxIdx) 00543 { 00544 word32 i = *inOutIdx; 00545 byte b = input[i++]; 00546 int length; 00547 00548 if (b != ASN_INTEGER) 00549 return ASN_PARSE_E; 00550 00551 if (GetLength(input, &i, &length, maxIdx) < 0) 00552 return ASN_PARSE_E; 00553 00554 if ( (b = input[i++]) == 0x00) 00555 length--; 00556 else 00557 i--; 00558 00559 if (mp_init(mpi) != MP_OKAY) 00560 return MP_INIT_E; 00561 00562 if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) { 00563 mp_clear(mpi); 00564 return ASN_GETINT_E; 00565 } 00566 00567 *inOutIdx = i + length; 00568 return 0; 00569 } 00570 00571 00572 static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, 00573 word32 maxIdx) 00574 { 00575 int length; 00576 word32 i = *inOutIdx; 00577 byte b; 00578 *oid = 0; 00579 00580 b = input[i++]; 00581 if (b != ASN_OBJECT_ID) 00582 return ASN_OBJECT_ID_E; 00583 00584 if (GetLength(input, &i, &length, maxIdx) < 0) 00585 return ASN_PARSE_E; 00586 00587 while(length--) 00588 *oid += input[i++]; 00589 /* just sum it up for now */ 00590 00591 *inOutIdx = i; 00592 00593 return 0; 00594 } 00595 00596 00597 CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, 00598 word32 maxIdx) 00599 { 00600 int length; 00601 word32 i = *inOutIdx; 00602 byte b; 00603 *oid = 0; 00604 00605 CYASSL_ENTER("GetAlgoId"); 00606 00607 if (GetSequence(input, &i, &length, maxIdx) < 0) 00608 return ASN_PARSE_E; 00609 00610 b = input[i++]; 00611 if (b != ASN_OBJECT_ID) 00612 return ASN_OBJECT_ID_E; 00613 00614 if (GetLength(input, &i, &length, maxIdx) < 0) 00615 return ASN_PARSE_E; 00616 00617 while(length--) { 00618 /* odd HC08 compiler behavior here when input[i++] */ 00619 *oid += input[i]; 00620 i++; 00621 } 00622 /* just sum it up for now */ 00623 00624 /* could have NULL tag and 0 terminator, but may not */ 00625 b = input[i++]; 00626 00627 if (b == ASN_TAG_NULL) { 00628 b = input[i++]; 00629 if (b != 0) 00630 return ASN_EXPECT_0_E; 00631 } 00632 else 00633 /* go back, didn't have it */ 00634 i--; 00635 00636 *inOutIdx = i; 00637 00638 return 0; 00639 } 00640 00641 #ifndef NO_RSA 00642 00643 00644 #ifdef HAVE_CAVIUM 00645 00646 static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input, 00647 word32* inOutIdx, word32 maxIdx, void* heap) 00648 { 00649 word32 i = *inOutIdx; 00650 byte b = input[i++]; 00651 int length; 00652 00653 if (b != ASN_INTEGER) 00654 return ASN_PARSE_E; 00655 00656 if (GetLength(input, &i, &length, maxIdx) < 0) 00657 return ASN_PARSE_E; 00658 00659 if ( (b = input[i++]) == 0x00) 00660 length--; 00661 else 00662 i--; 00663 00664 *buffSz = (word16)length; 00665 *buff = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA); 00666 if (*buff == NULL) 00667 return MEMORY_E; 00668 00669 XMEMCPY(*buff, input + i, *buffSz); 00670 00671 *inOutIdx = i + length; 00672 return 0; 00673 } 00674 00675 static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx, 00676 RsaKey* key, word32 inSz) 00677 { 00678 int version, length; 00679 void* h = key->heap; 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 (GetCaviumInt(&key->c_n, &key->c_nSz, input, inOutIdx, inSz, h) < 0 || 00690 GetCaviumInt(&key->c_e, &key->c_eSz, input, inOutIdx, inSz, h) < 0 || 00691 GetCaviumInt(&key->c_d, &key->c_dSz, input, inOutIdx, inSz, h) < 0 || 00692 GetCaviumInt(&key->c_p, &key->c_pSz, input, inOutIdx, inSz, h) < 0 || 00693 GetCaviumInt(&key->c_q, &key->c_qSz, input, inOutIdx, inSz, h) < 0 || 00694 GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 || 00695 GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 || 00696 GetCaviumInt(&key->c_u, &key->c_uSz, input, inOutIdx, inSz, h) < 0 ) 00697 return ASN_RSA_KEY_E; 00698 00699 return 0; 00700 } 00701 00702 00703 #endif /* HAVE_CAVIUM */ 00704 00705 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, 00706 word32 inSz) 00707 { 00708 int version, length; 00709 00710 #ifdef HAVE_CAVIUM 00711 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00712 return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz); 00713 #endif 00714 00715 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 00716 return ASN_PARSE_E; 00717 00718 if (GetMyVersion(input, inOutIdx, &version) < 0) 00719 return ASN_PARSE_E; 00720 00721 key->type = RSA_PRIVATE; 00722 00723 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || 00724 GetInt(&key->e, input, inOutIdx, inSz) < 0 || 00725 GetInt(&key->d, input, inOutIdx, inSz) < 0 || 00726 GetInt(&key->p, input, inOutIdx, inSz) < 0 || 00727 GetInt(&key->q, input, inOutIdx, inSz) < 0 || 00728 GetInt(&key->dP, input, inOutIdx, inSz) < 0 || 00729 GetInt(&key->dQ, input, inOutIdx, inSz) < 0 || 00730 GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; 00731 00732 return 0; 00733 } 00734 00735 #endif /* NO_RSA */ 00736 00737 /* Remove PKCS8 header, move beginning of traditional to beginning of input */ 00738 int ToTraditional(byte* input, word32 sz) 00739 { 00740 word32 inOutIdx = 0, oid; 00741 int version, length; 00742 00743 if (GetSequence(input, &inOutIdx, &length, sz) < 0) 00744 return ASN_PARSE_E; 00745 00746 if (GetMyVersion(input, &inOutIdx, &version) < 0) 00747 return ASN_PARSE_E; 00748 00749 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) 00750 return ASN_PARSE_E; 00751 00752 if (input[inOutIdx] == ASN_OBJECT_ID) { 00753 /* pkcs8 ecc uses slightly different format */ 00754 inOutIdx++; /* past id */ 00755 if (GetLength(input, &inOutIdx, &length, sz) < 0) 00756 return ASN_PARSE_E; 00757 inOutIdx += length; /* over sub id, key input will verify */ 00758 } 00759 00760 if (input[inOutIdx++] != ASN_OCTET_STRING) 00761 return ASN_PARSE_E; 00762 00763 if (GetLength(input, &inOutIdx, &length, sz) < 0) 00764 return ASN_PARSE_E; 00765 00766 XMEMMOVE(input, input + inOutIdx, length); 00767 00768 return length; 00769 } 00770 00771 00772 #ifndef NO_PWDBASED 00773 00774 /* Check To see if PKCS version algo is supported, set id if it is return 0 00775 < 0 on error */ 00776 static int CheckAlgo(int first, int second, int* id, int* version) 00777 { 00778 *id = ALGO_ID_E; 00779 *version = PKCS5; /* default */ 00780 00781 if (first == 1) { 00782 switch (second) { 00783 case 1: 00784 *id = PBE_SHA1_RC4_128; 00785 *version = PKCS12; 00786 return 0; 00787 case 3: 00788 *id = PBE_SHA1_DES3; 00789 *version = PKCS12; 00790 return 0; 00791 default: 00792 return ALGO_ID_E; 00793 } 00794 } 00795 00796 if (first != PKCS5) 00797 return ASN_INPUT_E; /* VERSION ERROR */ 00798 00799 if (second == PBES2) { 00800 *version = PKCS5v2; 00801 return 0; 00802 } 00803 00804 switch (second) { 00805 case 3: /* see RFC 2898 for ids */ 00806 *id = PBE_MD5_DES; 00807 return 0; 00808 case 10: 00809 *id = PBE_SHA1_DES; 00810 return 0; 00811 default: 00812 return ALGO_ID_E; 00813 00814 } 00815 } 00816 00817 00818 /* Check To see if PKCS v2 algo is supported, set id if it is return 0 00819 < 0 on error */ 00820 static int CheckAlgoV2(int oid, int* id) 00821 { 00822 switch (oid) { 00823 case 69: 00824 *id = PBE_SHA1_DES; 00825 return 0; 00826 case 652: 00827 *id = PBE_SHA1_DES3; 00828 return 0; 00829 default: 00830 return ALGO_ID_E; 00831 00832 } 00833 } 00834 00835 00836 /* Decrypt intput in place from parameters based on id */ 00837 static int DecryptKey(const char* password, int passwordSz, byte* salt, 00838 int saltSz, int iterations, int id, byte* input, 00839 int length, int version, byte* cbcIv) 00840 { 00841 byte key[MAX_KEY_SIZE]; 00842 int typeH; 00843 int derivedLen; 00844 int decryptionType; 00845 int ret = 0; 00846 00847 switch (id) { 00848 case PBE_MD5_DES: 00849 typeH = MD5; 00850 derivedLen = 16; /* may need iv for v1.5 */ 00851 decryptionType = DES_TYPE; 00852 break; 00853 00854 case PBE_SHA1_DES: 00855 typeH = SHA; 00856 derivedLen = 16; /* may need iv for v1.5 */ 00857 decryptionType = DES_TYPE; 00858 break; 00859 00860 case PBE_SHA1_DES3: 00861 typeH = SHA; 00862 derivedLen = 32; /* may need iv for v1.5 */ 00863 decryptionType = DES3_TYPE; 00864 break; 00865 00866 case PBE_SHA1_RC4_128: 00867 typeH = SHA; 00868 derivedLen = 16; 00869 decryptionType = RC4_TYPE; 00870 break; 00871 00872 default: 00873 return ALGO_ID_E; 00874 } 00875 00876 if (version == PKCS5v2) 00877 ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations, 00878 derivedLen, typeH); 00879 else if (version == PKCS5) 00880 ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations, 00881 derivedLen, typeH); 00882 else if (version == PKCS12) { 00883 int i, idx = 0; 00884 byte unicodePasswd[MAX_UNICODE_SZ]; 00885 00886 if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) 00887 return UNICODE_SIZE_E; 00888 00889 for (i = 0; i < passwordSz; i++) { 00890 unicodePasswd[idx++] = 0x00; 00891 unicodePasswd[idx++] = (byte)password[i]; 00892 } 00893 /* add trailing NULL */ 00894 unicodePasswd[idx++] = 0x00; 00895 unicodePasswd[idx++] = 0x00; 00896 00897 ret = PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz, 00898 iterations, derivedLen, typeH, 1); 00899 if (decryptionType != RC4_TYPE) 00900 ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz, 00901 iterations, 8, typeH, 2); 00902 } 00903 else 00904 return ALGO_ID_E; 00905 00906 if (ret != 0) 00907 return ret; 00908 00909 switch (decryptionType) { 00910 #ifndef NO_DES3 00911 case DES_TYPE: 00912 { 00913 Des dec; 00914 byte* desIv = key + 8; 00915 00916 if (version == PKCS5v2 || version == PKCS12) 00917 desIv = cbcIv; 00918 00919 ret = Des_SetKey(&dec, key, desIv, DES_DECRYPTION); 00920 if (ret != 0) 00921 return ret; 00922 00923 Des_CbcDecrypt(&dec, input, input, length); 00924 break; 00925 } 00926 00927 case DES3_TYPE: 00928 { 00929 Des3 dec; 00930 byte* desIv = key + 24; 00931 00932 if (version == PKCS5v2 || version == PKCS12) 00933 desIv = cbcIv; 00934 ret = Des3_SetKey(&dec, key, desIv, DES_DECRYPTION); 00935 if (ret != 0) 00936 return ret; 00937 ret = Des3_CbcDecrypt(&dec, input, input, length); 00938 if (ret != 0) 00939 return ret; 00940 break; 00941 } 00942 #endif 00943 #ifndef NO_RC4 00944 case RC4_TYPE: 00945 { 00946 Arc4 dec; 00947 00948 Arc4SetKey(&dec, key, derivedLen); 00949 Arc4Process(&dec, input, input, length); 00950 break; 00951 } 00952 #endif 00953 00954 default: 00955 return ALGO_ID_E; 00956 } 00957 00958 return 0; 00959 } 00960 00961 00962 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning 00963 of input */ 00964 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) 00965 { 00966 word32 inOutIdx = 0, oid; 00967 int first, second, length, version, saltSz, id; 00968 int iterations = 0; 00969 byte salt[MAX_SALT_SIZE]; 00970 byte cbcIv[MAX_IV_SIZE]; 00971 00972 if (GetSequence(input, &inOutIdx, &length, sz) < 0) 00973 return ASN_PARSE_E; 00974 00975 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) 00976 return ASN_PARSE_E; 00977 00978 first = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */ 00979 second = input[inOutIdx - 1]; /* version.algo, algo id last byte */ 00980 00981 if (CheckAlgo(first, second, &id, &version) < 0) 00982 return ASN_INPUT_E; /* Algo ID error */ 00983 00984 if (version == PKCS5v2) { 00985 00986 if (GetSequence(input, &inOutIdx, &length, sz) < 0) 00987 return ASN_PARSE_E; 00988 00989 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) 00990 return ASN_PARSE_E; 00991 00992 if (oid != PBKDF2_OID) 00993 return ASN_PARSE_E; 00994 } 00995 00996 if (GetSequence(input, &inOutIdx, &length, sz) < 0) 00997 return ASN_PARSE_E; 00998 00999 if (input[inOutIdx++] != ASN_OCTET_STRING) 01000 return ASN_PARSE_E; 01001 01002 if (GetLength(input, &inOutIdx, &saltSz, sz) < 0) 01003 return ASN_PARSE_E; 01004 01005 if (saltSz > MAX_SALT_SIZE) 01006 return ASN_PARSE_E; 01007 01008 XMEMCPY(salt, &input[inOutIdx], saltSz); 01009 inOutIdx += saltSz; 01010 01011 if (GetShortInt(input, &inOutIdx, &iterations) < 0) 01012 return ASN_PARSE_E; 01013 01014 if (version == PKCS5v2) { 01015 /* get encryption algo */ 01016 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) 01017 return ASN_PARSE_E; 01018 01019 if (CheckAlgoV2(oid, &id) < 0) 01020 return ASN_PARSE_E; /* PKCS v2 algo id error */ 01021 01022 if (input[inOutIdx++] != ASN_OCTET_STRING) 01023 return ASN_PARSE_E; 01024 01025 if (GetLength(input, &inOutIdx, &length, sz) < 0) 01026 return ASN_PARSE_E; 01027 01028 XMEMCPY(cbcIv, &input[inOutIdx], length); 01029 inOutIdx += length; 01030 } 01031 01032 if (input[inOutIdx++] != ASN_OCTET_STRING) 01033 return ASN_PARSE_E; 01034 01035 if (GetLength(input, &inOutIdx, &length, sz) < 0) 01036 return ASN_PARSE_E; 01037 01038 if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id, 01039 input + inOutIdx, length, version, cbcIv) < 0) 01040 return ASN_INPUT_E; /* decrypt failure */ 01041 01042 XMEMMOVE(input, input + inOutIdx, length); 01043 return ToTraditional(input, length); 01044 } 01045 01046 #endif /* NO_PWDBASED */ 01047 01048 #ifndef NO_RSA 01049 01050 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, 01051 word32 inSz) 01052 { 01053 int length; 01054 01055 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01056 return ASN_PARSE_E; 01057 01058 key->type = RSA_PUBLIC; 01059 01060 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA) 01061 { 01062 byte b = input[*inOutIdx]; 01063 if (b != ASN_INTEGER) { 01064 /* not from decoded cert, will have algo id, skip past */ 01065 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01066 return ASN_PARSE_E; 01067 01068 b = input[(*inOutIdx)++]; 01069 if (b != ASN_OBJECT_ID) 01070 return ASN_OBJECT_ID_E; 01071 01072 if (GetLength(input, inOutIdx, &length, inSz) < 0) 01073 return ASN_PARSE_E; 01074 01075 *inOutIdx += length; /* skip past */ 01076 01077 /* could have NULL tag and 0 terminator, but may not */ 01078 b = input[(*inOutIdx)++]; 01079 01080 if (b == ASN_TAG_NULL) { 01081 b = input[(*inOutIdx)++]; 01082 if (b != 0) 01083 return ASN_EXPECT_0_E; 01084 } 01085 else 01086 /* go back, didn't have it */ 01087 (*inOutIdx)--; 01088 01089 /* should have bit tag length and seq next */ 01090 b = input[(*inOutIdx)++]; 01091 if (b != ASN_BIT_STRING) 01092 return ASN_BITSTR_E; 01093 01094 if (GetLength(input, inOutIdx, &length, inSz) < 0) 01095 return ASN_PARSE_E; 01096 01097 /* could have 0 */ 01098 b = input[(*inOutIdx)++]; 01099 if (b != 0) 01100 (*inOutIdx)--; 01101 01102 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01103 return ASN_PARSE_E; 01104 } /* end if */ 01105 } /* openssl var block */ 01106 #endif /* OPENSSL_EXTRA */ 01107 01108 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || 01109 GetInt(&key->e, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; 01110 01111 return 0; 01112 } 01113 01114 #endif 01115 01116 #ifndef NO_DH 01117 01118 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz) 01119 { 01120 int length; 01121 01122 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01123 return ASN_PARSE_E; 01124 01125 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || 01126 GetInt(&key->g, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; 01127 01128 return 0; 01129 } 01130 01131 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) 01132 { 01133 if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) 01134 return BAD_FUNC_ARG; 01135 01136 /* may have leading 0 */ 01137 if (p[0] == 0) { 01138 pSz--; p++; 01139 } 01140 01141 if (g[0] == 0) { 01142 gSz--; g++; 01143 } 01144 01145 if (mp_init(&key->p) != MP_OKAY) 01146 return MP_INIT_E; 01147 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) { 01148 mp_clear(&key->p); 01149 return ASN_DH_KEY_E; 01150 } 01151 01152 if (mp_init(&key->g) != MP_OKAY) { 01153 mp_clear(&key->p); 01154 return MP_INIT_E; 01155 } 01156 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) { 01157 mp_clear(&key->g); 01158 mp_clear(&key->p); 01159 return ASN_DH_KEY_E; 01160 } 01161 01162 return 0; 01163 } 01164 01165 01166 #ifdef OPENSSL_EXTRA 01167 01168 int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, 01169 byte* g, word32* gInOutSz) 01170 { 01171 word32 i = 0; 01172 byte b; 01173 int length; 01174 01175 if (GetSequence(input, &i, &length, inSz) < 0) 01176 return ASN_PARSE_E; 01177 01178 b = input[i++]; 01179 if (b != ASN_INTEGER) 01180 return ASN_PARSE_E; 01181 01182 if (GetLength(input, &i, &length, inSz) < 0) 01183 return ASN_PARSE_E; 01184 01185 if ( (b = input[i++]) == 0x00) 01186 length--; 01187 else 01188 i--; 01189 01190 if (length <= (int)*pInOutSz) { 01191 XMEMCPY(p, &input[i], length); 01192 *pInOutSz = length; 01193 } 01194 else 01195 return BUFFER_E; 01196 01197 i += length; 01198 01199 b = input[i++]; 01200 if (b != ASN_INTEGER) 01201 return ASN_PARSE_E; 01202 01203 if (GetLength(input, &i, &length, inSz) < 0) 01204 return ASN_PARSE_E; 01205 01206 if (length <= (int)*gInOutSz) { 01207 XMEMCPY(g, &input[i], length); 01208 *gInOutSz = length; 01209 } 01210 else 01211 return BUFFER_E; 01212 01213 return 0; 01214 } 01215 01216 #endif /* OPENSSL_EXTRA */ 01217 #endif /* NO_DH */ 01218 01219 01220 #ifndef NO_DSA 01221 01222 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, 01223 word32 inSz) 01224 { 01225 int length; 01226 01227 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01228 return ASN_PARSE_E; 01229 01230 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || 01231 GetInt(&key->q, input, inOutIdx, inSz) < 0 || 01232 GetInt(&key->g, input, inOutIdx, inSz) < 0 || 01233 GetInt(&key->y, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; 01234 01235 key->type = DSA_PUBLIC; 01236 return 0; 01237 } 01238 01239 01240 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, 01241 word32 inSz) 01242 { 01243 int length, version; 01244 01245 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 01246 return ASN_PARSE_E; 01247 01248 if (GetMyVersion(input, inOutIdx, &version) < 0) 01249 return ASN_PARSE_E; 01250 01251 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || 01252 GetInt(&key->q, input, inOutIdx, inSz) < 0 || 01253 GetInt(&key->g, input, inOutIdx, inSz) < 0 || 01254 GetInt(&key->y, input, inOutIdx, inSz) < 0 || 01255 GetInt(&key->x, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; 01256 01257 key->type = DSA_PRIVATE; 01258 return 0; 01259 } 01260 01261 #endif /* NO_DSA */ 01262 01263 01264 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) 01265 { 01266 cert->publicKey = 0; 01267 cert->pubKeySize = 0; 01268 cert->pubKeyStored = 0; 01269 cert->version = 0; 01270 cert->signature = 0; 01271 cert->subjectCN = 0; 01272 cert->subjectCNLen = 0; 01273 cert->subjectCNStored = 0; 01274 cert->altNames = NULL; 01275 #ifndef IGNORE_NAME_CONSTRAINTS 01276 cert->altEmailNames = NULL; 01277 cert->permittedNames = NULL; 01278 cert->excludedNames = NULL; 01279 #endif /* IGNORE_NAME_CONSTRAINTS */ 01280 cert->issuer[0] = '\0'; 01281 cert->subject[0] = '\0'; 01282 cert->source = source; /* don't own */ 01283 cert->srcIdx = 0; 01284 cert->maxIdx = inSz; /* can't go over this index */ 01285 cert->heap = heap; 01286 XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE); 01287 cert->serialSz = 0; 01288 cert->extensions = 0; 01289 cert->extensionsSz = 0; 01290 cert->extensionsIdx = 0; 01291 cert->extAuthInfo = NULL; 01292 cert->extAuthInfoSz = 0; 01293 cert->extCrlInfo = NULL; 01294 cert->extCrlInfoSz = 0; 01295 XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE); 01296 cert->extSubjKeyIdSet = 0; 01297 XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE); 01298 cert->extAuthKeyIdSet = 0; 01299 cert->extKeyUsageSet = 0; 01300 cert->extKeyUsage = 0; 01301 cert->extExtKeyUsageSet = 0; 01302 cert->extExtKeyUsage = 0; 01303 cert->isCA = 0; 01304 #ifdef HAVE_PKCS7 01305 cert->issuerRaw = NULL; 01306 cert->issuerRawLen = 0; 01307 #endif 01308 #ifdef CYASSL_CERT_GEN 01309 cert->subjectSN = 0; 01310 cert->subjectSNLen = 0; 01311 cert->subjectC = 0; 01312 cert->subjectCLen = 0; 01313 cert->subjectL = 0; 01314 cert->subjectLLen = 0; 01315 cert->subjectST = 0; 01316 cert->subjectSTLen = 0; 01317 cert->subjectO = 0; 01318 cert->subjectOLen = 0; 01319 cert->subjectOU = 0; 01320 cert->subjectOULen = 0; 01321 cert->subjectEmail = 0; 01322 cert->subjectEmailLen = 0; 01323 #endif /* CYASSL_CERT_GEN */ 01324 cert->beforeDate = NULL; 01325 cert->beforeDateLen = 0; 01326 cert->afterDate = NULL; 01327 cert->afterDateLen = 0; 01328 #ifdef OPENSSL_EXTRA 01329 XMEMSET(&cert->issuerName, 0, sizeof(DecodedName)); 01330 XMEMSET(&cert->subjectName, 0, sizeof(DecodedName)); 01331 cert->extBasicConstSet = 0; 01332 cert->extBasicConstCrit = 0; 01333 cert->extBasicConstPlSet = 0; 01334 cert->pathLength = 0; 01335 cert->extSubjAltNameSet = 0; 01336 cert->extSubjAltNameCrit = 0; 01337 cert->extAuthKeyIdCrit = 0; 01338 cert->extSubjKeyIdCrit = 0; 01339 cert->extKeyUsageCrit = 0; 01340 cert->extExtKeyUsageCrit = 0; 01341 cert->extExtKeyUsageSrc = NULL; 01342 cert->extExtKeyUsageSz = 0; 01343 cert->extExtKeyUsageCount = 0; 01344 cert->extAuthKeyIdSrc = NULL; 01345 cert->extAuthKeyIdSz = 0; 01346 cert->extSubjKeyIdSrc = NULL; 01347 cert->extSubjKeyIdSz = 0; 01348 #endif /* OPENSSL_EXTRA */ 01349 #if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS) 01350 cert->extNameConstraintSet = 0; 01351 #endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */ 01352 #ifdef HAVE_ECC 01353 cert->pkCurveOID = 0; 01354 #endif /* HAVE_ECC */ 01355 #ifdef CYASSL_SEP 01356 cert->deviceTypeSz = 0; 01357 cert->deviceType = NULL; 01358 cert->hwTypeSz = 0; 01359 cert->hwType = NULL; 01360 cert->hwSerialNumSz = 0; 01361 cert->hwSerialNum = NULL; 01362 #ifdef OPENSSL_EXTRA 01363 cert->extCertPolicySet = 0; 01364 cert->extCertPolicyCrit = 0; 01365 #endif /* OPENSSL_EXTRA */ 01366 #endif /* CYASSL_SEP */ 01367 } 01368 01369 01370 void FreeAltNames(DNS_entry* altNames, void* heap) 01371 { 01372 (void)heap; 01373 01374 while (altNames) { 01375 DNS_entry* tmp = altNames->next; 01376 01377 XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME); 01378 XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME); 01379 altNames = tmp; 01380 } 01381 } 01382 01383 #ifndef IGNORE_NAME_CONSTRAINTS 01384 01385 void FreeNameSubtrees(Base_entry* names, void* heap) 01386 { 01387 (void)heap; 01388 01389 while (names) { 01390 Base_entry* tmp = names->next; 01391 01392 XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME); 01393 XFREE(names, heap, DYNAMIC_TYPE_ALTNAME); 01394 names = tmp; 01395 } 01396 } 01397 01398 #endif /* IGNORE_NAME_CONSTRAINTS */ 01399 01400 void FreeDecodedCert(DecodedCert* cert) 01401 { 01402 if (cert->subjectCNStored == 1) 01403 XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN); 01404 if (cert->pubKeyStored == 1) 01405 XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); 01406 if (cert->altNames) 01407 FreeAltNames(cert->altNames, cert->heap); 01408 #ifndef IGNORE_NAME_CONSTRAINTS 01409 if (cert->altEmailNames) 01410 FreeAltNames(cert->altEmailNames, cert->heap); 01411 if (cert->permittedNames) 01412 FreeNameSubtrees(cert->permittedNames, cert->heap); 01413 if (cert->excludedNames) 01414 FreeNameSubtrees(cert->excludedNames, cert->heap); 01415 #endif /* IGNORE_NAME_CONSTRAINTS */ 01416 #ifdef CYASSL_SEP 01417 XFREE(cert->deviceType, cert->heap, 0); 01418 XFREE(cert->hwType, cert->heap, 0); 01419 XFREE(cert->hwSerialNum, cert->heap, 0); 01420 #endif /* CYASSL_SEP */ 01421 #ifdef OPENSSL_EXTRA 01422 if (cert->issuerName.fullName != NULL) 01423 XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509); 01424 if (cert->subjectName.fullName != NULL) 01425 XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509); 01426 #endif /* OPENSSL_EXTRA */ 01427 } 01428 01429 01430 static int GetCertHeader(DecodedCert* cert) 01431 { 01432 int ret = 0, len; 01433 byte serialTmp[EXTERNAL_SERIAL_SIZE]; 01434 mp_int mpi; 01435 01436 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) 01437 return ASN_PARSE_E; 01438 01439 cert->certBegin = cert->srcIdx; 01440 01441 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) 01442 return ASN_PARSE_E; 01443 cert->sigIndex = len + cert->srcIdx; 01444 01445 if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0) 01446 return ASN_PARSE_E; 01447 01448 if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) 01449 return ASN_PARSE_E; 01450 01451 len = mp_unsigned_bin_size(&mpi); 01452 if (len < (int)sizeof(serialTmp)) { 01453 if ( (ret = mp_to_unsigned_bin(&mpi, serialTmp)) == MP_OKAY) { 01454 if (len > EXTERNAL_SERIAL_SIZE) 01455 len = EXTERNAL_SERIAL_SIZE; 01456 XMEMCPY(cert->serial, serialTmp, len); 01457 cert->serialSz = len; 01458 } 01459 } 01460 mp_clear(&mpi); 01461 return ret; 01462 } 01463 01464 #if !defined(NO_RSA) 01465 /* Store Rsa Key, may save later, Dsa could use in future */ 01466 static int StoreRsaKey(DecodedCert* cert) 01467 { 01468 int length; 01469 word32 recvd = cert->srcIdx; 01470 01471 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01472 return ASN_PARSE_E; 01473 01474 recvd = cert->srcIdx - recvd; 01475 length += recvd; 01476 01477 while (recvd--) 01478 cert->srcIdx--; 01479 01480 cert->pubKeySize = length; 01481 cert->publicKey = cert->source + cert->srcIdx; 01482 cert->srcIdx += length; 01483 01484 return 0; 01485 } 01486 #endif 01487 01488 01489 #ifdef HAVE_ECC 01490 01491 /* return 0 on sucess if the ECC curve oid sum is supported */ 01492 static int CheckCurve(word32 oid) 01493 { 01494 if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid != 01495 ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1) 01496 return ALGO_ID_E; 01497 01498 return 0; 01499 } 01500 01501 #endif /* HAVE_ECC */ 01502 01503 01504 static int GetKey(DecodedCert* cert) 01505 { 01506 int length; 01507 #ifdef HAVE_NTRU 01508 int tmpIdx = cert->srcIdx; 01509 #endif 01510 01511 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01512 return ASN_PARSE_E; 01513 01514 if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0) 01515 return ASN_PARSE_E; 01516 01517 switch (cert->keyOID) { 01518 #ifndef NO_RSA 01519 case RSAk: 01520 { 01521 byte b = cert->source[cert->srcIdx++]; 01522 if (b != ASN_BIT_STRING) 01523 return ASN_BITSTR_E; 01524 01525 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) 01526 return ASN_PARSE_E; 01527 b = cert->source[cert->srcIdx++]; 01528 if (b != 0x00) 01529 return ASN_EXPECT_0_E; 01530 01531 return StoreRsaKey(cert); 01532 } 01533 01534 #endif /* NO_RSA */ 01535 #ifdef HAVE_NTRU 01536 case NTRUk: 01537 { 01538 const byte* key = &cert->source[tmpIdx]; 01539 byte* next = (byte*)key; 01540 word16 keyLen; 01541 byte keyBlob[MAX_NTRU_KEY_SZ]; 01542 01543 word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, 01544 &keyLen, NULL, &next); 01545 01546 if (rc != NTRU_OK) 01547 return ASN_NTRU_KEY_E; 01548 if (keyLen > sizeof(keyBlob)) 01549 return ASN_NTRU_KEY_E; 01550 01551 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen, 01552 keyBlob, &next); 01553 if (rc != NTRU_OK) 01554 return ASN_NTRU_KEY_E; 01555 01556 if ( (next - key) < 0) 01557 return ASN_NTRU_KEY_E; 01558 01559 cert->srcIdx = tmpIdx + (int)(next - key); 01560 01561 cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, 01562 DYNAMIC_TYPE_PUBLIC_KEY); 01563 if (cert->publicKey == NULL) 01564 return MEMORY_E; 01565 XMEMCPY(cert->publicKey, keyBlob, keyLen); 01566 cert->pubKeyStored = 1; 01567 cert->pubKeySize = keyLen; 01568 01569 return 0; 01570 } 01571 #endif /* HAVE_NTRU */ 01572 #ifdef HAVE_ECC 01573 case ECDSAk: 01574 { 01575 int oidSz = 0; 01576 byte b = cert->source[cert->srcIdx++]; 01577 01578 if (b != ASN_OBJECT_ID) 01579 return ASN_OBJECT_ID_E; 01580 01581 if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0) 01582 return ASN_PARSE_E; 01583 01584 while(oidSz--) 01585 cert->pkCurveOID += cert->source[cert->srcIdx++]; 01586 01587 if (CheckCurve(cert->pkCurveOID) < 0) 01588 return ECC_CURVE_OID_E; 01589 01590 /* key header */ 01591 b = cert->source[cert->srcIdx++]; 01592 if (b != ASN_BIT_STRING) 01593 return ASN_BITSTR_E; 01594 01595 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) 01596 return ASN_PARSE_E; 01597 b = cert->source[cert->srcIdx++]; 01598 if (b != 0x00) 01599 return ASN_EXPECT_0_E; 01600 01601 /* actual key, use length - 1 since ate preceding 0 */ 01602 length -= 1; 01603 01604 cert->publicKey = (byte*) XMALLOC(length, cert->heap, 01605 DYNAMIC_TYPE_PUBLIC_KEY); 01606 if (cert->publicKey == NULL) 01607 return MEMORY_E; 01608 XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length); 01609 cert->pubKeyStored = 1; 01610 cert->pubKeySize = length; 01611 01612 cert->srcIdx += length; 01613 01614 return 0; 01615 } 01616 #endif /* HAVE_ECC */ 01617 default: 01618 return ASN_UNKNOWN_OID_E; 01619 } 01620 } 01621 01622 01623 /* process NAME, either issuer or subject */ 01624 static int GetName(DecodedCert* cert, int nameType) 01625 { 01626 Sha sha; /* MUST have SHA-1 hash for cert names */ 01627 int length; /* length of all distinguished names */ 01628 int dummy; 01629 int ret; 01630 char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; 01631 word32 idx; 01632 #ifdef OPENSSL_EXTRA 01633 DecodedName* dName = 01634 (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName; 01635 #endif /* OPENSSL_EXTRA */ 01636 01637 CYASSL_MSG("Getting Cert Name"); 01638 01639 if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) { 01640 CYASSL_MSG("Trying optional prefix..."); 01641 01642 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01643 return ASN_PARSE_E; 01644 01645 cert->srcIdx += length; 01646 CYASSL_MSG("Got optional prefix"); 01647 } 01648 01649 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be 01650 * calculated over the entire DER encoding of the Name field, including 01651 * the tag and length. */ 01652 idx = cert->srcIdx; 01653 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01654 return ASN_PARSE_E; 01655 01656 ret = InitSha(&sha); 01657 if (ret != 0) 01658 return ret; 01659 ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx); 01660 if (nameType == ISSUER) 01661 ShaFinal(&sha, cert->issuerHash); 01662 else 01663 ShaFinal(&sha, cert->subjectHash); 01664 01665 length += cert->srcIdx; 01666 idx = 0; 01667 01668 #ifdef HAVE_PKCS7 01669 /* store pointer to raw issuer */ 01670 if (nameType == ISSUER) { 01671 cert->issuerRaw = &cert->source[cert->srcIdx]; 01672 cert->issuerRawLen = length - cert->srcIdx; 01673 } 01674 #endif 01675 #ifndef IGNORE_NAME_CONSTRAINTS 01676 if (nameType == SUBJECT) { 01677 cert->subjectRaw = &cert->source[cert->srcIdx]; 01678 cert->subjectRawLen = length - cert->srcIdx; 01679 } 01680 #endif 01681 01682 while (cert->srcIdx < (word32)length) { 01683 byte b; 01684 byte joint[2]; 01685 byte tooBig = FALSE; 01686 int oidSz; 01687 01688 if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) { 01689 CYASSL_MSG("Cert name lacks set header, trying sequence"); 01690 } 01691 01692 if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) 01693 return ASN_PARSE_E; 01694 01695 b = cert->source[cert->srcIdx++]; 01696 if (b != ASN_OBJECT_ID) 01697 return ASN_OBJECT_ID_E; 01698 01699 if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0) 01700 return ASN_PARSE_E; 01701 01702 XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint)); 01703 01704 /* v1 name types */ 01705 if (joint[0] == 0x55 && joint[1] == 0x04) { 01706 byte id; 01707 byte copy = FALSE; 01708 int strLen; 01709 01710 cert->srcIdx += 2; 01711 id = cert->source[cert->srcIdx++]; 01712 b = cert->source[cert->srcIdx++]; /* strType */ 01713 (void)b; /* may want to validate? */ 01714 01715 if (GetLength(cert->source, &cert->srcIdx, &strLen, 01716 cert->maxIdx) < 0) 01717 return ASN_PARSE_E; 01718 01719 if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) { 01720 /* include biggest pre fix header too 4 = "/serialNumber=" */ 01721 CYASSL_MSG("ASN Name too big, skipping"); 01722 tooBig = TRUE; 01723 } 01724 01725 if (id == ASN_COMMON_NAME) { 01726 if (nameType == SUBJECT) { 01727 cert->subjectCN = (char *)&cert->source[cert->srcIdx]; 01728 cert->subjectCNLen = strLen; 01729 } 01730 01731 if (!tooBig) { 01732 XMEMCPY(&full[idx], "/CN=", 4); 01733 idx += 4; 01734 copy = TRUE; 01735 } 01736 #ifdef OPENSSL_EXTRA 01737 dName->cnIdx = cert->srcIdx; 01738 dName->cnLen = strLen; 01739 #endif /* OPENSSL_EXTRA */ 01740 } 01741 else if (id == ASN_SUR_NAME) { 01742 if (!tooBig) { 01743 XMEMCPY(&full[idx], "/SN=", 4); 01744 idx += 4; 01745 copy = TRUE; 01746 } 01747 #ifdef CYASSL_CERT_GEN 01748 if (nameType == SUBJECT) { 01749 cert->subjectSN = (char*)&cert->source[cert->srcIdx]; 01750 cert->subjectSNLen = strLen; 01751 } 01752 #endif /* CYASSL_CERT_GEN */ 01753 #ifdef OPENSSL_EXTRA 01754 dName->snIdx = cert->srcIdx; 01755 dName->snLen = strLen; 01756 #endif /* OPENSSL_EXTRA */ 01757 } 01758 else if (id == ASN_COUNTRY_NAME) { 01759 if (!tooBig) { 01760 XMEMCPY(&full[idx], "/C=", 3); 01761 idx += 3; 01762 copy = TRUE; 01763 } 01764 #ifdef CYASSL_CERT_GEN 01765 if (nameType == SUBJECT) { 01766 cert->subjectC = (char*)&cert->source[cert->srcIdx]; 01767 cert->subjectCLen = strLen; 01768 } 01769 #endif /* CYASSL_CERT_GEN */ 01770 #ifdef OPENSSL_EXTRA 01771 dName->cIdx = cert->srcIdx; 01772 dName->cLen = strLen; 01773 #endif /* OPENSSL_EXTRA */ 01774 } 01775 else if (id == ASN_LOCALITY_NAME) { 01776 if (!tooBig) { 01777 XMEMCPY(&full[idx], "/L=", 3); 01778 idx += 3; 01779 copy = TRUE; 01780 } 01781 #ifdef CYASSL_CERT_GEN 01782 if (nameType == SUBJECT) { 01783 cert->subjectL = (char*)&cert->source[cert->srcIdx]; 01784 cert->subjectLLen = strLen; 01785 } 01786 #endif /* CYASSL_CERT_GEN */ 01787 #ifdef OPENSSL_EXTRA 01788 dName->lIdx = cert->srcIdx; 01789 dName->lLen = strLen; 01790 #endif /* OPENSSL_EXTRA */ 01791 } 01792 else if (id == ASN_STATE_NAME) { 01793 if (!tooBig) { 01794 XMEMCPY(&full[idx], "/ST=", 4); 01795 idx += 4; 01796 copy = TRUE; 01797 } 01798 #ifdef CYASSL_CERT_GEN 01799 if (nameType == SUBJECT) { 01800 cert->subjectST = (char*)&cert->source[cert->srcIdx]; 01801 cert->subjectSTLen = strLen; 01802 } 01803 #endif /* CYASSL_CERT_GEN */ 01804 #ifdef OPENSSL_EXTRA 01805 dName->stIdx = cert->srcIdx; 01806 dName->stLen = strLen; 01807 #endif /* OPENSSL_EXTRA */ 01808 } 01809 else if (id == ASN_ORG_NAME) { 01810 if (!tooBig) { 01811 XMEMCPY(&full[idx], "/O=", 3); 01812 idx += 3; 01813 copy = TRUE; 01814 } 01815 #ifdef CYASSL_CERT_GEN 01816 if (nameType == SUBJECT) { 01817 cert->subjectO = (char*)&cert->source[cert->srcIdx]; 01818 cert->subjectOLen = strLen; 01819 } 01820 #endif /* CYASSL_CERT_GEN */ 01821 #ifdef OPENSSL_EXTRA 01822 dName->oIdx = cert->srcIdx; 01823 dName->oLen = strLen; 01824 #endif /* OPENSSL_EXTRA */ 01825 } 01826 else if (id == ASN_ORGUNIT_NAME) { 01827 if (!tooBig) { 01828 XMEMCPY(&full[idx], "/OU=", 4); 01829 idx += 4; 01830 copy = TRUE; 01831 } 01832 #ifdef CYASSL_CERT_GEN 01833 if (nameType == SUBJECT) { 01834 cert->subjectOU = (char*)&cert->source[cert->srcIdx]; 01835 cert->subjectOULen = strLen; 01836 } 01837 #endif /* CYASSL_CERT_GEN */ 01838 #ifdef OPENSSL_EXTRA 01839 dName->ouIdx = cert->srcIdx; 01840 dName->ouLen = strLen; 01841 #endif /* OPENSSL_EXTRA */ 01842 } 01843 else if (id == ASN_SERIAL_NUMBER) { 01844 if (!tooBig) { 01845 XMEMCPY(&full[idx], "/serialNumber=", 14); 01846 idx += 14; 01847 copy = TRUE; 01848 } 01849 #ifdef OPENSSL_EXTRA 01850 dName->snIdx = cert->srcIdx; 01851 dName->snLen = strLen; 01852 #endif /* OPENSSL_EXTRA */ 01853 } 01854 01855 if (copy && !tooBig) { 01856 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen); 01857 idx += strLen; 01858 } 01859 01860 cert->srcIdx += strLen; 01861 } 01862 else { 01863 /* skip */ 01864 byte email = FALSE; 01865 byte uid = FALSE; 01866 int adv; 01867 01868 if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */ 01869 email = TRUE; 01870 01871 if (joint[0] == 0x9 && joint[1] == 0x92) /* uid id hdr */ 01872 uid = TRUE; 01873 01874 cert->srcIdx += oidSz + 1; 01875 01876 if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0) 01877 return ASN_PARSE_E; 01878 01879 if (adv > (int)(ASN_NAME_MAX - idx)) { 01880 CYASSL_MSG("ASN name too big, skipping"); 01881 tooBig = TRUE; 01882 } 01883 01884 if (email) { 01885 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) { 01886 CYASSL_MSG("ASN name too big, skipping"); 01887 tooBig = TRUE; 01888 } 01889 if (!tooBig) { 01890 XMEMCPY(&full[idx], "/emailAddress=", 14); 01891 idx += 14; 01892 } 01893 01894 #ifdef CYASSL_CERT_GEN 01895 if (nameType == SUBJECT) { 01896 cert->subjectEmail = (char*)&cert->source[cert->srcIdx]; 01897 cert->subjectEmailLen = adv; 01898 } 01899 #endif /* CYASSL_CERT_GEN */ 01900 #ifdef OPENSSL_EXTRA 01901 dName->emailIdx = cert->srcIdx; 01902 dName->emailLen = adv; 01903 #endif /* OPENSSL_EXTRA */ 01904 #ifndef IGNORE_NAME_CONSTRAINTS 01905 { 01906 DNS_entry* emailName = NULL; 01907 01908 emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry), 01909 cert->heap, DYNAMIC_TYPE_ALTNAME); 01910 if (emailName == NULL) { 01911 CYASSL_MSG("\tOut of Memory"); 01912 return MEMORY_E; 01913 } 01914 emailName->name = (char*)XMALLOC(adv + 1, 01915 cert->heap, DYNAMIC_TYPE_ALTNAME); 01916 if (emailName->name == NULL) { 01917 CYASSL_MSG("\tOut of Memory"); 01918 return MEMORY_E; 01919 } 01920 XMEMCPY(emailName->name, 01921 &cert->source[cert->srcIdx], adv); 01922 emailName->name[adv] = 0; 01923 01924 emailName->next = cert->altEmailNames; 01925 cert->altEmailNames = emailName; 01926 } 01927 #endif /* IGNORE_NAME_CONSTRAINTS */ 01928 if (!tooBig) { 01929 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); 01930 idx += adv; 01931 } 01932 } 01933 01934 if (uid) { 01935 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) { 01936 CYASSL_MSG("ASN name too big, skipping"); 01937 tooBig = TRUE; 01938 } 01939 if (!tooBig) { 01940 XMEMCPY(&full[idx], "/UID=", 5); 01941 idx += 5; 01942 01943 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); 01944 idx += adv; 01945 } 01946 #ifdef OPENSSL_EXTRA 01947 dName->uidIdx = cert->srcIdx; 01948 dName->uidLen = adv; 01949 #endif /* OPENSSL_EXTRA */ 01950 } 01951 01952 cert->srcIdx += adv; 01953 } 01954 } 01955 full[idx++] = 0; 01956 01957 #ifdef OPENSSL_EXTRA 01958 { 01959 int totalLen = 0; 01960 01961 if (dName->cnLen != 0) 01962 totalLen += dName->cnLen + 4; 01963 if (dName->snLen != 0) 01964 totalLen += dName->snLen + 4; 01965 if (dName->cLen != 0) 01966 totalLen += dName->cLen + 3; 01967 if (dName->lLen != 0) 01968 totalLen += dName->lLen + 3; 01969 if (dName->stLen != 0) 01970 totalLen += dName->stLen + 4; 01971 if (dName->oLen != 0) 01972 totalLen += dName->oLen + 3; 01973 if (dName->ouLen != 0) 01974 totalLen += dName->ouLen + 4; 01975 if (dName->emailLen != 0) 01976 totalLen += dName->emailLen + 14; 01977 if (dName->uidLen != 0) 01978 totalLen += dName->uidLen + 5; 01979 if (dName->serialLen != 0) 01980 totalLen += dName->serialLen + 14; 01981 01982 dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509); 01983 if (dName->fullName != NULL) { 01984 idx = 0; 01985 01986 if (dName->cnLen != 0) { 01987 dName->entryCount++; 01988 XMEMCPY(&dName->fullName[idx], "/CN=", 4); 01989 idx += 4; 01990 XMEMCPY(&dName->fullName[idx], 01991 &cert->source[dName->cnIdx], dName->cnLen); 01992 dName->cnIdx = idx; 01993 idx += dName->cnLen; 01994 } 01995 if (dName->snLen != 0) { 01996 dName->entryCount++; 01997 XMEMCPY(&dName->fullName[idx], "/SN=", 4); 01998 idx += 4; 01999 XMEMCPY(&dName->fullName[idx], 02000 &cert->source[dName->snIdx], dName->snLen); 02001 dName->snIdx = idx; 02002 idx += dName->snLen; 02003 } 02004 if (dName->cLen != 0) { 02005 dName->entryCount++; 02006 XMEMCPY(&dName->fullName[idx], "/C=", 3); 02007 idx += 3; 02008 XMEMCPY(&dName->fullName[idx], 02009 &cert->source[dName->cIdx], dName->cLen); 02010 dName->cIdx = idx; 02011 idx += dName->cLen; 02012 } 02013 if (dName->lLen != 0) { 02014 dName->entryCount++; 02015 XMEMCPY(&dName->fullName[idx], "/L=", 3); 02016 idx += 3; 02017 XMEMCPY(&dName->fullName[idx], 02018 &cert->source[dName->lIdx], dName->lLen); 02019 dName->lIdx = idx; 02020 idx += dName->lLen; 02021 } 02022 if (dName->stLen != 0) { 02023 dName->entryCount++; 02024 XMEMCPY(&dName->fullName[idx], "/ST=", 4); 02025 idx += 4; 02026 XMEMCPY(&dName->fullName[idx], 02027 &cert->source[dName->stIdx], dName->stLen); 02028 dName->stIdx = idx; 02029 idx += dName->stLen; 02030 } 02031 if (dName->oLen != 0) { 02032 dName->entryCount++; 02033 XMEMCPY(&dName->fullName[idx], "/O=", 3); 02034 idx += 3; 02035 XMEMCPY(&dName->fullName[idx], 02036 &cert->source[dName->oIdx], dName->oLen); 02037 dName->oIdx = idx; 02038 idx += dName->oLen; 02039 } 02040 if (dName->ouLen != 0) { 02041 dName->entryCount++; 02042 XMEMCPY(&dName->fullName[idx], "/OU=", 4); 02043 idx += 4; 02044 XMEMCPY(&dName->fullName[idx], 02045 &cert->source[dName->ouIdx], dName->ouLen); 02046 dName->ouIdx = idx; 02047 idx += dName->ouLen; 02048 } 02049 if (dName->emailLen != 0) { 02050 dName->entryCount++; 02051 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14); 02052 idx += 14; 02053 XMEMCPY(&dName->fullName[idx], 02054 &cert->source[dName->emailIdx], dName->emailLen); 02055 dName->emailIdx = idx; 02056 idx += dName->emailLen; 02057 } 02058 if (dName->uidLen != 0) { 02059 dName->entryCount++; 02060 XMEMCPY(&dName->fullName[idx], "/UID=", 5); 02061 idx += 5; 02062 XMEMCPY(&dName->fullName[idx], 02063 &cert->source[dName->uidIdx], dName->uidLen); 02064 dName->uidIdx = idx; 02065 idx += dName->uidLen; 02066 } 02067 if (dName->serialLen != 0) { 02068 dName->entryCount++; 02069 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14); 02070 idx += 14; 02071 XMEMCPY(&dName->fullName[idx], 02072 &cert->source[dName->serialIdx], dName->serialLen); 02073 dName->serialIdx = idx; 02074 idx += dName->serialLen; 02075 } 02076 dName->fullName[idx] = '\0'; 02077 dName->fullNameLen = totalLen; 02078 } 02079 } 02080 #endif /* OPENSSL_EXTRA */ 02081 02082 return 0; 02083 } 02084 02085 02086 #ifndef NO_TIME_H 02087 02088 /* to the second */ 02089 static int DateGreaterThan(const struct tm* a, const struct tm* b) 02090 { 02091 if (a->tm_year > b->tm_year) 02092 return 1; 02093 02094 if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon) 02095 return 1; 02096 02097 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02098 a->tm_mday > b->tm_mday) 02099 return 1; 02100 02101 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02102 a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour) 02103 return 1; 02104 02105 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02106 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && 02107 a->tm_min > b->tm_min) 02108 return 1; 02109 02110 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02111 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && 02112 a->tm_min == b->tm_min && a->tm_sec > b->tm_sec) 02113 return 1; 02114 02115 return 0; /* false */ 02116 } 02117 02118 02119 static INLINE int DateLessThan(const struct tm* a, const struct tm* b) 02120 { 02121 return !DateGreaterThan(a,b); 02122 } 02123 02124 02125 /* like atoi but only use first byte */ 02126 /* Make sure before and after dates are valid */ 02127 int ValidateDate(const byte* date, byte format, int dateType) 02128 { 02129 time_t ltime; 02130 struct tm certTime; 02131 struct tm* localTime; 02132 int i = 0; 02133 02134 ltime = XTIME(0); 02135 XMEMSET(&certTime, 0, sizeof(certTime)); 02136 02137 if (format == ASN_UTC_TIME) { 02138 if (btoi(date[0]) >= 5) 02139 certTime.tm_year = 1900; 02140 else 02141 certTime.tm_year = 2000; 02142 } 02143 else { /* format == GENERALIZED_TIME */ 02144 certTime.tm_year += btoi(date[i++]) * 1000; 02145 certTime.tm_year += btoi(date[i++]) * 100; 02146 } 02147 02148 GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */ 02149 GetTime(&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; /* adjust */ 02150 GetTime(&certTime.tm_mday, date, &i); 02151 GetTime(&certTime.tm_hour, date, &i); 02152 GetTime(&certTime.tm_min, date, &i); 02153 GetTime(&certTime.tm_sec, date, &i); 02154 02155 if (date[i] != 'Z') { /* only Zulu supported for this profile */ 02156 CYASSL_MSG("Only Zulu time supported for this profile"); 02157 return 0; 02158 } 02159 02160 localTime = XGMTIME(<ime); 02161 02162 if (dateType == BEFORE) { 02163 if (DateLessThan(localTime, &certTime)) 02164 return 0; 02165 } 02166 else 02167 if (DateGreaterThan(localTime, &certTime)) 02168 return 0; 02169 02170 return 1; 02171 } 02172 02173 #endif /* NO_TIME_H */ 02174 02175 02176 static int GetDate(DecodedCert* cert, int dateType) 02177 { 02178 int length; 02179 byte date[MAX_DATE_SIZE]; 02180 byte b; 02181 word32 startIdx = 0; 02182 02183 if (dateType == BEFORE) 02184 cert->beforeDate = &cert->source[cert->srcIdx]; 02185 else 02186 cert->afterDate = &cert->source[cert->srcIdx]; 02187 startIdx = cert->srcIdx; 02188 02189 b = cert->source[cert->srcIdx++]; 02190 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) 02191 return ASN_TIME_E; 02192 02193 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02194 return ASN_PARSE_E; 02195 02196 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) 02197 return ASN_DATE_SZ_E; 02198 02199 XMEMCPY(date, &cert->source[cert->srcIdx], length); 02200 cert->srcIdx += length; 02201 02202 if (dateType == BEFORE) 02203 cert->beforeDateLen = cert->srcIdx - startIdx; 02204 else 02205 cert->afterDateLen = cert->srcIdx - startIdx; 02206 02207 if (!XVALIDATE_DATE(date, b, dateType)) { 02208 if (dateType == BEFORE) 02209 return ASN_BEFORE_DATE_E; 02210 else 02211 return ASN_AFTER_DATE_E; 02212 } 02213 02214 return 0; 02215 } 02216 02217 02218 static int GetValidity(DecodedCert* cert, int verify) 02219 { 02220 int length; 02221 int badDate = 0; 02222 02223 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02224 return ASN_PARSE_E; 02225 02226 if (GetDate(cert, BEFORE) < 0 && verify) 02227 badDate = ASN_BEFORE_DATE_E; /* continue parsing */ 02228 02229 if (GetDate(cert, AFTER) < 0 && verify) 02230 return ASN_AFTER_DATE_E; 02231 02232 if (badDate != 0) 02233 return badDate; 02234 02235 return 0; 02236 } 02237 02238 02239 int DecodeToKey(DecodedCert* cert, int verify) 02240 { 02241 int badDate = 0; 02242 int ret; 02243 02244 if ( (ret = GetCertHeader(cert)) < 0) 02245 return ret; 02246 02247 CYASSL_MSG("Got Cert Header"); 02248 02249 if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, 02250 cert->maxIdx)) < 0) 02251 return ret; 02252 02253 CYASSL_MSG("Got Algo ID"); 02254 02255 if ( (ret = GetName(cert, ISSUER)) < 0) 02256 return ret; 02257 02258 if ( (ret = GetValidity(cert, verify)) < 0) 02259 badDate = ret; 02260 02261 if ( (ret = GetName(cert, SUBJECT)) < 0) 02262 return ret; 02263 02264 CYASSL_MSG("Got Subject Name"); 02265 02266 if ( (ret = GetKey(cert)) < 0) 02267 return ret; 02268 02269 CYASSL_MSG("Got Key"); 02270 02271 if (badDate != 0) 02272 return badDate; 02273 02274 return ret; 02275 } 02276 02277 02278 static int GetSignature(DecodedCert* cert) 02279 { 02280 int length; 02281 byte b = cert->source[cert->srcIdx++]; 02282 02283 if (b != ASN_BIT_STRING) 02284 return ASN_BITSTR_E; 02285 02286 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02287 return ASN_PARSE_E; 02288 02289 cert->sigLength = length; 02290 02291 b = cert->source[cert->srcIdx++]; 02292 if (b != 0x00) 02293 return ASN_EXPECT_0_E; 02294 02295 cert->sigLength--; 02296 cert->signature = &cert->source[cert->srcIdx]; 02297 cert->srcIdx += cert->sigLength; 02298 02299 return 0; 02300 } 02301 02302 02303 static word32 SetDigest(const byte* digest, word32 digSz, byte* output) 02304 { 02305 output[0] = ASN_OCTET_STRING; 02306 output[1] = (byte)digSz; 02307 XMEMCPY(&output[2], digest, digSz); 02308 02309 return digSz + 2; 02310 } 02311 02312 02313 static word32 BytePrecision(word32 value) 02314 { 02315 word32 i; 02316 for (i = sizeof(value); i; --i) 02317 if (value >> ((i - 1) * CYASSL_BIT_SIZE)) 02318 break; 02319 02320 return i; 02321 } 02322 02323 02324 CYASSL_LOCAL word32 SetLength(word32 length, byte* output) 02325 { 02326 word32 i = 0, j; 02327 02328 if (length < ASN_LONG_LENGTH) 02329 output[i++] = (byte)length; 02330 else { 02331 output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH); 02332 02333 for (j = BytePrecision(length); j; --j) { 02334 output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE)); 02335 i++; 02336 } 02337 } 02338 02339 return i; 02340 } 02341 02342 02343 CYASSL_LOCAL word32 SetSequence(word32 len, byte* output) 02344 { 02345 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED; 02346 return SetLength(len, output + 1) + 1; 02347 } 02348 02349 CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output) 02350 { 02351 output[0] = ASN_OCTET_STRING; 02352 return SetLength(len, output + 1) + 1; 02353 } 02354 02355 /* Write a set header to output */ 02356 CYASSL_LOCAL word32 SetSet(word32 len, byte* output) 02357 { 02358 output[0] = ASN_SET | ASN_CONSTRUCTED; 02359 return SetLength(len, output + 1) + 1; 02360 } 02361 02362 CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output) 02363 { 02364 02365 output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0) 02366 | ASN_CONTEXT_SPECIFIC | number; 02367 return SetLength(len, output + 1) + 1; 02368 } 02369 02370 CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output) 02371 { 02372 output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; 02373 return SetLength(len, output + 1) + 1; 02374 } 02375 02376 02377 #if defined(HAVE_ECC) && defined(CYASSL_CERT_GEN) 02378 02379 static word32 SetCurve(ecc_key* key, byte* output) 02380 { 02381 02382 /* curve types */ 02383 static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02384 0x03, 0x01, 0x01}; 02385 static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02386 0x03, 0x01, 0x07}; 02387 static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02388 0x02}; 02389 static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02390 0x21}; 02391 static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02392 0x22}; 02393 static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02394 0x23}; 02395 02396 int oidSz = 0; 02397 int idx = 0; 02398 int lenSz = 0; 02399 const byte* oid = 0; 02400 02401 output[0] = ASN_OBJECT_ID; 02402 idx++; 02403 02404 switch (key->dp->size) { 02405 case 20: 02406 oidSz = sizeof(ECC_160r1_AlgoID); 02407 oid = ECC_160r1_AlgoID; 02408 break; 02409 02410 case 24: 02411 oidSz = sizeof(ECC_192v1_AlgoID); 02412 oid = ECC_192v1_AlgoID; 02413 break; 02414 02415 case 28: 02416 oidSz = sizeof(ECC_224r1_AlgoID); 02417 oid = ECC_224r1_AlgoID; 02418 break; 02419 02420 case 32: 02421 oidSz = sizeof(ECC_256v1_AlgoID); 02422 oid = ECC_256v1_AlgoID; 02423 break; 02424 02425 case 48: 02426 oidSz = sizeof(ECC_384r1_AlgoID); 02427 oid = ECC_384r1_AlgoID; 02428 break; 02429 02430 case 66: 02431 oidSz = sizeof(ECC_521r1_AlgoID); 02432 oid = ECC_521r1_AlgoID; 02433 break; 02434 02435 default: 02436 return ASN_UNKNOWN_OID_E; 02437 } 02438 lenSz = SetLength(oidSz, output+idx); 02439 idx += lenSz; 02440 02441 XMEMCPY(output+idx, oid, oidSz); 02442 idx += oidSz; 02443 02444 return idx; 02445 } 02446 02447 #endif /* HAVE_ECC && CYASSL_CERT_GEN */ 02448 02449 02450 CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz) 02451 { 02452 /* adding TAG_NULL and 0 to end */ 02453 02454 /* hashTypes */ 02455 static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a, 02456 0x05, 0x00 }; 02457 static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02458 0x04, 0x02, 0x01, 0x05, 0x00 }; 02459 static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02460 0x04, 0x02, 0x02, 0x05, 0x00 }; 02461 static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02462 0x04, 0x02, 0x03, 0x05, 0x00 }; 02463 static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02464 0x02, 0x05, 0x05, 0x00 }; 02465 static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02466 0x02, 0x02, 0x05, 0x00}; 02467 02468 /* blkTypes, no NULL tags because IV is there instead */ 02469 static const byte desCbcAlgoID[] = { 0x2B, 0x0E, 0x03, 0x02, 0x07 }; 02470 static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 02471 0x0D, 0x03, 0x07 }; 02472 02473 /* RSA sigTypes */ 02474 #ifndef NO_RSA 02475 static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02476 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00}; 02477 static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02478 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00}; 02479 static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02480 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00}; 02481 static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 02482 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00}; 02483 static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 02484 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00}; 02485 #endif /* NO_RSA */ 02486 02487 /* ECDSA sigTypes */ 02488 #ifdef HAVE_ECC 02489 static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02490 0x04, 0x01, 0x05, 0x00}; 02491 static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02492 0x04, 0x03, 0x02, 0x05, 0x00}; 02493 static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02494 0x04, 0x03, 0x03, 0x05, 0x00}; 02495 static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02496 0x04, 0x03, 0x04, 0x05, 0x00}; 02497 #endif /* HAVE_ECC */ 02498 02499 /* RSA keyType */ 02500 #ifndef NO_RSA 02501 static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02502 0x01, 0x01, 0x01, 0x05, 0x00}; 02503 #endif /* NO_RSA */ 02504 02505 #ifdef HAVE_ECC 02506 /* ECC keyType */ 02507 /* no tags, so set tagSz smaller later */ 02508 static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02509 0x02, 0x01}; 02510 #endif /* HAVE_ECC */ 02511 02512 int algoSz = 0; 02513 int tagSz = 2; /* tag null and terminator */ 02514 word32 idSz, seqSz; 02515 const byte* algoName = 0; 02516 byte ID_Length[MAX_LENGTH_SZ]; 02517 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */ 02518 02519 if (type == hashType) { 02520 switch (algoOID) { 02521 case SHAh: 02522 algoSz = sizeof(shaAlgoID); 02523 algoName = shaAlgoID; 02524 break; 02525 02526 case SHA256h: 02527 algoSz = sizeof(sha256AlgoID); 02528 algoName = sha256AlgoID; 02529 break; 02530 02531 case SHA384h: 02532 algoSz = sizeof(sha384AlgoID); 02533 algoName = sha384AlgoID; 02534 break; 02535 02536 case SHA512h: 02537 algoSz = sizeof(sha512AlgoID); 02538 algoName = sha512AlgoID; 02539 break; 02540 02541 case MD2h: 02542 algoSz = sizeof(md2AlgoID); 02543 algoName = md2AlgoID; 02544 break; 02545 02546 case MD5h: 02547 algoSz = sizeof(md5AlgoID); 02548 algoName = md5AlgoID; 02549 break; 02550 02551 default: 02552 CYASSL_MSG("Unknown Hash Algo"); 02553 return 0; /* UNKOWN_HASH_E; */ 02554 } 02555 } 02556 else if (type == blkType) { 02557 switch (algoOID) { 02558 case DESb: 02559 algoSz = sizeof(desCbcAlgoID); 02560 algoName = desCbcAlgoID; 02561 tagSz = 0; 02562 break; 02563 case DES3b: 02564 algoSz = sizeof(des3CbcAlgoID); 02565 algoName = des3CbcAlgoID; 02566 tagSz = 0; 02567 break; 02568 default: 02569 CYASSL_MSG("Unknown Block Algo"); 02570 return 0; 02571 } 02572 } 02573 else if (type == sigType) { /* sigType */ 02574 switch (algoOID) { 02575 #ifndef NO_RSA 02576 case CTC_MD5wRSA: 02577 algoSz = sizeof(md5wRSA_AlgoID); 02578 algoName = md5wRSA_AlgoID; 02579 break; 02580 02581 case CTC_SHAwRSA: 02582 algoSz = sizeof(shawRSA_AlgoID); 02583 algoName = shawRSA_AlgoID; 02584 break; 02585 02586 case CTC_SHA256wRSA: 02587 algoSz = sizeof(sha256wRSA_AlgoID); 02588 algoName = sha256wRSA_AlgoID; 02589 break; 02590 02591 case CTC_SHA384wRSA: 02592 algoSz = sizeof(sha384wRSA_AlgoID); 02593 algoName = sha384wRSA_AlgoID; 02594 break; 02595 02596 case CTC_SHA512wRSA: 02597 algoSz = sizeof(sha512wRSA_AlgoID); 02598 algoName = sha512wRSA_AlgoID; 02599 break; 02600 #endif /* NO_RSA */ 02601 #ifdef HAVE_ECC 02602 case CTC_SHAwECDSA: 02603 algoSz = sizeof(shawECDSA_AlgoID); 02604 algoName = shawECDSA_AlgoID; 02605 break; 02606 02607 case CTC_SHA256wECDSA: 02608 algoSz = sizeof(sha256wECDSA_AlgoID); 02609 algoName = sha256wECDSA_AlgoID; 02610 break; 02611 02612 case CTC_SHA384wECDSA: 02613 algoSz = sizeof(sha384wECDSA_AlgoID); 02614 algoName = sha384wECDSA_AlgoID; 02615 break; 02616 02617 case CTC_SHA512wECDSA: 02618 algoSz = sizeof(sha512wECDSA_AlgoID); 02619 algoName = sha512wECDSA_AlgoID; 02620 break; 02621 #endif /* HAVE_ECC */ 02622 default: 02623 CYASSL_MSG("Unknown Signature Algo"); 02624 return 0; 02625 } 02626 } 02627 else if (type == keyType) { /* keyType */ 02628 switch (algoOID) { 02629 #ifndef NO_RSA 02630 case RSAk: 02631 algoSz = sizeof(RSA_AlgoID); 02632 algoName = RSA_AlgoID; 02633 break; 02634 #endif /* NO_RSA */ 02635 #ifdef HAVE_ECC 02636 case ECDSAk: 02637 algoSz = sizeof(ECC_AlgoID); 02638 algoName = ECC_AlgoID; 02639 tagSz = 0; 02640 break; 02641 #endif /* HAVE_ECC */ 02642 default: 02643 CYASSL_MSG("Unknown Key Algo"); 02644 return 0; 02645 } 02646 } 02647 else { 02648 CYASSL_MSG("Unknown Algo type"); 02649 return 0; 02650 } 02651 02652 idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */ 02653 seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray); 02654 /* +1 for object id, curveID of curveSz follows for ecc */ 02655 seqArray[seqSz++] = ASN_OBJECT_ID; 02656 02657 XMEMCPY(output, seqArray, seqSz); 02658 XMEMCPY(output + seqSz, ID_Length, idSz); 02659 XMEMCPY(output + seqSz + idSz, algoName, algoSz); 02660 02661 return seqSz + idSz + algoSz; 02662 02663 } 02664 02665 02666 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) 02667 { 02668 byte digArray[MAX_ENCODED_DIG_SZ]; 02669 byte algoArray[MAX_ALGO_SZ]; 02670 byte seqArray[MAX_SEQ_SZ]; 02671 word32 encDigSz, algoSz, seqSz; 02672 02673 encDigSz = SetDigest(digest, digSz, digArray); 02674 algoSz = SetAlgoID(hashOID, algoArray, hashType, 0); 02675 seqSz = SetSequence(encDigSz + algoSz, seqArray); 02676 02677 XMEMCPY(out, seqArray, seqSz); 02678 XMEMCPY(out + seqSz, algoArray, algoSz); 02679 XMEMCPY(out + seqSz + algoSz, digArray, encDigSz); 02680 02681 return encDigSz + algoSz + seqSz; 02682 } 02683 02684 02685 /* return true (1) for Confirmation */ 02686 static int ConfirmSignature(const byte* buf, word32 bufSz, 02687 const byte* key, word32 keySz, word32 keyOID, 02688 const byte* sig, word32 sigSz, word32 sigOID, 02689 void* heap) 02690 { 02691 #ifdef CYASSL_SHA512 02692 byte digest[SHA512_DIGEST_SIZE]; /* max size */ 02693 #elif !defined(NO_SHA256) 02694 byte digest[SHA256_DIGEST_SIZE]; /* max size */ 02695 #else 02696 byte digest[SHA_DIGEST_SIZE]; /* max size */ 02697 #endif 02698 int typeH, digestSz, ret = 0; 02699 02700 (void)key; 02701 (void)keySz; 02702 (void)sig; 02703 (void)sigSz; 02704 (void)heap; 02705 (void)ret; 02706 02707 switch (sigOID) { 02708 #ifndef NO_MD5 02709 case CTC_MD5wRSA: 02710 { 02711 Md5 md5; 02712 InitMd5(&md5); 02713 Md5Update(&md5, buf, bufSz); 02714 Md5Final(&md5, digest); 02715 typeH = MD5h; 02716 digestSz = MD5_DIGEST_SIZE; 02717 } 02718 break; 02719 #endif 02720 #if defined(CYASSL_MD2) 02721 case CTC_MD2wRSA: 02722 { 02723 Md2 md2; 02724 InitMd2(&md2); 02725 Md2Update(&md2, buf, bufSz); 02726 Md2Final(&md2, digest); 02727 typeH = MD2h; 02728 digestSz = MD2_DIGEST_SIZE; 02729 } 02730 break; 02731 #endif 02732 #ifndef NO_SHA 02733 case CTC_SHAwRSA: 02734 case CTC_SHAwDSA: 02735 case CTC_SHAwECDSA: 02736 { 02737 Sha sha; 02738 ret = InitSha(&sha); 02739 if (ret != 0) { 02740 CYASSL_MSG("InitSha failed"); 02741 return 0; /* not confirmed */ 02742 } 02743 ShaUpdate(&sha, buf, bufSz); 02744 ShaFinal(&sha, digest); 02745 typeH = SHAh; 02746 digestSz = SHA_DIGEST_SIZE; 02747 } 02748 break; 02749 #endif 02750 #ifndef NO_SHA256 02751 case CTC_SHA256wRSA: 02752 case CTC_SHA256wECDSA: 02753 { 02754 Sha256 sha256; 02755 ret = InitSha256(&sha256); 02756 if (ret != 0) { 02757 CYASSL_MSG("InitSha256 failed"); 02758 return 0; /* not confirmed */ 02759 } 02760 02761 ret = Sha256Update(&sha256, buf, bufSz); 02762 if (ret != 0) { 02763 CYASSL_MSG("Sha256Update failed"); 02764 return 0; /* not confirmed */ 02765 } 02766 02767 ret = Sha256Final(&sha256, digest); 02768 if (ret != 0) { 02769 CYASSL_MSG("Sha256Final failed"); 02770 return 0; /* not confirmed */ 02771 } 02772 02773 typeH = SHA256h; 02774 digestSz = SHA256_DIGEST_SIZE; 02775 } 02776 break; 02777 #endif 02778 #ifdef CYASSL_SHA512 02779 case CTC_SHA512wRSA: 02780 case CTC_SHA512wECDSA: 02781 { 02782 Sha512 sha512; 02783 ret = InitSha512(&sha512); 02784 if (ret != 0) { 02785 CYASSL_MSG("InitSha512 failed"); 02786 return 0; /* not confirmed */ 02787 } 02788 02789 ret = Sha512Update(&sha512, buf, bufSz); 02790 if (ret != 0) { 02791 CYASSL_MSG("Sha512Update failed"); 02792 return 0; /* not confirmed */ 02793 } 02794 02795 ret = Sha512Final(&sha512, digest); 02796 if (ret != 0) { 02797 CYASSL_MSG("Sha512Final failed"); 02798 return 0; /* not confirmed */ 02799 } 02800 02801 typeH = SHA512h; 02802 digestSz = SHA512_DIGEST_SIZE; 02803 } 02804 break; 02805 #endif 02806 #ifdef CYASSL_SHA384 02807 case CTC_SHA384wRSA: 02808 case CTC_SHA384wECDSA: 02809 { 02810 Sha384 sha384; 02811 ret = InitSha384(&sha384); 02812 if (ret != 0) { 02813 CYASSL_MSG("InitSha384 failed"); 02814 return 0; /* not confirmed */ 02815 } 02816 02817 ret = Sha384Update(&sha384, buf, bufSz); 02818 if (ret != 0) { 02819 CYASSL_MSG("Sha384Update failed"); 02820 return 0; /* not confirmed */ 02821 } 02822 02823 ret = Sha384Final(&sha384, digest); 02824 if (ret != 0) { 02825 CYASSL_MSG("Sha384Final failed"); 02826 return 0; /* not confirmed */ 02827 } 02828 02829 typeH = SHA384h; 02830 digestSz = SHA384_DIGEST_SIZE; 02831 } 02832 break; 02833 #endif 02834 default: 02835 CYASSL_MSG("Verify Signautre has unsupported type"); 02836 return 0; 02837 } 02838 (void)typeH; /* some builds won't read */ 02839 02840 switch (keyOID) { 02841 #ifndef NO_RSA 02842 case RSAk: 02843 { 02844 RsaKey pubKey; 02845 byte encodedSig[MAX_ENCODED_SIG_SZ]; 02846 byte plain[MAX_ENCODED_SIG_SZ]; 02847 word32 idx = 0; 02848 int encodedSigSz, verifySz; 02849 byte* out; 02850 02851 if (sigSz > MAX_ENCODED_SIG_SZ) { 02852 CYASSL_MSG("Verify Signautre is too big"); 02853 return 0; 02854 } 02855 02856 ret = InitRsaKey(&pubKey, heap); 02857 if (ret != 0) return ret; 02858 if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { 02859 CYASSL_MSG("ASN Key decode error RSA"); 02860 ret = 0; 02861 } 02862 else { 02863 XMEMCPY(plain, sig, sigSz); 02864 if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, 02865 &pubKey)) < 0) { 02866 CYASSL_MSG("Rsa SSL verify error"); 02867 ret = 0; 02868 } 02869 else { 02870 /* make sure we're right justified */ 02871 encodedSigSz = 02872 EncodeSignature(encodedSig, digest, digestSz, typeH); 02873 if (encodedSigSz != verifySz || 02874 XMEMCMP(out, encodedSig, encodedSigSz) != 0) { 02875 CYASSL_MSG("Rsa SSL verify match encode error"); 02876 ret = 0; 02877 } 02878 else 02879 ret = 1; /* match */ 02880 02881 #ifdef CYASSL_DEBUG_ENCODING 02882 { 02883 int x; 02884 printf("cyassl encodedSig:\n"); 02885 for (x = 0; x < encodedSigSz; x++) { 02886 printf("%02x ", encodedSig[x]); 02887 if ( (x % 16) == 15) 02888 printf("\n"); 02889 } 02890 printf("\n"); 02891 printf("actual digest:\n"); 02892 for (x = 0; x < verifySz; x++) { 02893 printf("%02x ", out[x]); 02894 if ( (x % 16) == 15) 02895 printf("\n"); 02896 } 02897 printf("\n"); 02898 } 02899 #endif /* CYASSL_DEBUG_ENCODING */ 02900 } 02901 } 02902 FreeRsaKey(&pubKey); 02903 return ret; 02904 } 02905 02906 #endif /* NO_RSA */ 02907 #ifdef HAVE_ECC 02908 case ECDSAk: 02909 { 02910 ecc_key pubKey; 02911 int verify = 0; 02912 02913 if (ecc_import_x963(key, keySz, &pubKey) < 0) { 02914 CYASSL_MSG("ASN Key import error ECC"); 02915 return 0; 02916 } 02917 02918 ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey); 02919 ecc_free(&pubKey); 02920 if (ret == 0 && verify == 1) 02921 return 1; /* match */ 02922 02923 CYASSL_MSG("ECC Verify didn't match"); 02924 return 0; 02925 } 02926 #endif /* HAVE_ECC */ 02927 default: 02928 CYASSL_MSG("Verify Key type unknown"); 02929 return 0; 02930 } 02931 } 02932 02933 02934 #ifndef IGNORE_NAME_CONSTRAINTS 02935 02936 static int MatchBaseName(int type, const char* name, int nameSz, 02937 const char* base, int baseSz) 02938 { 02939 if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 || 02940 name[0] == '.' || nameSz < baseSz || 02941 (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE)) 02942 return 0; 02943 02944 /* If an email type, handle special cases where the base is only 02945 * a domain, or is an email address itself. */ 02946 if (type == ASN_RFC822_TYPE) { 02947 const char* p = NULL; 02948 int count = 0; 02949 02950 if (base[0] != '.') { 02951 p = base; 02952 count = 0; 02953 02954 /* find the '@' in the base */ 02955 while (*p != '@' && count < baseSz) { 02956 count++; 02957 p++; 02958 } 02959 02960 /* No '@' in base, reset p to NULL */ 02961 if (count >= baseSz) 02962 p = NULL; 02963 } 02964 02965 if (p == NULL) { 02966 /* Base isn't an email address, it is a domain name, 02967 * wind the name forward one character past its '@'. */ 02968 p = name; 02969 count = 0; 02970 while (*p != '@' && count < baseSz) { 02971 count++; 02972 p++; 02973 } 02974 02975 if (count < baseSz && *p == '@') { 02976 name = p + 1; 02977 nameSz -= count + 1; 02978 } 02979 } 02980 } 02981 02982 if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') { 02983 int szAdjust = nameSz - baseSz; 02984 name += szAdjust; 02985 nameSz -= szAdjust; 02986 } 02987 02988 while (nameSz > 0) { 02989 if (XTOLOWER(*name++) != XTOLOWER(*base++)) 02990 return 0; 02991 nameSz--; 02992 } 02993 02994 return 1; 02995 } 02996 02997 02998 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) 02999 { 03000 if (signer == NULL || cert == NULL) 03001 return 0; 03002 03003 /* Check against the excluded list */ 03004 if (signer->excludedNames) { 03005 Base_entry* base = signer->excludedNames; 03006 03007 while (base != NULL) { 03008 if (base->type == ASN_DNS_TYPE) { 03009 DNS_entry* name = cert->altNames; 03010 while (name != NULL) { 03011 if (MatchBaseName(ASN_DNS_TYPE, 03012 name->name, (int)XSTRLEN(name->name), 03013 base->name, base->nameSz)) 03014 return 0; 03015 name = name->next; 03016 } 03017 } 03018 else if (base->type == ASN_RFC822_TYPE) { 03019 DNS_entry* name = cert->altEmailNames; 03020 while (name != NULL) { 03021 if (MatchBaseName(ASN_RFC822_TYPE, 03022 name->name, (int)XSTRLEN(name->name), 03023 base->name, base->nameSz)) 03024 return 0; 03025 03026 name = name->next; 03027 } 03028 } 03029 else if (base->type == ASN_DIR_TYPE) { 03030 if (cert->subjectRawLen == base->nameSz && 03031 XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { 03032 03033 return 0; 03034 } 03035 } 03036 base = base->next; 03037 } 03038 } 03039 03040 /* Check against the permitted list */ 03041 if (signer->permittedNames != NULL) { 03042 int needDns = 0; 03043 int matchDns = 0; 03044 int needEmail = 0; 03045 int matchEmail = 0; 03046 int needDir = 0; 03047 int matchDir = 0; 03048 Base_entry* base = signer->permittedNames; 03049 03050 while (base != NULL) { 03051 if (base->type == ASN_DNS_TYPE) { 03052 DNS_entry* name = cert->altNames; 03053 03054 if (name != NULL) 03055 needDns = 1; 03056 03057 while (name != NULL) { 03058 matchDns = MatchBaseName(ASN_DNS_TYPE, 03059 name->name, (int)XSTRLEN(name->name), 03060 base->name, base->nameSz); 03061 name = name->next; 03062 } 03063 } 03064 else if (base->type == ASN_RFC822_TYPE) { 03065 DNS_entry* name = cert->altEmailNames; 03066 03067 if (name != NULL) 03068 needEmail = 1; 03069 03070 while (name != NULL) { 03071 matchEmail = MatchBaseName(ASN_DNS_TYPE, 03072 name->name, (int)XSTRLEN(name->name), 03073 base->name, base->nameSz); 03074 name = name->next; 03075 } 03076 } 03077 else if (base->type == ASN_DIR_TYPE) { 03078 needDir = 1; 03079 if (cert->subjectRaw != NULL && 03080 cert->subjectRawLen == base->nameSz && 03081 XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { 03082 03083 matchDir = 1; 03084 } 03085 } 03086 base = base->next; 03087 } 03088 03089 if ((needDns && !matchDns) || (needEmail && !matchEmail) || 03090 (needDir && !matchDir)) { 03091 03092 return 0; 03093 } 03094 } 03095 03096 return 1; 03097 } 03098 03099 #endif /* IGNORE_NAME_CONSTRAINTS */ 03100 03101 03102 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert) 03103 { 03104 word32 idx = 0; 03105 int length = 0; 03106 03107 CYASSL_ENTER("DecodeAltNames"); 03108 03109 if (GetSequence(input, &idx, &length, sz) < 0) { 03110 CYASSL_MSG("\tBad Sequence"); 03111 return ASN_PARSE_E; 03112 } 03113 03114 while (length > 0) { 03115 byte b = input[idx++]; 03116 03117 length--; 03118 03119 /* Save DNS Type names in the altNames list. */ 03120 /* Save Other Type names in the cert's OidMap */ 03121 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) { 03122 DNS_entry* dnsEntry; 03123 int strLen; 03124 word32 lenStartIdx = idx; 03125 03126 if (GetLength(input, &idx, &strLen, sz) < 0) { 03127 CYASSL_MSG("\tfail: str length"); 03128 return ASN_PARSE_E; 03129 } 03130 length -= (idx - lenStartIdx); 03131 03132 dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, 03133 DYNAMIC_TYPE_ALTNAME); 03134 if (dnsEntry == NULL) { 03135 CYASSL_MSG("\tOut of Memory"); 03136 return ASN_PARSE_E; 03137 } 03138 03139 dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, 03140 DYNAMIC_TYPE_ALTNAME); 03141 if (dnsEntry->name == NULL) { 03142 CYASSL_MSG("\tOut of Memory"); 03143 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); 03144 return ASN_PARSE_E; 03145 } 03146 03147 XMEMCPY(dnsEntry->name, &input[idx], strLen); 03148 dnsEntry->name[strLen] = '\0'; 03149 03150 dnsEntry->next = cert->altNames; 03151 cert->altNames = dnsEntry; 03152 03153 length -= strLen; 03154 idx += strLen; 03155 } 03156 #ifndef IGNORE_NAME_CONSTRAINTS 03157 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) { 03158 DNS_entry* emailEntry; 03159 int strLen; 03160 word32 lenStartIdx = idx; 03161 03162 if (GetLength(input, &idx, &strLen, sz) < 0) { 03163 CYASSL_MSG("\tfail: str length"); 03164 return ASN_PARSE_E; 03165 } 03166 length -= (idx - lenStartIdx); 03167 03168 emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, 03169 DYNAMIC_TYPE_ALTNAME); 03170 if (emailEntry == NULL) { 03171 CYASSL_MSG("\tOut of Memory"); 03172 return ASN_PARSE_E; 03173 } 03174 03175 emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, 03176 DYNAMIC_TYPE_ALTNAME); 03177 if (emailEntry->name == NULL) { 03178 CYASSL_MSG("\tOut of Memory"); 03179 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); 03180 return ASN_PARSE_E; 03181 } 03182 03183 XMEMCPY(emailEntry->name, &input[idx], strLen); 03184 emailEntry->name[strLen] = '\0'; 03185 03186 emailEntry->next = cert->altEmailNames; 03187 cert->altEmailNames = emailEntry; 03188 03189 length -= strLen; 03190 idx += strLen; 03191 } 03192 #endif /* IGNORE_NAME_CONSTRAINTS */ 03193 #ifdef CYASSL_SEP 03194 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) 03195 { 03196 int strLen; 03197 word32 lenStartIdx = idx; 03198 word32 oid = 0; 03199 03200 if (GetLength(input, &idx, &strLen, sz) < 0) { 03201 CYASSL_MSG("\tfail: other name length"); 03202 return ASN_PARSE_E; 03203 } 03204 /* Consume the rest of this sequence. */ 03205 length -= (strLen + idx - lenStartIdx); 03206 03207 if (GetObjectId(input, &idx, &oid, sz) < 0) { 03208 CYASSL_MSG("\tbad OID"); 03209 return ASN_PARSE_E; 03210 } 03211 03212 if (oid != HW_NAME_OID) { 03213 CYASSL_MSG("\tincorrect OID"); 03214 return ASN_PARSE_E; 03215 } 03216 03217 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { 03218 CYASSL_MSG("\twrong type"); 03219 return ASN_PARSE_E; 03220 } 03221 03222 if (GetLength(input, &idx, &strLen, sz) < 0) { 03223 CYASSL_MSG("\tfail: str len"); 03224 return ASN_PARSE_E; 03225 } 03226 03227 if (GetSequence(input, &idx, &strLen, sz) < 0) { 03228 CYASSL_MSG("\tBad Sequence"); 03229 return ASN_PARSE_E; 03230 } 03231 03232 if (input[idx++] != ASN_OBJECT_ID) { 03233 CYASSL_MSG("\texpected OID"); 03234 return ASN_PARSE_E; 03235 } 03236 03237 if (GetLength(input, &idx, &strLen, sz) < 0) { 03238 CYASSL_MSG("\tfailed: str len"); 03239 return ASN_PARSE_E; 03240 } 03241 03242 cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0); 03243 if (cert->hwType == NULL) { 03244 CYASSL_MSG("\tOut of Memory"); 03245 return MEMORY_E; 03246 } 03247 03248 XMEMCPY(cert->hwType, &input[idx], strLen); 03249 cert->hwTypeSz = strLen; 03250 idx += strLen; 03251 03252 if (input[idx++] != ASN_OCTET_STRING) { 03253 CYASSL_MSG("\texpected Octet String"); 03254 return ASN_PARSE_E; 03255 } 03256 03257 if (GetLength(input, &idx, &strLen, sz) < 0) { 03258 CYASSL_MSG("\tfailed: str len"); 03259 return ASN_PARSE_E; 03260 } 03261 03262 cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0); 03263 if (cert->hwSerialNum == NULL) { 03264 CYASSL_MSG("\tOut of Memory"); 03265 return MEMORY_E; 03266 } 03267 03268 XMEMCPY(cert->hwSerialNum, &input[idx], strLen); 03269 cert->hwSerialNum[strLen] = '\0'; 03270 cert->hwSerialNumSz = strLen; 03271 idx += strLen; 03272 } 03273 #endif /* CYASSL_SEP */ 03274 else { 03275 int strLen; 03276 word32 lenStartIdx = idx; 03277 03278 CYASSL_MSG("\tUnsupported name type, skipping"); 03279 03280 if (GetLength(input, &idx, &strLen, sz) < 0) { 03281 CYASSL_MSG("\tfail: unsupported name length"); 03282 return ASN_PARSE_E; 03283 } 03284 length -= (strLen + idx - lenStartIdx); 03285 idx += strLen; 03286 } 03287 } 03288 return 0; 03289 } 03290 03291 03292 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert) 03293 { 03294 word32 idx = 0; 03295 int length = 0; 03296 03297 CYASSL_ENTER("DecodeBasicCaConstraint"); 03298 if (GetSequence(input, &idx, &length, sz) < 0) { 03299 CYASSL_MSG("\tfail: bad SEQUENCE"); 03300 return ASN_PARSE_E; 03301 } 03302 03303 if (length == 0) 03304 return 0; 03305 03306 /* If the basic ca constraint is false, this extension may be named, but 03307 * left empty. So, if the length is 0, just return. */ 03308 03309 if (input[idx++] != ASN_BOOLEAN) 03310 { 03311 CYASSL_MSG("\tfail: constraint not BOOLEAN"); 03312 return ASN_PARSE_E; 03313 } 03314 03315 if (GetLength(input, &idx, &length, sz) < 0) 03316 { 03317 CYASSL_MSG("\tfail: length"); 03318 return ASN_PARSE_E; 03319 } 03320 03321 if (input[idx++]) 03322 cert->isCA = 1; 03323 03324 #ifdef OPENSSL_EXTRA 03325 /* If there isn't any more data, return. */ 03326 if (idx >= (word32)sz) 03327 return 0; 03328 03329 /* Anything left should be the optional pathlength */ 03330 if (input[idx++] != ASN_INTEGER) { 03331 CYASSL_MSG("\tfail: pathlen not INTEGER"); 03332 return ASN_PARSE_E; 03333 } 03334 03335 if (input[idx++] != 1) { 03336 CYASSL_MSG("\tfail: pathlen too long"); 03337 return ASN_PARSE_E; 03338 } 03339 03340 cert->pathLength = input[idx]; 03341 cert->extBasicConstPlSet = 1; 03342 #endif /* OPENSSL_EXTRA */ 03343 03344 return 0; 03345 } 03346 03347 03348 #define CRLDP_FULL_NAME 0 03349 /* From RFC3280 SS4.2.1.14, Distribution Point Name*/ 03350 #define GENERALNAME_URI 6 03351 /* From RFC3280 SS4.2.1.7, GeneralName */ 03352 03353 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert) 03354 { 03355 word32 idx = 0; 03356 int length = 0; 03357 03358 CYASSL_ENTER("DecodeCrlDist"); 03359 03360 /* Unwrap the list of Distribution Points*/ 03361 if (GetSequence(input, &idx, &length, sz) < 0) 03362 return ASN_PARSE_E; 03363 03364 /* Unwrap a single Distribution Point */ 03365 if (GetSequence(input, &idx, &length, sz) < 0) 03366 return ASN_PARSE_E; 03367 03368 /* The Distribution Point has three explicit optional members 03369 * First check for a DistributionPointName 03370 */ 03371 if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) 03372 { 03373 idx++; 03374 if (GetLength(input, &idx, &length, sz) < 0) 03375 return ASN_PARSE_E; 03376 03377 if (input[idx] == 03378 (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME)) 03379 { 03380 idx++; 03381 if (GetLength(input, &idx, &length, sz) < 0) 03382 return ASN_PARSE_E; 03383 03384 if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) 03385 { 03386 idx++; 03387 if (GetLength(input, &idx, &length, sz) < 0) 03388 return ASN_PARSE_E; 03389 03390 cert->extCrlInfoSz = length; 03391 cert->extCrlInfo = input + idx; 03392 idx += length; 03393 } 03394 else 03395 /* This isn't a URI, skip it. */ 03396 idx += length; 03397 } 03398 else 03399 /* This isn't a FULLNAME, skip it. */ 03400 idx += length; 03401 } 03402 03403 /* Check for reasonFlags */ 03404 if (idx < (word32)sz && 03405 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) 03406 { 03407 idx++; 03408 if (GetLength(input, &idx, &length, sz) < 0) 03409 return ASN_PARSE_E; 03410 idx += length; 03411 } 03412 03413 /* Check for cRLIssuer */ 03414 if (idx < (word32)sz && 03415 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) 03416 { 03417 idx++; 03418 if (GetLength(input, &idx, &length, sz) < 0) 03419 return ASN_PARSE_E; 03420 idx += length; 03421 } 03422 03423 if (idx < (word32)sz) 03424 { 03425 CYASSL_MSG("\tThere are more CRL Distribution Point records, " 03426 "but we only use the first one."); 03427 } 03428 03429 return 0; 03430 } 03431 03432 03433 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert) 03434 /* 03435 * Read the first of the Authority Information Access records. If there are 03436 * any issues, return without saving the record. 03437 */ 03438 { 03439 word32 idx = 0; 03440 int length = 0; 03441 byte b; 03442 word32 oid; 03443 03444 CYASSL_ENTER("DecodeAuthInfo"); 03445 03446 /* Unwrap the list of AIAs */ 03447 if (GetSequence(input, &idx, &length, sz) < 0) 03448 return ASN_PARSE_E; 03449 03450 while (idx < (word32)sz) { 03451 /* Unwrap a single AIA */ 03452 if (GetSequence(input, &idx, &length, sz) < 0) 03453 return ASN_PARSE_E; 03454 03455 oid = 0; 03456 if (GetObjectId(input, &idx, &oid, sz) < 0) 03457 return ASN_PARSE_E; 03458 03459 /* Only supporting URIs right now. */ 03460 b = input[idx++]; 03461 if (GetLength(input, &idx, &length, sz) < 0) 03462 return ASN_PARSE_E; 03463 03464 if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) && 03465 oid == AIA_OCSP_OID) 03466 { 03467 cert->extAuthInfoSz = length; 03468 cert->extAuthInfo = input + idx; 03469 break; 03470 } 03471 idx += length; 03472 } 03473 03474 return 0; 03475 } 03476 03477 03478 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) 03479 { 03480 word32 idx = 0; 03481 int length = 0, ret = 0; 03482 03483 CYASSL_ENTER("DecodeAuthKeyId"); 03484 03485 if (GetSequence(input, &idx, &length, sz) < 0) { 03486 CYASSL_MSG("\tfail: should be a SEQUENCE\n"); 03487 return ASN_PARSE_E; 03488 } 03489 03490 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { 03491 CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n"); 03492 return ASN_PARSE_E; 03493 } 03494 03495 if (GetLength(input, &idx, &length, sz) < 0) { 03496 CYASSL_MSG("\tfail: extension data length"); 03497 return ASN_PARSE_E; 03498 } 03499 03500 #ifdef OPENSSL_EXTRA 03501 cert->extAuthKeyIdSrc = &input[idx]; 03502 cert->extAuthKeyIdSz = length; 03503 #endif /* OPENSSL_EXTRA */ 03504 03505 if (length == SHA_SIZE) { 03506 XMEMCPY(cert->extAuthKeyId, input + idx, length); 03507 } 03508 else { 03509 Sha sha; 03510 ret = InitSha(&sha); 03511 if (ret != 0) 03512 return ret; 03513 ShaUpdate(&sha, input + idx, length); 03514 ShaFinal(&sha, cert->extAuthKeyId); 03515 } 03516 03517 return 0; 03518 } 03519 03520 03521 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert) 03522 { 03523 word32 idx = 0; 03524 int length = 0, ret = 0; 03525 03526 CYASSL_ENTER("DecodeSubjKeyId"); 03527 03528 if (input[idx++] != ASN_OCTET_STRING) { 03529 CYASSL_MSG("\tfail: should be an OCTET STRING"); 03530 return ASN_PARSE_E; 03531 } 03532 03533 if (GetLength(input, &idx, &length, sz) < 0) { 03534 CYASSL_MSG("\tfail: extension data length"); 03535 return ASN_PARSE_E; 03536 } 03537 03538 #ifdef OPENSSL_EXTRA 03539 cert->extSubjKeyIdSrc = &input[idx]; 03540 cert->extSubjKeyIdSz = length; 03541 #endif /* OPENSSL_EXTRA */ 03542 03543 if (length == SIGNER_DIGEST_SIZE) { 03544 XMEMCPY(cert->extSubjKeyId, input + idx, length); 03545 } 03546 else { 03547 Sha sha; 03548 ret = InitSha(&sha); 03549 if (ret != 0) 03550 return ret; 03551 ShaUpdate(&sha, input + idx, length); 03552 ShaFinal(&sha, cert->extSubjKeyId); 03553 } 03554 03555 return ret; 03556 } 03557 03558 03559 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert) 03560 { 03561 word32 idx = 0; 03562 int length; 03563 byte unusedBits; 03564 CYASSL_ENTER("DecodeKeyUsage"); 03565 03566 if (input[idx++] != ASN_BIT_STRING) { 03567 CYASSL_MSG("\tfail: key usage expected bit string"); 03568 return ASN_PARSE_E; 03569 } 03570 03571 if (GetLength(input, &idx, &length, sz) < 0) { 03572 CYASSL_MSG("\tfail: key usage bad length"); 03573 return ASN_PARSE_E; 03574 } 03575 03576 unusedBits = input[idx++]; 03577 length--; 03578 03579 if (length == 2) { 03580 cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]); 03581 cert->extKeyUsage >>= unusedBits; 03582 } 03583 else if (length == 1) 03584 cert->extKeyUsage = (word16)(input[idx] << 1); 03585 03586 return 0; 03587 } 03588 03589 03590 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert) 03591 { 03592 word32 idx = 0, oid; 03593 int length; 03594 03595 CYASSL_ENTER("DecodeExtKeyUsage"); 03596 03597 if (GetSequence(input, &idx, &length, sz) < 0) { 03598 CYASSL_MSG("\tfail: should be a SEQUENCE"); 03599 return ASN_PARSE_E; 03600 } 03601 03602 #ifdef OPENSSL_EXTRA 03603 cert->extExtKeyUsageSrc = input + idx; 03604 cert->extExtKeyUsageSz = length; 03605 #endif 03606 03607 while (idx < (word32)sz) { 03608 if (GetObjectId(input, &idx, &oid, sz) < 0) 03609 return ASN_PARSE_E; 03610 03611 switch (oid) { 03612 case EKU_ANY_OID: 03613 cert->extExtKeyUsage |= EXTKEYUSE_ANY; 03614 break; 03615 case EKU_SERVER_AUTH_OID: 03616 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH; 03617 break; 03618 case EKU_CLIENT_AUTH_OID: 03619 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH; 03620 break; 03621 case EKU_OCSP_SIGN_OID: 03622 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN; 03623 break; 03624 } 03625 03626 #ifdef OPENSSL_EXTRA 03627 cert->extExtKeyUsageCount++; 03628 #endif 03629 } 03630 03631 return 0; 03632 } 03633 03634 03635 #ifndef IGNORE_NAME_CONSTRAINTS 03636 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap) 03637 { 03638 word32 idx = 0; 03639 03640 (void)heap; 03641 03642 while (idx < (word32)sz) { 03643 int seqLength, strLength; 03644 word32 nameIdx; 03645 byte b; 03646 03647 if (GetSequence(input, &idx, &seqLength, sz) < 0) { 03648 CYASSL_MSG("\tfail: should be a SEQUENCE"); 03649 return ASN_PARSE_E; 03650 } 03651 03652 nameIdx = idx; 03653 b = input[nameIdx++]; 03654 if (GetLength(input, &nameIdx, &strLength, sz) <= 0) { 03655 CYASSL_MSG("\tinvalid length"); 03656 return ASN_PARSE_E; 03657 } 03658 03659 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) || 03660 b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) || 03661 b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) { 03662 03663 Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry), 03664 heap, DYNAMIC_TYPE_ALTNAME); 03665 03666 if (entry == NULL) { 03667 CYASSL_MSG("allocate error"); 03668 return MEMORY_E; 03669 } 03670 03671 entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME); 03672 if (entry->name == NULL) { 03673 CYASSL_MSG("allocate error"); 03674 return MEMORY_E; 03675 } 03676 03677 XMEMCPY(entry->name, &input[nameIdx], strLength); 03678 entry->nameSz = strLength; 03679 entry->type = b & 0x0F; 03680 03681 entry->next = *head; 03682 *head = entry; 03683 } 03684 03685 idx += seqLength; 03686 } 03687 03688 return 0; 03689 } 03690 03691 03692 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert) 03693 { 03694 word32 idx = 0; 03695 int length = 0; 03696 03697 CYASSL_ENTER("DecodeNameConstraints"); 03698 03699 if (GetSequence(input, &idx, &length, sz) < 0) { 03700 CYASSL_MSG("\tfail: should be a SEQUENCE"); 03701 return ASN_PARSE_E; 03702 } 03703 03704 while (idx < (word32)sz) { 03705 byte b = input[idx++]; 03706 Base_entry** subtree = NULL; 03707 03708 if (GetLength(input, &idx, &length, sz) <= 0) { 03709 CYASSL_MSG("\tinvalid length"); 03710 return ASN_PARSE_E; 03711 } 03712 03713 if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) 03714 subtree = &cert->permittedNames; 03715 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) 03716 subtree = &cert->excludedNames; 03717 else { 03718 CYASSL_MSG("\tinvalid subtree"); 03719 return ASN_PARSE_E; 03720 } 03721 03722 DecodeSubtree(input + idx, length, subtree, cert->heap); 03723 03724 idx += length; 03725 } 03726 03727 return 0; 03728 } 03729 #endif /* IGNORE_NAME_CONSTRAINTS */ 03730 03731 03732 #ifdef CYASSL_SEP 03733 static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert) 03734 { 03735 word32 idx = 0; 03736 int length = 0; 03737 03738 CYASSL_ENTER("DecodeCertPolicy"); 03739 03740 /* Unwrap certificatePolicies */ 03741 if (GetSequence(input, &idx, &length, sz) < 0) { 03742 CYASSL_MSG("\tdeviceType isn't OID"); 03743 return ASN_PARSE_E; 03744 } 03745 03746 if (GetSequence(input, &idx, &length, sz) < 0) { 03747 CYASSL_MSG("\tdeviceType isn't OID"); 03748 return ASN_PARSE_E; 03749 } 03750 03751 if (input[idx++] != ASN_OBJECT_ID) { 03752 CYASSL_MSG("\tdeviceType isn't OID"); 03753 return ASN_PARSE_E; 03754 } 03755 03756 if (GetLength(input, &idx, &length, sz) < 0) { 03757 CYASSL_MSG("\tCouldn't read length of deviceType"); 03758 return ASN_PARSE_E; 03759 } 03760 03761 if (length > 0) { 03762 cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0); 03763 if (cert->deviceType == NULL) { 03764 CYASSL_MSG("\tCouldn't alloc memory for deviceType"); 03765 return MEMORY_E; 03766 } 03767 cert->deviceTypeSz = length; 03768 XMEMCPY(cert->deviceType, input + idx, length); 03769 } 03770 03771 CYASSL_LEAVE("DecodeCertPolicy", 0); 03772 return 0; 03773 } 03774 #endif /* CYASSL_SEP */ 03775 03776 03777 static int DecodeCertExtensions(DecodedCert* cert) 03778 /* 03779 * Processing the Certificate Extensions. This does not modify the current 03780 * index. It is works starting with the recorded extensions pointer. 03781 */ 03782 { 03783 word32 idx = 0; 03784 int sz = cert->extensionsSz; 03785 byte* input = cert->extensions; 03786 int length; 03787 word32 oid; 03788 byte critical = 0; 03789 byte criticalFail = 0; 03790 03791 CYASSL_ENTER("DecodeCertExtensions"); 03792 03793 if (input == NULL || sz == 0) 03794 return BAD_FUNC_ARG; 03795 03796 if (input[idx++] != ASN_EXTENSIONS) 03797 return ASN_PARSE_E; 03798 03799 if (GetLength(input, &idx, &length, sz) < 0) 03800 return ASN_PARSE_E; 03801 03802 if (GetSequence(input, &idx, &length, sz) < 0) 03803 return ASN_PARSE_E; 03804 03805 while (idx < (word32)sz) { 03806 if (GetSequence(input, &idx, &length, sz) < 0) { 03807 CYASSL_MSG("\tfail: should be a SEQUENCE"); 03808 return ASN_PARSE_E; 03809 } 03810 03811 oid = 0; 03812 if (GetObjectId(input, &idx, &oid, sz) < 0) { 03813 CYASSL_MSG("\tfail: OBJECT ID"); 03814 return ASN_PARSE_E; 03815 } 03816 03817 /* check for critical flag */ 03818 critical = 0; 03819 if (input[idx] == ASN_BOOLEAN) { 03820 int boolLength = 0; 03821 idx++; 03822 if (GetLength(input, &idx, &boolLength, sz) < 0) { 03823 CYASSL_MSG("\tfail: critical boolean length"); 03824 return ASN_PARSE_E; 03825 } 03826 if (input[idx++]) 03827 critical = 1; 03828 } 03829 03830 /* process the extension based on the OID */ 03831 if (input[idx++] != ASN_OCTET_STRING) { 03832 CYASSL_MSG("\tfail: should be an OCTET STRING"); 03833 return ASN_PARSE_E; 03834 } 03835 03836 if (GetLength(input, &idx, &length, sz) < 0) { 03837 CYASSL_MSG("\tfail: extension data length"); 03838 return ASN_PARSE_E; 03839 } 03840 03841 switch (oid) { 03842 case BASIC_CA_OID: 03843 #ifdef OPENSSL_EXTRA 03844 cert->extBasicConstSet = 1; 03845 cert->extBasicConstCrit = critical; 03846 #endif 03847 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0) 03848 return ASN_PARSE_E; 03849 break; 03850 03851 case CRL_DIST_OID: 03852 if (DecodeCrlDist(&input[idx], length, cert) < 0) 03853 return ASN_PARSE_E; 03854 break; 03855 03856 case AUTH_INFO_OID: 03857 if (DecodeAuthInfo(&input[idx], length, cert) < 0) 03858 return ASN_PARSE_E; 03859 break; 03860 03861 case ALT_NAMES_OID: 03862 #ifdef OPENSSL_EXTRA 03863 cert->extSubjAltNameSet = 1; 03864 cert->extSubjAltNameCrit = critical; 03865 #endif 03866 if (DecodeAltNames(&input[idx], length, cert) < 0) 03867 return ASN_PARSE_E; 03868 break; 03869 03870 case AUTH_KEY_OID: 03871 cert->extAuthKeyIdSet = 1; 03872 #ifdef OPENSSL_EXTRA 03873 cert->extAuthKeyIdCrit = critical; 03874 #endif 03875 if (DecodeAuthKeyId(&input[idx], length, cert) < 0) 03876 return ASN_PARSE_E; 03877 break; 03878 03879 case SUBJ_KEY_OID: 03880 cert->extSubjKeyIdSet = 1; 03881 #ifdef OPENSSL_EXTRA 03882 cert->extSubjKeyIdCrit = critical; 03883 #endif 03884 if (DecodeSubjKeyId(&input[idx], length, cert) < 0) 03885 return ASN_PARSE_E; 03886 break; 03887 03888 case CERT_POLICY_OID: 03889 CYASSL_MSG("Certificate Policy extension not supported yet."); 03890 #ifdef CYASSL_SEP 03891 #ifdef OPENSSL_EXTRA 03892 cert->extCertPolicySet = 1; 03893 cert->extCertPolicyCrit = critical; 03894 #endif 03895 if (DecodeCertPolicy(&input[idx], length, cert) < 0) 03896 return ASN_PARSE_E; 03897 #endif 03898 break; 03899 03900 case KEY_USAGE_OID: 03901 cert->extKeyUsageSet = 1; 03902 #ifdef OPENSSL_EXTRA 03903 cert->extKeyUsageCrit = critical; 03904 #endif 03905 if (DecodeKeyUsage(&input[idx], length, cert) < 0) 03906 return ASN_PARSE_E; 03907 break; 03908 03909 case EXT_KEY_USAGE_OID: 03910 cert->extExtKeyUsageSet = 1; 03911 #ifdef OPENSSL_EXTRA 03912 cert->extExtKeyUsageCrit = critical; 03913 #endif 03914 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0) 03915 return ASN_PARSE_E; 03916 break; 03917 03918 #ifndef IGNORE_NAME_CONSTRAINTS 03919 case NAME_CONS_OID: 03920 cert->extNameConstraintSet = 1; 03921 #ifdef OPENSSL_EXTRA 03922 cert->extNameConstraintCrit = critical; 03923 #endif 03924 if (DecodeNameConstraints(&input[idx], length, cert) < 0) 03925 return ASN_PARSE_E; 03926 break; 03927 #endif /* IGNORE_NAME_CONSTRAINTS */ 03928 03929 case INHIBIT_ANY_OID: 03930 CYASSL_MSG("Inhibit anyPolicy extension not supported yet."); 03931 break; 03932 03933 default: 03934 /* While it is a failure to not support critical extensions, 03935 * still parse the certificate ignoring the unsupported 03936 * extention to allow caller to accept it with the verify 03937 * callback. */ 03938 if (critical) 03939 criticalFail = 1; 03940 break; 03941 } 03942 idx += length; 03943 } 03944 03945 return criticalFail ? ASN_CRIT_EXT_E : 0; 03946 } 03947 03948 03949 int ParseCert(DecodedCert* cert, int type, int verify, void* cm) 03950 { 03951 int ret; 03952 char* ptr; 03953 03954 ret = ParseCertRelative(cert, type, verify, cm); 03955 if (ret < 0) 03956 return ret; 03957 03958 if (cert->subjectCNLen > 0) { 03959 ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap, 03960 DYNAMIC_TYPE_SUBJECT_CN); 03961 if (ptr == NULL) 03962 return MEMORY_E; 03963 XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen); 03964 ptr[cert->subjectCNLen] = '\0'; 03965 cert->subjectCN = ptr; 03966 cert->subjectCNStored = 1; 03967 } 03968 03969 if (cert->keyOID == RSAk && 03970 cert->publicKey != NULL && cert->pubKeySize > 0) { 03971 ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap, 03972 DYNAMIC_TYPE_PUBLIC_KEY); 03973 if (ptr == NULL) 03974 return MEMORY_E; 03975 XMEMCPY(ptr, cert->publicKey, cert->pubKeySize); 03976 cert->publicKey = (byte *)ptr; 03977 cert->pubKeyStored = 1; 03978 } 03979 03980 return ret; 03981 } 03982 03983 03984 /* from SSL proper, for locking can't do find here anymore */ 03985 #ifdef __cplusplus 03986 extern "C" { 03987 #endif 03988 CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash); 03989 #ifndef NO_SKID 03990 CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash); 03991 #endif 03992 #ifdef __cplusplus 03993 } 03994 #endif 03995 03996 03997 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) 03998 { 03999 word32 confirmOID; 04000 int ret; 04001 int badDate = 0; 04002 int criticalExt = 0; 04003 04004 if ((ret = DecodeToKey(cert, verify)) < 0) { 04005 if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) 04006 badDate = ret; 04007 else 04008 return ret; 04009 } 04010 04011 CYASSL_MSG("Parsed Past Key"); 04012 04013 if (cert->srcIdx < cert->sigIndex) { 04014 #ifndef ALLOW_V1_EXTENSIONS 04015 if (cert->version < 2) { 04016 CYASSL_MSG(" v1 and v2 certs not allowed extensions"); 04017 return ASN_VERSION_E; 04018 } 04019 #endif 04020 /* save extensions */ 04021 cert->extensions = &cert->source[cert->srcIdx]; 04022 cert->extensionsSz = cert->sigIndex - cert->srcIdx; 04023 cert->extensionsIdx = cert->srcIdx; /* for potential later use */ 04024 04025 if ((ret = DecodeCertExtensions(cert)) < 0) { 04026 if (ret == ASN_CRIT_EXT_E) 04027 criticalExt = ret; 04028 else 04029 return ret; 04030 } 04031 04032 /* advance past extensions */ 04033 cert->srcIdx = cert->sigIndex; 04034 } 04035 04036 if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID, 04037 cert->maxIdx)) < 0) 04038 return ret; 04039 04040 if ((ret = GetSignature(cert)) < 0) 04041 return ret; 04042 04043 if (confirmOID != cert->signatureOID) 04044 return ASN_SIG_OID_E; 04045 04046 #ifndef NO_SKID 04047 if (cert->extSubjKeyIdSet == 0 04048 && cert->publicKey != NULL && cert->pubKeySize > 0) { 04049 Sha sha; 04050 ret = InitSha(&sha); 04051 if (ret != 0) 04052 return ret; 04053 ShaUpdate(&sha, cert->publicKey, cert->pubKeySize); 04054 ShaFinal(&sha, cert->extSubjKeyId); 04055 } 04056 #endif 04057 04058 if (verify && type != CA_TYPE) { 04059 Signer* ca = NULL; 04060 #ifndef NO_SKID 04061 if (cert->extAuthKeyIdSet) 04062 ca = GetCA(cm, cert->extAuthKeyId); 04063 if (ca == NULL) 04064 ca = GetCAByName(cm, cert->issuerHash); 04065 #else /* NO_SKID */ 04066 ca = GetCA(cm, cert->issuerHash); 04067 #endif /* NO SKID */ 04068 CYASSL_MSG("About to verify certificate signature"); 04069 04070 if (ca) { 04071 #ifdef HAVE_OCSP 04072 /* Need the ca's public key hash for OCSP */ 04073 { 04074 Sha sha; 04075 ret = InitSha(&sha); 04076 if (ret != 0) 04077 return ret; 04078 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize); 04079 ShaFinal(&sha, cert->issuerKeyHash); 04080 } 04081 #endif /* HAVE_OCSP */ 04082 /* try to confirm/verify signature */ 04083 if (!ConfirmSignature(cert->source + cert->certBegin, 04084 cert->sigIndex - cert->certBegin, 04085 ca->publicKey, ca->pubKeySize, ca->keyOID, 04086 cert->signature, cert->sigLength, cert->signatureOID, 04087 cert->heap)) { 04088 CYASSL_MSG("Confirm signature failed"); 04089 return ASN_SIG_CONFIRM_E; 04090 } 04091 #ifndef IGNORE_NAME_CONSTRAINTS 04092 /* check that this cert's name is permitted by the signer's 04093 * name constraints */ 04094 if (!ConfirmNameConstraints(ca, cert)) { 04095 CYASSL_MSG("Confirm name constraint failed"); 04096 return ASN_NAME_INVALID_E; 04097 } 04098 #endif /* IGNORE_NAME_CONSTRAINTS */ 04099 } 04100 else { 04101 /* no signer */ 04102 CYASSL_MSG("No CA signer to verify with"); 04103 return ASN_NO_SIGNER_E; 04104 } 04105 } 04106 04107 if (badDate != 0) 04108 return badDate; 04109 04110 if (criticalExt != 0) 04111 return criticalExt; 04112 04113 return 0; 04114 } 04115 04116 04117 /* Create and init an new signer */ 04118 Signer* MakeSigner(void* heap) 04119 { 04120 Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, 04121 DYNAMIC_TYPE_SIGNER); 04122 if (signer) { 04123 signer->pubKeySize = 0; 04124 signer->keyOID = 0; 04125 signer->publicKey = NULL; 04126 signer->nameLen = 0; 04127 signer->name = NULL; 04128 #ifndef IGNORE_NAME_CONSTRAINTS 04129 signer->permittedNames = NULL; 04130 signer->excludedNames = NULL; 04131 #endif /* IGNORE_NAME_CONSTRAINTS */ 04132 signer->next = NULL; 04133 } 04134 (void)heap; 04135 04136 return signer; 04137 } 04138 04139 04140 /* Free an individual signer */ 04141 void FreeSigner(Signer* signer, void* heap) 04142 { 04143 XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); 04144 XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); 04145 #ifndef IGNORE_NAME_CONSTRAINTS 04146 if (signer->permittedNames) 04147 FreeNameSubtrees(signer->permittedNames, heap); 04148 if (signer->excludedNames) 04149 FreeNameSubtrees(signer->excludedNames, heap); 04150 #endif 04151 XFREE(signer, heap, DYNAMIC_TYPE_SIGNER); 04152 04153 (void)heap; 04154 } 04155 04156 04157 /* Free the whole singer table with number of rows */ 04158 void FreeSignerTable(Signer** table, int rows, void* heap) 04159 { 04160 int i; 04161 04162 for (i = 0; i < rows; i++) { 04163 Signer* signer = table[i]; 04164 while (signer) { 04165 Signer* next = signer->next; 04166 FreeSigner(signer, heap); 04167 signer = next; 04168 } 04169 table[i] = NULL; 04170 } 04171 } 04172 04173 04174 CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header) 04175 { 04176 int i = 0; 04177 04178 if (header) { 04179 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED; 04180 output[i++] = ASN_BIT_STRING; 04181 } 04182 output[i++] = ASN_INTEGER; 04183 output[i++] = 0x01; 04184 output[i++] = (byte)version; 04185 04186 return i; 04187 } 04188 04189 04190 CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output) 04191 { 04192 int result = 0; 04193 04194 CYASSL_ENTER("SetSerialNumber"); 04195 04196 if (snSz <= EXTERNAL_SERIAL_SIZE) { 04197 output[0] = ASN_INTEGER; 04198 /* The serial number is always positive. When encoding the 04199 * INTEGER, if the MSB is 1, add a padding zero to keep the 04200 * number positive. */ 04201 if (sn[0] & 0x80) { 04202 output[1] = (byte)snSz + 1; 04203 output[2] = 0; 04204 XMEMCPY(&output[3], sn, snSz); 04205 result = snSz + 3; 04206 } 04207 else { 04208 output[1] = (byte)snSz; 04209 XMEMCPY(&output[2], sn, snSz); 04210 result = snSz + 2; 04211 } 04212 } 04213 return result; 04214 } 04215 04216 04217 04218 04219 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) 04220 04221 /* convert der buffer to pem into output, can't do inplace, der and output 04222 need to be different */ 04223 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, 04224 int type) 04225 { 04226 char header[80]; 04227 char footer[80]; 04228 04229 int headerLen; 04230 int footerLen; 04231 int i; 04232 int err; 04233 int outLen; /* return length or error */ 04234 04235 if (der == output) /* no in place conversion */ 04236 return BAD_FUNC_ARG; 04237 04238 if (type == CERT_TYPE) { 04239 XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header)); 04240 XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer)); 04241 } 04242 else if (type == PRIVATEKEY_TYPE) { 04243 XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header)); 04244 XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer)); 04245 } 04246 #ifdef HAVE_ECC 04247 else if (type == ECC_PRIVATEKEY_TYPE) { 04248 XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", sizeof(header)); 04249 XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", sizeof(footer)); 04250 } 04251 #endif 04252 #ifdef CYASSL_CERT_REQ 04253 else if (type == CERTREQ_TYPE) 04254 { 04255 XSTRNCPY(header, 04256 "-----BEGIN CERTIFICATE REQUEST-----\n", sizeof(header)); 04257 XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", sizeof(footer)); 04258 } 04259 #endif 04260 else 04261 return BAD_FUNC_ARG; 04262 04263 headerLen = (int)XSTRLEN(header); 04264 footerLen = (int)XSTRLEN(footer); 04265 04266 if (!der || !output) 04267 return BAD_FUNC_ARG; 04268 04269 /* don't even try if outSz too short */ 04270 if (outSz < headerLen + footerLen + derSz) 04271 return BAD_FUNC_ARG; 04272 04273 /* header */ 04274 XMEMCPY(output, header, headerLen); 04275 i = headerLen; 04276 04277 /* body */ 04278 outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */ 04279 if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) 04280 return err; 04281 i += outLen; 04282 04283 /* footer */ 04284 if ( (i + footerLen) > (int)outSz) 04285 return BAD_FUNC_ARG; 04286 XMEMCPY(output + i, footer, footerLen); 04287 04288 return outLen + headerLen + footerLen; 04289 } 04290 04291 04292 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */ 04293 04294 04295 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) 04296 04297 04298 static mp_int* GetRsaInt(RsaKey* key, int idx) 04299 { 04300 if (idx == 0) 04301 return &key->n; 04302 if (idx == 1) 04303 return &key->e; 04304 if (idx == 2) 04305 return &key->d; 04306 if (idx == 3) 04307 return &key->p; 04308 if (idx == 4) 04309 return &key->q; 04310 if (idx == 5) 04311 return &key->dP; 04312 if (idx == 6) 04313 return &key->dQ; 04314 if (idx == 7) 04315 return &key->u; 04316 04317 return NULL; 04318 } 04319 04320 04321 /* Release Tmp RSA resources */ 04322 static INLINE void FreeTmpRsas(byte** tmps, void* heap) 04323 { 04324 int i; 04325 04326 (void)heap; 04327 04328 for (i = 0; i < RSA_INTS; i++) 04329 XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA); 04330 } 04331 04332 04333 /* Convert RsaKey key to DER format, write to output (inLen), return bytes 04334 written */ 04335 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) 04336 { 04337 word32 seqSz, verSz, rawLen, intTotalLen = 0; 04338 word32 sizes[RSA_INTS]; 04339 int i, j, outLen, ret = 0; 04340 04341 byte seq[MAX_SEQ_SZ]; 04342 byte ver[MAX_VERSION_SZ]; 04343 byte* tmps[RSA_INTS]; 04344 04345 if (!key || !output) 04346 return BAD_FUNC_ARG; 04347 04348 if (key->type != RSA_PRIVATE) 04349 return BAD_FUNC_ARG; 04350 04351 for (i = 0; i < RSA_INTS; i++) 04352 tmps[i] = NULL; 04353 04354 /* write all big ints from key to DER tmps */ 04355 for (i = 0; i < RSA_INTS; i++) { 04356 mp_int* keyInt = GetRsaInt(key, i); 04357 rawLen = mp_unsigned_bin_size(keyInt); 04358 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap, 04359 DYNAMIC_TYPE_RSA); 04360 if (tmps[i] == NULL) { 04361 ret = MEMORY_E; 04362 break; 04363 } 04364 04365 tmps[i][0] = ASN_INTEGER; 04366 sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ 04367 04368 if (sizes[i] <= MAX_SEQ_SZ) { 04369 int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); 04370 if (err == MP_OKAY) { 04371 sizes[i] += rawLen; 04372 intTotalLen += sizes[i]; 04373 } 04374 else { 04375 ret = err; 04376 break; 04377 } 04378 } 04379 else { 04380 ret = ASN_INPUT_E; 04381 break; 04382 } 04383 } 04384 04385 if (ret != 0) { 04386 FreeTmpRsas(tmps, key->heap); 04387 return ret; 04388 } 04389 04390 /* make headers */ 04391 verSz = SetMyVersion(0, ver, FALSE); 04392 seqSz = SetSequence(verSz + intTotalLen, seq); 04393 04394 outLen = seqSz + verSz + intTotalLen; 04395 if (outLen > (int)inLen) 04396 return BAD_FUNC_ARG; 04397 04398 /* write to output */ 04399 XMEMCPY(output, seq, seqSz); 04400 j = seqSz; 04401 XMEMCPY(output + j, ver, verSz); 04402 j += verSz; 04403 04404 for (i = 0; i < RSA_INTS; i++) { 04405 XMEMCPY(output + j, tmps[i], sizes[i]); 04406 j += sizes[i]; 04407 } 04408 FreeTmpRsas(tmps, key->heap); 04409 04410 return outLen; 04411 } 04412 04413 #endif /* CYASSL_KEY_GEN && !NO_RSA */ 04414 04415 04416 #if defined(CYASSL_CERT_GEN) && !defined(NO_RSA) 04417 04418 04419 #ifndef min 04420 04421 static INLINE word32 min(word32 a, word32 b) 04422 { 04423 return a > b ? b : a; 04424 } 04425 04426 #endif /* min */ 04427 04428 04429 /* Initialize and Set Certficate defaults: 04430 version = 3 (0x2) 04431 serial = 0 04432 sigType = SHA_WITH_RSA 04433 issuer = blank 04434 daysValid = 500 04435 selfSigned = 1 (true) use subject as issuer 04436 subject = blank 04437 */ 04438 void InitCert(Cert* cert) 04439 { 04440 cert->version = 2; /* version 3 is hex 2 */ 04441 cert->sigType = CTC_SHAwRSA; 04442 cert->daysValid = 500; 04443 cert->selfSigned = 1; 04444 cert->isCA = 0; 04445 cert->bodySz = 0; 04446 #ifdef CYASSL_ALT_NAMES 04447 cert->altNamesSz = 0; 04448 cert->beforeDateSz = 0; 04449 cert->afterDateSz = 0; 04450 #endif 04451 cert->keyType = RSA_KEY; 04452 XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); 04453 04454 cert->issuer.country[0] = '\0'; 04455 cert->issuer.state[0] = '\0'; 04456 cert->issuer.locality[0] = '\0'; 04457 cert->issuer.sur[0] = '\0'; 04458 cert->issuer.org[0] = '\0'; 04459 cert->issuer.unit[0] = '\0'; 04460 cert->issuer.commonName[0] = '\0'; 04461 cert->issuer.email[0] = '\0'; 04462 04463 cert->subject.country[0] = '\0'; 04464 cert->subject.state[0] = '\0'; 04465 cert->subject.locality[0] = '\0'; 04466 cert->subject.sur[0] = '\0'; 04467 cert->subject.org[0] = '\0'; 04468 cert->subject.unit[0] = '\0'; 04469 cert->subject.commonName[0] = '\0'; 04470 cert->subject.email[0] = '\0'; 04471 04472 #ifdef CYASSL_CERT_REQ 04473 cert->challengePw[0] ='\0'; 04474 #endif 04475 } 04476 04477 04478 /* DER encoded x509 Certificate */ 04479 typedef struct DerCert { 04480 byte size[MAX_LENGTH_SZ]; /* length encoded */ 04481 byte version[MAX_VERSION_SZ]; /* version encoded */ 04482 byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */ 04483 byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */ 04484 byte issuer[ASN_NAME_MAX]; /* issuer encoded */ 04485 byte subject[ASN_NAME_MAX]; /* subject encoded */ 04486 byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */ 04487 byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */ 04488 byte ca[MAX_CA_SZ]; /* basic constraint CA true size */ 04489 byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */ 04490 #ifdef CYASSL_CERT_REQ 04491 byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */ 04492 #endif 04493 int sizeSz; /* encoded size length */ 04494 int versionSz; /* encoded version length */ 04495 int serialSz; /* encoded serial length */ 04496 int sigAlgoSz; /* enocded sig alog length */ 04497 int issuerSz; /* encoded issuer length */ 04498 int subjectSz; /* encoded subject length */ 04499 int validitySz; /* encoded validity length */ 04500 int publicKeySz; /* encoded public key length */ 04501 int caSz; /* encoded CA extension length */ 04502 int extensionsSz; /* encoded extensions total length */ 04503 int total; /* total encoded lengths */ 04504 #ifdef CYASSL_CERT_REQ 04505 int attribSz; 04506 #endif 04507 } DerCert; 04508 04509 04510 #ifdef CYASSL_CERT_REQ 04511 04512 /* Write a set header to output */ 04513 static word32 SetUTF8String(word32 len, byte* output) 04514 { 04515 output[0] = ASN_UTF8STRING; 04516 return SetLength(len, output + 1) + 1; 04517 } 04518 04519 #endif /* CYASSL_CERT_REQ */ 04520 04521 04522 /* Write a serial number to output */ 04523 static int SetSerial(const byte* serial, byte* output) 04524 { 04525 int length = 0; 04526 04527 output[length++] = ASN_INTEGER; 04528 length += SetLength(CTC_SERIAL_SIZE, &output[length]); 04529 XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE); 04530 04531 return length + CTC_SERIAL_SIZE; 04532 } 04533 04534 04535 #ifdef HAVE_ECC 04536 04537 /* Write a public ECC key to output */ 04538 static int SetEccPublicKey(byte* output, ecc_key* key) 04539 { 04540 byte algo[MAX_ALGO_SZ]; 04541 byte curve[MAX_ALGO_SZ]; 04542 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ 04543 byte pub[ECC_BUFSIZE]; 04544 int algoSz; 04545 int curveSz; 04546 int lenSz; 04547 int idx; 04548 word32 pubSz = sizeof(pub); 04549 04550 int ret = ecc_export_x963(key, pub, &pubSz); 04551 if (ret != 0) return ret; 04552 04553 /* headers */ 04554 curveSz = SetCurve(key, curve); 04555 if (curveSz <= 0) return curveSz; 04556 04557 algoSz = SetAlgoID(ECDSAk, algo, keyType, curveSz); 04558 lenSz = SetLength(pubSz + 1, len); 04559 len[lenSz++] = 0; /* trailing 0 */ 04560 04561 /* write */ 04562 idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output); 04563 /* 1 is for ASN_BIT_STRING */ 04564 /* algo */ 04565 XMEMCPY(output + idx, algo, algoSz); 04566 idx += algoSz; 04567 /* curve */ 04568 XMEMCPY(output + idx, curve, curveSz); 04569 idx += curveSz; 04570 /* bit string */ 04571 output[idx++] = ASN_BIT_STRING; 04572 /* length */ 04573 XMEMCPY(output + idx, len, lenSz); 04574 idx += lenSz; 04575 /* pub */ 04576 XMEMCPY(output + idx, pub, pubSz); 04577 idx += pubSz; 04578 04579 return idx; 04580 } 04581 04582 04583 #endif /* HAVE_ECC */ 04584 04585 04586 /* Write a public RSA key to output */ 04587 static int SetRsaPublicKey(byte* output, RsaKey* key) 04588 { 04589 byte n[MAX_RSA_INT_SZ]; 04590 byte e[MAX_RSA_E_SZ]; 04591 byte algo[MAX_ALGO_SZ]; 04592 byte seq[MAX_SEQ_SZ]; 04593 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ 04594 int nSz; 04595 int eSz; 04596 int algoSz; 04597 int seqSz; 04598 int lenSz; 04599 int idx; 04600 int rawLen; 04601 int leadingBit; 04602 int err; 04603 04604 /* n */ 04605 leadingBit = mp_leading_bit(&key->n); 04606 rawLen = mp_unsigned_bin_size(&key->n) + leadingBit; 04607 n[0] = ASN_INTEGER; 04608 nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ 04609 04610 if ( (nSz + rawLen) < (int)sizeof(n)) { 04611 if (leadingBit) 04612 n[nSz] = 0; 04613 err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit); 04614 if (err == MP_OKAY) 04615 nSz += rawLen; 04616 else 04617 return MP_TO_E; 04618 } 04619 else 04620 return BUFFER_E; 04621 04622 /* e */ 04623 leadingBit = mp_leading_bit(&key->e); 04624 rawLen = mp_unsigned_bin_size(&key->e) + leadingBit; 04625 e[0] = ASN_INTEGER; 04626 eSz = SetLength(rawLen, e + 1) + 1; /* int tag */ 04627 04628 if ( (eSz + rawLen) < (int)sizeof(e)) { 04629 if (leadingBit) 04630 e[eSz] = 0; 04631 err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit); 04632 if (err == MP_OKAY) 04633 eSz += rawLen; 04634 else 04635 return MP_TO_E; 04636 } 04637 else 04638 return BUFFER_E; 04639 04640 /* headers */ 04641 algoSz = SetAlgoID(RSAk, algo, keyType, 0); 04642 seqSz = SetSequence(nSz + eSz, seq); 04643 lenSz = SetLength(seqSz + nSz + eSz + 1, len); 04644 len[lenSz++] = 0; /* trailing 0 */ 04645 04646 /* write */ 04647 idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output); 04648 /* 1 is for ASN_BIT_STRING */ 04649 /* algo */ 04650 XMEMCPY(output + idx, algo, algoSz); 04651 idx += algoSz; 04652 /* bit string */ 04653 output[idx++] = ASN_BIT_STRING; 04654 /* length */ 04655 XMEMCPY(output + idx, len, lenSz); 04656 idx += lenSz; 04657 /* seq */ 04658 XMEMCPY(output + idx, seq, seqSz); 04659 idx += seqSz; 04660 /* n */ 04661 XMEMCPY(output + idx, n, nSz); 04662 idx += nSz; 04663 /* e */ 04664 XMEMCPY(output + idx, e, eSz); 04665 idx += eSz; 04666 04667 return idx; 04668 } 04669 04670 04671 static INLINE byte itob(int number) 04672 { 04673 return (byte)number + 0x30; 04674 } 04675 04676 04677 /* write time to output, format */ 04678 static void SetTime(struct tm* date, byte* output) 04679 { 04680 int i = 0; 04681 04682 output[i++] = itob((date->tm_year % 10000) / 1000); 04683 output[i++] = itob((date->tm_year % 1000) / 100); 04684 output[i++] = itob((date->tm_year % 100) / 10); 04685 output[i++] = itob( date->tm_year % 10); 04686 04687 output[i++] = itob(date->tm_mon / 10); 04688 output[i++] = itob(date->tm_mon % 10); 04689 04690 output[i++] = itob(date->tm_mday / 10); 04691 output[i++] = itob(date->tm_mday % 10); 04692 04693 output[i++] = itob(date->tm_hour / 10); 04694 output[i++] = itob(date->tm_hour % 10); 04695 04696 output[i++] = itob(date->tm_min / 10); 04697 output[i++] = itob(date->tm_min % 10); 04698 04699 output[i++] = itob(date->tm_sec / 10); 04700 output[i++] = itob(date->tm_sec % 10); 04701 04702 output[i] = 'Z'; /* Zulu profile */ 04703 } 04704 04705 04706 #ifdef CYASSL_ALT_NAMES 04707 04708 /* Copy Dates from cert, return bytes written */ 04709 static int CopyValidity(byte* output, Cert* cert) 04710 { 04711 int seqSz; 04712 04713 CYASSL_ENTER("CopyValidity"); 04714 04715 /* headers and output */ 04716 seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output); 04717 XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz); 04718 XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate, 04719 cert->afterDateSz); 04720 return seqSz + cert->beforeDateSz + cert->afterDateSz; 04721 } 04722 04723 #endif 04724 04725 04726 /* Set Date validity from now until now + daysValid */ 04727 static int SetValidity(byte* output, int daysValid) 04728 { 04729 byte before[MAX_DATE_SIZE]; 04730 byte after[MAX_DATE_SIZE]; 04731 04732 int beforeSz; 04733 int afterSz; 04734 int seqSz; 04735 04736 time_t ticks; 04737 struct tm* now; 04738 struct tm local; 04739 04740 ticks = XTIME(0); 04741 now = XGMTIME(&ticks); 04742 04743 /* before now */ 04744 local = *now; 04745 before[0] = ASN_GENERALIZED_TIME; 04746 beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ 04747 04748 /* subtract 1 day for more compliance */ 04749 local.tm_mday -= 1; 04750 mktime(&local); 04751 04752 /* adjust */ 04753 local.tm_year += 1900; 04754 local.tm_mon += 1; 04755 04756 SetTime(&local, before + beforeSz); 04757 beforeSz += ASN_GEN_TIME_SZ; 04758 04759 /* after now + daysValid */ 04760 local = *now; 04761 after[0] = ASN_GENERALIZED_TIME; 04762 afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ 04763 04764 /* add daysValid */ 04765 local.tm_mday += daysValid; 04766 mktime(&local); 04767 04768 /* adjust */ 04769 local.tm_year += 1900; 04770 local.tm_mon += 1; 04771 04772 SetTime(&local, after + afterSz); 04773 afterSz += ASN_GEN_TIME_SZ; 04774 04775 /* headers and output */ 04776 seqSz = SetSequence(beforeSz + afterSz, output); 04777 XMEMCPY(output + seqSz, before, beforeSz); 04778 XMEMCPY(output + seqSz + beforeSz, after, afterSz); 04779 04780 return seqSz + beforeSz + afterSz; 04781 } 04782 04783 04784 /* ASN Encoded Name field */ 04785 typedef struct EncodedName { 04786 int nameLen; /* actual string value length */ 04787 int totalLen; /* total encoded length */ 04788 int type; /* type of name */ 04789 int used; /* are we actually using this one */ 04790 byte encoded[CTC_NAME_SIZE * 2]; /* encoding */ 04791 } EncodedName; 04792 04793 04794 /* Get Which Name from index */ 04795 static const char* GetOneName(CertName* name, int idx) 04796 { 04797 switch (idx) { 04798 case 0: 04799 return name->country; 04800 04801 case 1: 04802 return name->state; 04803 04804 case 2: 04805 return name->locality; 04806 04807 case 3: 04808 return name->sur; 04809 04810 case 4: 04811 return name->org; 04812 04813 case 5: 04814 return name->unit; 04815 04816 case 6: 04817 return name->commonName; 04818 04819 case 7: 04820 return name->email; 04821 04822 default: 04823 return 0; 04824 } 04825 } 04826 04827 04828 /* Get ASN Name from index */ 04829 static byte GetNameId(int idx) 04830 { 04831 switch (idx) { 04832 case 0: 04833 return ASN_COUNTRY_NAME; 04834 04835 case 1: 04836 return ASN_STATE_NAME; 04837 04838 case 2: 04839 return ASN_LOCALITY_NAME; 04840 04841 case 3: 04842 return ASN_SUR_NAME; 04843 04844 case 4: 04845 return ASN_ORG_NAME; 04846 04847 case 5: 04848 return ASN_ORGUNIT_NAME; 04849 04850 case 6: 04851 return ASN_COMMON_NAME; 04852 04853 case 7: 04854 /* email uses different id type */ 04855 return 0; 04856 04857 default: 04858 return 0; 04859 } 04860 } 04861 04862 04863 /* encode all extensions, return total bytes written */ 04864 static int SetExtensions(byte* output, const byte* ext, int extSz, int header) 04865 { 04866 byte sequence[MAX_SEQ_SZ]; 04867 byte len[MAX_LENGTH_SZ]; 04868 04869 int sz = 0; 04870 int seqSz = SetSequence(extSz, sequence); 04871 04872 if (header) { 04873 int lenSz = SetLength(seqSz + extSz, len); 04874 output[0] = ASN_EXTENSIONS; /* extensions id */ 04875 sz++; 04876 XMEMCPY(&output[sz], len, lenSz); /* length */ 04877 sz += lenSz; 04878 } 04879 XMEMCPY(&output[sz], sequence, seqSz); /* sequence */ 04880 sz += seqSz; 04881 XMEMCPY(&output[sz], ext, extSz); /* extensions */ 04882 sz += extSz; 04883 04884 return sz; 04885 } 04886 04887 04888 /* encode CA basic constraint true, return total bytes written */ 04889 static int SetCa(byte* output) 04890 { 04891 static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 04892 0x05, 0x30, 0x03, 0x01, 0x01, 0xff }; 04893 04894 XMEMCPY(output, ca, sizeof(ca)); 04895 04896 return (int)sizeof(ca); 04897 } 04898 04899 04900 /* encode CertName into output, return total bytes written */ 04901 static int SetName(byte* output, CertName* name) 04902 { 04903 int totalBytes = 0, i, idx; 04904 EncodedName names[NAME_ENTRIES]; 04905 04906 for (i = 0; i < NAME_ENTRIES; i++) { 04907 const char* nameStr = GetOneName(name, i); 04908 if (nameStr) { 04909 /* bottom up */ 04910 byte firstLen[MAX_LENGTH_SZ]; 04911 byte secondLen[MAX_LENGTH_SZ]; 04912 byte sequence[MAX_SEQ_SZ]; 04913 byte set[MAX_SET_SZ]; 04914 04915 int email = i == (NAME_ENTRIES - 1) ? 1 : 0; 04916 int strLen = (int)XSTRLEN(nameStr); 04917 int thisLen = strLen; 04918 int firstSz, secondSz, seqSz, setSz; 04919 04920 if (strLen == 0) { /* no user data for this item */ 04921 names[i].used = 0; 04922 continue; 04923 } 04924 04925 secondSz = SetLength(strLen, secondLen); 04926 thisLen += secondSz; 04927 if (email) { 04928 thisLen += EMAIL_JOINT_LEN; 04929 thisLen ++; /* id type */ 04930 firstSz = SetLength(EMAIL_JOINT_LEN, firstLen); 04931 } 04932 else { 04933 thisLen++; /* str type */ 04934 thisLen++; /* id type */ 04935 thisLen += JOINT_LEN; 04936 firstSz = SetLength(JOINT_LEN + 1, firstLen); 04937 } 04938 thisLen += firstSz; 04939 thisLen++; /* object id */ 04940 04941 seqSz = SetSequence(thisLen, sequence); 04942 thisLen += seqSz; 04943 setSz = SetSet(thisLen, set); 04944 thisLen += setSz; 04945 04946 if (thisLen > (int)sizeof(names[i].encoded)) 04947 return BUFFER_E; 04948 04949 /* store it */ 04950 idx = 0; 04951 /* set */ 04952 XMEMCPY(names[i].encoded, set, setSz); 04953 idx += setSz; 04954 /* seq */ 04955 XMEMCPY(names[i].encoded + idx, sequence, seqSz); 04956 idx += seqSz; 04957 /* asn object id */ 04958 names[i].encoded[idx++] = ASN_OBJECT_ID; 04959 /* first length */ 04960 XMEMCPY(names[i].encoded + idx, firstLen, firstSz); 04961 idx += firstSz; 04962 if (email) { 04963 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 04964 0x01, 0x09, 0x01, 0x16 }; 04965 /* email joint id */ 04966 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); 04967 idx += (int)sizeof(EMAIL_OID); 04968 } 04969 else { 04970 /* joint id */ 04971 byte bType = GetNameId(i); 04972 names[i].encoded[idx++] = 0x55; 04973 names[i].encoded[idx++] = 0x04; 04974 /* id type */ 04975 names[i].encoded[idx++] = bType; 04976 /* str type */ 04977 if (bType == ASN_COUNTRY_NAME) 04978 names[i].encoded[idx++] = 0x13; /* printable */ 04979 else 04980 names[i].encoded[idx++] = 0x0c; /* utf8 */ 04981 } 04982 /* second length */ 04983 XMEMCPY(names[i].encoded + idx, secondLen, secondSz); 04984 idx += secondSz; 04985 /* str value */ 04986 XMEMCPY(names[i].encoded + idx, nameStr, strLen); 04987 idx += strLen; 04988 04989 totalBytes += idx; 04990 names[i].totalLen = idx; 04991 names[i].used = 1; 04992 } 04993 else 04994 names[i].used = 0; 04995 } 04996 04997 /* header */ 04998 idx = SetSequence(totalBytes, output); 04999 totalBytes += idx; 05000 if (totalBytes > ASN_NAME_MAX) 05001 return BUFFER_E; 05002 05003 for (i = 0; i < NAME_ENTRIES; i++) { 05004 if (names[i].used) { 05005 XMEMCPY(output + idx, names[i].encoded, names[i].totalLen); 05006 idx += names[i].totalLen; 05007 } 05008 } 05009 return totalBytes; 05010 } 05011 05012 /* encode info from cert into DER encoded format */ 05013 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, 05014 RNG* rng, const byte* ntruKey, word16 ntruSz) 05015 { 05016 int ret; 05017 05018 (void)eccKey; 05019 (void)ntruKey; 05020 (void)ntruSz; 05021 05022 /* init */ 05023 XMEMSET(der, 0, sizeof(DerCert)); 05024 05025 /* version */ 05026 der->versionSz = SetMyVersion(cert->version, der->version, TRUE); 05027 05028 /* serial number */ 05029 ret = RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); 05030 if (ret != 0) 05031 return ret; 05032 05033 cert->serial[0] = 0x01; /* ensure positive */ 05034 der->serialSz = SetSerial(cert->serial, der->serial); 05035 05036 /* signature algo */ 05037 der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0); 05038 if (der->sigAlgoSz == 0) 05039 return ALGO_ID_E; 05040 05041 /* public key */ 05042 if (cert->keyType == RSA_KEY) { 05043 if (rsaKey == NULL) 05044 return PUBLIC_KEY_E; 05045 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); 05046 if (der->publicKeySz <= 0) 05047 return PUBLIC_KEY_E; 05048 } 05049 05050 #ifdef HAVE_ECC 05051 if (cert->keyType == ECC_KEY) { 05052 if (eccKey == NULL) 05053 return PUBLIC_KEY_E; 05054 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); 05055 if (der->publicKeySz <= 0) 05056 return PUBLIC_KEY_E; 05057 } 05058 #endif /* HAVE_ECC */ 05059 05060 #ifdef HAVE_NTRU 05061 if (cert->keyType == NTRU_KEY) { 05062 word32 rc; 05063 word16 encodedSz; 05064 05065 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, 05066 ntruKey, &encodedSz, NULL); 05067 if (rc != NTRU_OK) 05068 return PUBLIC_KEY_E; 05069 if (encodedSz > MAX_PUBLIC_KEY_SZ) 05070 return PUBLIC_KEY_E; 05071 05072 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, 05073 ntruKey, &encodedSz, der->publicKey); 05074 if (rc != NTRU_OK) 05075 return PUBLIC_KEY_E; 05076 05077 der->publicKeySz = encodedSz; 05078 } 05079 #endif /* HAVE_NTRU */ 05080 05081 der->validitySz = 0; 05082 #ifdef CYASSL_ALT_NAMES 05083 /* date validity copy ? */ 05084 if (cert->beforeDateSz && cert->afterDateSz) { 05085 der->validitySz = CopyValidity(der->validity, cert); 05086 if (der->validitySz == 0) 05087 return DATE_E; 05088 } 05089 #endif 05090 05091 /* date validity */ 05092 if (der->validitySz == 0) { 05093 der->validitySz = SetValidity(der->validity, cert->daysValid); 05094 if (der->validitySz == 0) 05095 return DATE_E; 05096 } 05097 05098 /* subject name */ 05099 der->subjectSz = SetName(der->subject, &cert->subject); 05100 if (der->subjectSz == 0) 05101 return SUBJECT_E; 05102 05103 /* issuer name */ 05104 der->issuerSz = SetName(der->issuer, cert->selfSigned ? 05105 &cert->subject : &cert->issuer); 05106 if (der->issuerSz == 0) 05107 return ISSUER_E; 05108 05109 /* CA */ 05110 if (cert->isCA) { 05111 der->caSz = SetCa(der->ca); 05112 if (der->caSz == 0) 05113 return CA_TRUE_E; 05114 } 05115 else 05116 der->caSz = 0; 05117 05118 /* extensions, just CA now */ 05119 if (cert->isCA) { 05120 der->extensionsSz = SetExtensions(der->extensions, 05121 der->ca, der->caSz, TRUE); 05122 if (der->extensionsSz == 0) 05123 return EXTENSIONS_E; 05124 } 05125 else 05126 der->extensionsSz = 0; 05127 05128 #ifdef CYASSL_ALT_NAMES 05129 if (der->extensionsSz == 0 && cert->altNamesSz) { 05130 der->extensionsSz = SetExtensions(der->extensions, cert->altNames, 05131 cert->altNamesSz, TRUE); 05132 if (der->extensionsSz == 0) 05133 return EXTENSIONS_E; 05134 } 05135 #endif 05136 05137 der->total = der->versionSz + der->serialSz + der->sigAlgoSz + 05138 der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz + 05139 der->extensionsSz; 05140 05141 return 0; 05142 } 05143 05144 05145 /* write DER encoded cert to buffer, size already checked */ 05146 static int WriteCertBody(DerCert* der, byte* buffer) 05147 { 05148 int idx; 05149 05150 /* signed part header */ 05151 idx = SetSequence(der->total, buffer); 05152 /* version */ 05153 XMEMCPY(buffer + idx, der->version, der->versionSz); 05154 idx += der->versionSz; 05155 /* serial */ 05156 XMEMCPY(buffer + idx, der->serial, der->serialSz); 05157 idx += der->serialSz; 05158 /* sig algo */ 05159 XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz); 05160 idx += der->sigAlgoSz; 05161 /* issuer */ 05162 XMEMCPY(buffer + idx, der->issuer, der->issuerSz); 05163 idx += der->issuerSz; 05164 /* validity */ 05165 XMEMCPY(buffer + idx, der->validity, der->validitySz); 05166 idx += der->validitySz; 05167 /* subject */ 05168 XMEMCPY(buffer + idx, der->subject, der->subjectSz); 05169 idx += der->subjectSz; 05170 /* public key */ 05171 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); 05172 idx += der->publicKeySz; 05173 if (der->extensionsSz) { 05174 /* extensions */ 05175 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, 05176 sizeof(der->extensions))); 05177 idx += der->extensionsSz; 05178 } 05179 05180 return idx; 05181 } 05182 05183 05184 /* Make RSA signature from buffer (sz), write to sig (sigSz) */ 05185 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, 05186 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, 05187 int sigAlgoType) 05188 { 05189 byte digest[SHA256_DIGEST_SIZE]; /* max size */ 05190 byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; 05191 int encSigSz, digestSz, typeH, ret = 0; 05192 05193 (void)eccKey; 05194 05195 if (sigAlgoType == CTC_MD5wRSA) { 05196 Md5 md5; 05197 05198 InitMd5(&md5); 05199 Md5Update(&md5, buffer, sz); 05200 Md5Final(&md5, digest); 05201 05202 digestSz = MD5_DIGEST_SIZE; 05203 typeH = MD5h; 05204 } 05205 else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) { 05206 Sha sha; 05207 05208 ret = InitSha(&sha); 05209 if (ret != 0) 05210 return ret; 05211 05212 ShaUpdate(&sha, buffer, sz); 05213 ShaFinal(&sha, digest); 05214 05215 digestSz = SHA_DIGEST_SIZE; 05216 typeH = SHAh; 05217 } 05218 else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) { 05219 Sha256 sha256; 05220 05221 ret = InitSha256(&sha256); 05222 if (ret != 0) 05223 return ret; 05224 05225 ret = Sha256Update(&sha256, buffer, sz); 05226 if (ret != 0) 05227 return ret; 05228 05229 ret = Sha256Final(&sha256, digest); 05230 if (ret != 0) 05231 return ret; 05232 05233 digestSz = SHA256_DIGEST_SIZE; 05234 typeH = SHA256h; 05235 } 05236 else 05237 return ALGO_ID_E; 05238 05239 if (rsaKey) { 05240 /* signature */ 05241 encSigSz = EncodeSignature(encSig, digest, digestSz, typeH); 05242 return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); 05243 } 05244 #ifdef HAVE_ECC 05245 else if (eccKey) { 05246 word32 outSz = sigSz; 05247 ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey); 05248 05249 if (ret != 0) 05250 return ret; 05251 return outSz; 05252 } 05253 #endif /* HAVE_ECC */ 05254 05255 return ALGO_ID_E; 05256 } 05257 05258 05259 /* add signature to end of buffer, size of buffer assumed checked, return 05260 new length */ 05261 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz, 05262 int sigAlgoType) 05263 { 05264 byte seq[MAX_SEQ_SZ]; 05265 int idx = bodySz, seqSz; 05266 05267 /* algo */ 05268 idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0); 05269 /* bit string */ 05270 buffer[idx++] = ASN_BIT_STRING; 05271 /* length */ 05272 idx += SetLength(sigSz + 1, buffer + idx); 05273 buffer[idx++] = 0; /* trailing 0 */ 05274 /* signature */ 05275 XMEMCPY(buffer + idx, sig, sigSz); 05276 idx += sigSz; 05277 05278 /* make room for overall header */ 05279 seqSz = SetSequence(idx, seq); 05280 XMEMMOVE(buffer + seqSz, buffer, idx); 05281 XMEMCPY(buffer, seq, seqSz); 05282 05283 return idx + seqSz; 05284 } 05285 05286 05287 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */ 05288 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, 05289 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, 05290 const byte* ntruKey, word16 ntruSz) 05291 { 05292 DerCert der; 05293 int ret; 05294 05295 if (eccKey) 05296 cert->keyType = ECC_KEY; 05297 else 05298 cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY; 05299 ret = EncodeCert(cert, &der, rsaKey, eccKey, rng, ntruKey, ntruSz); 05300 if (ret != 0) 05301 return ret; 05302 05303 if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) 05304 return BUFFER_E; 05305 05306 return cert->bodySz = WriteCertBody(&der, derBuffer); 05307 } 05308 05309 05310 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ 05311 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, 05312 ecc_key* eccKey, RNG* rng) 05313 { 05314 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0); 05315 } 05316 05317 05318 #ifdef HAVE_NTRU 05319 05320 int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, 05321 const byte* ntruKey, word16 keySz, RNG* rng) 05322 { 05323 return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz); 05324 } 05325 05326 #endif /* HAVE_NTRU */ 05327 05328 05329 #ifdef CYASSL_CERT_REQ 05330 05331 static int SetReqAttrib(byte* output, char* pw, int extSz) 05332 { 05333 static const byte cpOid[] = 05334 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 05335 0x09, 0x07 }; 05336 static const byte erOid[] = 05337 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 05338 0x09, 0x0e }; 05339 05340 int sz = 0; /* overall size */ 05341 int cpSz = 0; /* Challenge Password section size */ 05342 int cpSeqSz = 0; 05343 int cpSetSz = 0; 05344 int cpStrSz = 0; 05345 int pwSz = 0; 05346 int erSz = 0; /* Extension Request section size */ 05347 int erSeqSz = 0; 05348 int erSetSz = 0; 05349 byte cpSeq[MAX_SEQ_SZ]; 05350 byte cpSet[MAX_SET_SZ]; 05351 byte cpStr[MAX_PRSTR_SZ]; 05352 byte erSeq[MAX_SEQ_SZ]; 05353 byte erSet[MAX_SET_SZ]; 05354 05355 output[0] = 0xa0; 05356 sz++; 05357 05358 if (pw && pw[0]) { 05359 pwSz = (int)XSTRLEN(pw); 05360 cpStrSz = SetUTF8String(pwSz, cpStr); 05361 cpSetSz = SetSet(cpStrSz + pwSz, cpSet); 05362 cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq); 05363 cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz; 05364 } 05365 05366 if (extSz) { 05367 erSetSz = SetSet(extSz, erSet); 05368 erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq); 05369 erSz = extSz + erSetSz + erSeqSz + sizeof(erOid); 05370 } 05371 05372 /* Put the pieces together. */ 05373 sz += SetLength(cpSz + erSz, &output[sz]); 05374 05375 if (cpSz) { 05376 XMEMCPY(&output[sz], cpSeq, cpSeqSz); 05377 sz += cpSeqSz; 05378 XMEMCPY(&output[sz], cpOid, sizeof(cpOid)); 05379 sz += sizeof(cpOid); 05380 XMEMCPY(&output[sz], cpSet, cpSetSz); 05381 sz += cpSetSz; 05382 XMEMCPY(&output[sz], cpStr, cpStrSz); 05383 sz += cpStrSz; 05384 XMEMCPY(&output[sz], pw, pwSz); 05385 sz += pwSz; 05386 } 05387 05388 if (erSz) { 05389 XMEMCPY(&output[sz], erSeq, erSeqSz); 05390 sz += erSeqSz; 05391 XMEMCPY(&output[sz], erOid, sizeof(erOid)); 05392 sz += sizeof(erOid); 05393 XMEMCPY(&output[sz], erSet, erSetSz); 05394 sz += erSetSz; 05395 /* The actual extension data will be tacked onto the output later. */ 05396 } 05397 05398 return sz; 05399 } 05400 05401 05402 /* encode info from cert into DER encoded format */ 05403 static int EncodeCertReq(Cert* cert, DerCert* der, 05404 RsaKey* rsaKey, ecc_key* eccKey) 05405 { 05406 (void)eccKey; 05407 05408 /* init */ 05409 XMEMSET(der, 0, sizeof(DerCert)); 05410 05411 /* version */ 05412 der->versionSz = SetMyVersion(cert->version, der->version, FALSE); 05413 05414 /* subject name */ 05415 der->subjectSz = SetName(der->subject, &cert->subject); 05416 if (der->subjectSz == 0) 05417 return SUBJECT_E; 05418 05419 /* public key */ 05420 if (cert->keyType == RSA_KEY) { 05421 if (rsaKey == NULL) 05422 return PUBLIC_KEY_E; 05423 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); 05424 if (der->publicKeySz <= 0) 05425 return PUBLIC_KEY_E; 05426 } 05427 05428 #ifdef HAVE_ECC 05429 if (cert->keyType == ECC_KEY) { 05430 if (eccKey == NULL) 05431 return PUBLIC_KEY_E; 05432 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); 05433 if (der->publicKeySz <= 0) 05434 return PUBLIC_KEY_E; 05435 } 05436 #endif /* HAVE_ECC */ 05437 05438 /* CA */ 05439 if (cert->isCA) { 05440 der->caSz = SetCa(der->ca); 05441 if (der->caSz == 0) 05442 return CA_TRUE_E; 05443 } 05444 else 05445 der->caSz = 0; 05446 05447 /* extensions, just CA now */ 05448 if (cert->isCA) { 05449 der->extensionsSz = SetExtensions(der->extensions, 05450 der->ca, der->caSz, FALSE); 05451 if (der->extensionsSz == 0) 05452 return EXTENSIONS_E; 05453 } 05454 else 05455 der->extensionsSz = 0; 05456 05457 der->attribSz = SetReqAttrib(der->attrib, 05458 cert->challengePw, der->extensionsSz); 05459 if (der->attribSz == 0) 05460 return REQ_ATTRIBUTE_E; 05461 05462 der->total = der->versionSz + der->subjectSz + der->publicKeySz + 05463 der->extensionsSz + der->attribSz; 05464 05465 return 0; 05466 } 05467 05468 05469 /* write DER encoded cert req to buffer, size already checked */ 05470 static int WriteCertReqBody(DerCert* der, byte* buffer) 05471 { 05472 int idx; 05473 05474 /* signed part header */ 05475 idx = SetSequence(der->total, buffer); 05476 /* version */ 05477 XMEMCPY(buffer + idx, der->version, der->versionSz); 05478 idx += der->versionSz; 05479 /* subject */ 05480 XMEMCPY(buffer + idx, der->subject, der->subjectSz); 05481 idx += der->subjectSz; 05482 /* public key */ 05483 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); 05484 idx += der->publicKeySz; 05485 /* attributes */ 05486 XMEMCPY(buffer + idx, der->attrib, der->attribSz); 05487 idx += der->attribSz; 05488 /* extensions */ 05489 if (der->extensionsSz) { 05490 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, 05491 sizeof(der->extensions))); 05492 idx += der->extensionsSz; 05493 } 05494 05495 return idx; 05496 } 05497 05498 05499 int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, 05500 RsaKey* rsaKey, ecc_key* eccKey) 05501 { 05502 DerCert der; 05503 int ret; 05504 05505 cert->keyType = (eccKey != NULL) ? ECC_KEY : RSA_KEY; 05506 ret = EncodeCertReq(cert, &der, rsaKey, eccKey); 05507 if (ret != 0) 05508 return ret; 05509 05510 if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) 05511 return BUFFER_E; 05512 05513 return cert->bodySz = WriteCertReqBody(&der, derBuffer); 05514 } 05515 05516 #endif /* CYASSL_CERT_REQ */ 05517 05518 05519 int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, 05520 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng) 05521 { 05522 byte sig[MAX_ENCODED_SIG_SZ]; 05523 int sigSz; 05524 05525 if (requestSz < 0) 05526 return requestSz; 05527 05528 sigSz = MakeSignature(buffer, requestSz, sig, sizeof(sig), rsaKey, eccKey, 05529 rng, sType); 05530 if (sigSz < 0) 05531 return sigSz; 05532 05533 if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) 05534 return BUFFER_E; 05535 05536 return AddSignature(buffer, requestSz, sig, sigSz, sType); 05537 } 05538 05539 05540 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) 05541 { 05542 int ret = MakeCert(cert, buffer, buffSz, key, NULL, rng); 05543 05544 if (ret < 0) 05545 return ret; 05546 05547 return SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng); 05548 } 05549 05550 05551 #ifdef CYASSL_ALT_NAMES 05552 05553 /* Set Alt Names from der cert, return 0 on success */ 05554 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) 05555 { 05556 DecodedCert decoded; 05557 int ret; 05558 05559 if (derSz < 0) 05560 return derSz; 05561 05562 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05563 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05564 05565 if (ret < 0) { 05566 FreeDecodedCert(&decoded); 05567 return ret; 05568 } 05569 05570 if (decoded.extensions) { 05571 byte b; 05572 int length; 05573 word32 maxExtensionsIdx; 05574 05575 decoded.srcIdx = decoded.extensionsIdx; 05576 b = decoded.source[decoded.srcIdx++]; 05577 if (b != ASN_EXTENSIONS) { 05578 FreeDecodedCert(&decoded); 05579 return ASN_PARSE_E; 05580 } 05581 05582 if (GetLength(decoded.source, &decoded.srcIdx, &length, 05583 decoded.maxIdx) < 0) { 05584 FreeDecodedCert(&decoded); 05585 return ASN_PARSE_E; 05586 } 05587 05588 if (GetSequence(decoded.source, &decoded.srcIdx, &length, 05589 decoded.maxIdx) < 0) { 05590 FreeDecodedCert(&decoded); 05591 return ASN_PARSE_E; 05592 } 05593 05594 maxExtensionsIdx = decoded.srcIdx + length; 05595 05596 while (decoded.srcIdx < maxExtensionsIdx) { 05597 word32 oid; 05598 word32 startIdx = decoded.srcIdx; 05599 word32 tmpIdx; 05600 05601 if (GetSequence(decoded.source, &decoded.srcIdx, &length, 05602 decoded.maxIdx) < 0) { 05603 FreeDecodedCert(&decoded); 05604 return ASN_PARSE_E; 05605 } 05606 05607 tmpIdx = decoded.srcIdx; 05608 decoded.srcIdx = startIdx; 05609 05610 if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid, 05611 decoded.maxIdx) < 0) { 05612 FreeDecodedCert(&decoded); 05613 return ASN_PARSE_E; 05614 } 05615 05616 if (oid == ALT_NAMES_OID) { 05617 cert->altNamesSz = length + (tmpIdx - startIdx); 05618 05619 if (cert->altNamesSz < (int)sizeof(cert->altNames)) 05620 XMEMCPY(cert->altNames, &decoded.source[startIdx], 05621 cert->altNamesSz); 05622 else { 05623 cert->altNamesSz = 0; 05624 CYASSL_MSG("AltNames extensions too big"); 05625 FreeDecodedCert(&decoded); 05626 return ALT_NAME_E; 05627 } 05628 } 05629 decoded.srcIdx = tmpIdx + length; 05630 } 05631 } 05632 FreeDecodedCert(&decoded); 05633 05634 return 0; 05635 } 05636 05637 05638 /* Set Dates from der cert, return 0 on success */ 05639 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) 05640 { 05641 DecodedCert decoded; 05642 int ret; 05643 05644 CYASSL_ENTER("SetDatesFromCert"); 05645 if (derSz < 0) 05646 return derSz; 05647 05648 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05649 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05650 05651 if (ret < 0) { 05652 CYASSL_MSG("ParseCertRelative error"); 05653 FreeDecodedCert(&decoded); 05654 return ret; 05655 } 05656 05657 if (decoded.beforeDate == NULL || decoded.afterDate == NULL) { 05658 CYASSL_MSG("Couldn't extract dates"); 05659 FreeDecodedCert(&decoded); 05660 return -1; 05661 } 05662 05663 if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen > 05664 MAX_DATE_SIZE) { 05665 CYASSL_MSG("Bad date size"); 05666 FreeDecodedCert(&decoded); 05667 return -1; 05668 } 05669 05670 XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen); 05671 XMEMCPY(cert->afterDate, decoded.afterDate, decoded.afterDateLen); 05672 05673 cert->beforeDateSz = decoded.beforeDateLen; 05674 cert->afterDateSz = decoded.afterDateLen; 05675 05676 return 0; 05677 } 05678 05679 05680 #endif /* CYASSL_ALT_NAMES && !NO_RSA */ 05681 05682 05683 /* Set cn name from der buffer, return 0 on success */ 05684 static int SetNameFromCert(CertName* cn, const byte* der, int derSz) 05685 { 05686 DecodedCert decoded; 05687 int ret; 05688 int sz; 05689 05690 if (derSz < 0) 05691 return derSz; 05692 05693 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05694 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05695 05696 if (ret < 0) 05697 return ret; 05698 05699 if (decoded.subjectCN) { 05700 sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen : 05701 CTC_NAME_SIZE - 1; 05702 strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE); 05703 cn->commonName[sz] = 0; 05704 } 05705 if (decoded.subjectC) { 05706 sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen : 05707 CTC_NAME_SIZE - 1; 05708 strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE); 05709 cn->country[sz] = 0; 05710 } 05711 if (decoded.subjectST) { 05712 sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen : 05713 CTC_NAME_SIZE - 1; 05714 strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE); 05715 cn->state[sz] = 0; 05716 } 05717 if (decoded.subjectL) { 05718 sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen : 05719 CTC_NAME_SIZE - 1; 05720 strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE); 05721 cn->locality[sz] = 0; 05722 } 05723 if (decoded.subjectO) { 05724 sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen : 05725 CTC_NAME_SIZE - 1; 05726 strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE); 05727 cn->org[sz] = 0; 05728 } 05729 if (decoded.subjectOU) { 05730 sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen : 05731 CTC_NAME_SIZE - 1; 05732 strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE); 05733 cn->unit[sz] = 0; 05734 } 05735 if (decoded.subjectSN) { 05736 sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen : 05737 CTC_NAME_SIZE - 1; 05738 strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE); 05739 cn->sur[sz] = 0; 05740 } 05741 if (decoded.subjectEmail) { 05742 sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ? 05743 decoded.subjectEmailLen : CTC_NAME_SIZE - 1; 05744 strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE); 05745 cn->email[sz] = 0; 05746 } 05747 05748 FreeDecodedCert(&decoded); 05749 05750 return 0; 05751 } 05752 05753 05754 #ifndef NO_FILESYSTEM 05755 05756 /* forward from CyaSSL */ 05757 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz); 05758 05759 /* Set cert issuer from issuerFile in PEM */ 05760 int SetIssuer(Cert* cert, const char* issuerFile) 05761 { 05762 int ret; 05763 int derSz; 05764 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05765 05766 if (der == NULL) { 05767 CYASSL_MSG("SetIssuer OOF Problem"); 05768 return MEMORY_E; 05769 } 05770 derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF); 05771 cert->selfSigned = 0; 05772 ret = SetNameFromCert(&cert->issuer, der, derSz); 05773 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05774 05775 return ret; 05776 } 05777 05778 05779 /* Set cert subject from subjectFile in PEM */ 05780 int SetSubject(Cert* cert, const char* subjectFile) 05781 { 05782 int ret; 05783 int derSz; 05784 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05785 05786 if (der == NULL) { 05787 CYASSL_MSG("SetSubject OOF Problem"); 05788 return MEMORY_E; 05789 } 05790 derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF); 05791 ret = SetNameFromCert(&cert->subject, der, derSz); 05792 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05793 05794 return ret; 05795 } 05796 05797 05798 #ifdef CYASSL_ALT_NAMES 05799 05800 /* Set atl names from file in PEM */ 05801 int SetAltNames(Cert* cert, const char* file) 05802 { 05803 int ret; 05804 int derSz; 05805 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05806 05807 if (der == NULL) { 05808 CYASSL_MSG("SetAltNames OOF Problem"); 05809 return MEMORY_E; 05810 } 05811 derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF); 05812 ret = SetAltNamesFromCert(cert, der, derSz); 05813 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05814 05815 return ret; 05816 } 05817 05818 #endif /* CYASSL_ALT_NAMES */ 05819 05820 #endif /* NO_FILESYSTEM */ 05821 05822 /* Set cert issuer from DER buffer */ 05823 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz) 05824 { 05825 cert->selfSigned = 0; 05826 return SetNameFromCert(&cert->issuer, der, derSz); 05827 } 05828 05829 05830 /* Set cert subject from DER buffer */ 05831 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz) 05832 { 05833 return SetNameFromCert(&cert->subject, der, derSz); 05834 } 05835 05836 05837 #ifdef CYASSL_ALT_NAMES 05838 05839 /* Set cert alt names from DER buffer */ 05840 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) 05841 { 05842 return SetAltNamesFromCert(cert, der, derSz); 05843 } 05844 05845 /* Set cert dates from DER buffer */ 05846 int SetDatesBuffer(Cert* cert, const byte* der, int derSz) 05847 { 05848 return SetDatesFromCert(cert, der, derSz); 05849 } 05850 05851 #endif /* CYASSL_ALT_NAMES */ 05852 05853 #endif /* CYASSL_CERT_GEN */ 05854 05855 05856 #ifdef HAVE_ECC 05857 05858 /* Der Encode r & s ints into out, outLen is (in/out) size */ 05859 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) 05860 { 05861 word32 idx = 0; 05862 word32 rSz; /* encoding size */ 05863 word32 sSz; 05864 word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */ 05865 05866 /* If the leading bit on the INTEGER is a 1, add a leading zero */ 05867 int rLeadingZero = mp_leading_bit(r); 05868 int sLeadingZero = mp_leading_bit(s); 05869 int rLen = mp_unsigned_bin_size(r); /* big int size */ 05870 int sLen = mp_unsigned_bin_size(s); 05871 int err; 05872 05873 if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero + 05874 headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */ 05875 return BAD_FUNC_ARG; 05876 05877 idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out); 05878 05879 /* store r */ 05880 out[idx++] = ASN_INTEGER; 05881 rSz = SetLength(rLen + rLeadingZero, &out[idx]); 05882 idx += rSz; 05883 if (rLeadingZero) 05884 out[idx++] = 0; 05885 err = mp_to_unsigned_bin(r, &out[idx]); 05886 if (err != MP_OKAY) return err; 05887 idx += rLen; 05888 05889 /* store s */ 05890 out[idx++] = ASN_INTEGER; 05891 sSz = SetLength(sLen + sLeadingZero, &out[idx]); 05892 idx += sSz; 05893 if (sLeadingZero) 05894 out[idx++] = 0; 05895 err = mp_to_unsigned_bin(s, &out[idx]); 05896 if (err != MP_OKAY) return err; 05897 idx += sLen; 05898 05899 *outLen = idx; 05900 05901 return 0; 05902 } 05903 05904 05905 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */ 05906 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) 05907 { 05908 word32 idx = 0; 05909 int len = 0; 05910 05911 if (GetSequence(sig, &idx, &len, sigLen) < 0) 05912 return ASN_ECC_KEY_E; 05913 05914 if ((word32)len > (sigLen - idx)) 05915 return ASN_ECC_KEY_E; 05916 05917 if (GetInt(r, sig, &idx, sigLen) < 0) 05918 return ASN_ECC_KEY_E; 05919 05920 if (GetInt(s, sig, &idx, sigLen) < 0) 05921 return ASN_ECC_KEY_E; 05922 05923 return 0; 05924 } 05925 05926 05927 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, 05928 word32 inSz) 05929 { 05930 word32 oid = 0; 05931 int version, length; 05932 int privSz, pubSz; 05933 byte b; 05934 byte priv[ECC_MAXSIZE]; 05935 byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ 05936 05937 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) 05938 return BAD_FUNC_ARG; 05939 05940 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 05941 return ASN_PARSE_E; 05942 05943 if (GetMyVersion(input, inOutIdx, &version) < 0) 05944 return ASN_PARSE_E; 05945 05946 b = input[*inOutIdx]; 05947 *inOutIdx += 1; 05948 05949 /* priv type */ 05950 if (b != 4 && b != 6 && b != 7) 05951 return ASN_PARSE_E; 05952 05953 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05954 return ASN_PARSE_E; 05955 05956 /* priv key */ 05957 privSz = length; 05958 XMEMCPY(priv, &input[*inOutIdx], privSz); 05959 *inOutIdx += length; 05960 05961 /* prefix 0, may have */ 05962 b = input[*inOutIdx]; 05963 if (b == ECC_PREFIX_0) { 05964 *inOutIdx += 1; 05965 05966 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05967 return ASN_PARSE_E; 05968 05969 /* object id */ 05970 b = input[*inOutIdx]; 05971 *inOutIdx += 1; 05972 05973 if (b != ASN_OBJECT_ID) 05974 return ASN_OBJECT_ID_E; 05975 05976 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05977 return ASN_PARSE_E; 05978 05979 while(length--) { 05980 oid += input[*inOutIdx]; 05981 *inOutIdx += 1; 05982 } 05983 if (CheckCurve(oid) < 0) 05984 return ECC_CURVE_OID_E; 05985 } 05986 05987 /* prefix 1 */ 05988 b = input[*inOutIdx]; 05989 *inOutIdx += 1; 05990 if (b != ECC_PREFIX_1) 05991 return ASN_ECC_KEY_E; 05992 05993 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05994 return ASN_PARSE_E; 05995 05996 /* key header */ 05997 b = input[*inOutIdx]; 05998 *inOutIdx += 1; 05999 if (b != ASN_BIT_STRING) 06000 return ASN_BITSTR_E; 06001 06002 if (GetLength(input, inOutIdx, &length, inSz) < 0) 06003 return ASN_PARSE_E; 06004 b = input[*inOutIdx]; 06005 *inOutIdx += 1; 06006 if (b != 0x00) 06007 return ASN_EXPECT_0_E; 06008 06009 pubSz = length - 1; /* null prefix */ 06010 XMEMCPY(pub, &input[*inOutIdx], pubSz); 06011 06012 *inOutIdx += length; 06013 06014 return ecc_import_private_key(priv, privSz, pub, pubSz, key); 06015 } 06016 06017 #endif /* HAVE_ECC */ 06018 06019 06020 #if defined(HAVE_OCSP) || defined(HAVE_CRL) 06021 06022 /* Get raw Date only, no processing, 0 on success */ 06023 static int GetBasicDate(const byte* source, word32* idx, byte* date, 06024 byte* format, int maxIdx) 06025 { 06026 int length; 06027 06028 CYASSL_ENTER("GetBasicDate"); 06029 06030 *format = source[*idx]; 06031 *idx += 1; 06032 if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME) 06033 return ASN_TIME_E; 06034 06035 if (GetLength(source, idx, &length, maxIdx) < 0) 06036 return ASN_PARSE_E; 06037 06038 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) 06039 return ASN_DATE_SZ_E; 06040 06041 XMEMCPY(date, &source[*idx], length); 06042 *idx += length; 06043 06044 return 0; 06045 } 06046 06047 #endif 06048 06049 06050 #ifdef HAVE_OCSP 06051 06052 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value) 06053 { 06054 word32 idx = *inOutIdx; 06055 word32 len; 06056 06057 CYASSL_ENTER("GetEnumerated"); 06058 06059 *value = 0; 06060 06061 if (input[idx++] != ASN_ENUMERATED) 06062 return ASN_PARSE_E; 06063 06064 len = input[idx++]; 06065 if (len > 4) 06066 return ASN_PARSE_E; 06067 06068 while (len--) { 06069 *value = *value << 8 | input[idx++]; 06070 } 06071 06072 *inOutIdx = idx; 06073 06074 return *value; 06075 } 06076 06077 06078 static int DecodeSingleResponse(byte* source, 06079 word32* ioIndex, OcspResponse* resp, word32 size) 06080 { 06081 word32 idx = *ioIndex, prevIndex, oid; 06082 int length, wrapperSz; 06083 CertStatus* cs = resp->status; 06084 06085 CYASSL_ENTER("DecodeSingleResponse"); 06086 06087 /* Outer wrapper of the SEQUENCE OF Single Responses. */ 06088 if (GetSequence(source, &idx, &wrapperSz, size) < 0) 06089 return ASN_PARSE_E; 06090 06091 prevIndex = idx; 06092 06093 /* When making a request, we only request one status on one certificate 06094 * at a time. There should only be one SingleResponse */ 06095 06096 /* Wrapper around the Single Response */ 06097 if (GetSequence(source, &idx, &length, size) < 0) 06098 return ASN_PARSE_E; 06099 06100 /* Wrapper around the CertID */ 06101 if (GetSequence(source, &idx, &length, size) < 0) 06102 return ASN_PARSE_E; 06103 /* Skip the hash algorithm */ 06104 if (GetAlgoId(source, &idx, &oid, size) < 0) 06105 return ASN_PARSE_E; 06106 /* Save reference to the hash of CN */ 06107 if (source[idx++] != ASN_OCTET_STRING) 06108 return ASN_PARSE_E; 06109 if (GetLength(source, &idx, &length, size) < 0) 06110 return ASN_PARSE_E; 06111 resp->issuerHash = source + idx; 06112 idx += length; 06113 /* Save reference to the hash of the issuer public key */ 06114 if (source[idx++] != ASN_OCTET_STRING) 06115 return ASN_PARSE_E; 06116 if (GetLength(source, &idx, &length, size) < 0) 06117 return ASN_PARSE_E; 06118 resp->issuerKeyHash = source + idx; 06119 idx += length; 06120 06121 /* Read the serial number, it is handled as a string, not as a 06122 * proper number. Just XMEMCPY the data over, rather than load it 06123 * as an mp_int. */ 06124 if (source[idx++] != ASN_INTEGER) 06125 return ASN_PARSE_E; 06126 if (GetLength(source, &idx, &length, size) < 0) 06127 return ASN_PARSE_E; 06128 if (length <= EXTERNAL_SERIAL_SIZE) 06129 { 06130 if (source[idx] == 0) 06131 { 06132 idx++; 06133 length--; 06134 } 06135 XMEMCPY(cs->serial, source + idx, length); 06136 cs->serialSz = length; 06137 } 06138 else 06139 { 06140 return ASN_GETINT_E; 06141 } 06142 idx += length; 06143 06144 /* CertStatus */ 06145 switch (source[idx++]) 06146 { 06147 case (ASN_CONTEXT_SPECIFIC | CERT_GOOD): 06148 cs->status = CERT_GOOD; 06149 idx++; 06150 break; 06151 case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED): 06152 cs->status = CERT_REVOKED; 06153 if (GetLength(source, &idx, &length, size) < 0) 06154 return ASN_PARSE_E; 06155 idx += length; 06156 break; 06157 case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN): 06158 cs->status = CERT_UNKNOWN; 06159 idx++; 06160 break; 06161 default: 06162 return ASN_PARSE_E; 06163 } 06164 06165 if (GetBasicDate(source, &idx, cs->thisDate, 06166 &cs->thisDateFormat, size) < 0) 06167 return ASN_PARSE_E; 06168 if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE)) 06169 return ASN_BEFORE_DATE_E; 06170 06171 /* The following items are optional. Only check for them if there is more 06172 * unprocessed data in the singleResponse wrapper. */ 06173 06174 if (((int)(idx - prevIndex) < wrapperSz) && 06175 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))) 06176 { 06177 idx++; 06178 if (GetLength(source, &idx, &length, size) < 0) 06179 return ASN_PARSE_E; 06180 if (GetBasicDate(source, &idx, cs->nextDate, 06181 &cs->nextDateFormat, size) < 0) 06182 return ASN_PARSE_E; 06183 } 06184 if (((int)(idx - prevIndex) < wrapperSz) && 06185 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))) 06186 { 06187 idx++; 06188 if (GetLength(source, &idx, &length, size) < 0) 06189 return ASN_PARSE_E; 06190 idx += length; 06191 } 06192 06193 *ioIndex = idx; 06194 06195 return 0; 06196 } 06197 06198 static int DecodeOcspRespExtensions(byte* source, 06199 word32* ioIndex, OcspResponse* resp, word32 sz) 06200 { 06201 word32 idx = *ioIndex; 06202 int length; 06203 int ext_bound; /* boundary index for the sequence of extensions */ 06204 word32 oid; 06205 06206 CYASSL_ENTER("DecodeOcspRespExtensions"); 06207 06208 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) 06209 return ASN_PARSE_E; 06210 06211 if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E; 06212 06213 if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E; 06214 06215 ext_bound = idx + length; 06216 06217 while (idx < (word32)ext_bound) { 06218 if (GetSequence(source, &idx, &length, sz) < 0) { 06219 CYASSL_MSG("\tfail: should be a SEQUENCE"); 06220 return ASN_PARSE_E; 06221 } 06222 06223 oid = 0; 06224 if (GetObjectId(source, &idx, &oid, sz) < 0) { 06225 CYASSL_MSG("\tfail: OBJECT ID"); 06226 return ASN_PARSE_E; 06227 } 06228 06229 /* check for critical flag */ 06230 if (source[idx] == ASN_BOOLEAN) { 06231 CYASSL_MSG("\tfound optional critical flag, moving past"); 06232 idx += (ASN_BOOL_SIZE + 1); 06233 } 06234 06235 /* process the extension based on the OID */ 06236 if (source[idx++] != ASN_OCTET_STRING) { 06237 CYASSL_MSG("\tfail: should be an OCTET STRING"); 06238 return ASN_PARSE_E; 06239 } 06240 06241 if (GetLength(source, &idx, &length, sz) < 0) { 06242 CYASSL_MSG("\tfail: extension data length"); 06243 return ASN_PARSE_E; 06244 } 06245 06246 if (oid == OCSP_NONCE_OID) { 06247 resp->nonce = source + idx; 06248 resp->nonceSz = length; 06249 } 06250 06251 idx += length; 06252 } 06253 06254 *ioIndex = idx; 06255 return 0; 06256 } 06257 06258 06259 static int DecodeResponseData(byte* source, 06260 word32* ioIndex, OcspResponse* resp, word32 size) 06261 { 06262 word32 idx = *ioIndex, prev_idx; 06263 int length; 06264 int version; 06265 word32 responderId = 0; 06266 06267 CYASSL_ENTER("DecodeResponseData"); 06268 06269 resp->response = source + idx; 06270 prev_idx = idx; 06271 if (GetSequence(source, &idx, &length, size) < 0) 06272 return ASN_PARSE_E; 06273 resp->responseSz = length + idx - prev_idx; 06274 06275 /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this 06276 * item isn't an EXPLICIT[0], then set version to zero and move 06277 * onto the next item. 06278 */ 06279 if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) 06280 { 06281 idx += 2; /* Eat the value and length */ 06282 if (GetMyVersion(source, &idx, &version) < 0) 06283 return ASN_PARSE_E; 06284 } else 06285 version = 0; 06286 06287 responderId = source[idx++]; 06288 if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) || 06289 (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))) 06290 { 06291 if (GetLength(source, &idx, &length, size) < 0) 06292 return ASN_PARSE_E; 06293 idx += length; 06294 } 06295 else 06296 return ASN_PARSE_E; 06297 06298 /* save pointer to the producedAt time */ 06299 if (GetBasicDate(source, &idx, resp->producedDate, 06300 &resp->producedDateFormat, size) < 0) 06301 return ASN_PARSE_E; 06302 06303 if (DecodeSingleResponse(source, &idx, resp, size) < 0) 06304 return ASN_PARSE_E; 06305 06306 if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0) 06307 return ASN_PARSE_E; 06308 06309 *ioIndex = idx; 06310 return 0; 06311 } 06312 06313 06314 static int DecodeCerts(byte* source, 06315 word32* ioIndex, OcspResponse* resp, word32 size) 06316 { 06317 word32 idx = *ioIndex; 06318 06319 CYASSL_ENTER("DecodeCerts"); 06320 06321 if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) 06322 { 06323 int length; 06324 06325 if (GetLength(source, &idx, &length, size) < 0) 06326 return ASN_PARSE_E; 06327 06328 if (GetSequence(source, &idx, &length, size) < 0) 06329 return ASN_PARSE_E; 06330 06331 resp->cert = source + idx; 06332 resp->certSz = length; 06333 06334 idx += length; 06335 } 06336 *ioIndex = idx; 06337 return 0; 06338 } 06339 06340 static int DecodeBasicOcspResponse(byte* source, 06341 word32* ioIndex, OcspResponse* resp, word32 size) 06342 { 06343 int length; 06344 word32 idx = *ioIndex; 06345 word32 end_index; 06346 06347 CYASSL_ENTER("DecodeBasicOcspResponse"); 06348 06349 if (GetSequence(source, &idx, &length, size) < 0) 06350 return ASN_PARSE_E; 06351 06352 if (idx + length > size) 06353 return ASN_INPUT_E; 06354 end_index = idx + length; 06355 06356 if (DecodeResponseData(source, &idx, resp, size) < 0) 06357 return ASN_PARSE_E; 06358 06359 /* Get the signature algorithm */ 06360 if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0) 06361 return ASN_PARSE_E; 06362 06363 /* Obtain pointer to the start of the signature, and save the size */ 06364 if (source[idx++] == ASN_BIT_STRING) 06365 { 06366 int sigLength = 0; 06367 if (GetLength(source, &idx, &sigLength, size) < 0) 06368 return ASN_PARSE_E; 06369 resp->sigSz = sigLength; 06370 resp->sig = source + idx; 06371 idx += sigLength; 06372 } 06373 06374 /* 06375 * Check the length of the BasicOcspResponse against the current index to 06376 * see if there are certificates, they are optional. 06377 */ 06378 if (idx < end_index) 06379 { 06380 DecodedCert cert; 06381 int ret; 06382 06383 if (DecodeCerts(source, &idx, resp, size) < 0) 06384 return ASN_PARSE_E; 06385 06386 InitDecodedCert(&cert, resp->cert, resp->certSz, 0); 06387 ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0); 06388 if (ret < 0) 06389 return ret; 06390 06391 ret = ConfirmSignature(resp->response, resp->responseSz, 06392 cert.publicKey, cert.pubKeySize, cert.keyOID, 06393 resp->sig, resp->sigSz, resp->sigOID, NULL); 06394 FreeDecodedCert(&cert); 06395 06396 if (ret == 0) 06397 { 06398 CYASSL_MSG("\tOCSP Confirm signature failed"); 06399 return ASN_OCSP_CONFIRM_E; 06400 } 06401 } 06402 06403 *ioIndex = idx; 06404 return 0; 06405 } 06406 06407 06408 void InitOcspResponse(OcspResponse* resp, CertStatus* status, 06409 byte* source, word32 inSz) 06410 { 06411 CYASSL_ENTER("InitOcspResponse"); 06412 06413 resp->responseStatus = -1; 06414 resp->response = NULL; 06415 resp->responseSz = 0; 06416 resp->producedDateFormat = 0; 06417 resp->issuerHash = NULL; 06418 resp->issuerKeyHash = NULL; 06419 resp->sig = NULL; 06420 resp->sigSz = 0; 06421 resp->sigOID = 0; 06422 resp->status = status; 06423 resp->nonce = NULL; 06424 resp->nonceSz = 0; 06425 resp->source = source; 06426 resp->maxIdx = inSz; 06427 } 06428 06429 06430 int OcspResponseDecode(OcspResponse* resp) 06431 { 06432 int length = 0; 06433 word32 idx = 0; 06434 byte* source = resp->source; 06435 word32 size = resp->maxIdx; 06436 word32 oid; 06437 06438 CYASSL_ENTER("OcspResponseDecode"); 06439 06440 /* peel the outer SEQUENCE wrapper */ 06441 if (GetSequence(source, &idx, &length, size) < 0) 06442 return ASN_PARSE_E; 06443 06444 /* First get the responseStatus, an ENUMERATED */ 06445 if (GetEnumerated(source, &idx, &resp->responseStatus) < 0) 06446 return ASN_PARSE_E; 06447 06448 if (resp->responseStatus != OCSP_SUCCESSFUL) 06449 return 0; 06450 06451 /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ 06452 if (idx >= size) 06453 return ASN_INPUT_E; 06454 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) 06455 return ASN_PARSE_E; 06456 if (GetLength(source, &idx, &length, size) < 0) 06457 return ASN_PARSE_E; 06458 06459 /* Get the responseBytes SEQUENCE */ 06460 if (GetSequence(source, &idx, &length, size) < 0) 06461 return ASN_PARSE_E; 06462 06463 /* Check ObjectID for the resposeBytes */ 06464 if (GetObjectId(source, &idx, &oid, size) < 0) 06465 return ASN_PARSE_E; 06466 if (oid != OCSP_BASIC_OID) 06467 return ASN_PARSE_E; 06468 if (source[idx++] != ASN_OCTET_STRING) 06469 return ASN_PARSE_E; 06470 06471 if (GetLength(source, &idx, &length, size) < 0) 06472 return ASN_PARSE_E; 06473 06474 if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0) 06475 return ASN_PARSE_E; 06476 06477 return 0; 06478 } 06479 06480 06481 static word32 SetOcspReqExtensions(word32 extSz, byte* output, 06482 const byte* nonce, word32 nonceSz) 06483 { 06484 static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 06485 0x30, 0x01, 0x02 }; 06486 byte seqArray[5][MAX_SEQ_SZ]; 06487 word32 seqSz[5], totalSz; 06488 06489 CYASSL_ENTER("SetOcspReqExtensions"); 06490 06491 if (nonce == NULL || nonceSz == 0) return 0; 06492 06493 seqArray[0][0] = ASN_OCTET_STRING; 06494 seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]); 06495 06496 seqArray[1][0] = ASN_OBJECT_ID; 06497 seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]); 06498 06499 totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId); 06500 06501 seqSz[2] = SetSequence(totalSz, seqArray[2]); 06502 totalSz += seqSz[2]; 06503 06504 seqSz[3] = SetSequence(totalSz, seqArray[3]); 06505 totalSz += seqSz[3]; 06506 06507 seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2); 06508 seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]); 06509 totalSz += seqSz[4]; 06510 06511 if (totalSz < extSz) 06512 { 06513 totalSz = 0; 06514 XMEMCPY(output + totalSz, seqArray[4], seqSz[4]); 06515 totalSz += seqSz[4]; 06516 XMEMCPY(output + totalSz, seqArray[3], seqSz[3]); 06517 totalSz += seqSz[3]; 06518 XMEMCPY(output + totalSz, seqArray[2], seqSz[2]); 06519 totalSz += seqSz[2]; 06520 XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); 06521 totalSz += seqSz[1]; 06522 XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId)); 06523 totalSz += (word32)sizeof(NonceObjId); 06524 XMEMCPY(output + totalSz, seqArray[0], seqSz[0]); 06525 totalSz += seqSz[0]; 06526 XMEMCPY(output + totalSz, nonce, nonceSz); 06527 totalSz += nonceSz; 06528 } 06529 06530 return totalSz; 06531 } 06532 06533 06534 int EncodeOcspRequest(OcspRequest* req) 06535 { 06536 byte seqArray[5][MAX_SEQ_SZ]; 06537 /* The ASN.1 of the OCSP Request is an onion of sequences */ 06538 byte algoArray[MAX_ALGO_SZ]; 06539 byte issuerArray[MAX_ENCODED_DIG_SZ]; 06540 byte issuerKeyArray[MAX_ENCODED_DIG_SZ]; 06541 byte snArray[MAX_SN_SZ]; 06542 byte extArray[MAX_OCSP_EXT_SZ]; 06543 byte* output = req->dest; 06544 word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; 06545 int i; 06546 06547 CYASSL_ENTER("EncodeOcspRequest"); 06548 06549 algoSz = SetAlgoID(SHAh, algoArray, hashType, 0); 06550 06551 req->issuerHash = req->cert->issuerHash; 06552 issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray); 06553 06554 req->issuerKeyHash = req->cert->issuerKeyHash; 06555 issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray); 06556 06557 req->serial = req->cert->serial; 06558 req->serialSz = req->cert->serialSz; 06559 snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); 06560 06561 extSz = 0; 06562 if (req->useNonce) { 06563 RNG rng; 06564 if (InitRng(&rng) != 0) { 06565 CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); 06566 } else { 06567 if (RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0) 06568 CYASSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce."); 06569 else { 06570 req->nonceSz = MAX_OCSP_NONCE_SZ; 06571 extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, 06572 req->nonce, req->nonceSz); 06573 } 06574 } 06575 } 06576 06577 totalSz = algoSz + issuerSz + issuerKeySz + snSz; 06578 06579 for (i = 4; i >= 0; i--) { 06580 seqSz[i] = SetSequence(totalSz, seqArray[i]); 06581 totalSz += seqSz[i]; 06582 if (i == 2) totalSz += extSz; 06583 } 06584 totalSz = 0; 06585 for (i = 0; i < 5; i++) { 06586 XMEMCPY(output + totalSz, seqArray[i], seqSz[i]); 06587 totalSz += seqSz[i]; 06588 } 06589 XMEMCPY(output + totalSz, algoArray, algoSz); 06590 totalSz += algoSz; 06591 XMEMCPY(output + totalSz, issuerArray, issuerSz); 06592 totalSz += issuerSz; 06593 XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz); 06594 totalSz += issuerKeySz; 06595 XMEMCPY(output + totalSz, snArray, snSz); 06596 totalSz += snSz; 06597 if (extSz != 0) { 06598 XMEMCPY(output + totalSz, extArray, extSz); 06599 totalSz += extSz; 06600 } 06601 06602 return totalSz; 06603 } 06604 06605 06606 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, 06607 byte* dest, word32 destSz) 06608 { 06609 CYASSL_ENTER("InitOcspRequest"); 06610 06611 req->cert = cert; 06612 req->useNonce = useNonce; 06613 req->nonceSz = 0; 06614 req->issuerHash = NULL; 06615 req->issuerKeyHash = NULL; 06616 req->serial = NULL; 06617 req->dest = dest; 06618 req->destSz = destSz; 06619 } 06620 06621 06622 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) 06623 { 06624 int cmp; 06625 06626 CYASSL_ENTER("CompareOcspReqResp"); 06627 06628 if (req == NULL) 06629 { 06630 CYASSL_MSG("\tReq missing"); 06631 return -1; 06632 } 06633 06634 if (resp == NULL) 06635 { 06636 CYASSL_MSG("\tResp missing"); 06637 return 1; 06638 } 06639 06640 /* Nonces are not critical. The responder may not necessarily add 06641 * the nonce to the response. */ 06642 if (req->useNonce && resp->nonceSz != 0) { 06643 cmp = req->nonceSz - resp->nonceSz; 06644 if (cmp != 0) 06645 { 06646 CYASSL_MSG("\tnonceSz mismatch"); 06647 return cmp; 06648 } 06649 06650 cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); 06651 if (cmp != 0) 06652 { 06653 CYASSL_MSG("\tnonce mismatch"); 06654 return cmp; 06655 } 06656 } 06657 06658 cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE); 06659 if (cmp != 0) 06660 { 06661 CYASSL_MSG("\tissuerHash mismatch"); 06662 return cmp; 06663 } 06664 06665 cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE); 06666 if (cmp != 0) 06667 { 06668 CYASSL_MSG("\tissuerKeyHash mismatch"); 06669 return cmp; 06670 } 06671 06672 cmp = req->serialSz - resp->status->serialSz; 06673 if (cmp != 0) 06674 { 06675 CYASSL_MSG("\tserialSz mismatch"); 06676 return cmp; 06677 } 06678 06679 cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz); 06680 if (cmp != 0) 06681 { 06682 CYASSL_MSG("\tserial mismatch"); 06683 return cmp; 06684 } 06685 06686 return 0; 06687 } 06688 06689 #endif 06690 06691 06692 /* store SHA1 hash of NAME */ 06693 CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, 06694 int maxIdx) 06695 { 06696 Sha sha; 06697 int length; /* length of all distinguished names */ 06698 int ret = 0; 06699 word32 dummy; 06700 06701 CYASSL_ENTER("GetNameHash"); 06702 06703 if (source[*idx] == ASN_OBJECT_ID) { 06704 CYASSL_MSG("Trying optional prefix..."); 06705 06706 if (GetLength(source, idx, &length, maxIdx) < 0) 06707 return ASN_PARSE_E; 06708 06709 *idx += length; 06710 CYASSL_MSG("Got optional prefix"); 06711 } 06712 06713 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be 06714 * calculated over the entire DER encoding of the Name field, including 06715 * the tag and length. */ 06716 dummy = *idx; 06717 if (GetSequence(source, idx, &length, maxIdx) < 0) 06718 return ASN_PARSE_E; 06719 06720 ret = InitSha(&sha); 06721 if (ret != 0) 06722 return ret; 06723 ShaUpdate(&sha, source + dummy, length + *idx - dummy); 06724 ShaFinal(&sha, hash); 06725 06726 *idx += length; 06727 06728 return 0; 06729 } 06730 06731 06732 #ifdef HAVE_CRL 06733 06734 /* initialize decoded CRL */ 06735 void InitDecodedCRL(DecodedCRL* dcrl) 06736 { 06737 CYASSL_MSG("InitDecodedCRL"); 06738 06739 dcrl->certBegin = 0; 06740 dcrl->sigIndex = 0; 06741 dcrl->sigLength = 0; 06742 dcrl->signatureOID = 0; 06743 dcrl->certs = NULL; 06744 dcrl->totalCerts = 0; 06745 } 06746 06747 06748 /* free decoded CRL resources */ 06749 void FreeDecodedCRL(DecodedCRL* dcrl) 06750 { 06751 RevokedCert* tmp = dcrl->certs; 06752 06753 CYASSL_MSG("FreeDecodedCRL"); 06754 06755 while(tmp) { 06756 RevokedCert* next = tmp->next; 06757 XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); 06758 tmp = next; 06759 } 06760 } 06761 06762 06763 /* Get Revoked Cert list, 0 on success */ 06764 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, 06765 int maxIdx) 06766 { 06767 int len; 06768 word32 end; 06769 byte b; 06770 RevokedCert* rc; 06771 06772 CYASSL_ENTER("GetRevoked"); 06773 06774 if (GetSequence(buff, idx, &len, maxIdx) < 0) 06775 return ASN_PARSE_E; 06776 06777 end = *idx + len; 06778 06779 /* get serial number */ 06780 b = buff[*idx]; 06781 *idx += 1; 06782 06783 if (b != ASN_INTEGER) { 06784 CYASSL_MSG("Expecting Integer"); 06785 return ASN_PARSE_E; 06786 } 06787 06788 if (GetLength(buff, idx, &len, maxIdx) < 0) 06789 return ASN_PARSE_E; 06790 06791 if (len > EXTERNAL_SERIAL_SIZE) { 06792 CYASSL_MSG("Serial Size too big"); 06793 return ASN_PARSE_E; 06794 } 06795 06796 rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL); 06797 if (rc == NULL) { 06798 CYASSL_MSG("Alloc Revoked Cert failed"); 06799 return MEMORY_E; 06800 } 06801 06802 XMEMCPY(rc->serialNumber, &buff[*idx], len); 06803 rc->serialSz = len; 06804 06805 /* add to list */ 06806 rc->next = dcrl->certs; 06807 dcrl->certs = rc; 06808 dcrl->totalCerts++; 06809 06810 *idx += len; 06811 06812 /* get date */ 06813 b = buff[*idx]; 06814 *idx += 1; 06815 06816 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) { 06817 CYASSL_MSG("Expecting Date"); 06818 return ASN_PARSE_E; 06819 } 06820 06821 if (GetLength(buff, idx, &len, maxIdx) < 0) 06822 return ASN_PARSE_E; 06823 06824 /* skip for now */ 06825 *idx += len; 06826 06827 if (*idx != end) /* skip extensions */ 06828 *idx = end; 06829 06830 return 0; 06831 } 06832 06833 06834 /* Get CRL Signature, 0 on success */ 06835 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl, 06836 int maxIdx) 06837 { 06838 int length; 06839 byte b; 06840 06841 CYASSL_ENTER("GetCRL_Signature"); 06842 06843 b = source[*idx]; 06844 *idx += 1; 06845 if (b != ASN_BIT_STRING) 06846 return ASN_BITSTR_E; 06847 06848 if (GetLength(source, idx, &length, maxIdx) < 0) 06849 return ASN_PARSE_E; 06850 06851 dcrl->sigLength = length; 06852 06853 b = source[*idx]; 06854 *idx += 1; 06855 if (b != 0x00) 06856 return ASN_EXPECT_0_E; 06857 06858 dcrl->sigLength--; 06859 dcrl->signature = (byte*)&source[*idx]; 06860 06861 *idx += dcrl->sigLength; 06862 06863 return 0; 06864 } 06865 06866 06867 /* prase crl buffer into decoded state, 0 on success */ 06868 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) 06869 { 06870 int version, len; 06871 word32 oid, idx = 0; 06872 Signer* ca = NULL; 06873 06874 CYASSL_MSG("ParseCRL"); 06875 06876 /* raw crl hash */ 06877 /* hash here if needed for optimized comparisons 06878 * Sha sha; 06879 * InitSha(&sha); 06880 * ShaUpdate(&sha, buff, sz); 06881 * ShaFinal(&sha, dcrl->crlHash); */ 06882 06883 if (GetSequence(buff, &idx, &len, sz) < 0) 06884 return ASN_PARSE_E; 06885 06886 dcrl->certBegin = idx; 06887 06888 if (GetSequence(buff, &idx, &len, sz) < 0) 06889 return ASN_PARSE_E; 06890 dcrl->sigIndex = len + idx; 06891 06892 /* may have version */ 06893 if (buff[idx] == ASN_INTEGER) { 06894 if (GetMyVersion(buff, &idx, &version) < 0) 06895 return ASN_PARSE_E; 06896 } 06897 06898 if (GetAlgoId(buff, &idx, &oid, sz) < 0) 06899 return ASN_PARSE_E; 06900 06901 if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) 06902 return ASN_PARSE_E; 06903 06904 if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) 06905 return ASN_PARSE_E; 06906 06907 if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) 06908 return ASN_PARSE_E; 06909 06910 if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) { 06911 CYASSL_MSG("CRL after date is no longer valid"); 06912 return ASN_AFTER_DATE_E; 06913 } 06914 06915 if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) { 06916 if (GetSequence(buff, &idx, &len, sz) < 0) 06917 return ASN_PARSE_E; 06918 06919 len += idx; 06920 06921 while (idx < (word32)len) { 06922 if (GetRevoked(buff, &idx, dcrl, sz) < 0) 06923 return ASN_PARSE_E; 06924 } 06925 } 06926 06927 if (idx != dcrl->sigIndex) 06928 idx = dcrl->sigIndex; /* skip extensions */ 06929 06930 if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0) 06931 return ASN_PARSE_E; 06932 06933 if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0) 06934 return ASN_PARSE_E; 06935 06936 /* openssl doesn't add skid by default for CRLs cause firefox chokes 06937 we're not assuming it's available yet */ 06938 #if !defined(NO_SKID) && defined(CRL_SKID_READY) 06939 if (dcrl->extAuthKeyIdSet) 06940 ca = GetCA(cm, dcrl->extAuthKeyId); 06941 if (ca == NULL) 06942 ca = GetCAByName(cm, dcrl->issuerHash); 06943 #else /* NO_SKID */ 06944 ca = GetCA(cm, dcrl->issuerHash); 06945 #endif /* NO_SKID */ 06946 CYASSL_MSG("About to verify CRL signature"); 06947 06948 if (ca) { 06949 CYASSL_MSG("Found CRL issuer CA"); 06950 /* try to confirm/verify signature */ 06951 #ifndef IGNORE_KEY_EXTENSIONS 06952 if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) { 06953 CYASSL_MSG("CA cannot sign CRLs"); 06954 return ASN_CRL_NO_SIGNER_E; 06955 } 06956 #endif /* IGNORE_KEY_EXTENSIONS */ 06957 if (!ConfirmSignature(buff + dcrl->certBegin, 06958 dcrl->sigIndex - dcrl->certBegin, 06959 ca->publicKey, ca->pubKeySize, ca->keyOID, 06960 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) { 06961 CYASSL_MSG("CRL Confirm signature failed"); 06962 return ASN_CRL_CONFIRM_E; 06963 } 06964 } 06965 else { 06966 CYASSL_MSG("Did NOT find CRL issuer CA"); 06967 return ASN_CRL_NO_SIGNER_E; 06968 } 06969 06970 return 0; 06971 } 06972 06973 #endif /* HAVE_CRL */ 06974 #endif 06975 06976 #ifdef CYASSL_SEP 06977 06978 06979 06980 #endif /* CYASSL_SEP */ 06981 06982
Generated on Tue Jul 12 2022 21:40:04 by
1.7.2
