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.
asn.c
00001 /* asn.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_ASN 00029 00030 #ifdef HAVE_RTP_SYS 00031 #include "os.h" /* dc_rtc_api needs */ 00032 #include "dc_rtc_api.h" /* to get current time */ 00033 #endif 00034 00035 #include <cyassl/ctaocrypt/integer.h> 00036 #include <cyassl/ctaocrypt/asn.h> 00037 #include <cyassl/ctaocrypt/coding.h> 00038 #include <cyassl/ctaocrypt/sha.h> 00039 #include <cyassl/ctaocrypt/md5.h> 00040 #include <cyassl/ctaocrypt/md2.h> 00041 #include <cyassl/ctaocrypt/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 #ifdef OPENSSL_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 cert->issuer[0] = '\0'; 01276 cert->subject[0] = '\0'; 01277 cert->source = source; /* don't own */ 01278 cert->srcIdx = 0; 01279 cert->maxIdx = inSz; /* can't go over this index */ 01280 cert->heap = heap; 01281 XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE); 01282 cert->serialSz = 0; 01283 cert->extensions = 0; 01284 cert->extensionsSz = 0; 01285 cert->extensionsIdx = 0; 01286 cert->extAuthInfo = NULL; 01287 cert->extAuthInfoSz = 0; 01288 cert->extCrlInfo = NULL; 01289 cert->extCrlInfoSz = 0; 01290 XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE); 01291 cert->extSubjKeyIdSet = 0; 01292 XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE); 01293 cert->extAuthKeyIdSet = 0; 01294 cert->extKeyUsageSet = 0; 01295 cert->extKeyUsage = 0; 01296 cert->extExtKeyUsageSet = 0; 01297 cert->extExtKeyUsage = 0; 01298 cert->isCA = 0; 01299 #ifdef HAVE_PKCS7 01300 cert->issuerRaw = NULL; 01301 cert->issuerRawLen = 0; 01302 #endif 01303 #ifdef CYASSL_CERT_GEN 01304 cert->subjectSN = 0; 01305 cert->subjectSNLen = 0; 01306 cert->subjectC = 0; 01307 cert->subjectCLen = 0; 01308 cert->subjectL = 0; 01309 cert->subjectLLen = 0; 01310 cert->subjectST = 0; 01311 cert->subjectSTLen = 0; 01312 cert->subjectO = 0; 01313 cert->subjectOLen = 0; 01314 cert->subjectOU = 0; 01315 cert->subjectOULen = 0; 01316 cert->subjectEmail = 0; 01317 cert->subjectEmailLen = 0; 01318 #endif /* CYASSL_CERT_GEN */ 01319 cert->beforeDate = NULL; 01320 cert->beforeDateLen = 0; 01321 cert->afterDate = NULL; 01322 cert->afterDateLen = 0; 01323 #ifdef OPENSSL_EXTRA 01324 XMEMSET(&cert->issuerName, 0, sizeof(DecodedName)); 01325 XMEMSET(&cert->subjectName, 0, sizeof(DecodedName)); 01326 cert->extBasicConstSet = 0; 01327 cert->extBasicConstCrit = 0; 01328 cert->extBasicConstPlSet = 0; 01329 cert->pathLength = 0; 01330 cert->extSubjAltNameSet = 0; 01331 cert->extSubjAltNameCrit = 0; 01332 cert->extAuthKeyIdCrit = 0; 01333 cert->extSubjKeyIdCrit = 0; 01334 cert->extKeyUsageCrit = 0; 01335 cert->extExtKeyUsageCrit = 0; 01336 cert->extExtKeyUsageSrc = NULL; 01337 cert->extExtKeyUsageSz = 0; 01338 cert->extExtKeyUsageCount = 0; 01339 cert->extAuthKeyIdSrc = NULL; 01340 cert->extAuthKeyIdSz = 0; 01341 cert->extSubjKeyIdSrc = NULL; 01342 cert->extSubjKeyIdSz = 0; 01343 #endif /* OPENSSL_EXTRA */ 01344 #ifdef HAVE_ECC 01345 cert->pkCurveOID = 0; 01346 #endif /* HAVE_ECC */ 01347 #ifdef CYASSL_SEP 01348 cert->deviceTypeSz = 0; 01349 cert->deviceType = NULL; 01350 cert->hwTypeSz = 0; 01351 cert->hwType = NULL; 01352 cert->hwSerialNumSz = 0; 01353 cert->hwSerialNum = NULL; 01354 #ifdef OPENSSL_EXTRA 01355 cert->extCertPolicySet = 0; 01356 cert->extCertPolicyCrit = 0; 01357 #endif /* OPENSSL_EXTRA */ 01358 #endif /* CYASSL_SEP */ 01359 } 01360 01361 01362 void FreeAltNames(DNS_entry* altNames, void* heap) 01363 { 01364 (void)heap; 01365 01366 while (altNames) { 01367 DNS_entry* tmp = altNames->next; 01368 01369 XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME); 01370 XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME); 01371 altNames = tmp; 01372 } 01373 } 01374 01375 01376 void FreeDecodedCert(DecodedCert* cert) 01377 { 01378 if (cert->subjectCNStored == 1) 01379 XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN); 01380 if (cert->pubKeyStored == 1) 01381 XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); 01382 if (cert->altNames) 01383 FreeAltNames(cert->altNames, cert->heap); 01384 #ifdef CYASSL_SEP 01385 XFREE(cert->deviceType, cert->heap, 0); 01386 XFREE(cert->hwType, cert->heap, 0); 01387 XFREE(cert->hwSerialNum, cert->heap, 0); 01388 #endif /* CYASSL_SEP */ 01389 #ifdef OPENSSL_EXTRA 01390 if (cert->issuerName.fullName != NULL) 01391 XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509); 01392 if (cert->subjectName.fullName != NULL) 01393 XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509); 01394 #endif /* OPENSSL_EXTRA */ 01395 } 01396 01397 01398 static int GetCertHeader(DecodedCert* cert) 01399 { 01400 int ret = 0, len; 01401 byte serialTmp[EXTERNAL_SERIAL_SIZE]; 01402 mp_int mpi; 01403 01404 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) 01405 return ASN_PARSE_E; 01406 01407 cert->certBegin = cert->srcIdx; 01408 01409 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) 01410 return ASN_PARSE_E; 01411 cert->sigIndex = len + cert->srcIdx; 01412 01413 if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0) 01414 return ASN_PARSE_E; 01415 01416 if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) 01417 return ASN_PARSE_E; 01418 01419 len = mp_unsigned_bin_size(&mpi); 01420 if (len < (int)sizeof(serialTmp)) { 01421 if ( (ret = mp_to_unsigned_bin(&mpi, serialTmp)) == MP_OKAY) { 01422 if (len > EXTERNAL_SERIAL_SIZE) 01423 len = EXTERNAL_SERIAL_SIZE; 01424 XMEMCPY(cert->serial, serialTmp, len); 01425 cert->serialSz = len; 01426 } 01427 } 01428 mp_clear(&mpi); 01429 return ret; 01430 } 01431 01432 #if !defined(NO_RSA) 01433 /* Store Rsa Key, may save later, Dsa could use in future */ 01434 static int StoreRsaKey(DecodedCert* cert) 01435 { 01436 int length; 01437 word32 recvd = cert->srcIdx; 01438 01439 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01440 return ASN_PARSE_E; 01441 01442 recvd = cert->srcIdx - recvd; 01443 length += recvd; 01444 01445 while (recvd--) 01446 cert->srcIdx--; 01447 01448 cert->pubKeySize = length; 01449 cert->publicKey = cert->source + cert->srcIdx; 01450 cert->srcIdx += length; 01451 01452 return 0; 01453 } 01454 #endif 01455 01456 01457 #ifdef HAVE_ECC 01458 01459 /* return 0 on sucess if the ECC curve oid sum is supported */ 01460 static int CheckCurve(word32 oid) 01461 { 01462 if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid != 01463 ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1) 01464 return ALGO_ID_E; 01465 01466 return 0; 01467 } 01468 01469 #endif /* HAVE_ECC */ 01470 01471 01472 static int GetKey(DecodedCert* cert) 01473 { 01474 int length; 01475 #ifdef HAVE_NTRU 01476 int tmpIdx = cert->srcIdx; 01477 #endif 01478 01479 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01480 return ASN_PARSE_E; 01481 01482 if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0) 01483 return ASN_PARSE_E; 01484 01485 switch (cert->keyOID) { 01486 #ifndef NO_RSA 01487 case RSAk: 01488 { 01489 byte b = cert->source[cert->srcIdx++]; 01490 if (b != ASN_BIT_STRING) 01491 return ASN_BITSTR_E; 01492 01493 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) 01494 return ASN_PARSE_E; 01495 b = cert->source[cert->srcIdx++]; 01496 if (b != 0x00) 01497 return ASN_EXPECT_0_E; 01498 01499 return StoreRsaKey(cert); 01500 } 01501 01502 #endif /* NO_RSA */ 01503 #ifdef HAVE_NTRU 01504 case NTRUk: 01505 { 01506 const byte* key = &cert->source[tmpIdx]; 01507 byte* next = (byte*)key; 01508 word16 keyLen; 01509 byte keyBlob[MAX_NTRU_KEY_SZ]; 01510 01511 word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, 01512 &keyLen, NULL, &next); 01513 01514 if (rc != NTRU_OK) 01515 return ASN_NTRU_KEY_E; 01516 if (keyLen > sizeof(keyBlob)) 01517 return ASN_NTRU_KEY_E; 01518 01519 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen, 01520 keyBlob, &next); 01521 if (rc != NTRU_OK) 01522 return ASN_NTRU_KEY_E; 01523 01524 if ( (next - key) < 0) 01525 return ASN_NTRU_KEY_E; 01526 01527 cert->srcIdx = tmpIdx + (int)(next - key); 01528 01529 cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, 01530 DYNAMIC_TYPE_PUBLIC_KEY); 01531 if (cert->publicKey == NULL) 01532 return MEMORY_E; 01533 XMEMCPY(cert->publicKey, keyBlob, keyLen); 01534 cert->pubKeyStored = 1; 01535 cert->pubKeySize = keyLen; 01536 01537 return 0; 01538 } 01539 #endif /* HAVE_NTRU */ 01540 #ifdef HAVE_ECC 01541 case ECDSAk: 01542 { 01543 int oidSz = 0; 01544 byte b = cert->source[cert->srcIdx++]; 01545 01546 if (b != ASN_OBJECT_ID) 01547 return ASN_OBJECT_ID_E; 01548 01549 if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0) 01550 return ASN_PARSE_E; 01551 01552 while(oidSz--) 01553 cert->pkCurveOID += cert->source[cert->srcIdx++]; 01554 01555 if (CheckCurve(cert->pkCurveOID) < 0) 01556 return ECC_CURVE_OID_E; 01557 01558 /* key header */ 01559 b = cert->source[cert->srcIdx++]; 01560 if (b != ASN_BIT_STRING) 01561 return ASN_BITSTR_E; 01562 01563 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) 01564 return ASN_PARSE_E; 01565 b = cert->source[cert->srcIdx++]; 01566 if (b != 0x00) 01567 return ASN_EXPECT_0_E; 01568 01569 /* actual key, use length - 1 since ate preceding 0 */ 01570 length -= 1; 01571 01572 cert->publicKey = (byte*) XMALLOC(length, cert->heap, 01573 DYNAMIC_TYPE_PUBLIC_KEY); 01574 if (cert->publicKey == NULL) 01575 return MEMORY_E; 01576 XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length); 01577 cert->pubKeyStored = 1; 01578 cert->pubKeySize = length; 01579 01580 cert->srcIdx += length; 01581 01582 return 0; 01583 } 01584 #endif /* HAVE_ECC */ 01585 default: 01586 return ASN_UNKNOWN_OID_E; 01587 } 01588 } 01589 01590 01591 /* process NAME, either issuer or subject */ 01592 static int GetName(DecodedCert* cert, int nameType) 01593 { 01594 Sha sha; /* MUST have SHA-1 hash for cert names */ 01595 int length; /* length of all distinguished names */ 01596 int dummy; 01597 int ret; 01598 char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; 01599 word32 idx; 01600 #ifdef OPENSSL_EXTRA 01601 DecodedName* dName = 01602 (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName; 01603 #endif /* OPENSSL_EXTRA */ 01604 01605 CYASSL_MSG("Getting Cert Name"); 01606 01607 if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) { 01608 CYASSL_MSG("Trying optional prefix..."); 01609 01610 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01611 return ASN_PARSE_E; 01612 01613 cert->srcIdx += length; 01614 CYASSL_MSG("Got optional prefix"); 01615 } 01616 01617 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be 01618 * calculated over the entire DER encoding of the Name field, including 01619 * the tag and length. */ 01620 idx = cert->srcIdx; 01621 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 01622 return ASN_PARSE_E; 01623 01624 ret = InitSha(&sha); 01625 if (ret != 0) 01626 return ret; 01627 ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx); 01628 if (nameType == ISSUER) 01629 ShaFinal(&sha, cert->issuerHash); 01630 else 01631 ShaFinal(&sha, cert->subjectHash); 01632 01633 length += cert->srcIdx; 01634 idx = 0; 01635 01636 #ifdef HAVE_PKCS7 01637 /* store pointer to raw issuer */ 01638 if (nameType == ISSUER) { 01639 cert->issuerRaw = &cert->source[cert->srcIdx]; 01640 cert->issuerRawLen = length - cert->srcIdx; 01641 } 01642 #endif 01643 01644 while (cert->srcIdx < (word32)length) { 01645 byte b; 01646 byte joint[2]; 01647 byte tooBig = FALSE; 01648 int oidSz; 01649 01650 if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) { 01651 CYASSL_MSG("Cert name lacks set header, trying sequence"); 01652 } 01653 01654 if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) 01655 return ASN_PARSE_E; 01656 01657 b = cert->source[cert->srcIdx++]; 01658 if (b != ASN_OBJECT_ID) 01659 return ASN_OBJECT_ID_E; 01660 01661 if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0) 01662 return ASN_PARSE_E; 01663 01664 XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint)); 01665 01666 /* v1 name types */ 01667 if (joint[0] == 0x55 && joint[1] == 0x04) { 01668 byte id; 01669 byte copy = FALSE; 01670 int strLen; 01671 01672 cert->srcIdx += 2; 01673 id = cert->source[cert->srcIdx++]; 01674 b = cert->source[cert->srcIdx++]; /* strType */ 01675 (void)b; /* may want to validate? */ 01676 01677 if (GetLength(cert->source, &cert->srcIdx, &strLen, 01678 cert->maxIdx) < 0) 01679 return ASN_PARSE_E; 01680 01681 if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) { 01682 /* include biggest pre fix header too 4 = "/serialNumber=" */ 01683 CYASSL_MSG("ASN Name too big, skipping"); 01684 tooBig = TRUE; 01685 } 01686 01687 if (id == ASN_COMMON_NAME) { 01688 if (nameType == SUBJECT) { 01689 cert->subjectCN = (char *)&cert->source[cert->srcIdx]; 01690 cert->subjectCNLen = strLen; 01691 } 01692 01693 if (!tooBig) { 01694 XMEMCPY(&full[idx], "/CN=", 4); 01695 idx += 4; 01696 copy = TRUE; 01697 } 01698 #ifdef OPENSSL_EXTRA 01699 dName->cnIdx = cert->srcIdx; 01700 dName->cnLen = strLen; 01701 #endif /* OPENSSL_EXTRA */ 01702 } 01703 else if (id == ASN_SUR_NAME) { 01704 if (!tooBig) { 01705 XMEMCPY(&full[idx], "/SN=", 4); 01706 idx += 4; 01707 copy = TRUE; 01708 } 01709 #ifdef CYASSL_CERT_GEN 01710 if (nameType == SUBJECT) { 01711 cert->subjectSN = (char*)&cert->source[cert->srcIdx]; 01712 cert->subjectSNLen = strLen; 01713 } 01714 #endif /* CYASSL_CERT_GEN */ 01715 #ifdef OPENSSL_EXTRA 01716 dName->snIdx = cert->srcIdx; 01717 dName->snLen = strLen; 01718 #endif /* OPENSSL_EXTRA */ 01719 } 01720 else if (id == ASN_COUNTRY_NAME) { 01721 if (!tooBig) { 01722 XMEMCPY(&full[idx], "/C=", 3); 01723 idx += 3; 01724 copy = TRUE; 01725 } 01726 #ifdef CYASSL_CERT_GEN 01727 if (nameType == SUBJECT) { 01728 cert->subjectC = (char*)&cert->source[cert->srcIdx]; 01729 cert->subjectCLen = strLen; 01730 } 01731 #endif /* CYASSL_CERT_GEN */ 01732 #ifdef OPENSSL_EXTRA 01733 dName->cIdx = cert->srcIdx; 01734 dName->cLen = strLen; 01735 #endif /* OPENSSL_EXTRA */ 01736 } 01737 else if (id == ASN_LOCALITY_NAME) { 01738 if (!tooBig) { 01739 XMEMCPY(&full[idx], "/L=", 3); 01740 idx += 3; 01741 copy = TRUE; 01742 } 01743 #ifdef CYASSL_CERT_GEN 01744 if (nameType == SUBJECT) { 01745 cert->subjectL = (char*)&cert->source[cert->srcIdx]; 01746 cert->subjectLLen = strLen; 01747 } 01748 #endif /* CYASSL_CERT_GEN */ 01749 #ifdef OPENSSL_EXTRA 01750 dName->lIdx = cert->srcIdx; 01751 dName->lLen = strLen; 01752 #endif /* OPENSSL_EXTRA */ 01753 } 01754 else if (id == ASN_STATE_NAME) { 01755 if (!tooBig) { 01756 XMEMCPY(&full[idx], "/ST=", 4); 01757 idx += 4; 01758 copy = TRUE; 01759 } 01760 #ifdef CYASSL_CERT_GEN 01761 if (nameType == SUBJECT) { 01762 cert->subjectST = (char*)&cert->source[cert->srcIdx]; 01763 cert->subjectSTLen = strLen; 01764 } 01765 #endif /* CYASSL_CERT_GEN */ 01766 #ifdef OPENSSL_EXTRA 01767 dName->stIdx = cert->srcIdx; 01768 dName->stLen = strLen; 01769 #endif /* OPENSSL_EXTRA */ 01770 } 01771 else if (id == ASN_ORG_NAME) { 01772 if (!tooBig) { 01773 XMEMCPY(&full[idx], "/O=", 3); 01774 idx += 3; 01775 copy = TRUE; 01776 } 01777 #ifdef CYASSL_CERT_GEN 01778 if (nameType == SUBJECT) { 01779 cert->subjectO = (char*)&cert->source[cert->srcIdx]; 01780 cert->subjectOLen = strLen; 01781 } 01782 #endif /* CYASSL_CERT_GEN */ 01783 #ifdef OPENSSL_EXTRA 01784 dName->oIdx = cert->srcIdx; 01785 dName->oLen = strLen; 01786 #endif /* OPENSSL_EXTRA */ 01787 } 01788 else if (id == ASN_ORGUNIT_NAME) { 01789 if (!tooBig) { 01790 XMEMCPY(&full[idx], "/OU=", 4); 01791 idx += 4; 01792 copy = TRUE; 01793 } 01794 #ifdef CYASSL_CERT_GEN 01795 if (nameType == SUBJECT) { 01796 cert->subjectOU = (char*)&cert->source[cert->srcIdx]; 01797 cert->subjectOULen = strLen; 01798 } 01799 #endif /* CYASSL_CERT_GEN */ 01800 #ifdef OPENSSL_EXTRA 01801 dName->ouIdx = cert->srcIdx; 01802 dName->ouLen = strLen; 01803 #endif /* OPENSSL_EXTRA */ 01804 } 01805 else if (id == ASN_SERIAL_NUMBER) { 01806 if (!tooBig) { 01807 XMEMCPY(&full[idx], "/serialNumber=", 14); 01808 idx += 14; 01809 copy = TRUE; 01810 } 01811 #ifdef OPENSSL_EXTRA 01812 dName->snIdx = cert->srcIdx; 01813 dName->snLen = strLen; 01814 #endif /* OPENSSL_EXTRA */ 01815 } 01816 01817 if (copy && !tooBig) { 01818 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen); 01819 idx += strLen; 01820 } 01821 01822 cert->srcIdx += strLen; 01823 } 01824 else { 01825 /* skip */ 01826 byte email = FALSE; 01827 byte uid = FALSE; 01828 int adv; 01829 01830 if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */ 01831 email = TRUE; 01832 01833 if (joint[0] == 0x9 && joint[1] == 0x92) /* uid id hdr */ 01834 uid = TRUE; 01835 01836 cert->srcIdx += oidSz + 1; 01837 01838 if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0) 01839 return ASN_PARSE_E; 01840 01841 if (adv > (int)(ASN_NAME_MAX - idx)) { 01842 CYASSL_MSG("ASN name too big, skipping"); 01843 tooBig = TRUE; 01844 } 01845 01846 if (email) { 01847 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) { 01848 CYASSL_MSG("ASN name too big, skipping"); 01849 tooBig = TRUE; 01850 } 01851 if (!tooBig) { 01852 XMEMCPY(&full[idx], "/emailAddress=", 14); 01853 idx += 14; 01854 } 01855 01856 #ifdef CYASSL_CERT_GEN 01857 if (nameType == SUBJECT) { 01858 cert->subjectEmail = (char*)&cert->source[cert->srcIdx]; 01859 cert->subjectEmailLen = adv; 01860 } 01861 #endif /* CYASSL_CERT_GEN */ 01862 #ifdef OPENSSL_EXTRA 01863 dName->emailIdx = cert->srcIdx; 01864 dName->emailLen = adv; 01865 #endif /* OPENSSL_EXTRA */ 01866 01867 if (!tooBig) { 01868 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); 01869 idx += adv; 01870 } 01871 } 01872 01873 if (uid) { 01874 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) { 01875 CYASSL_MSG("ASN name too big, skipping"); 01876 tooBig = TRUE; 01877 } 01878 if (!tooBig) { 01879 XMEMCPY(&full[idx], "/UID=", 5); 01880 idx += 5; 01881 01882 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); 01883 idx += adv; 01884 } 01885 #ifdef OPENSSL_EXTRA 01886 dName->uidIdx = cert->srcIdx; 01887 dName->uidLen = adv; 01888 #endif /* OPENSSL_EXTRA */ 01889 } 01890 01891 cert->srcIdx += adv; 01892 } 01893 } 01894 full[idx++] = 0; 01895 01896 #ifdef OPENSSL_EXTRA 01897 { 01898 int totalLen = 0; 01899 01900 if (dName->cnLen != 0) 01901 totalLen += dName->cnLen + 4; 01902 if (dName->snLen != 0) 01903 totalLen += dName->snLen + 4; 01904 if (dName->cLen != 0) 01905 totalLen += dName->cLen + 3; 01906 if (dName->lLen != 0) 01907 totalLen += dName->lLen + 3; 01908 if (dName->stLen != 0) 01909 totalLen += dName->stLen + 4; 01910 if (dName->oLen != 0) 01911 totalLen += dName->oLen + 3; 01912 if (dName->ouLen != 0) 01913 totalLen += dName->ouLen + 4; 01914 if (dName->emailLen != 0) 01915 totalLen += dName->emailLen + 14; 01916 if (dName->uidLen != 0) 01917 totalLen += dName->uidLen + 5; 01918 if (dName->serialLen != 0) 01919 totalLen += dName->serialLen + 14; 01920 01921 dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509); 01922 if (dName->fullName != NULL) { 01923 idx = 0; 01924 01925 if (dName->cnLen != 0) { 01926 dName->entryCount++; 01927 XMEMCPY(&dName->fullName[idx], "/CN=", 4); 01928 idx += 4; 01929 XMEMCPY(&dName->fullName[idx], 01930 &cert->source[dName->cnIdx], dName->cnLen); 01931 dName->cnIdx = idx; 01932 idx += dName->cnLen; 01933 } 01934 if (dName->snLen != 0) { 01935 dName->entryCount++; 01936 XMEMCPY(&dName->fullName[idx], "/SN=", 4); 01937 idx += 4; 01938 XMEMCPY(&dName->fullName[idx], 01939 &cert->source[dName->snIdx], dName->snLen); 01940 dName->snIdx = idx; 01941 idx += dName->snLen; 01942 } 01943 if (dName->cLen != 0) { 01944 dName->entryCount++; 01945 XMEMCPY(&dName->fullName[idx], "/C=", 3); 01946 idx += 3; 01947 XMEMCPY(&dName->fullName[idx], 01948 &cert->source[dName->cIdx], dName->cLen); 01949 dName->cIdx = idx; 01950 idx += dName->cLen; 01951 } 01952 if (dName->lLen != 0) { 01953 dName->entryCount++; 01954 XMEMCPY(&dName->fullName[idx], "/L=", 3); 01955 idx += 3; 01956 XMEMCPY(&dName->fullName[idx], 01957 &cert->source[dName->lIdx], dName->lLen); 01958 dName->lIdx = idx; 01959 idx += dName->lLen; 01960 } 01961 if (dName->stLen != 0) { 01962 dName->entryCount++; 01963 XMEMCPY(&dName->fullName[idx], "/ST=", 4); 01964 idx += 4; 01965 XMEMCPY(&dName->fullName[idx], 01966 &cert->source[dName->stIdx], dName->stLen); 01967 dName->stIdx = idx; 01968 idx += dName->stLen; 01969 } 01970 if (dName->oLen != 0) { 01971 dName->entryCount++; 01972 XMEMCPY(&dName->fullName[idx], "/O=", 3); 01973 idx += 3; 01974 XMEMCPY(&dName->fullName[idx], 01975 &cert->source[dName->oIdx], dName->oLen); 01976 dName->oIdx = idx; 01977 idx += dName->oLen; 01978 } 01979 if (dName->ouLen != 0) { 01980 dName->entryCount++; 01981 XMEMCPY(&dName->fullName[idx], "/OU=", 4); 01982 idx += 4; 01983 XMEMCPY(&dName->fullName[idx], 01984 &cert->source[dName->ouIdx], dName->ouLen); 01985 dName->ouIdx = idx; 01986 idx += dName->ouLen; 01987 } 01988 if (dName->emailLen != 0) { 01989 dName->entryCount++; 01990 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14); 01991 idx += 14; 01992 XMEMCPY(&dName->fullName[idx], 01993 &cert->source[dName->emailIdx], dName->emailLen); 01994 dName->emailIdx = idx; 01995 idx += dName->emailLen; 01996 } 01997 if (dName->uidLen != 0) { 01998 dName->entryCount++; 01999 XMEMCPY(&dName->fullName[idx], "/UID=", 5); 02000 idx += 5; 02001 XMEMCPY(&dName->fullName[idx], 02002 &cert->source[dName->uidIdx], dName->uidLen); 02003 dName->uidIdx = idx; 02004 idx += dName->uidLen; 02005 } 02006 if (dName->serialLen != 0) { 02007 dName->entryCount++; 02008 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14); 02009 idx += 14; 02010 XMEMCPY(&dName->fullName[idx], 02011 &cert->source[dName->serialIdx], dName->serialLen); 02012 dName->serialIdx = idx; 02013 idx += dName->serialLen; 02014 } 02015 dName->fullName[idx] = '\0'; 02016 dName->fullNameLen = totalLen; 02017 } 02018 } 02019 #endif /* OPENSSL_EXTRA */ 02020 02021 return 0; 02022 } 02023 02024 02025 #ifndef NO_TIME_H 02026 02027 /* to the second */ 02028 static int DateGreaterThan(const struct tm* a, const struct tm* b) 02029 { 02030 if (a->tm_year > b->tm_year) 02031 return 1; 02032 02033 if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon) 02034 return 1; 02035 02036 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02037 a->tm_mday > b->tm_mday) 02038 return 1; 02039 02040 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02041 a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour) 02042 return 1; 02043 02044 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02045 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && 02046 a->tm_min > b->tm_min) 02047 return 1; 02048 02049 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && 02050 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && 02051 a->tm_min == b->tm_min && a->tm_sec > b->tm_sec) 02052 return 1; 02053 02054 return 0; /* false */ 02055 } 02056 02057 02058 static INLINE int DateLessThan(const struct tm* a, const struct tm* b) 02059 { 02060 return !DateGreaterThan(a,b); 02061 } 02062 02063 02064 /* like atoi but only use first byte */ 02065 /* Make sure before and after dates are valid */ 02066 int ValidateDate(const byte* date, byte format, int dateType) 02067 { 02068 time_t ltime; 02069 struct tm certTime; 02070 struct tm* localTime; 02071 int i = 0; 02072 02073 ltime = XTIME(0); 02074 XMEMSET(&certTime, 0, sizeof(certTime)); 02075 02076 if (format == ASN_UTC_TIME) { 02077 if (btoi(date[0]) >= 5) 02078 certTime.tm_year = 1900; 02079 else 02080 certTime.tm_year = 2000; 02081 } 02082 else { /* format == GENERALIZED_TIME */ 02083 certTime.tm_year += btoi(date[i++]) * 1000; 02084 certTime.tm_year += btoi(date[i++]) * 100; 02085 } 02086 02087 GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */ 02088 GetTime(&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; /* adjust */ 02089 GetTime(&certTime.tm_mday, date, &i); 02090 GetTime(&certTime.tm_hour, date, &i); 02091 GetTime(&certTime.tm_min, date, &i); 02092 GetTime(&certTime.tm_sec, date, &i); 02093 02094 if (date[i] != 'Z') { /* only Zulu supported for this profile */ 02095 CYASSL_MSG("Only Zulu time supported for this profile"); 02096 return 0; 02097 } 02098 02099 localTime = XGMTIME(<ime); 02100 02101 if (dateType == BEFORE) { 02102 if (DateLessThan(localTime, &certTime)) 02103 return 0; 02104 } 02105 else 02106 if (DateGreaterThan(localTime, &certTime)) 02107 return 0; 02108 02109 return 1; 02110 } 02111 02112 #endif /* NO_TIME_H */ 02113 02114 02115 static int GetDate(DecodedCert* cert, int dateType) 02116 { 02117 int length; 02118 byte date[MAX_DATE_SIZE]; 02119 byte b; 02120 word32 startIdx = 0; 02121 02122 if (dateType == BEFORE) 02123 cert->beforeDate = &cert->source[cert->srcIdx]; 02124 else 02125 cert->afterDate = &cert->source[cert->srcIdx]; 02126 startIdx = cert->srcIdx; 02127 02128 b = cert->source[cert->srcIdx++]; 02129 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) 02130 return ASN_TIME_E; 02131 02132 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02133 return ASN_PARSE_E; 02134 02135 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) 02136 return ASN_DATE_SZ_E; 02137 02138 XMEMCPY(date, &cert->source[cert->srcIdx], length); 02139 cert->srcIdx += length; 02140 02141 if (dateType == BEFORE) 02142 cert->beforeDateLen = cert->srcIdx - startIdx; 02143 else 02144 cert->afterDateLen = cert->srcIdx - startIdx; 02145 02146 if (!XVALIDATE_DATE(date, b, dateType)) { 02147 if (dateType == BEFORE) 02148 return ASN_BEFORE_DATE_E; 02149 else 02150 return ASN_AFTER_DATE_E; 02151 } 02152 02153 return 0; 02154 } 02155 02156 02157 static int GetValidity(DecodedCert* cert, int verify) 02158 { 02159 int length; 02160 int badDate = 0; 02161 02162 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02163 return ASN_PARSE_E; 02164 02165 if (GetDate(cert, BEFORE) < 0 && verify) 02166 badDate = ASN_BEFORE_DATE_E; /* continue parsing */ 02167 02168 if (GetDate(cert, AFTER) < 0 && verify) 02169 return ASN_AFTER_DATE_E; 02170 02171 if (badDate != 0) 02172 return badDate; 02173 02174 return 0; 02175 } 02176 02177 02178 int DecodeToKey(DecodedCert* cert, int verify) 02179 { 02180 int badDate = 0; 02181 int ret; 02182 02183 if ( (ret = GetCertHeader(cert)) < 0) 02184 return ret; 02185 02186 CYASSL_MSG("Got Cert Header"); 02187 02188 if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, 02189 cert->maxIdx)) < 0) 02190 return ret; 02191 02192 CYASSL_MSG("Got Algo ID"); 02193 02194 if ( (ret = GetName(cert, ISSUER)) < 0) 02195 return ret; 02196 02197 if ( (ret = GetValidity(cert, verify)) < 0) 02198 badDate = ret; 02199 02200 if ( (ret = GetName(cert, SUBJECT)) < 0) 02201 return ret; 02202 02203 CYASSL_MSG("Got Subject Name"); 02204 02205 if ( (ret = GetKey(cert)) < 0) 02206 return ret; 02207 02208 CYASSL_MSG("Got Key"); 02209 02210 if (badDate != 0) 02211 return badDate; 02212 02213 return ret; 02214 } 02215 02216 02217 static int GetSignature(DecodedCert* cert) 02218 { 02219 int length; 02220 byte b = cert->source[cert->srcIdx++]; 02221 02222 if (b != ASN_BIT_STRING) 02223 return ASN_BITSTR_E; 02224 02225 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) 02226 return ASN_PARSE_E; 02227 02228 cert->sigLength = length; 02229 02230 b = cert->source[cert->srcIdx++]; 02231 if (b != 0x00) 02232 return ASN_EXPECT_0_E; 02233 02234 cert->sigLength--; 02235 cert->signature = &cert->source[cert->srcIdx]; 02236 cert->srcIdx += cert->sigLength; 02237 02238 return 0; 02239 } 02240 02241 02242 static word32 SetDigest(const byte* digest, word32 digSz, byte* output) 02243 { 02244 output[0] = ASN_OCTET_STRING; 02245 output[1] = (byte)digSz; 02246 XMEMCPY(&output[2], digest, digSz); 02247 02248 return digSz + 2; 02249 } 02250 02251 02252 static word32 BytePrecision(word32 value) 02253 { 02254 word32 i; 02255 for (i = sizeof(value); i; --i) 02256 if (value >> ((i - 1) * CYASSL_BIT_SIZE)) 02257 break; 02258 02259 return i; 02260 } 02261 02262 02263 CYASSL_LOCAL word32 SetLength(word32 length, byte* output) 02264 { 02265 word32 i = 0, j; 02266 02267 if (length < ASN_LONG_LENGTH) 02268 output[i++] = (byte)length; 02269 else { 02270 output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH); 02271 02272 for (j = BytePrecision(length); j; --j) { 02273 output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE)); 02274 i++; 02275 } 02276 } 02277 02278 return i; 02279 } 02280 02281 02282 CYASSL_LOCAL word32 SetSequence(word32 len, byte* output) 02283 { 02284 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED; 02285 return SetLength(len, output + 1) + 1; 02286 } 02287 02288 CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output) 02289 { 02290 output[0] = ASN_OCTET_STRING; 02291 return SetLength(len, output + 1) + 1; 02292 } 02293 02294 /* Write a set header to output */ 02295 CYASSL_LOCAL word32 SetSet(word32 len, byte* output) 02296 { 02297 output[0] = ASN_SET | ASN_CONSTRUCTED; 02298 return SetLength(len, output + 1) + 1; 02299 } 02300 02301 CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output) 02302 { 02303 02304 output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0) 02305 | ASN_CONTEXT_SPECIFIC | number; 02306 return SetLength(len, output + 1) + 1; 02307 } 02308 02309 CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output) 02310 { 02311 output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; 02312 return SetLength(len, output + 1) + 1; 02313 } 02314 02315 02316 #if defined(HAVE_ECC) && defined(CYASSL_CERT_GEN) 02317 02318 static word32 SetCurve(ecc_key* key, byte* output) 02319 { 02320 02321 /* curve types */ 02322 static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02323 0x03, 0x01, 0x01}; 02324 static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02325 0x03, 0x01, 0x07}; 02326 static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02327 0x02}; 02328 static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02329 0x21}; 02330 static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02331 0x22}; 02332 static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, 02333 0x23}; 02334 02335 int oidSz = 0; 02336 int idx = 0; 02337 int lenSz = 0; 02338 const byte* oid = 0; 02339 02340 output[0] = ASN_OBJECT_ID; 02341 idx++; 02342 02343 switch (key->dp->size) { 02344 case 20: 02345 oidSz = sizeof(ECC_160r1_AlgoID); 02346 oid = ECC_160r1_AlgoID; 02347 break; 02348 02349 case 24: 02350 oidSz = sizeof(ECC_192v1_AlgoID); 02351 oid = ECC_192v1_AlgoID; 02352 break; 02353 02354 case 28: 02355 oidSz = sizeof(ECC_224r1_AlgoID); 02356 oid = ECC_224r1_AlgoID; 02357 break; 02358 02359 case 32: 02360 oidSz = sizeof(ECC_256v1_AlgoID); 02361 oid = ECC_256v1_AlgoID; 02362 break; 02363 02364 case 48: 02365 oidSz = sizeof(ECC_384r1_AlgoID); 02366 oid = ECC_384r1_AlgoID; 02367 break; 02368 02369 case 66: 02370 oidSz = sizeof(ECC_521r1_AlgoID); 02371 oid = ECC_521r1_AlgoID; 02372 break; 02373 02374 default: 02375 return ASN_UNKNOWN_OID_E; 02376 } 02377 lenSz = SetLength(oidSz, output+idx); 02378 idx += lenSz; 02379 02380 XMEMCPY(output+idx, oid, oidSz); 02381 idx += oidSz; 02382 02383 return idx; 02384 } 02385 02386 #endif /* HAVE_ECC && CYASSL_CERT_GEN */ 02387 02388 02389 CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz) 02390 { 02391 /* adding TAG_NULL and 0 to end */ 02392 02393 /* hashTypes */ 02394 static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a, 02395 0x05, 0x00 }; 02396 static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02397 0x04, 0x02, 0x01, 0x05, 0x00 }; 02398 static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02399 0x04, 0x02, 0x02, 0x05, 0x00 }; 02400 static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 02401 0x04, 0x02, 0x03, 0x05, 0x00 }; 02402 static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02403 0x02, 0x05, 0x05, 0x00 }; 02404 static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02405 0x02, 0x02, 0x05, 0x00}; 02406 02407 /* blkTypes, no NULL tags because IV is there instead */ 02408 static const byte desCbcAlgoID[] = { 0x2B, 0x0E, 0x03, 0x02, 0x07 }; 02409 static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 02410 0x0D, 0x03, 0x07 }; 02411 02412 /* RSA sigTypes */ 02413 #ifndef NO_RSA 02414 static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02415 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00}; 02416 static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02417 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00}; 02418 static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 02419 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00}; 02420 static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 02421 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00}; 02422 static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 02423 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00}; 02424 #endif /* NO_RSA */ 02425 02426 /* ECDSA sigTypes */ 02427 #ifdef HAVE_ECC 02428 static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02429 0x04, 0x01, 0x05, 0x00}; 02430 static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02431 0x04, 0x03, 0x02, 0x05, 0x00}; 02432 static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02433 0x04, 0x03, 0x03, 0x05, 0x00}; 02434 static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, 02435 0x04, 0x03, 0x04, 0x05, 0x00}; 02436 #endif /* HAVE_ECC */ 02437 02438 /* RSA keyType */ 02439 #ifndef NO_RSA 02440 static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 02441 0x01, 0x01, 0x01, 0x05, 0x00}; 02442 #endif /* NO_RSA */ 02443 02444 #ifdef HAVE_ECC 02445 /* ECC keyType */ 02446 /* no tags, so set tagSz smaller later */ 02447 static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, 02448 0x02, 0x01}; 02449 #endif /* HAVE_ECC */ 02450 02451 int algoSz = 0; 02452 int tagSz = 2; /* tag null and terminator */ 02453 word32 idSz, seqSz; 02454 const byte* algoName = 0; 02455 byte ID_Length[MAX_LENGTH_SZ]; 02456 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */ 02457 02458 if (type == hashType) { 02459 switch (algoOID) { 02460 case SHAh: 02461 algoSz = sizeof(shaAlgoID); 02462 algoName = shaAlgoID; 02463 break; 02464 02465 case SHA256h: 02466 algoSz = sizeof(sha256AlgoID); 02467 algoName = sha256AlgoID; 02468 break; 02469 02470 case SHA384h: 02471 algoSz = sizeof(sha384AlgoID); 02472 algoName = sha384AlgoID; 02473 break; 02474 02475 case SHA512h: 02476 algoSz = sizeof(sha512AlgoID); 02477 algoName = sha512AlgoID; 02478 break; 02479 02480 case MD2h: 02481 algoSz = sizeof(md2AlgoID); 02482 algoName = md2AlgoID; 02483 break; 02484 02485 case MD5h: 02486 algoSz = sizeof(md5AlgoID); 02487 algoName = md5AlgoID; 02488 break; 02489 02490 default: 02491 CYASSL_MSG("Unknown Hash Algo"); 02492 return 0; /* UNKOWN_HASH_E; */ 02493 } 02494 } 02495 else if (type == blkType) { 02496 switch (algoOID) { 02497 case DESb: 02498 algoSz = sizeof(desCbcAlgoID); 02499 algoName = desCbcAlgoID; 02500 tagSz = 0; 02501 break; 02502 case DES3b: 02503 algoSz = sizeof(des3CbcAlgoID); 02504 algoName = des3CbcAlgoID; 02505 tagSz = 0; 02506 break; 02507 default: 02508 CYASSL_MSG("Unknown Block Algo"); 02509 return 0; 02510 } 02511 } 02512 else if (type == sigType) { /* sigType */ 02513 switch (algoOID) { 02514 #ifndef NO_RSA 02515 case CTC_MD5wRSA: 02516 algoSz = sizeof(md5wRSA_AlgoID); 02517 algoName = md5wRSA_AlgoID; 02518 break; 02519 02520 case CTC_SHAwRSA: 02521 algoSz = sizeof(shawRSA_AlgoID); 02522 algoName = shawRSA_AlgoID; 02523 break; 02524 02525 case CTC_SHA256wRSA: 02526 algoSz = sizeof(sha256wRSA_AlgoID); 02527 algoName = sha256wRSA_AlgoID; 02528 break; 02529 02530 case CTC_SHA384wRSA: 02531 algoSz = sizeof(sha384wRSA_AlgoID); 02532 algoName = sha384wRSA_AlgoID; 02533 break; 02534 02535 case CTC_SHA512wRSA: 02536 algoSz = sizeof(sha512wRSA_AlgoID); 02537 algoName = sha512wRSA_AlgoID; 02538 break; 02539 #endif /* NO_RSA */ 02540 #ifdef HAVE_ECC 02541 case CTC_SHAwECDSA: 02542 algoSz = sizeof(shawECDSA_AlgoID); 02543 algoName = shawECDSA_AlgoID; 02544 break; 02545 02546 case CTC_SHA256wECDSA: 02547 algoSz = sizeof(sha256wECDSA_AlgoID); 02548 algoName = sha256wECDSA_AlgoID; 02549 break; 02550 02551 case CTC_SHA384wECDSA: 02552 algoSz = sizeof(sha384wECDSA_AlgoID); 02553 algoName = sha384wECDSA_AlgoID; 02554 break; 02555 02556 case CTC_SHA512wECDSA: 02557 algoSz = sizeof(sha512wECDSA_AlgoID); 02558 algoName = sha512wECDSA_AlgoID; 02559 break; 02560 #endif /* HAVE_ECC */ 02561 default: 02562 CYASSL_MSG("Unknown Signature Algo"); 02563 return 0; 02564 } 02565 } 02566 else if (type == keyType) { /* keyType */ 02567 switch (algoOID) { 02568 #ifndef NO_RSA 02569 case RSAk: 02570 algoSz = sizeof(RSA_AlgoID); 02571 algoName = RSA_AlgoID; 02572 break; 02573 #endif /* NO_RSA */ 02574 #ifdef HAVE_ECC 02575 case ECDSAk: 02576 algoSz = sizeof(ECC_AlgoID); 02577 algoName = ECC_AlgoID; 02578 tagSz = 0; 02579 break; 02580 #endif /* HAVE_ECC */ 02581 default: 02582 CYASSL_MSG("Unknown Key Algo"); 02583 return 0; 02584 } 02585 } 02586 else { 02587 CYASSL_MSG("Unknown Algo type"); 02588 return 0; 02589 } 02590 02591 idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */ 02592 seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray); 02593 /* +1 for object id, curveID of curveSz follows for ecc */ 02594 seqArray[seqSz++] = ASN_OBJECT_ID; 02595 02596 XMEMCPY(output, seqArray, seqSz); 02597 XMEMCPY(output + seqSz, ID_Length, idSz); 02598 XMEMCPY(output + seqSz + idSz, algoName, algoSz); 02599 02600 return seqSz + idSz + algoSz; 02601 02602 } 02603 02604 02605 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) 02606 { 02607 byte digArray[MAX_ENCODED_DIG_SZ]; 02608 byte algoArray[MAX_ALGO_SZ]; 02609 byte seqArray[MAX_SEQ_SZ]; 02610 word32 encDigSz, algoSz, seqSz; 02611 02612 encDigSz = SetDigest(digest, digSz, digArray); 02613 algoSz = SetAlgoID(hashOID, algoArray, hashType, 0); 02614 seqSz = SetSequence(encDigSz + algoSz, seqArray); 02615 02616 XMEMCPY(out, seqArray, seqSz); 02617 XMEMCPY(out + seqSz, algoArray, algoSz); 02618 XMEMCPY(out + seqSz + algoSz, digArray, encDigSz); 02619 02620 return encDigSz + algoSz + seqSz; 02621 } 02622 02623 02624 /* return true (1) for Confirmation */ 02625 static int ConfirmSignature(const byte* buf, word32 bufSz, 02626 const byte* key, word32 keySz, word32 keyOID, 02627 const byte* sig, word32 sigSz, word32 sigOID, 02628 void* heap) 02629 { 02630 #ifdef CYASSL_SHA512 02631 byte digest[SHA512_DIGEST_SIZE]; /* max size */ 02632 #elif !defined(NO_SHA256) 02633 byte digest[SHA256_DIGEST_SIZE]; /* max size */ 02634 #else 02635 byte digest[SHA_DIGEST_SIZE]; /* max size */ 02636 #endif 02637 int typeH, digestSz, ret = 0; 02638 02639 (void)key; 02640 (void)keySz; 02641 (void)sig; 02642 (void)sigSz; 02643 (void)heap; 02644 (void)ret; 02645 02646 switch (sigOID) { 02647 #ifndef NO_MD5 02648 case CTC_MD5wRSA: 02649 { 02650 Md5 md5; 02651 InitMd5(&md5); 02652 Md5Update(&md5, buf, bufSz); 02653 Md5Final(&md5, digest); 02654 typeH = MD5h; 02655 digestSz = MD5_DIGEST_SIZE; 02656 } 02657 break; 02658 #endif 02659 #if defined(CYASSL_MD2) 02660 case CTC_MD2wRSA: 02661 { 02662 Md2 md2; 02663 InitMd2(&md2); 02664 Md2Update(&md2, buf, bufSz); 02665 Md2Final(&md2, digest); 02666 typeH = MD2h; 02667 digestSz = MD2_DIGEST_SIZE; 02668 } 02669 break; 02670 #endif 02671 #ifndef NO_SHA 02672 case CTC_SHAwRSA: 02673 case CTC_SHAwDSA: 02674 case CTC_SHAwECDSA: 02675 { 02676 Sha sha; 02677 ret = InitSha(&sha); 02678 if (ret != 0) { 02679 CYASSL_MSG("InitSha failed"); 02680 return 0; /* not confirmed */ 02681 } 02682 ShaUpdate(&sha, buf, bufSz); 02683 ShaFinal(&sha, digest); 02684 typeH = SHAh; 02685 digestSz = SHA_DIGEST_SIZE; 02686 } 02687 break; 02688 #endif 02689 #ifndef NO_SHA256 02690 case CTC_SHA256wRSA: 02691 case CTC_SHA256wECDSA: 02692 { 02693 Sha256 sha256; 02694 ret = InitSha256(&sha256); 02695 if (ret != 0) { 02696 CYASSL_MSG("InitSha256 failed"); 02697 return 0; /* not confirmed */ 02698 } 02699 Sha256Update(&sha256, buf, bufSz); 02700 Sha256Final(&sha256, digest); 02701 typeH = SHA256h; 02702 digestSz = SHA256_DIGEST_SIZE; 02703 } 02704 break; 02705 #endif 02706 #ifdef CYASSL_SHA512 02707 case CTC_SHA512wRSA: 02708 case CTC_SHA512wECDSA: 02709 { 02710 Sha512 sha512; 02711 ret = InitSha512(&sha512); 02712 if (ret != 0) { 02713 CYASSL_MSG("InitSha512 failed"); 02714 return 0; /* not confirmed */ 02715 } 02716 Sha512Update(&sha512, buf, bufSz); 02717 Sha512Final(&sha512, digest); 02718 typeH = SHA512h; 02719 digestSz = SHA512_DIGEST_SIZE; 02720 } 02721 break; 02722 #endif 02723 #ifdef CYASSL_SHA384 02724 case CTC_SHA384wRSA: 02725 case CTC_SHA384wECDSA: 02726 { 02727 Sha384 sha384; 02728 ret = InitSha384(&sha384); 02729 if (ret != 0) { 02730 CYASSL_MSG("InitSha384 failed"); 02731 return 0; /* not confirmed */ 02732 } 02733 Sha384Update(&sha384, buf, bufSz); 02734 Sha384Final(&sha384, digest); 02735 typeH = SHA384h; 02736 digestSz = SHA384_DIGEST_SIZE; 02737 } 02738 break; 02739 #endif 02740 default: 02741 CYASSL_MSG("Verify Signautre has unsupported type"); 02742 return 0; 02743 } 02744 (void)typeH; /* some builds won't read */ 02745 02746 switch (keyOID) { 02747 #ifndef NO_RSA 02748 case RSAk: 02749 { 02750 RsaKey pubKey; 02751 byte encodedSig[MAX_ENCODED_SIG_SZ]; 02752 byte plain[MAX_ENCODED_SIG_SZ]; 02753 word32 idx = 0; 02754 int encodedSigSz, verifySz; 02755 byte* out; 02756 02757 if (sigSz > MAX_ENCODED_SIG_SZ) { 02758 CYASSL_MSG("Verify Signautre is too big"); 02759 return 0; 02760 } 02761 02762 ret = InitRsaKey(&pubKey, heap); 02763 if (ret != 0) return ret; 02764 if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { 02765 CYASSL_MSG("ASN Key decode error RSA"); 02766 ret = 0; 02767 } 02768 else { 02769 XMEMCPY(plain, sig, sigSz); 02770 if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, 02771 &pubKey)) < 0) { 02772 CYASSL_MSG("Rsa SSL verify error"); 02773 ret = 0; 02774 } 02775 else { 02776 /* make sure we're right justified */ 02777 encodedSigSz = 02778 EncodeSignature(encodedSig, digest, digestSz, typeH); 02779 if (encodedSigSz != verifySz || 02780 XMEMCMP(out, encodedSig, encodedSigSz) != 0) { 02781 CYASSL_MSG("Rsa SSL verify match encode error"); 02782 ret = 0; 02783 } 02784 else 02785 ret = 1; /* match */ 02786 02787 #ifdef CYASSL_DEBUG_ENCODING 02788 { 02789 int x; 02790 printf("cyassl encodedSig:\n"); 02791 for (x = 0; x < encodedSigSz; x++) { 02792 printf("%02x ", encodedSig[x]); 02793 if ( (x % 16) == 15) 02794 printf("\n"); 02795 } 02796 printf("\n"); 02797 printf("actual digest:\n"); 02798 for (x = 0; x < verifySz; x++) { 02799 printf("%02x ", out[x]); 02800 if ( (x % 16) == 15) 02801 printf("\n"); 02802 } 02803 printf("\n"); 02804 } 02805 #endif /* CYASSL_DEBUG_ENCODING */ 02806 } 02807 } 02808 FreeRsaKey(&pubKey); 02809 return ret; 02810 } 02811 02812 #endif /* NO_RSA */ 02813 #ifdef HAVE_ECC 02814 case ECDSAk: 02815 { 02816 ecc_key pubKey; 02817 int verify = 0; 02818 02819 if (ecc_import_x963(key, keySz, &pubKey) < 0) { 02820 CYASSL_MSG("ASN Key import error ECC"); 02821 return 0; 02822 } 02823 02824 ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey); 02825 ecc_free(&pubKey); 02826 if (ret == 0 && verify == 1) 02827 return 1; /* match */ 02828 02829 CYASSL_MSG("ECC Verify didn't match"); 02830 return 0; 02831 } 02832 #endif /* HAVE_ECC */ 02833 default: 02834 CYASSL_MSG("Verify Key type unknown"); 02835 return 0; 02836 } 02837 } 02838 02839 02840 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert) 02841 { 02842 word32 idx = 0; 02843 int length = 0; 02844 02845 CYASSL_ENTER("DecodeAltNames"); 02846 02847 if (GetSequence(input, &idx, &length, sz) < 0) { 02848 CYASSL_MSG("\tBad Sequence"); 02849 return ASN_PARSE_E; 02850 } 02851 02852 while (length > 0) { 02853 byte b = input[idx++]; 02854 02855 length--; 02856 02857 /* Save DNS Type names in the altNames list. */ 02858 /* Save Other Type names in the cert's OidMap */ 02859 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) { 02860 DNS_entry* dnsEntry; 02861 int strLen; 02862 word32 lenStartIdx = idx; 02863 02864 if (GetLength(input, &idx, &strLen, sz) < 0) { 02865 CYASSL_MSG("\tfail: str length"); 02866 return ASN_PARSE_E; 02867 } 02868 length -= (idx - lenStartIdx); 02869 02870 dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, 02871 DYNAMIC_TYPE_ALTNAME); 02872 if (dnsEntry == NULL) { 02873 CYASSL_MSG("\tOut of Memory"); 02874 return ASN_PARSE_E; 02875 } 02876 02877 dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, 02878 DYNAMIC_TYPE_ALTNAME); 02879 if (dnsEntry->name == NULL) { 02880 CYASSL_MSG("\tOut of Memory"); 02881 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); 02882 return ASN_PARSE_E; 02883 } 02884 02885 XMEMCPY(dnsEntry->name, &input[idx], strLen); 02886 dnsEntry->name[strLen] = '\0'; 02887 02888 dnsEntry->next = cert->altNames; 02889 cert->altNames = dnsEntry; 02890 02891 length -= strLen; 02892 idx += strLen; 02893 } 02894 #ifdef CYASSL_SEP 02895 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) 02896 { 02897 int strLen; 02898 word32 lenStartIdx = idx; 02899 word32 oid = 0; 02900 02901 if (GetLength(input, &idx, &strLen, sz) < 0) { 02902 CYASSL_MSG("\tfail: other name length"); 02903 return ASN_PARSE_E; 02904 } 02905 /* Consume the rest of this sequence. */ 02906 length -= (strLen + idx - lenStartIdx); 02907 02908 if (GetObjectId(input, &idx, &oid, sz) < 0) { 02909 CYASSL_MSG("\tbad OID"); 02910 return ASN_PARSE_E; 02911 } 02912 02913 if (oid != HW_NAME_OID) { 02914 CYASSL_MSG("\tincorrect OID"); 02915 return ASN_PARSE_E; 02916 } 02917 02918 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { 02919 CYASSL_MSG("\twrong type"); 02920 return ASN_PARSE_E; 02921 } 02922 02923 if (GetLength(input, &idx, &strLen, sz) < 0) { 02924 CYASSL_MSG("\tfail: str len"); 02925 return ASN_PARSE_E; 02926 } 02927 02928 if (GetSequence(input, &idx, &strLen, sz) < 0) { 02929 CYASSL_MSG("\tBad Sequence"); 02930 return ASN_PARSE_E; 02931 } 02932 02933 if (input[idx++] != ASN_OBJECT_ID) { 02934 CYASSL_MSG("\texpected OID"); 02935 return ASN_PARSE_E; 02936 } 02937 02938 if (GetLength(input, &idx, &strLen, sz) < 0) { 02939 CYASSL_MSG("\tfailed: str len"); 02940 return ASN_PARSE_E; 02941 } 02942 02943 cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0); 02944 if (cert->hwType == NULL) { 02945 CYASSL_MSG("\tOut of Memory"); 02946 return MEMORY_E; 02947 } 02948 02949 XMEMCPY(cert->hwType, &input[idx], strLen); 02950 cert->hwTypeSz = strLen; 02951 idx += strLen; 02952 02953 if (input[idx++] != ASN_OCTET_STRING) { 02954 CYASSL_MSG("\texpected Octet String"); 02955 return ASN_PARSE_E; 02956 } 02957 02958 if (GetLength(input, &idx, &strLen, sz) < 0) { 02959 CYASSL_MSG("\tfailed: str len"); 02960 return ASN_PARSE_E; 02961 } 02962 02963 cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0); 02964 if (cert->hwSerialNum == NULL) { 02965 CYASSL_MSG("\tOut of Memory"); 02966 return MEMORY_E; 02967 } 02968 02969 XMEMCPY(cert->hwSerialNum, &input[idx], strLen); 02970 cert->hwSerialNum[strLen] = '\0'; 02971 cert->hwSerialNumSz = strLen; 02972 idx += strLen; 02973 } 02974 #endif /* CYASSL_SEP */ 02975 else { 02976 int strLen; 02977 word32 lenStartIdx = idx; 02978 02979 CYASSL_MSG("\tUnsupported name type, skipping"); 02980 02981 if (GetLength(input, &idx, &strLen, sz) < 0) { 02982 CYASSL_MSG("\tfail: unsupported name length"); 02983 return ASN_PARSE_E; 02984 } 02985 length -= (strLen + idx - lenStartIdx); 02986 idx += strLen; 02987 } 02988 } 02989 return 0; 02990 } 02991 02992 02993 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert) 02994 { 02995 word32 idx = 0; 02996 int length = 0; 02997 02998 CYASSL_ENTER("DecodeBasicCaConstraint"); 02999 if (GetSequence(input, &idx, &length, sz) < 0) { 03000 CYASSL_MSG("\tfail: bad SEQUENCE"); 03001 return ASN_PARSE_E; 03002 } 03003 03004 if (length == 0) 03005 return 0; 03006 03007 /* If the basic ca constraint is false, this extension may be named, but 03008 * left empty. So, if the length is 0, just return. */ 03009 03010 if (input[idx++] != ASN_BOOLEAN) 03011 { 03012 CYASSL_MSG("\tfail: constraint not BOOLEAN"); 03013 return ASN_PARSE_E; 03014 } 03015 03016 if (GetLength(input, &idx, &length, sz) < 0) 03017 { 03018 CYASSL_MSG("\tfail: length"); 03019 return ASN_PARSE_E; 03020 } 03021 03022 if (input[idx++]) 03023 cert->isCA = 1; 03024 03025 #ifdef OPENSSL_EXTRA 03026 /* If there isn't any more data, return. */ 03027 if (idx >= (word32)sz) 03028 return 0; 03029 03030 /* Anything left should be the optional pathlength */ 03031 if (input[idx++] != ASN_INTEGER) { 03032 CYASSL_MSG("\tfail: pathlen not INTEGER"); 03033 return ASN_PARSE_E; 03034 } 03035 03036 if (input[idx++] != 1) { 03037 CYASSL_MSG("\tfail: pathlen too long"); 03038 return ASN_PARSE_E; 03039 } 03040 03041 cert->pathLength = input[idx]; 03042 cert->extBasicConstPlSet = 1; 03043 #endif /* OPENSSL_EXTRA */ 03044 03045 return 0; 03046 } 03047 03048 03049 #define CRLDP_FULL_NAME 0 03050 /* From RFC3280 SS4.2.1.14, Distribution Point Name*/ 03051 #define GENERALNAME_URI 6 03052 /* From RFC3280 SS4.2.1.7, GeneralName */ 03053 03054 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert) 03055 { 03056 word32 idx = 0; 03057 int length = 0; 03058 03059 CYASSL_ENTER("DecodeCrlDist"); 03060 03061 /* Unwrap the list of Distribution Points*/ 03062 if (GetSequence(input, &idx, &length, sz) < 0) 03063 return ASN_PARSE_E; 03064 03065 /* Unwrap a single Distribution Point */ 03066 if (GetSequence(input, &idx, &length, sz) < 0) 03067 return ASN_PARSE_E; 03068 03069 /* The Distribution Point has three explicit optional members 03070 * First check for a DistributionPointName 03071 */ 03072 if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) 03073 { 03074 idx++; 03075 if (GetLength(input, &idx, &length, sz) < 0) 03076 return ASN_PARSE_E; 03077 03078 if (input[idx] == 03079 (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME)) 03080 { 03081 idx++; 03082 if (GetLength(input, &idx, &length, sz) < 0) 03083 return ASN_PARSE_E; 03084 03085 if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) 03086 { 03087 idx++; 03088 if (GetLength(input, &idx, &length, sz) < 0) 03089 return ASN_PARSE_E; 03090 03091 cert->extCrlInfoSz = length; 03092 cert->extCrlInfo = input + idx; 03093 idx += length; 03094 } 03095 else 03096 /* This isn't a URI, skip it. */ 03097 idx += length; 03098 } 03099 else 03100 /* This isn't a FULLNAME, skip it. */ 03101 idx += length; 03102 } 03103 03104 /* Check for reasonFlags */ 03105 if (idx < (word32)sz && 03106 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) 03107 { 03108 idx++; 03109 if (GetLength(input, &idx, &length, sz) < 0) 03110 return ASN_PARSE_E; 03111 idx += length; 03112 } 03113 03114 /* Check for cRLIssuer */ 03115 if (idx < (word32)sz && 03116 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) 03117 { 03118 idx++; 03119 if (GetLength(input, &idx, &length, sz) < 0) 03120 return ASN_PARSE_E; 03121 idx += length; 03122 } 03123 03124 if (idx < (word32)sz) 03125 { 03126 CYASSL_MSG("\tThere are more CRL Distribution Point records, " 03127 "but we only use the first one."); 03128 } 03129 03130 return 0; 03131 } 03132 03133 03134 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert) 03135 /* 03136 * Read the first of the Authority Information Access records. If there are 03137 * any issues, return without saving the record. 03138 */ 03139 { 03140 word32 idx = 0; 03141 int length = 0; 03142 byte b; 03143 word32 oid; 03144 03145 CYASSL_ENTER("DecodeAuthInfo"); 03146 03147 /* Unwrap the list of AIAs */ 03148 if (GetSequence(input, &idx, &length, sz) < 0) 03149 return ASN_PARSE_E; 03150 03151 while (idx < (word32)sz) { 03152 /* Unwrap a single AIA */ 03153 if (GetSequence(input, &idx, &length, sz) < 0) 03154 return ASN_PARSE_E; 03155 03156 oid = 0; 03157 if (GetObjectId(input, &idx, &oid, sz) < 0) 03158 return ASN_PARSE_E; 03159 03160 /* Only supporting URIs right now. */ 03161 b = input[idx++]; 03162 if (GetLength(input, &idx, &length, sz) < 0) 03163 return ASN_PARSE_E; 03164 03165 if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) && 03166 oid == AIA_OCSP_OID) 03167 { 03168 cert->extAuthInfoSz = length; 03169 cert->extAuthInfo = input + idx; 03170 break; 03171 } 03172 idx += length; 03173 } 03174 03175 return 0; 03176 } 03177 03178 03179 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) 03180 { 03181 word32 idx = 0; 03182 int length = 0, ret = 0; 03183 03184 CYASSL_ENTER("DecodeAuthKeyId"); 03185 03186 if (GetSequence(input, &idx, &length, sz) < 0) { 03187 CYASSL_MSG("\tfail: should be a SEQUENCE\n"); 03188 return ASN_PARSE_E; 03189 } 03190 03191 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { 03192 CYASSL_MSG("\tfail: wanted OPTIONAL item 0, not available\n"); 03193 return ASN_PARSE_E; 03194 } 03195 03196 if (GetLength(input, &idx, &length, sz) < 0) { 03197 CYASSL_MSG("\tfail: extension data length"); 03198 return ASN_PARSE_E; 03199 } 03200 03201 #ifdef OPENSSL_EXTRA 03202 cert->extAuthKeyIdSrc = &input[idx]; 03203 cert->extAuthKeyIdSz = length; 03204 #endif /* OPENSSL_EXTRA */ 03205 03206 if (length == SHA_SIZE) { 03207 XMEMCPY(cert->extAuthKeyId, input + idx, length); 03208 } 03209 else { 03210 Sha sha; 03211 ret = InitSha(&sha); 03212 if (ret != 0) 03213 return ret; 03214 ShaUpdate(&sha, input + idx, length); 03215 ShaFinal(&sha, cert->extAuthKeyId); 03216 } 03217 03218 return 0; 03219 } 03220 03221 03222 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert) 03223 { 03224 word32 idx = 0; 03225 int length = 0, ret = 0; 03226 03227 CYASSL_ENTER("DecodeSubjKeyId"); 03228 03229 if (input[idx++] != ASN_OCTET_STRING) { 03230 CYASSL_MSG("\tfail: should be an OCTET STRING"); 03231 return ASN_PARSE_E; 03232 } 03233 03234 if (GetLength(input, &idx, &length, sz) < 0) { 03235 CYASSL_MSG("\tfail: extension data length"); 03236 return ASN_PARSE_E; 03237 } 03238 03239 #ifdef OPENSSL_EXTRA 03240 cert->extSubjKeyIdSrc = &input[idx]; 03241 cert->extSubjKeyIdSz = length; 03242 #endif /* OPENSSL_EXTRA */ 03243 03244 if (length == SIGNER_DIGEST_SIZE) { 03245 XMEMCPY(cert->extSubjKeyId, input + idx, length); 03246 } 03247 else { 03248 Sha sha; 03249 ret = InitSha(&sha); 03250 if (ret != 0) 03251 return ret; 03252 ShaUpdate(&sha, input + idx, length); 03253 ShaFinal(&sha, cert->extSubjKeyId); 03254 } 03255 03256 return ret; 03257 } 03258 03259 03260 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert) 03261 { 03262 word32 idx = 0; 03263 int length; 03264 byte unusedBits; 03265 CYASSL_ENTER("DecodeKeyUsage"); 03266 03267 if (input[idx++] != ASN_BIT_STRING) { 03268 CYASSL_MSG("\tfail: key usage expected bit string"); 03269 return ASN_PARSE_E; 03270 } 03271 03272 if (GetLength(input, &idx, &length, sz) < 0) { 03273 CYASSL_MSG("\tfail: key usage bad length"); 03274 return ASN_PARSE_E; 03275 } 03276 03277 unusedBits = input[idx++]; 03278 length--; 03279 03280 if (length == 2) { 03281 cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]); 03282 cert->extKeyUsage >>= unusedBits; 03283 } 03284 else if (length == 1) 03285 cert->extKeyUsage = (word16)(input[idx] << 1); 03286 03287 return 0; 03288 } 03289 03290 03291 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert) 03292 { 03293 word32 idx = 0, oid; 03294 int length; 03295 03296 CYASSL_ENTER("DecodeExtKeyUsage"); 03297 03298 if (GetSequence(input, &idx, &length, sz) < 0) { 03299 CYASSL_MSG("\tfail: should be a SEQUENCE\n"); 03300 return ASN_PARSE_E; 03301 } 03302 03303 #ifdef OPENSSL_EXTRA 03304 cert->extExtKeyUsageSrc = input + idx; 03305 cert->extExtKeyUsageSz = length; 03306 #endif 03307 03308 while (idx < (word32)sz) { 03309 if (GetObjectId(input, &idx, &oid, sz) < 0) 03310 return ASN_PARSE_E; 03311 03312 switch (oid) { 03313 case EKU_ANY_OID: 03314 cert->extExtKeyUsage |= EXTKEYUSE_ANY; 03315 break; 03316 case EKU_SERVER_AUTH_OID: 03317 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH; 03318 break; 03319 case EKU_CLIENT_AUTH_OID: 03320 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH; 03321 break; 03322 case EKU_OCSP_SIGN_OID: 03323 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN; 03324 break; 03325 } 03326 03327 #ifdef OPENSSL_EXTRA 03328 cert->extExtKeyUsageCount++; 03329 #endif 03330 } 03331 03332 return 0; 03333 } 03334 03335 03336 #ifdef CYASSL_SEP 03337 static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert) 03338 { 03339 word32 idx = 0; 03340 int length = 0; 03341 03342 CYASSL_ENTER("DecodeCertPolicy"); 03343 03344 /* Unwrap certificatePolicies */ 03345 if (GetSequence(input, &idx, &length, sz) < 0) { 03346 CYASSL_MSG("\tdeviceType isn't OID"); 03347 return ASN_PARSE_E; 03348 } 03349 03350 if (GetSequence(input, &idx, &length, sz) < 0) { 03351 CYASSL_MSG("\tdeviceType isn't OID"); 03352 return ASN_PARSE_E; 03353 } 03354 03355 if (input[idx++] != ASN_OBJECT_ID) { 03356 CYASSL_MSG("\tdeviceType isn't OID"); 03357 return ASN_PARSE_E; 03358 } 03359 03360 if (GetLength(input, &idx, &length, sz) < 0) { 03361 CYASSL_MSG("\tCouldn't read length of deviceType"); 03362 return ASN_PARSE_E; 03363 } 03364 03365 if (length > 0) { 03366 cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0); 03367 if (cert->deviceType == NULL) { 03368 CYASSL_MSG("\tCouldn't alloc memory for deviceType"); 03369 return MEMORY_E; 03370 } 03371 cert->deviceTypeSz = length; 03372 XMEMCPY(cert->deviceType, input + idx, length); 03373 } 03374 03375 CYASSL_LEAVE("DecodeCertPolicy", 0); 03376 return 0; 03377 } 03378 #endif /* CYASSL_SEP */ 03379 03380 03381 static int DecodeCertExtensions(DecodedCert* cert) 03382 /* 03383 * Processing the Certificate Extensions. This does not modify the current 03384 * index. It is works starting with the recorded extensions pointer. 03385 */ 03386 { 03387 word32 idx = 0; 03388 int sz = cert->extensionsSz; 03389 byte* input = cert->extensions; 03390 int length; 03391 word32 oid; 03392 byte critical = 0; 03393 byte criticalFail = 0; 03394 03395 CYASSL_ENTER("DecodeCertExtensions"); 03396 03397 if (input == NULL || sz == 0) 03398 return BAD_FUNC_ARG; 03399 03400 if (input[idx++] != ASN_EXTENSIONS) 03401 return ASN_PARSE_E; 03402 03403 if (GetLength(input, &idx, &length, sz) < 0) 03404 return ASN_PARSE_E; 03405 03406 if (GetSequence(input, &idx, &length, sz) < 0) 03407 return ASN_PARSE_E; 03408 03409 while (idx < (word32)sz) { 03410 if (GetSequence(input, &idx, &length, sz) < 0) { 03411 CYASSL_MSG("\tfail: should be a SEQUENCE"); 03412 return ASN_PARSE_E; 03413 } 03414 03415 oid = 0; 03416 if (GetObjectId(input, &idx, &oid, sz) < 0) { 03417 CYASSL_MSG("\tfail: OBJECT ID"); 03418 return ASN_PARSE_E; 03419 } 03420 03421 /* check for critical flag */ 03422 critical = 0; 03423 if (input[idx] == ASN_BOOLEAN) { 03424 int boolLength = 0; 03425 idx++; 03426 if (GetLength(input, &idx, &boolLength, sz) < 0) { 03427 CYASSL_MSG("\tfail: critical boolean length"); 03428 return ASN_PARSE_E; 03429 } 03430 if (input[idx++]) 03431 critical = 1; 03432 } 03433 03434 /* process the extension based on the OID */ 03435 if (input[idx++] != ASN_OCTET_STRING) { 03436 CYASSL_MSG("\tfail: should be an OCTET STRING"); 03437 return ASN_PARSE_E; 03438 } 03439 03440 if (GetLength(input, &idx, &length, sz) < 0) { 03441 CYASSL_MSG("\tfail: extension data length"); 03442 return ASN_PARSE_E; 03443 } 03444 03445 switch (oid) { 03446 case BASIC_CA_OID: 03447 #ifdef OPENSSL_EXTRA 03448 cert->extBasicConstSet = 1; 03449 cert->extBasicConstCrit = critical; 03450 #endif 03451 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0) 03452 return ASN_PARSE_E; 03453 break; 03454 03455 case CRL_DIST_OID: 03456 if (DecodeCrlDist(&input[idx], length, cert) < 0) 03457 return ASN_PARSE_E; 03458 break; 03459 03460 case AUTH_INFO_OID: 03461 if (DecodeAuthInfo(&input[idx], length, cert) < 0) 03462 return ASN_PARSE_E; 03463 break; 03464 03465 case ALT_NAMES_OID: 03466 #ifdef OPENSSL_EXTRA 03467 cert->extSubjAltNameSet = 1; 03468 cert->extSubjAltNameCrit = critical; 03469 #endif 03470 if (DecodeAltNames(&input[idx], length, cert) < 0) 03471 return ASN_PARSE_E; 03472 break; 03473 03474 case AUTH_KEY_OID: 03475 cert->extAuthKeyIdSet = 1; 03476 #ifdef OPENSSL_EXTRA 03477 cert->extAuthKeyIdCrit = critical; 03478 #endif 03479 if (DecodeAuthKeyId(&input[idx], length, cert) < 0) 03480 return ASN_PARSE_E; 03481 break; 03482 03483 case SUBJ_KEY_OID: 03484 cert->extSubjKeyIdSet = 1; 03485 #ifdef OPENSSL_EXTRA 03486 cert->extSubjKeyIdCrit = critical; 03487 #endif 03488 if (DecodeSubjKeyId(&input[idx], length, cert) < 0) 03489 return ASN_PARSE_E; 03490 break; 03491 03492 case CERT_POLICY_OID: 03493 CYASSL_MSG("Certificate Policy extension not supported yet."); 03494 #ifdef CYASSL_SEP 03495 #ifdef OPENSSL_EXTRA 03496 cert->extCertPolicySet = 1; 03497 cert->extCertPolicyCrit = critical; 03498 #endif 03499 if (DecodeCertPolicy(&input[idx], length, cert) < 0) 03500 return ASN_PARSE_E; 03501 #endif 03502 break; 03503 03504 case KEY_USAGE_OID: 03505 cert->extKeyUsageSet = 1; 03506 #ifdef OPENSSL_EXTRA 03507 cert->extKeyUsageCrit = critical; 03508 #endif 03509 if (DecodeKeyUsage(&input[idx], length, cert) < 0) 03510 return ASN_PARSE_E; 03511 break; 03512 03513 case EXT_KEY_USAGE_OID: 03514 cert->extExtKeyUsageSet = 1; 03515 #ifdef OPENSSL_EXTRA 03516 cert->extExtKeyUsageCrit = critical; 03517 #endif 03518 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0) 03519 return ASN_PARSE_E; 03520 break; 03521 03522 case INHIBIT_ANY_OID: 03523 CYASSL_MSG("Inhibit anyPolicy extension not supported yet."); 03524 break; 03525 03526 default: 03527 /* While it is a failure to not support critical extensions, 03528 * still parse the certificate ignoring the unsupported 03529 * extention to allow caller to accept it with the verify 03530 * callback. */ 03531 if (critical) 03532 criticalFail = 1; 03533 break; 03534 } 03535 idx += length; 03536 } 03537 03538 return criticalFail ? ASN_CRIT_EXT_E : 0; 03539 } 03540 03541 03542 int ParseCert(DecodedCert* cert, int type, int verify, void* cm) 03543 { 03544 int ret; 03545 char* ptr; 03546 03547 ret = ParseCertRelative(cert, type, verify, cm); 03548 if (ret < 0) 03549 return ret; 03550 03551 if (cert->subjectCNLen > 0) { 03552 ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap, 03553 DYNAMIC_TYPE_SUBJECT_CN); 03554 if (ptr == NULL) 03555 return MEMORY_E; 03556 XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen); 03557 ptr[cert->subjectCNLen] = '\0'; 03558 cert->subjectCN = ptr; 03559 cert->subjectCNStored = 1; 03560 } 03561 03562 if (cert->keyOID == RSAk && 03563 cert->publicKey != NULL && cert->pubKeySize > 0) { 03564 ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap, 03565 DYNAMIC_TYPE_PUBLIC_KEY); 03566 if (ptr == NULL) 03567 return MEMORY_E; 03568 XMEMCPY(ptr, cert->publicKey, cert->pubKeySize); 03569 cert->publicKey = (byte *)ptr; 03570 cert->pubKeyStored = 1; 03571 } 03572 03573 return ret; 03574 } 03575 03576 03577 /* from SSL proper, for locking can't do find here anymore */ 03578 #ifdef __cplusplus 03579 extern "C" { 03580 #endif 03581 CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash); 03582 #ifndef NO_SKID 03583 CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash); 03584 #endif 03585 #ifdef __cplusplus 03586 } 03587 #endif 03588 03589 03590 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) 03591 { 03592 word32 confirmOID; 03593 int ret; 03594 int badDate = 0; 03595 int criticalExt = 0; 03596 03597 if ((ret = DecodeToKey(cert, verify)) < 0) { 03598 if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) 03599 badDate = ret; 03600 else 03601 return ret; 03602 } 03603 03604 CYASSL_MSG("Parsed Past Key"); 03605 03606 if (cert->srcIdx != cert->sigIndex) { 03607 if (cert->srcIdx < cert->sigIndex) { 03608 /* save extensions */ 03609 cert->extensions = &cert->source[cert->srcIdx]; 03610 cert->extensionsSz = cert->sigIndex - cert->srcIdx; 03611 cert->extensionsIdx = cert->srcIdx; /* for potential later use */ 03612 } 03613 if ((ret = DecodeCertExtensions(cert)) < 0) { 03614 if (ret == ASN_CRIT_EXT_E) 03615 criticalExt = ret; 03616 else 03617 return ret; 03618 } 03619 03620 /* advance past extensions */ 03621 cert->srcIdx = cert->sigIndex; 03622 } 03623 03624 if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID, 03625 cert->maxIdx)) < 0) 03626 return ret; 03627 03628 if ((ret = GetSignature(cert)) < 0) 03629 return ret; 03630 03631 if (confirmOID != cert->signatureOID) 03632 return ASN_SIG_OID_E; 03633 03634 #ifndef NO_SKID 03635 if (cert->extSubjKeyIdSet == 0 03636 && cert->publicKey != NULL && cert->pubKeySize > 0) { 03637 Sha sha; 03638 ret = InitSha(&sha); 03639 if (ret != 0) 03640 return ret; 03641 ShaUpdate(&sha, cert->publicKey, cert->pubKeySize); 03642 ShaFinal(&sha, cert->extSubjKeyId); 03643 } 03644 #endif 03645 03646 if (verify && type != CA_TYPE) { 03647 Signer* ca = NULL; 03648 #ifndef NO_SKID 03649 if (cert->extAuthKeyIdSet) 03650 ca = GetCA(cm, cert->extAuthKeyId); 03651 if (ca == NULL) 03652 ca = GetCAByName(cm, cert->issuerHash); 03653 #else /* NO_SKID */ 03654 ca = GetCA(cm, cert->issuerHash); 03655 #endif /* NO SKID */ 03656 CYASSL_MSG("About to verify certificate signature"); 03657 03658 if (ca) { 03659 #ifdef HAVE_OCSP 03660 /* Need the ca's public key hash for OCSP */ 03661 { 03662 Sha sha; 03663 ret = InitSha(&sha); 03664 if (ret != 0) 03665 return ret; 03666 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize); 03667 ShaFinal(&sha, cert->issuerKeyHash); 03668 } 03669 #endif /* HAVE_OCSP */ 03670 /* try to confirm/verify signature */ 03671 if (!ConfirmSignature(cert->source + cert->certBegin, 03672 cert->sigIndex - cert->certBegin, 03673 ca->publicKey, ca->pubKeySize, ca->keyOID, 03674 cert->signature, cert->sigLength, cert->signatureOID, 03675 cert->heap)) { 03676 CYASSL_MSG("Confirm signature failed"); 03677 return ASN_SIG_CONFIRM_E; 03678 } 03679 } 03680 else { 03681 /* no signer */ 03682 CYASSL_MSG("No CA signer to verify with"); 03683 return ASN_NO_SIGNER_E; 03684 } 03685 } 03686 03687 if (badDate != 0) 03688 return badDate; 03689 03690 if (criticalExt != 0) 03691 return criticalExt; 03692 03693 return 0; 03694 } 03695 03696 03697 /* Create and init an new signer */ 03698 Signer* MakeSigner(void* heap) 03699 { 03700 Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, 03701 DYNAMIC_TYPE_SIGNER); 03702 if (signer) { 03703 signer->pubKeySize = 0; 03704 signer->keyOID = 0; 03705 signer->publicKey = NULL; 03706 signer->nameLen = 0; 03707 signer->name = NULL; 03708 signer->next = NULL; 03709 } 03710 (void)heap; 03711 03712 return signer; 03713 } 03714 03715 03716 /* Free an individual signer */ 03717 void FreeSigner(Signer* signer, void* heap) 03718 { 03719 XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); 03720 XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); 03721 XFREE(signer, heap, DYNAMIC_TYPE_SIGNER); 03722 03723 (void)heap; 03724 } 03725 03726 03727 /* Free the whole singer table with number of rows */ 03728 void FreeSignerTable(Signer** table, int rows, void* heap) 03729 { 03730 int i; 03731 03732 for (i = 0; i < rows; i++) { 03733 Signer* signer = table[i]; 03734 while (signer) { 03735 Signer* next = signer->next; 03736 FreeSigner(signer, heap); 03737 signer = next; 03738 } 03739 table[i] = NULL; 03740 } 03741 } 03742 03743 03744 CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header) 03745 { 03746 int i = 0; 03747 03748 if (header) { 03749 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED; 03750 output[i++] = ASN_BIT_STRING; 03751 } 03752 output[i++] = ASN_INTEGER; 03753 output[i++] = 0x01; 03754 output[i++] = (byte)version; 03755 03756 return i; 03757 } 03758 03759 03760 CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output) 03761 { 03762 int result = 0; 03763 03764 CYASSL_ENTER("SetSerialNumber"); 03765 03766 if (snSz <= EXTERNAL_SERIAL_SIZE) { 03767 output[0] = ASN_INTEGER; 03768 /* The serial number is always positive. When encoding the 03769 * INTEGER, if the MSB is 1, add a padding zero to keep the 03770 * number positive. */ 03771 if (sn[0] & 0x80) { 03772 output[1] = (byte)snSz + 1; 03773 output[2] = 0; 03774 XMEMCPY(&output[3], sn, snSz); 03775 result = snSz + 3; 03776 } 03777 else { 03778 output[1] = (byte)snSz; 03779 XMEMCPY(&output[2], sn, snSz); 03780 result = snSz + 2; 03781 } 03782 } 03783 return result; 03784 } 03785 03786 03787 03788 03789 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) 03790 03791 /* convert der buffer to pem into output, can't do inplace, der and output 03792 need to be different */ 03793 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, 03794 int type) 03795 { 03796 char header[80]; 03797 char footer[80]; 03798 03799 int headerLen; 03800 int footerLen; 03801 int i; 03802 int err; 03803 int outLen; /* return length or error */ 03804 03805 if (der == output) /* no in place conversion */ 03806 return BAD_FUNC_ARG; 03807 03808 if (type == CERT_TYPE) { 03809 XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header)); 03810 XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer)); 03811 } 03812 else if (type == PRIVATEKEY_TYPE) { 03813 XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header)); 03814 XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer)); 03815 } 03816 #ifdef HAVE_ECC 03817 else if (type == ECC_PRIVATEKEY_TYPE) { 03818 XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", sizeof(header)); 03819 XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", sizeof(footer)); 03820 } 03821 #endif 03822 #ifdef CYASSL_CERT_REQ 03823 else if (type == CERTREQ_TYPE) 03824 { 03825 XSTRNCPY(header, 03826 "-----BEGIN CERTIFICATE REQUEST-----\n", sizeof(header)); 03827 XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", sizeof(footer)); 03828 } 03829 #endif 03830 else 03831 return BAD_FUNC_ARG; 03832 03833 headerLen = (int)XSTRLEN(header); 03834 footerLen = (int)XSTRLEN(footer); 03835 03836 if (!der || !output) 03837 return BAD_FUNC_ARG; 03838 03839 /* don't even try if outSz too short */ 03840 if (outSz < headerLen + footerLen + derSz) 03841 return BAD_FUNC_ARG; 03842 03843 /* header */ 03844 XMEMCPY(output, header, headerLen); 03845 i = headerLen; 03846 03847 /* body */ 03848 outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */ 03849 if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) 03850 return err; 03851 i += outLen; 03852 03853 /* footer */ 03854 if ( (i + footerLen) > (int)outSz) 03855 return BAD_FUNC_ARG; 03856 XMEMCPY(output + i, footer, footerLen); 03857 03858 return outLen + headerLen + footerLen; 03859 } 03860 03861 03862 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */ 03863 03864 03865 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) 03866 03867 03868 static mp_int* GetRsaInt(RsaKey* key, int idx) 03869 { 03870 if (idx == 0) 03871 return &key->n; 03872 if (idx == 1) 03873 return &key->e; 03874 if (idx == 2) 03875 return &key->d; 03876 if (idx == 3) 03877 return &key->p; 03878 if (idx == 4) 03879 return &key->q; 03880 if (idx == 5) 03881 return &key->dP; 03882 if (idx == 6) 03883 return &key->dQ; 03884 if (idx == 7) 03885 return &key->u; 03886 03887 return NULL; 03888 } 03889 03890 03891 /* Release Tmp RSA resources */ 03892 static INLINE void FreeTmpRsas(byte** tmps, void* heap) 03893 { 03894 int i; 03895 03896 (void)heap; 03897 03898 for (i = 0; i < RSA_INTS; i++) 03899 XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA); 03900 } 03901 03902 03903 /* Convert RsaKey key to DER format, write to output (inLen), return bytes 03904 written */ 03905 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) 03906 { 03907 word32 seqSz, verSz, rawLen, intTotalLen = 0; 03908 word32 sizes[RSA_INTS]; 03909 int i, j, outLen, ret = 0; 03910 03911 byte seq[MAX_SEQ_SZ]; 03912 byte ver[MAX_VERSION_SZ]; 03913 byte* tmps[RSA_INTS]; 03914 03915 if (!key || !output) 03916 return BAD_FUNC_ARG; 03917 03918 if (key->type != RSA_PRIVATE) 03919 return BAD_FUNC_ARG; 03920 03921 for (i = 0; i < RSA_INTS; i++) 03922 tmps[i] = NULL; 03923 03924 /* write all big ints from key to DER tmps */ 03925 for (i = 0; i < RSA_INTS; i++) { 03926 mp_int* keyInt = GetRsaInt(key, i); 03927 rawLen = mp_unsigned_bin_size(keyInt); 03928 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap, 03929 DYNAMIC_TYPE_RSA); 03930 if (tmps[i] == NULL) { 03931 ret = MEMORY_E; 03932 break; 03933 } 03934 03935 tmps[i][0] = ASN_INTEGER; 03936 sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ 03937 03938 if (sizes[i] <= MAX_SEQ_SZ) { 03939 int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); 03940 if (err == MP_OKAY) { 03941 sizes[i] += rawLen; 03942 intTotalLen += sizes[i]; 03943 } 03944 else { 03945 ret = err; 03946 break; 03947 } 03948 } 03949 else { 03950 ret = ASN_INPUT_E; 03951 break; 03952 } 03953 } 03954 03955 if (ret != 0) { 03956 FreeTmpRsas(tmps, key->heap); 03957 return ret; 03958 } 03959 03960 /* make headers */ 03961 verSz = SetMyVersion(0, ver, FALSE); 03962 seqSz = SetSequence(verSz + intTotalLen, seq); 03963 03964 outLen = seqSz + verSz + intTotalLen; 03965 if (outLen > (int)inLen) 03966 return BAD_FUNC_ARG; 03967 03968 /* write to output */ 03969 XMEMCPY(output, seq, seqSz); 03970 j = seqSz; 03971 XMEMCPY(output + j, ver, verSz); 03972 j += verSz; 03973 03974 for (i = 0; i < RSA_INTS; i++) { 03975 XMEMCPY(output + j, tmps[i], sizes[i]); 03976 j += sizes[i]; 03977 } 03978 FreeTmpRsas(tmps, key->heap); 03979 03980 return outLen; 03981 } 03982 03983 #endif /* CYASSL_KEY_GEN && !NO_RSA */ 03984 03985 03986 #if defined(CYASSL_CERT_GEN) && !defined(NO_RSA) 03987 03988 03989 #ifndef min 03990 03991 static INLINE word32 min(word32 a, word32 b) 03992 { 03993 return a > b ? b : a; 03994 } 03995 03996 #endif /* min */ 03997 03998 03999 /* Initialize and Set Certficate defaults: 04000 version = 3 (0x2) 04001 serial = 0 04002 sigType = SHA_WITH_RSA 04003 issuer = blank 04004 daysValid = 500 04005 selfSigned = 1 (true) use subject as issuer 04006 subject = blank 04007 */ 04008 void InitCert(Cert* cert) 04009 { 04010 cert->version = 2; /* version 3 is hex 2 */ 04011 cert->sigType = CTC_SHAwRSA; 04012 cert->daysValid = 500; 04013 cert->selfSigned = 1; 04014 cert->isCA = 0; 04015 cert->bodySz = 0; 04016 #ifdef CYASSL_ALT_NAMES 04017 cert->altNamesSz = 0; 04018 cert->beforeDateSz = 0; 04019 cert->afterDateSz = 0; 04020 #endif 04021 cert->keyType = RSA_KEY; 04022 XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); 04023 04024 cert->issuer.country[0] = '\0'; 04025 cert->issuer.state[0] = '\0'; 04026 cert->issuer.locality[0] = '\0'; 04027 cert->issuer.sur[0] = '\0'; 04028 cert->issuer.org[0] = '\0'; 04029 cert->issuer.unit[0] = '\0'; 04030 cert->issuer.commonName[0] = '\0'; 04031 cert->issuer.email[0] = '\0'; 04032 04033 cert->subject.country[0] = '\0'; 04034 cert->subject.state[0] = '\0'; 04035 cert->subject.locality[0] = '\0'; 04036 cert->subject.sur[0] = '\0'; 04037 cert->subject.org[0] = '\0'; 04038 cert->subject.unit[0] = '\0'; 04039 cert->subject.commonName[0] = '\0'; 04040 cert->subject.email[0] = '\0'; 04041 04042 #ifdef CYASSL_CERT_REQ 04043 cert->challengePw[0] ='\0'; 04044 #endif 04045 } 04046 04047 04048 /* DER encoded x509 Certificate */ 04049 typedef struct DerCert { 04050 byte size[MAX_LENGTH_SZ]; /* length encoded */ 04051 byte version[MAX_VERSION_SZ]; /* version encoded */ 04052 byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */ 04053 byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */ 04054 byte issuer[ASN_NAME_MAX]; /* issuer encoded */ 04055 byte subject[ASN_NAME_MAX]; /* subject encoded */ 04056 byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */ 04057 byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */ 04058 byte ca[MAX_CA_SZ]; /* basic constraint CA true size */ 04059 byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */ 04060 #ifdef CYASSL_CERT_REQ 04061 byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */ 04062 #endif 04063 int sizeSz; /* encoded size length */ 04064 int versionSz; /* encoded version length */ 04065 int serialSz; /* encoded serial length */ 04066 int sigAlgoSz; /* enocded sig alog length */ 04067 int issuerSz; /* encoded issuer length */ 04068 int subjectSz; /* encoded subject length */ 04069 int validitySz; /* encoded validity length */ 04070 int publicKeySz; /* encoded public key length */ 04071 int caSz; /* encoded CA extension length */ 04072 int extensionsSz; /* encoded extensions total length */ 04073 int total; /* total encoded lengths */ 04074 #ifdef CYASSL_CERT_REQ 04075 int attribSz; 04076 #endif 04077 } DerCert; 04078 04079 04080 #ifdef CYASSL_CERT_REQ 04081 04082 /* Write a set header to output */ 04083 static word32 SetUTF8String(word32 len, byte* output) 04084 { 04085 output[0] = ASN_UTF8STRING; 04086 return SetLength(len, output + 1) + 1; 04087 } 04088 04089 #endif /* CYASSL_CERT_REQ */ 04090 04091 04092 /* Write a serial number to output */ 04093 static int SetSerial(const byte* serial, byte* output) 04094 { 04095 int length = 0; 04096 04097 output[length++] = ASN_INTEGER; 04098 length += SetLength(CTC_SERIAL_SIZE, &output[length]); 04099 XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE); 04100 04101 return length + CTC_SERIAL_SIZE; 04102 } 04103 04104 04105 #ifdef HAVE_ECC 04106 04107 /* Write a public ECC key to output */ 04108 static int SetEccPublicKey(byte* output, ecc_key* key) 04109 { 04110 byte algo[MAX_ALGO_SZ]; 04111 byte curve[MAX_ALGO_SZ]; 04112 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ 04113 byte pub[ECC_BUFSIZE]; 04114 int algoSz; 04115 int curveSz; 04116 int lenSz; 04117 int idx; 04118 word32 pubSz = sizeof(pub); 04119 04120 int ret = ecc_export_x963(key, pub, &pubSz); 04121 if (ret != 0) return ret; 04122 04123 /* headers */ 04124 curveSz = SetCurve(key, curve); 04125 if (curveSz <= 0) return curveSz; 04126 04127 algoSz = SetAlgoID(ECDSAk, algo, keyType, curveSz); 04128 lenSz = SetLength(pubSz + 1, len); 04129 len[lenSz++] = 0; /* trailing 0 */ 04130 04131 /* write */ 04132 idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output); 04133 /* 1 is for ASN_BIT_STRING */ 04134 /* algo */ 04135 XMEMCPY(output + idx, algo, algoSz); 04136 idx += algoSz; 04137 /* curve */ 04138 XMEMCPY(output + idx, curve, curveSz); 04139 idx += curveSz; 04140 /* bit string */ 04141 output[idx++] = ASN_BIT_STRING; 04142 /* length */ 04143 XMEMCPY(output + idx, len, lenSz); 04144 idx += lenSz; 04145 /* pub */ 04146 XMEMCPY(output + idx, pub, pubSz); 04147 idx += pubSz; 04148 04149 return idx; 04150 } 04151 04152 04153 #endif /* HAVE_ECC */ 04154 04155 04156 /* Write a public RSA key to output */ 04157 static int SetRsaPublicKey(byte* output, RsaKey* key) 04158 { 04159 byte n[MAX_RSA_INT_SZ]; 04160 byte e[MAX_RSA_E_SZ]; 04161 byte algo[MAX_ALGO_SZ]; 04162 byte seq[MAX_SEQ_SZ]; 04163 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ 04164 int nSz; 04165 int eSz; 04166 int algoSz; 04167 int seqSz; 04168 int lenSz; 04169 int idx; 04170 int rawLen; 04171 int leadingBit; 04172 int err; 04173 04174 /* n */ 04175 leadingBit = mp_leading_bit(&key->n); 04176 rawLen = mp_unsigned_bin_size(&key->n) + leadingBit; 04177 n[0] = ASN_INTEGER; 04178 nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ 04179 04180 if ( (nSz + rawLen) < (int)sizeof(n)) { 04181 if (leadingBit) 04182 n[nSz] = 0; 04183 err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit); 04184 if (err == MP_OKAY) 04185 nSz += rawLen; 04186 else 04187 return MP_TO_E; 04188 } 04189 else 04190 return BUFFER_E; 04191 04192 /* e */ 04193 leadingBit = mp_leading_bit(&key->e); 04194 rawLen = mp_unsigned_bin_size(&key->e) + leadingBit; 04195 e[0] = ASN_INTEGER; 04196 eSz = SetLength(rawLen, e + 1) + 1; /* int tag */ 04197 04198 if ( (eSz + rawLen) < (int)sizeof(e)) { 04199 if (leadingBit) 04200 e[eSz] = 0; 04201 err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit); 04202 if (err == MP_OKAY) 04203 eSz += rawLen; 04204 else 04205 return MP_TO_E; 04206 } 04207 else 04208 return BUFFER_E; 04209 04210 /* headers */ 04211 algoSz = SetAlgoID(RSAk, algo, keyType, 0); 04212 seqSz = SetSequence(nSz + eSz, seq); 04213 lenSz = SetLength(seqSz + nSz + eSz + 1, len); 04214 len[lenSz++] = 0; /* trailing 0 */ 04215 04216 /* write */ 04217 idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output); 04218 /* 1 is for ASN_BIT_STRING */ 04219 /* algo */ 04220 XMEMCPY(output + idx, algo, algoSz); 04221 idx += algoSz; 04222 /* bit string */ 04223 output[idx++] = ASN_BIT_STRING; 04224 /* length */ 04225 XMEMCPY(output + idx, len, lenSz); 04226 idx += lenSz; 04227 /* seq */ 04228 XMEMCPY(output + idx, seq, seqSz); 04229 idx += seqSz; 04230 /* n */ 04231 XMEMCPY(output + idx, n, nSz); 04232 idx += nSz; 04233 /* e */ 04234 XMEMCPY(output + idx, e, eSz); 04235 idx += eSz; 04236 04237 return idx; 04238 } 04239 04240 04241 static INLINE byte itob(int number) 04242 { 04243 return (byte)number + 0x30; 04244 } 04245 04246 04247 /* write time to output, format */ 04248 static void SetTime(struct tm* date, byte* output) 04249 { 04250 int i = 0; 04251 04252 output[i++] = itob((date->tm_year % 10000) / 1000); 04253 output[i++] = itob((date->tm_year % 1000) / 100); 04254 output[i++] = itob((date->tm_year % 100) / 10); 04255 output[i++] = itob( date->tm_year % 10); 04256 04257 output[i++] = itob(date->tm_mon / 10); 04258 output[i++] = itob(date->tm_mon % 10); 04259 04260 output[i++] = itob(date->tm_mday / 10); 04261 output[i++] = itob(date->tm_mday % 10); 04262 04263 output[i++] = itob(date->tm_hour / 10); 04264 output[i++] = itob(date->tm_hour % 10); 04265 04266 output[i++] = itob(date->tm_min / 10); 04267 output[i++] = itob(date->tm_min % 10); 04268 04269 output[i++] = itob(date->tm_sec / 10); 04270 output[i++] = itob(date->tm_sec % 10); 04271 04272 output[i] = 'Z'; /* Zulu profile */ 04273 } 04274 04275 04276 #ifdef CYASSL_ALT_NAMES 04277 04278 /* Copy Dates from cert, return bytes written */ 04279 static int CopyValidity(byte* output, Cert* cert) 04280 { 04281 int seqSz; 04282 04283 CYASSL_ENTER("CopyValidity"); 04284 04285 /* headers and output */ 04286 seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output); 04287 XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz); 04288 XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate, 04289 cert->afterDateSz); 04290 return seqSz + cert->beforeDateSz + cert->afterDateSz; 04291 } 04292 04293 #endif 04294 04295 04296 /* Set Date validity from now until now + daysValid */ 04297 static int SetValidity(byte* output, int daysValid) 04298 { 04299 byte before[MAX_DATE_SIZE]; 04300 byte after[MAX_DATE_SIZE]; 04301 04302 int beforeSz; 04303 int afterSz; 04304 int seqSz; 04305 04306 time_t ticks; 04307 struct tm* now; 04308 struct tm local; 04309 04310 ticks = XTIME(0); 04311 now = XGMTIME(&ticks); 04312 04313 /* before now */ 04314 local = *now; 04315 before[0] = ASN_GENERALIZED_TIME; 04316 beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ 04317 04318 /* subtract 1 day for more compliance */ 04319 local.tm_mday -= 1; 04320 mktime(&local); 04321 04322 /* adjust */ 04323 local.tm_year += 1900; 04324 local.tm_mon += 1; 04325 04326 SetTime(&local, before + beforeSz); 04327 beforeSz += ASN_GEN_TIME_SZ; 04328 04329 /* after now + daysValid */ 04330 local = *now; 04331 after[0] = ASN_GENERALIZED_TIME; 04332 afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ 04333 04334 /* add daysValid */ 04335 local.tm_mday += daysValid; 04336 mktime(&local); 04337 04338 /* adjust */ 04339 local.tm_year += 1900; 04340 local.tm_mon += 1; 04341 04342 SetTime(&local, after + afterSz); 04343 afterSz += ASN_GEN_TIME_SZ; 04344 04345 /* headers and output */ 04346 seqSz = SetSequence(beforeSz + afterSz, output); 04347 XMEMCPY(output + seqSz, before, beforeSz); 04348 XMEMCPY(output + seqSz + beforeSz, after, afterSz); 04349 04350 return seqSz + beforeSz + afterSz; 04351 } 04352 04353 04354 /* ASN Encoded Name field */ 04355 typedef struct EncodedName { 04356 int nameLen; /* actual string value length */ 04357 int totalLen; /* total encoded length */ 04358 int type; /* type of name */ 04359 int used; /* are we actually using this one */ 04360 byte encoded[CTC_NAME_SIZE * 2]; /* encoding */ 04361 } EncodedName; 04362 04363 04364 /* Get Which Name from index */ 04365 static const char* GetOneName(CertName* name, int idx) 04366 { 04367 switch (idx) { 04368 case 0: 04369 return name->country; 04370 04371 case 1: 04372 return name->state; 04373 04374 case 2: 04375 return name->locality; 04376 04377 case 3: 04378 return name->sur; 04379 04380 case 4: 04381 return name->org; 04382 04383 case 5: 04384 return name->unit; 04385 04386 case 6: 04387 return name->commonName; 04388 04389 case 7: 04390 return name->email; 04391 04392 default: 04393 return 0; 04394 } 04395 } 04396 04397 04398 /* Get ASN Name from index */ 04399 static byte GetNameId(int idx) 04400 { 04401 switch (idx) { 04402 case 0: 04403 return ASN_COUNTRY_NAME; 04404 04405 case 1: 04406 return ASN_STATE_NAME; 04407 04408 case 2: 04409 return ASN_LOCALITY_NAME; 04410 04411 case 3: 04412 return ASN_SUR_NAME; 04413 04414 case 4: 04415 return ASN_ORG_NAME; 04416 04417 case 5: 04418 return ASN_ORGUNIT_NAME; 04419 04420 case 6: 04421 return ASN_COMMON_NAME; 04422 04423 case 7: 04424 /* email uses different id type */ 04425 return 0; 04426 04427 default: 04428 return 0; 04429 } 04430 } 04431 04432 04433 /* encode all extensions, return total bytes written */ 04434 static int SetExtensions(byte* output, const byte* ext, int extSz, int header) 04435 { 04436 byte sequence[MAX_SEQ_SZ]; 04437 byte len[MAX_LENGTH_SZ]; 04438 04439 int sz = 0; 04440 int seqSz = SetSequence(extSz, sequence); 04441 04442 if (header) { 04443 int lenSz = SetLength(seqSz + extSz, len); 04444 output[0] = ASN_EXTENSIONS; /* extensions id */ 04445 sz++; 04446 XMEMCPY(&output[sz], len, lenSz); /* length */ 04447 sz += lenSz; 04448 } 04449 XMEMCPY(&output[sz], sequence, seqSz); /* sequence */ 04450 sz += seqSz; 04451 XMEMCPY(&output[sz], ext, extSz); /* extensions */ 04452 sz += extSz; 04453 04454 return sz; 04455 } 04456 04457 04458 /* encode CA basic constraint true, return total bytes written */ 04459 static int SetCa(byte* output) 04460 { 04461 static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 04462 0x05, 0x30, 0x03, 0x01, 0x01, 0xff }; 04463 04464 XMEMCPY(output, ca, sizeof(ca)); 04465 04466 return (int)sizeof(ca); 04467 } 04468 04469 04470 /* encode CertName into output, return total bytes written */ 04471 static int SetName(byte* output, CertName* name) 04472 { 04473 int totalBytes = 0, i, idx; 04474 EncodedName names[NAME_ENTRIES]; 04475 04476 for (i = 0; i < NAME_ENTRIES; i++) { 04477 const char* nameStr = GetOneName(name, i); 04478 if (nameStr) { 04479 /* bottom up */ 04480 byte firstLen[MAX_LENGTH_SZ]; 04481 byte secondLen[MAX_LENGTH_SZ]; 04482 byte sequence[MAX_SEQ_SZ]; 04483 byte set[MAX_SET_SZ]; 04484 04485 int email = i == (NAME_ENTRIES - 1) ? 1 : 0; 04486 int strLen = (int)XSTRLEN(nameStr); 04487 int thisLen = strLen; 04488 int firstSz, secondSz, seqSz, setSz; 04489 04490 if (strLen == 0) { /* no user data for this item */ 04491 names[i].used = 0; 04492 continue; 04493 } 04494 04495 secondSz = SetLength(strLen, secondLen); 04496 thisLen += secondSz; 04497 if (email) { 04498 thisLen += EMAIL_JOINT_LEN; 04499 thisLen ++; /* id type */ 04500 firstSz = SetLength(EMAIL_JOINT_LEN, firstLen); 04501 } 04502 else { 04503 thisLen++; /* str type */ 04504 thisLen++; /* id type */ 04505 thisLen += JOINT_LEN; 04506 firstSz = SetLength(JOINT_LEN + 1, firstLen); 04507 } 04508 thisLen += firstSz; 04509 thisLen++; /* object id */ 04510 04511 seqSz = SetSequence(thisLen, sequence); 04512 thisLen += seqSz; 04513 setSz = SetSet(thisLen, set); 04514 thisLen += setSz; 04515 04516 if (thisLen > (int)sizeof(names[i].encoded)) 04517 return BUFFER_E; 04518 04519 /* store it */ 04520 idx = 0; 04521 /* set */ 04522 XMEMCPY(names[i].encoded, set, setSz); 04523 idx += setSz; 04524 /* seq */ 04525 XMEMCPY(names[i].encoded + idx, sequence, seqSz); 04526 idx += seqSz; 04527 /* asn object id */ 04528 names[i].encoded[idx++] = ASN_OBJECT_ID; 04529 /* first length */ 04530 XMEMCPY(names[i].encoded + idx, firstLen, firstSz); 04531 idx += firstSz; 04532 if (email) { 04533 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 04534 0x01, 0x09, 0x01, 0x16 }; 04535 /* email joint id */ 04536 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); 04537 idx += (int)sizeof(EMAIL_OID); 04538 } 04539 else { 04540 /* joint id */ 04541 byte bType = GetNameId(i); 04542 names[i].encoded[idx++] = 0x55; 04543 names[i].encoded[idx++] = 0x04; 04544 /* id type */ 04545 names[i].encoded[idx++] = bType; 04546 /* str type */ 04547 if (bType == ASN_COUNTRY_NAME) 04548 names[i].encoded[idx++] = 0x13; /* printable */ 04549 else 04550 names[i].encoded[idx++] = 0x0c; /* utf8 */ 04551 } 04552 /* second length */ 04553 XMEMCPY(names[i].encoded + idx, secondLen, secondSz); 04554 idx += secondSz; 04555 /* str value */ 04556 XMEMCPY(names[i].encoded + idx, nameStr, strLen); 04557 idx += strLen; 04558 04559 totalBytes += idx; 04560 names[i].totalLen = idx; 04561 names[i].used = 1; 04562 } 04563 else 04564 names[i].used = 0; 04565 } 04566 04567 /* header */ 04568 idx = SetSequence(totalBytes, output); 04569 totalBytes += idx; 04570 if (totalBytes > ASN_NAME_MAX) 04571 return BUFFER_E; 04572 04573 for (i = 0; i < NAME_ENTRIES; i++) { 04574 if (names[i].used) { 04575 XMEMCPY(output + idx, names[i].encoded, names[i].totalLen); 04576 idx += names[i].totalLen; 04577 } 04578 } 04579 return totalBytes; 04580 } 04581 04582 /* encode info from cert into DER encoded format */ 04583 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, 04584 RNG* rng, const byte* ntruKey, word16 ntruSz) 04585 { 04586 (void)eccKey; 04587 (void)ntruKey; 04588 (void)ntruSz; 04589 04590 /* init */ 04591 XMEMSET(der, 0, sizeof(DerCert)); 04592 04593 /* version */ 04594 der->versionSz = SetMyVersion(cert->version, der->version, TRUE); 04595 04596 /* serial number */ 04597 RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); 04598 cert->serial[0] = 0x01; /* ensure positive */ 04599 der->serialSz = SetSerial(cert->serial, der->serial); 04600 04601 /* signature algo */ 04602 der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0); 04603 if (der->sigAlgoSz == 0) 04604 return ALGO_ID_E; 04605 04606 /* public key */ 04607 if (cert->keyType == RSA_KEY) { 04608 if (rsaKey == NULL) 04609 return PUBLIC_KEY_E; 04610 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); 04611 if (der->publicKeySz <= 0) 04612 return PUBLIC_KEY_E; 04613 } 04614 04615 #ifdef HAVE_ECC 04616 if (cert->keyType == ECC_KEY) { 04617 if (eccKey == NULL) 04618 return PUBLIC_KEY_E; 04619 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); 04620 if (der->publicKeySz <= 0) 04621 return PUBLIC_KEY_E; 04622 } 04623 #endif /* HAVE_ECC */ 04624 04625 #ifdef HAVE_NTRU 04626 if (cert->keyType == NTRU_KEY) { 04627 word32 rc; 04628 word16 encodedSz; 04629 04630 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, 04631 ntruKey, &encodedSz, NULL); 04632 if (rc != NTRU_OK) 04633 return PUBLIC_KEY_E; 04634 if (encodedSz > MAX_PUBLIC_KEY_SZ) 04635 return PUBLIC_KEY_E; 04636 04637 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, 04638 ntruKey, &encodedSz, der->publicKey); 04639 if (rc != NTRU_OK) 04640 return PUBLIC_KEY_E; 04641 04642 der->publicKeySz = encodedSz; 04643 } 04644 #endif /* HAVE_NTRU */ 04645 04646 der->validitySz = 0; 04647 #ifdef CYASSL_ALT_NAMES 04648 /* date validity copy ? */ 04649 if (cert->beforeDateSz && cert->afterDateSz) { 04650 der->validitySz = CopyValidity(der->validity, cert); 04651 if (der->validitySz == 0) 04652 return DATE_E; 04653 } 04654 #endif 04655 04656 /* date validity */ 04657 if (der->validitySz == 0) { 04658 der->validitySz = SetValidity(der->validity, cert->daysValid); 04659 if (der->validitySz == 0) 04660 return DATE_E; 04661 } 04662 04663 /* subject name */ 04664 der->subjectSz = SetName(der->subject, &cert->subject); 04665 if (der->subjectSz == 0) 04666 return SUBJECT_E; 04667 04668 /* issuer name */ 04669 der->issuerSz = SetName(der->issuer, cert->selfSigned ? 04670 &cert->subject : &cert->issuer); 04671 if (der->issuerSz == 0) 04672 return ISSUER_E; 04673 04674 /* CA */ 04675 if (cert->isCA) { 04676 der->caSz = SetCa(der->ca); 04677 if (der->caSz == 0) 04678 return CA_TRUE_E; 04679 } 04680 else 04681 der->caSz = 0; 04682 04683 /* extensions, just CA now */ 04684 if (cert->isCA) { 04685 der->extensionsSz = SetExtensions(der->extensions, 04686 der->ca, der->caSz, TRUE); 04687 if (der->extensionsSz == 0) 04688 return EXTENSIONS_E; 04689 } 04690 else 04691 der->extensionsSz = 0; 04692 04693 #ifdef CYASSL_ALT_NAMES 04694 if (der->extensionsSz == 0 && cert->altNamesSz) { 04695 der->extensionsSz = SetExtensions(der->extensions, cert->altNames, 04696 cert->altNamesSz, TRUE); 04697 if (der->extensionsSz == 0) 04698 return EXTENSIONS_E; 04699 } 04700 #endif 04701 04702 der->total = der->versionSz + der->serialSz + der->sigAlgoSz + 04703 der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz + 04704 der->extensionsSz; 04705 04706 return 0; 04707 } 04708 04709 04710 /* write DER encoded cert to buffer, size already checked */ 04711 static int WriteCertBody(DerCert* der, byte* buffer) 04712 { 04713 int idx; 04714 04715 /* signed part header */ 04716 idx = SetSequence(der->total, buffer); 04717 /* version */ 04718 XMEMCPY(buffer + idx, der->version, der->versionSz); 04719 idx += der->versionSz; 04720 /* serial */ 04721 XMEMCPY(buffer + idx, der->serial, der->serialSz); 04722 idx += der->serialSz; 04723 /* sig algo */ 04724 XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz); 04725 idx += der->sigAlgoSz; 04726 /* issuer */ 04727 XMEMCPY(buffer + idx, der->issuer, der->issuerSz); 04728 idx += der->issuerSz; 04729 /* validity */ 04730 XMEMCPY(buffer + idx, der->validity, der->validitySz); 04731 idx += der->validitySz; 04732 /* subject */ 04733 XMEMCPY(buffer + idx, der->subject, der->subjectSz); 04734 idx += der->subjectSz; 04735 /* public key */ 04736 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); 04737 idx += der->publicKeySz; 04738 if (der->extensionsSz) { 04739 /* extensions */ 04740 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, 04741 sizeof(der->extensions))); 04742 idx += der->extensionsSz; 04743 } 04744 04745 return idx; 04746 } 04747 04748 04749 /* Make RSA signature from buffer (sz), write to sig (sigSz) */ 04750 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, 04751 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, 04752 int sigAlgoType) 04753 { 04754 byte digest[SHA256_DIGEST_SIZE]; /* max size */ 04755 byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; 04756 int encSigSz, digestSz, typeH, ret = 0; 04757 04758 (void)eccKey; 04759 04760 if (sigAlgoType == CTC_MD5wRSA) { 04761 Md5 md5; 04762 InitMd5(&md5); 04763 Md5Update(&md5, buffer, sz); 04764 Md5Final(&md5, digest); 04765 digestSz = MD5_DIGEST_SIZE; 04766 typeH = MD5h; 04767 } 04768 else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) { 04769 Sha sha; 04770 ret = InitSha(&sha); 04771 if (ret != 0) 04772 return ret; 04773 ShaUpdate(&sha, buffer, sz); 04774 ShaFinal(&sha, digest); 04775 digestSz = SHA_DIGEST_SIZE; 04776 typeH = SHAh; 04777 } 04778 else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) { 04779 Sha256 sha256; 04780 ret = InitSha256(&sha256); 04781 if (ret != 0) 04782 return ret; 04783 Sha256Update(&sha256, buffer, sz); 04784 Sha256Final(&sha256, digest); 04785 digestSz = SHA256_DIGEST_SIZE; 04786 typeH = SHA256h; 04787 } 04788 else 04789 return ALGO_ID_E; 04790 04791 if (rsaKey) { 04792 /* signature */ 04793 encSigSz = EncodeSignature(encSig, digest, digestSz, typeH); 04794 return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); 04795 } 04796 #ifdef HAVE_ECC 04797 else if (eccKey) { 04798 word32 outSz = sigSz; 04799 ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey); 04800 04801 if (ret != 0) 04802 return ret; 04803 return outSz; 04804 } 04805 #endif /* HAVE_ECC */ 04806 04807 return ALGO_ID_E; 04808 } 04809 04810 04811 /* add signature to end of buffer, size of buffer assumed checked, return 04812 new length */ 04813 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz, 04814 int sigAlgoType) 04815 { 04816 byte seq[MAX_SEQ_SZ]; 04817 int idx = bodySz, seqSz; 04818 04819 /* algo */ 04820 idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0); 04821 /* bit string */ 04822 buffer[idx++] = ASN_BIT_STRING; 04823 /* length */ 04824 idx += SetLength(sigSz + 1, buffer + idx); 04825 buffer[idx++] = 0; /* trailing 0 */ 04826 /* signature */ 04827 XMEMCPY(buffer + idx, sig, sigSz); 04828 idx += sigSz; 04829 04830 /* make room for overall header */ 04831 seqSz = SetSequence(idx, seq); 04832 XMEMMOVE(buffer + seqSz, buffer, idx); 04833 XMEMCPY(buffer, seq, seqSz); 04834 04835 return idx + seqSz; 04836 } 04837 04838 04839 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */ 04840 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, 04841 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, 04842 const byte* ntruKey, word16 ntruSz) 04843 { 04844 DerCert der; 04845 int ret; 04846 04847 if (eccKey) 04848 cert->keyType = ECC_KEY; 04849 else 04850 cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY; 04851 ret = EncodeCert(cert, &der, rsaKey, eccKey, rng, ntruKey, ntruSz); 04852 if (ret != 0) 04853 return ret; 04854 04855 if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) 04856 return BUFFER_E; 04857 04858 return cert->bodySz = WriteCertBody(&der, derBuffer); 04859 } 04860 04861 04862 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ 04863 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, 04864 ecc_key* eccKey, RNG* rng) 04865 { 04866 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0); 04867 } 04868 04869 04870 #ifdef HAVE_NTRU 04871 04872 int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, 04873 const byte* ntruKey, word16 keySz, RNG* rng) 04874 { 04875 return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz); 04876 } 04877 04878 #endif /* HAVE_NTRU */ 04879 04880 04881 #ifdef CYASSL_CERT_REQ 04882 04883 static int SetReqAttrib(byte* output, char* pw, int extSz) 04884 { 04885 static const byte cpOid[] = 04886 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 04887 0x09, 0x07 }; 04888 static const byte erOid[] = 04889 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 04890 0x09, 0x0e }; 04891 04892 int sz = 0; /* overall size */ 04893 int cpSz = 0; /* Challenge Password section size */ 04894 int cpSeqSz = 0; 04895 int cpSetSz = 0; 04896 int cpStrSz = 0; 04897 int pwSz = 0; 04898 int erSz = 0; /* Extension Request section size */ 04899 int erSeqSz = 0; 04900 int erSetSz = 0; 04901 byte cpSeq[MAX_SEQ_SZ]; 04902 byte cpSet[MAX_SET_SZ]; 04903 byte cpStr[MAX_PRSTR_SZ]; 04904 byte erSeq[MAX_SEQ_SZ]; 04905 byte erSet[MAX_SET_SZ]; 04906 04907 output[0] = 0xa0; 04908 sz++; 04909 04910 if (pw && pw[0]) { 04911 pwSz = (int)XSTRLEN(pw); 04912 cpStrSz = SetUTF8String(pwSz, cpStr); 04913 cpSetSz = SetSet(cpStrSz + pwSz, cpSet); 04914 cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq); 04915 cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz; 04916 } 04917 04918 if (extSz) { 04919 erSetSz = SetSet(extSz, erSet); 04920 erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq); 04921 erSz = extSz + erSetSz + erSeqSz + sizeof(erOid); 04922 } 04923 04924 /* Put the pieces together. */ 04925 sz += SetLength(cpSz + erSz, &output[sz]); 04926 04927 if (cpSz) { 04928 XMEMCPY(&output[sz], cpSeq, cpSeqSz); 04929 sz += cpSeqSz; 04930 XMEMCPY(&output[sz], cpOid, sizeof(cpOid)); 04931 sz += sizeof(cpOid); 04932 XMEMCPY(&output[sz], cpSet, cpSetSz); 04933 sz += cpSetSz; 04934 XMEMCPY(&output[sz], cpStr, cpStrSz); 04935 sz += cpStrSz; 04936 XMEMCPY(&output[sz], pw, pwSz); 04937 sz += pwSz; 04938 } 04939 04940 if (erSz) { 04941 XMEMCPY(&output[sz], erSeq, erSeqSz); 04942 sz += erSeqSz; 04943 XMEMCPY(&output[sz], erOid, sizeof(erOid)); 04944 sz += sizeof(erOid); 04945 XMEMCPY(&output[sz], erSet, erSetSz); 04946 sz += erSetSz; 04947 /* The actual extension data will be tacked onto the output later. */ 04948 } 04949 04950 return sz; 04951 } 04952 04953 04954 /* encode info from cert into DER encoded format */ 04955 static int EncodeCertReq(Cert* cert, DerCert* der, 04956 RsaKey* rsaKey, ecc_key* eccKey) 04957 { 04958 (void)eccKey; 04959 04960 /* init */ 04961 XMEMSET(der, 0, sizeof(DerCert)); 04962 04963 /* version */ 04964 der->versionSz = SetMyVersion(cert->version, der->version, FALSE); 04965 04966 /* subject name */ 04967 der->subjectSz = SetName(der->subject, &cert->subject); 04968 if (der->subjectSz == 0) 04969 return SUBJECT_E; 04970 04971 /* public key */ 04972 if (cert->keyType == RSA_KEY) { 04973 if (rsaKey == NULL) 04974 return PUBLIC_KEY_E; 04975 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); 04976 if (der->publicKeySz <= 0) 04977 return PUBLIC_KEY_E; 04978 } 04979 04980 #ifdef HAVE_ECC 04981 if (cert->keyType == ECC_KEY) { 04982 if (eccKey == NULL) 04983 return PUBLIC_KEY_E; 04984 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); 04985 if (der->publicKeySz <= 0) 04986 return PUBLIC_KEY_E; 04987 } 04988 #endif /* HAVE_ECC */ 04989 04990 /* CA */ 04991 if (cert->isCA) { 04992 der->caSz = SetCa(der->ca); 04993 if (der->caSz == 0) 04994 return CA_TRUE_E; 04995 } 04996 else 04997 der->caSz = 0; 04998 04999 /* extensions, just CA now */ 05000 if (cert->isCA) { 05001 der->extensionsSz = SetExtensions(der->extensions, 05002 der->ca, der->caSz, FALSE); 05003 if (der->extensionsSz == 0) 05004 return EXTENSIONS_E; 05005 } 05006 else 05007 der->extensionsSz = 0; 05008 05009 der->attribSz = SetReqAttrib(der->attrib, 05010 cert->challengePw, der->extensionsSz); 05011 if (der->attribSz == 0) 05012 return REQ_ATTRIBUTE_E; 05013 05014 der->total = der->versionSz + der->subjectSz + der->publicKeySz + 05015 der->extensionsSz + der->attribSz; 05016 05017 return 0; 05018 } 05019 05020 05021 /* write DER encoded cert req to buffer, size already checked */ 05022 static int WriteCertReqBody(DerCert* der, byte* buffer) 05023 { 05024 int idx; 05025 05026 /* signed part header */ 05027 idx = SetSequence(der->total, buffer); 05028 /* version */ 05029 XMEMCPY(buffer + idx, der->version, der->versionSz); 05030 idx += der->versionSz; 05031 /* subject */ 05032 XMEMCPY(buffer + idx, der->subject, der->subjectSz); 05033 idx += der->subjectSz; 05034 /* public key */ 05035 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); 05036 idx += der->publicKeySz; 05037 /* attributes */ 05038 XMEMCPY(buffer + idx, der->attrib, der->attribSz); 05039 idx += der->attribSz; 05040 /* extensions */ 05041 if (der->extensionsSz) { 05042 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, 05043 sizeof(der->extensions))); 05044 idx += der->extensionsSz; 05045 } 05046 05047 return idx; 05048 } 05049 05050 05051 int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, 05052 RsaKey* rsaKey, ecc_key* eccKey) 05053 { 05054 DerCert der; 05055 int ret; 05056 05057 cert->keyType = (eccKey != NULL) ? ECC_KEY : RSA_KEY; 05058 ret = EncodeCertReq(cert, &der, rsaKey, eccKey); 05059 if (ret != 0) 05060 return ret; 05061 05062 if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) 05063 return BUFFER_E; 05064 05065 return cert->bodySz = WriteCertReqBody(&der, derBuffer); 05066 } 05067 05068 #endif /* CYASSL_CERT_REQ */ 05069 05070 05071 int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, 05072 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng) 05073 { 05074 byte sig[MAX_ENCODED_SIG_SZ]; 05075 int sigSz; 05076 05077 if (requestSz < 0) 05078 return requestSz; 05079 05080 sigSz = MakeSignature(buffer, requestSz, sig, sizeof(sig), rsaKey, eccKey, 05081 rng, sType); 05082 if (sigSz < 0) 05083 return sigSz; 05084 05085 if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) 05086 return BUFFER_E; 05087 05088 return AddSignature(buffer, requestSz, sig, sigSz, sType); 05089 } 05090 05091 05092 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) 05093 { 05094 int ret = MakeCert(cert, buffer, buffSz, key, NULL, rng); 05095 05096 if (ret < 0) 05097 return ret; 05098 05099 return SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng); 05100 } 05101 05102 05103 #ifdef CYASSL_ALT_NAMES 05104 05105 /* Set Alt Names from der cert, return 0 on success */ 05106 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) 05107 { 05108 DecodedCert decoded; 05109 int ret; 05110 05111 if (derSz < 0) 05112 return derSz; 05113 05114 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05115 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05116 05117 if (ret < 0) { 05118 FreeDecodedCert(&decoded); 05119 return ret; 05120 } 05121 05122 if (decoded.extensions) { 05123 byte b; 05124 int length; 05125 word32 maxExtensionsIdx; 05126 05127 decoded.srcIdx = decoded.extensionsIdx; 05128 b = decoded.source[decoded.srcIdx++]; 05129 if (b != ASN_EXTENSIONS) { 05130 FreeDecodedCert(&decoded); 05131 return ASN_PARSE_E; 05132 } 05133 05134 if (GetLength(decoded.source, &decoded.srcIdx, &length, 05135 decoded.maxIdx) < 0) { 05136 FreeDecodedCert(&decoded); 05137 return ASN_PARSE_E; 05138 } 05139 05140 if (GetSequence(decoded.source, &decoded.srcIdx, &length, 05141 decoded.maxIdx) < 0) { 05142 FreeDecodedCert(&decoded); 05143 return ASN_PARSE_E; 05144 } 05145 05146 maxExtensionsIdx = decoded.srcIdx + length; 05147 05148 while (decoded.srcIdx < maxExtensionsIdx) { 05149 word32 oid; 05150 word32 startIdx = decoded.srcIdx; 05151 word32 tmpIdx; 05152 05153 if (GetSequence(decoded.source, &decoded.srcIdx, &length, 05154 decoded.maxIdx) < 0) { 05155 FreeDecodedCert(&decoded); 05156 return ASN_PARSE_E; 05157 } 05158 05159 tmpIdx = decoded.srcIdx; 05160 decoded.srcIdx = startIdx; 05161 05162 if (GetAlgoId(decoded.source, &decoded.srcIdx, &oid, 05163 decoded.maxIdx) < 0) { 05164 FreeDecodedCert(&decoded); 05165 return ASN_PARSE_E; 05166 } 05167 05168 if (oid == ALT_NAMES_OID) { 05169 cert->altNamesSz = length + (tmpIdx - startIdx); 05170 05171 if (cert->altNamesSz < (int)sizeof(cert->altNames)) 05172 XMEMCPY(cert->altNames, &decoded.source[startIdx], 05173 cert->altNamesSz); 05174 else { 05175 cert->altNamesSz = 0; 05176 CYASSL_MSG("AltNames extensions too big"); 05177 FreeDecodedCert(&decoded); 05178 return ALT_NAME_E; 05179 } 05180 } 05181 decoded.srcIdx = tmpIdx + length; 05182 } 05183 } 05184 FreeDecodedCert(&decoded); 05185 05186 return 0; 05187 } 05188 05189 05190 /* Set Dates from der cert, return 0 on success */ 05191 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) 05192 { 05193 DecodedCert decoded; 05194 int ret; 05195 05196 CYASSL_ENTER("SetDatesFromCert"); 05197 if (derSz < 0) 05198 return derSz; 05199 05200 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05201 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05202 05203 if (ret < 0) { 05204 CYASSL_MSG("ParseCertRelative error"); 05205 FreeDecodedCert(&decoded); 05206 return ret; 05207 } 05208 05209 if (decoded.beforeDate == NULL || decoded.afterDate == NULL) { 05210 CYASSL_MSG("Couldn't extract dates"); 05211 FreeDecodedCert(&decoded); 05212 return -1; 05213 } 05214 05215 if (decoded.beforeDateLen > MAX_DATE_SIZE || decoded.afterDateLen > 05216 MAX_DATE_SIZE) { 05217 CYASSL_MSG("Bad date size"); 05218 FreeDecodedCert(&decoded); 05219 return -1; 05220 } 05221 05222 XMEMCPY(cert->beforeDate, decoded.beforeDate, decoded.beforeDateLen); 05223 XMEMCPY(cert->afterDate, decoded.afterDate, decoded.afterDateLen); 05224 05225 cert->beforeDateSz = decoded.beforeDateLen; 05226 cert->afterDateSz = decoded.afterDateLen; 05227 05228 return 0; 05229 } 05230 05231 05232 #endif /* CYASSL_ALT_NAMES && !NO_RSA */ 05233 05234 05235 /* Set cn name from der buffer, return 0 on success */ 05236 static int SetNameFromCert(CertName* cn, const byte* der, int derSz) 05237 { 05238 DecodedCert decoded; 05239 int ret; 05240 int sz; 05241 05242 if (derSz < 0) 05243 return derSz; 05244 05245 InitDecodedCert(&decoded, (byte*)der, derSz, 0); 05246 ret = ParseCertRelative(&decoded, CA_TYPE, NO_VERIFY, 0); 05247 05248 if (ret < 0) 05249 return ret; 05250 05251 if (decoded.subjectCN) { 05252 sz = (decoded.subjectCNLen < CTC_NAME_SIZE) ? decoded.subjectCNLen : 05253 CTC_NAME_SIZE - 1; 05254 strncpy(cn->commonName, decoded.subjectCN, CTC_NAME_SIZE); 05255 cn->commonName[sz] = 0; 05256 } 05257 if (decoded.subjectC) { 05258 sz = (decoded.subjectCLen < CTC_NAME_SIZE) ? decoded.subjectCLen : 05259 CTC_NAME_SIZE - 1; 05260 strncpy(cn->country, decoded.subjectC, CTC_NAME_SIZE); 05261 cn->country[sz] = 0; 05262 } 05263 if (decoded.subjectST) { 05264 sz = (decoded.subjectSTLen < CTC_NAME_SIZE) ? decoded.subjectSTLen : 05265 CTC_NAME_SIZE - 1; 05266 strncpy(cn->state, decoded.subjectST, CTC_NAME_SIZE); 05267 cn->state[sz] = 0; 05268 } 05269 if (decoded.subjectL) { 05270 sz = (decoded.subjectLLen < CTC_NAME_SIZE) ? decoded.subjectLLen : 05271 CTC_NAME_SIZE - 1; 05272 strncpy(cn->locality, decoded.subjectL, CTC_NAME_SIZE); 05273 cn->locality[sz] = 0; 05274 } 05275 if (decoded.subjectO) { 05276 sz = (decoded.subjectOLen < CTC_NAME_SIZE) ? decoded.subjectOLen : 05277 CTC_NAME_SIZE - 1; 05278 strncpy(cn->org, decoded.subjectO, CTC_NAME_SIZE); 05279 cn->org[sz] = 0; 05280 } 05281 if (decoded.subjectOU) { 05282 sz = (decoded.subjectOULen < CTC_NAME_SIZE) ? decoded.subjectOULen : 05283 CTC_NAME_SIZE - 1; 05284 strncpy(cn->unit, decoded.subjectOU, CTC_NAME_SIZE); 05285 cn->unit[sz] = 0; 05286 } 05287 if (decoded.subjectSN) { 05288 sz = (decoded.subjectSNLen < CTC_NAME_SIZE) ? decoded.subjectSNLen : 05289 CTC_NAME_SIZE - 1; 05290 strncpy(cn->sur, decoded.subjectSN, CTC_NAME_SIZE); 05291 cn->sur[sz] = 0; 05292 } 05293 if (decoded.subjectEmail) { 05294 sz = (decoded.subjectEmailLen < CTC_NAME_SIZE) ? 05295 decoded.subjectEmailLen : CTC_NAME_SIZE - 1; 05296 strncpy(cn->email, decoded.subjectEmail, CTC_NAME_SIZE); 05297 cn->email[sz] = 0; 05298 } 05299 05300 FreeDecodedCert(&decoded); 05301 05302 return 0; 05303 } 05304 05305 05306 #ifndef NO_FILESYSTEM 05307 05308 /* forward from CyaSSL */ 05309 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz); 05310 05311 /* Set cert issuer from issuerFile in PEM */ 05312 int SetIssuer(Cert* cert, const char* issuerFile) 05313 { 05314 int ret; 05315 int derSz; 05316 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05317 05318 if (der == NULL) { 05319 CYASSL_MSG("SetIssuer OOF Problem"); 05320 return MEMORY_E; 05321 } 05322 derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF); 05323 cert->selfSigned = 0; 05324 ret = SetNameFromCert(&cert->issuer, der, derSz); 05325 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05326 05327 return ret; 05328 } 05329 05330 05331 /* Set cert subject from subjectFile in PEM */ 05332 int SetSubject(Cert* cert, const char* subjectFile) 05333 { 05334 int ret; 05335 int derSz; 05336 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05337 05338 if (der == NULL) { 05339 CYASSL_MSG("SetSubject OOF Problem"); 05340 return MEMORY_E; 05341 } 05342 derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF); 05343 ret = SetNameFromCert(&cert->subject, der, derSz); 05344 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05345 05346 return ret; 05347 } 05348 05349 05350 #ifdef CYASSL_ALT_NAMES 05351 05352 /* Set atl names from file in PEM */ 05353 int SetAltNames(Cert* cert, const char* file) 05354 { 05355 int ret; 05356 int derSz; 05357 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); 05358 05359 if (der == NULL) { 05360 CYASSL_MSG("SetAltNames OOF Problem"); 05361 return MEMORY_E; 05362 } 05363 derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF); 05364 ret = SetAltNamesFromCert(cert, der, derSz); 05365 XFREE(der, NULL, DYNAMIC_TYPE_CERT); 05366 05367 return ret; 05368 } 05369 05370 #endif /* CYASSL_ALT_NAMES */ 05371 05372 #endif /* NO_FILESYSTEM */ 05373 05374 /* Set cert issuer from DER buffer */ 05375 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz) 05376 { 05377 cert->selfSigned = 0; 05378 return SetNameFromCert(&cert->issuer, der, derSz); 05379 } 05380 05381 05382 /* Set cert subject from DER buffer */ 05383 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz) 05384 { 05385 return SetNameFromCert(&cert->subject, der, derSz); 05386 } 05387 05388 05389 #ifdef CYASSL_ALT_NAMES 05390 05391 /* Set cert alt names from DER buffer */ 05392 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) 05393 { 05394 return SetAltNamesFromCert(cert, der, derSz); 05395 } 05396 05397 /* Set cert dates from DER buffer */ 05398 int SetDatesBuffer(Cert* cert, const byte* der, int derSz) 05399 { 05400 return SetDatesFromCert(cert, der, derSz); 05401 } 05402 05403 #endif /* CYASSL_ALT_NAMES */ 05404 05405 #endif /* CYASSL_CERT_GEN */ 05406 05407 05408 #ifdef HAVE_ECC 05409 05410 /* Der Encode r & s ints into out, outLen is (in/out) size */ 05411 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) 05412 { 05413 word32 idx = 0; 05414 word32 rSz; /* encoding size */ 05415 word32 sSz; 05416 word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */ 05417 05418 /* If the leading bit on the INTEGER is a 1, add a leading zero */ 05419 int rLeadingZero = mp_leading_bit(r); 05420 int sLeadingZero = mp_leading_bit(s); 05421 int rLen = mp_unsigned_bin_size(r); /* big int size */ 05422 int sLen = mp_unsigned_bin_size(s); 05423 int err; 05424 05425 if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero + 05426 headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */ 05427 return BAD_FUNC_ARG; 05428 05429 idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out); 05430 05431 /* store r */ 05432 out[idx++] = ASN_INTEGER; 05433 rSz = SetLength(rLen + rLeadingZero, &out[idx]); 05434 idx += rSz; 05435 if (rLeadingZero) 05436 out[idx++] = 0; 05437 err = mp_to_unsigned_bin(r, &out[idx]); 05438 if (err != MP_OKAY) return err; 05439 idx += rLen; 05440 05441 /* store s */ 05442 out[idx++] = ASN_INTEGER; 05443 sSz = SetLength(sLen + sLeadingZero, &out[idx]); 05444 idx += sSz; 05445 if (sLeadingZero) 05446 out[idx++] = 0; 05447 err = mp_to_unsigned_bin(s, &out[idx]); 05448 if (err != MP_OKAY) return err; 05449 idx += sLen; 05450 05451 *outLen = idx; 05452 05453 return 0; 05454 } 05455 05456 05457 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */ 05458 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) 05459 { 05460 word32 idx = 0; 05461 int len = 0; 05462 05463 if (GetSequence(sig, &idx, &len, sigLen) < 0) 05464 return ASN_ECC_KEY_E; 05465 05466 if ((word32)len > (sigLen - idx)) 05467 return ASN_ECC_KEY_E; 05468 05469 if (GetInt(r, sig, &idx, sigLen) < 0) 05470 return ASN_ECC_KEY_E; 05471 05472 if (GetInt(s, sig, &idx, sigLen) < 0) 05473 return ASN_ECC_KEY_E; 05474 05475 return 0; 05476 } 05477 05478 05479 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, 05480 word32 inSz) 05481 { 05482 word32 oid = 0; 05483 int version, length; 05484 int privSz, pubSz; 05485 byte b; 05486 byte priv[ECC_MAXSIZE]; 05487 byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ 05488 05489 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) 05490 return BAD_FUNC_ARG; 05491 05492 if (GetSequence(input, inOutIdx, &length, inSz) < 0) 05493 return ASN_PARSE_E; 05494 05495 if (GetMyVersion(input, inOutIdx, &version) < 0) 05496 return ASN_PARSE_E; 05497 05498 b = input[*inOutIdx]; 05499 *inOutIdx += 1; 05500 05501 /* priv type */ 05502 if (b != 4 && b != 6 && b != 7) 05503 return ASN_PARSE_E; 05504 05505 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05506 return ASN_PARSE_E; 05507 05508 /* priv key */ 05509 privSz = length; 05510 XMEMCPY(priv, &input[*inOutIdx], privSz); 05511 *inOutIdx += length; 05512 05513 /* prefix 0, may have */ 05514 b = input[*inOutIdx]; 05515 if (b == ECC_PREFIX_0) { 05516 *inOutIdx += 1; 05517 05518 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05519 return ASN_PARSE_E; 05520 05521 /* object id */ 05522 b = input[*inOutIdx]; 05523 *inOutIdx += 1; 05524 05525 if (b != ASN_OBJECT_ID) 05526 return ASN_OBJECT_ID_E; 05527 05528 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05529 return ASN_PARSE_E; 05530 05531 while(length--) { 05532 oid += input[*inOutIdx]; 05533 *inOutIdx += 1; 05534 } 05535 if (CheckCurve(oid) < 0) 05536 return ECC_CURVE_OID_E; 05537 } 05538 05539 /* prefix 1 */ 05540 b = input[*inOutIdx]; 05541 *inOutIdx += 1; 05542 if (b != ECC_PREFIX_1) 05543 return ASN_ECC_KEY_E; 05544 05545 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05546 return ASN_PARSE_E; 05547 05548 /* key header */ 05549 b = input[*inOutIdx]; 05550 *inOutIdx += 1; 05551 if (b != ASN_BIT_STRING) 05552 return ASN_BITSTR_E; 05553 05554 if (GetLength(input, inOutIdx, &length, inSz) < 0) 05555 return ASN_PARSE_E; 05556 b = input[*inOutIdx]; 05557 *inOutIdx += 1; 05558 if (b != 0x00) 05559 return ASN_EXPECT_0_E; 05560 05561 pubSz = length - 1; /* null prefix */ 05562 XMEMCPY(pub, &input[*inOutIdx], pubSz); 05563 05564 *inOutIdx += length; 05565 05566 return ecc_import_private_key(priv, privSz, pub, pubSz, key); 05567 } 05568 05569 #endif /* HAVE_ECC */ 05570 05571 05572 #if defined(HAVE_OCSP) || defined(HAVE_CRL) 05573 05574 /* Get raw Date only, no processing, 0 on success */ 05575 static int GetBasicDate(const byte* source, word32* idx, byte* date, 05576 byte* format, int maxIdx) 05577 { 05578 int length; 05579 05580 CYASSL_ENTER("GetBasicDate"); 05581 05582 *format = source[*idx]; 05583 *idx += 1; 05584 if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME) 05585 return ASN_TIME_E; 05586 05587 if (GetLength(source, idx, &length, maxIdx) < 0) 05588 return ASN_PARSE_E; 05589 05590 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) 05591 return ASN_DATE_SZ_E; 05592 05593 XMEMCPY(date, &source[*idx], length); 05594 *idx += length; 05595 05596 return 0; 05597 } 05598 05599 #endif 05600 05601 05602 #ifdef HAVE_OCSP 05603 05604 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value) 05605 { 05606 word32 idx = *inOutIdx; 05607 word32 len; 05608 05609 CYASSL_ENTER("GetEnumerated"); 05610 05611 *value = 0; 05612 05613 if (input[idx++] != ASN_ENUMERATED) 05614 return ASN_PARSE_E; 05615 05616 len = input[idx++]; 05617 if (len > 4) 05618 return ASN_PARSE_E; 05619 05620 while (len--) { 05621 *value = *value << 8 | input[idx++]; 05622 } 05623 05624 *inOutIdx = idx; 05625 05626 return *value; 05627 } 05628 05629 05630 static int DecodeSingleResponse(byte* source, 05631 word32* ioIndex, OcspResponse* resp, word32 size) 05632 { 05633 word32 idx = *ioIndex, prevIndex, oid; 05634 int length, wrapperSz; 05635 CertStatus* cs = resp->status; 05636 05637 CYASSL_ENTER("DecodeSingleResponse"); 05638 05639 /* Outer wrapper of the SEQUENCE OF Single Responses. */ 05640 if (GetSequence(source, &idx, &wrapperSz, size) < 0) 05641 return ASN_PARSE_E; 05642 05643 prevIndex = idx; 05644 05645 /* When making a request, we only request one status on one certificate 05646 * at a time. There should only be one SingleResponse */ 05647 05648 /* Wrapper around the Single Response */ 05649 if (GetSequence(source, &idx, &length, size) < 0) 05650 return ASN_PARSE_E; 05651 05652 /* Wrapper around the CertID */ 05653 if (GetSequence(source, &idx, &length, size) < 0) 05654 return ASN_PARSE_E; 05655 /* Skip the hash algorithm */ 05656 if (GetAlgoId(source, &idx, &oid, size) < 0) 05657 return ASN_PARSE_E; 05658 /* Save reference to the hash of CN */ 05659 if (source[idx++] != ASN_OCTET_STRING) 05660 return ASN_PARSE_E; 05661 if (GetLength(source, &idx, &length, size) < 0) 05662 return ASN_PARSE_E; 05663 resp->issuerHash = source + idx; 05664 idx += length; 05665 /* Save reference to the hash of the issuer public key */ 05666 if (source[idx++] != ASN_OCTET_STRING) 05667 return ASN_PARSE_E; 05668 if (GetLength(source, &idx, &length, size) < 0) 05669 return ASN_PARSE_E; 05670 resp->issuerKeyHash = source + idx; 05671 idx += length; 05672 05673 /* Read the serial number, it is handled as a string, not as a 05674 * proper number. Just XMEMCPY the data over, rather than load it 05675 * as an mp_int. */ 05676 if (source[idx++] != ASN_INTEGER) 05677 return ASN_PARSE_E; 05678 if (GetLength(source, &idx, &length, size) < 0) 05679 return ASN_PARSE_E; 05680 if (length <= EXTERNAL_SERIAL_SIZE) 05681 { 05682 if (source[idx] == 0) 05683 { 05684 idx++; 05685 length--; 05686 } 05687 XMEMCPY(cs->serial, source + idx, length); 05688 cs->serialSz = length; 05689 } 05690 else 05691 { 05692 return ASN_GETINT_E; 05693 } 05694 idx += length; 05695 05696 /* CertStatus */ 05697 switch (source[idx++]) 05698 { 05699 case (ASN_CONTEXT_SPECIFIC | CERT_GOOD): 05700 cs->status = CERT_GOOD; 05701 idx++; 05702 break; 05703 case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED): 05704 cs->status = CERT_REVOKED; 05705 if (GetLength(source, &idx, &length, size) < 0) 05706 return ASN_PARSE_E; 05707 idx += length; 05708 break; 05709 case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN): 05710 cs->status = CERT_UNKNOWN; 05711 idx++; 05712 break; 05713 default: 05714 return ASN_PARSE_E; 05715 } 05716 05717 if (GetBasicDate(source, &idx, cs->thisDate, 05718 &cs->thisDateFormat, size) < 0) 05719 return ASN_PARSE_E; 05720 if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE)) 05721 return ASN_BEFORE_DATE_E; 05722 05723 /* The following items are optional. Only check for them if there is more 05724 * unprocessed data in the singleResponse wrapper. */ 05725 05726 if (((int)(idx - prevIndex) < wrapperSz) && 05727 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))) 05728 { 05729 idx++; 05730 if (GetLength(source, &idx, &length, size) < 0) 05731 return ASN_PARSE_E; 05732 if (GetBasicDate(source, &idx, cs->nextDate, 05733 &cs->nextDateFormat, size) < 0) 05734 return ASN_PARSE_E; 05735 } 05736 if (((int)(idx - prevIndex) < wrapperSz) && 05737 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))) 05738 { 05739 idx++; 05740 if (GetLength(source, &idx, &length, size) < 0) 05741 return ASN_PARSE_E; 05742 idx += length; 05743 } 05744 05745 *ioIndex = idx; 05746 05747 return 0; 05748 } 05749 05750 static int DecodeOcspRespExtensions(byte* source, 05751 word32* ioIndex, OcspResponse* resp, word32 sz) 05752 { 05753 word32 idx = *ioIndex; 05754 int length; 05755 int ext_bound; /* boundary index for the sequence of extensions */ 05756 word32 oid; 05757 05758 CYASSL_ENTER("DecodeOcspRespExtensions"); 05759 05760 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) 05761 return ASN_PARSE_E; 05762 05763 if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E; 05764 05765 if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E; 05766 05767 ext_bound = idx + length; 05768 05769 while (idx < (word32)ext_bound) { 05770 if (GetSequence(source, &idx, &length, sz) < 0) { 05771 CYASSL_MSG("\tfail: should be a SEQUENCE"); 05772 return ASN_PARSE_E; 05773 } 05774 05775 oid = 0; 05776 if (GetObjectId(source, &idx, &oid, sz) < 0) { 05777 CYASSL_MSG("\tfail: OBJECT ID"); 05778 return ASN_PARSE_E; 05779 } 05780 05781 /* check for critical flag */ 05782 if (source[idx] == ASN_BOOLEAN) { 05783 CYASSL_MSG("\tfound optional critical flag, moving past"); 05784 idx += (ASN_BOOL_SIZE + 1); 05785 } 05786 05787 /* process the extension based on the OID */ 05788 if (source[idx++] != ASN_OCTET_STRING) { 05789 CYASSL_MSG("\tfail: should be an OCTET STRING"); 05790 return ASN_PARSE_E; 05791 } 05792 05793 if (GetLength(source, &idx, &length, sz) < 0) { 05794 CYASSL_MSG("\tfail: extension data length"); 05795 return ASN_PARSE_E; 05796 } 05797 05798 if (oid == OCSP_NONCE_OID) { 05799 resp->nonce = source + idx; 05800 resp->nonceSz = length; 05801 } 05802 05803 idx += length; 05804 } 05805 05806 *ioIndex = idx; 05807 return 0; 05808 } 05809 05810 05811 static int DecodeResponseData(byte* source, 05812 word32* ioIndex, OcspResponse* resp, word32 size) 05813 { 05814 word32 idx = *ioIndex, prev_idx; 05815 int length; 05816 int version; 05817 word32 responderId = 0; 05818 05819 CYASSL_ENTER("DecodeResponseData"); 05820 05821 resp->response = source + idx; 05822 prev_idx = idx; 05823 if (GetSequence(source, &idx, &length, size) < 0) 05824 return ASN_PARSE_E; 05825 resp->responseSz = length + idx - prev_idx; 05826 05827 /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this 05828 * item isn't an EXPLICIT[0], then set version to zero and move 05829 * onto the next item. 05830 */ 05831 if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) 05832 { 05833 idx += 2; /* Eat the value and length */ 05834 if (GetMyVersion(source, &idx, &version) < 0) 05835 return ASN_PARSE_E; 05836 } else 05837 version = 0; 05838 05839 responderId = source[idx++]; 05840 if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) || 05841 (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))) 05842 { 05843 if (GetLength(source, &idx, &length, size) < 0) 05844 return ASN_PARSE_E; 05845 idx += length; 05846 } 05847 else 05848 return ASN_PARSE_E; 05849 05850 /* save pointer to the producedAt time */ 05851 if (GetBasicDate(source, &idx, resp->producedDate, 05852 &resp->producedDateFormat, size) < 0) 05853 return ASN_PARSE_E; 05854 05855 if (DecodeSingleResponse(source, &idx, resp, size) < 0) 05856 return ASN_PARSE_E; 05857 05858 if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0) 05859 return ASN_PARSE_E; 05860 05861 *ioIndex = idx; 05862 return 0; 05863 } 05864 05865 05866 static int DecodeCerts(byte* source, 05867 word32* ioIndex, OcspResponse* resp, word32 size) 05868 { 05869 word32 idx = *ioIndex; 05870 05871 CYASSL_ENTER("DecodeCerts"); 05872 05873 if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) 05874 { 05875 int length; 05876 05877 if (GetLength(source, &idx, &length, size) < 0) 05878 return ASN_PARSE_E; 05879 05880 if (GetSequence(source, &idx, &length, size) < 0) 05881 return ASN_PARSE_E; 05882 05883 resp->cert = source + idx; 05884 resp->certSz = length; 05885 05886 idx += length; 05887 } 05888 *ioIndex = idx; 05889 return 0; 05890 } 05891 05892 static int DecodeBasicOcspResponse(byte* source, 05893 word32* ioIndex, OcspResponse* resp, word32 size) 05894 { 05895 int length; 05896 word32 idx = *ioIndex; 05897 word32 end_index; 05898 05899 CYASSL_ENTER("DecodeBasicOcspResponse"); 05900 05901 if (GetSequence(source, &idx, &length, size) < 0) 05902 return ASN_PARSE_E; 05903 05904 if (idx + length > size) 05905 return ASN_INPUT_E; 05906 end_index = idx + length; 05907 05908 if (DecodeResponseData(source, &idx, resp, size) < 0) 05909 return ASN_PARSE_E; 05910 05911 /* Get the signature algorithm */ 05912 if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0) 05913 return ASN_PARSE_E; 05914 05915 /* Obtain pointer to the start of the signature, and save the size */ 05916 if (source[idx++] == ASN_BIT_STRING) 05917 { 05918 int sigLength = 0; 05919 if (GetLength(source, &idx, &sigLength, size) < 0) 05920 return ASN_PARSE_E; 05921 resp->sigSz = sigLength; 05922 resp->sig = source + idx; 05923 idx += sigLength; 05924 } 05925 05926 /* 05927 * Check the length of the BasicOcspResponse against the current index to 05928 * see if there are certificates, they are optional. 05929 */ 05930 if (idx < end_index) 05931 { 05932 DecodedCert cert; 05933 int ret; 05934 05935 if (DecodeCerts(source, &idx, resp, size) < 0) 05936 return ASN_PARSE_E; 05937 05938 InitDecodedCert(&cert, resp->cert, resp->certSz, 0); 05939 ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0); 05940 if (ret < 0) 05941 return ret; 05942 05943 ret = ConfirmSignature(resp->response, resp->responseSz, 05944 cert.publicKey, cert.pubKeySize, cert.keyOID, 05945 resp->sig, resp->sigSz, resp->sigOID, NULL); 05946 FreeDecodedCert(&cert); 05947 05948 if (ret == 0) 05949 { 05950 CYASSL_MSG("\tOCSP Confirm signature failed"); 05951 return ASN_OCSP_CONFIRM_E; 05952 } 05953 } 05954 05955 *ioIndex = idx; 05956 return 0; 05957 } 05958 05959 05960 void InitOcspResponse(OcspResponse* resp, CertStatus* status, 05961 byte* source, word32 inSz) 05962 { 05963 CYASSL_ENTER("InitOcspResponse"); 05964 05965 resp->responseStatus = -1; 05966 resp->response = NULL; 05967 resp->responseSz = 0; 05968 resp->producedDateFormat = 0; 05969 resp->issuerHash = NULL; 05970 resp->issuerKeyHash = NULL; 05971 resp->sig = NULL; 05972 resp->sigSz = 0; 05973 resp->sigOID = 0; 05974 resp->status = status; 05975 resp->nonce = NULL; 05976 resp->nonceSz = 0; 05977 resp->source = source; 05978 resp->maxIdx = inSz; 05979 } 05980 05981 05982 int OcspResponseDecode(OcspResponse* resp) 05983 { 05984 int length = 0; 05985 word32 idx = 0; 05986 byte* source = resp->source; 05987 word32 size = resp->maxIdx; 05988 word32 oid; 05989 05990 CYASSL_ENTER("OcspResponseDecode"); 05991 05992 /* peel the outer SEQUENCE wrapper */ 05993 if (GetSequence(source, &idx, &length, size) < 0) 05994 return ASN_PARSE_E; 05995 05996 /* First get the responseStatus, an ENUMERATED */ 05997 if (GetEnumerated(source, &idx, &resp->responseStatus) < 0) 05998 return ASN_PARSE_E; 05999 06000 if (resp->responseStatus != OCSP_SUCCESSFUL) 06001 return 0; 06002 06003 /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ 06004 if (idx >= size) 06005 return ASN_INPUT_E; 06006 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) 06007 return ASN_PARSE_E; 06008 if (GetLength(source, &idx, &length, size) < 0) 06009 return ASN_PARSE_E; 06010 06011 /* Get the responseBytes SEQUENCE */ 06012 if (GetSequence(source, &idx, &length, size) < 0) 06013 return ASN_PARSE_E; 06014 06015 /* Check ObjectID for the resposeBytes */ 06016 if (GetObjectId(source, &idx, &oid, size) < 0) 06017 return ASN_PARSE_E; 06018 if (oid != OCSP_BASIC_OID) 06019 return ASN_PARSE_E; 06020 if (source[idx++] != ASN_OCTET_STRING) 06021 return ASN_PARSE_E; 06022 06023 if (GetLength(source, &idx, &length, size) < 0) 06024 return ASN_PARSE_E; 06025 06026 if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0) 06027 return ASN_PARSE_E; 06028 06029 return 0; 06030 } 06031 06032 06033 static word32 SetOcspReqExtensions(word32 extSz, byte* output, 06034 const byte* nonce, word32 nonceSz) 06035 { 06036 static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 06037 0x30, 0x01, 0x02 }; 06038 byte seqArray[5][MAX_SEQ_SZ]; 06039 word32 seqSz[5], totalSz; 06040 06041 CYASSL_ENTER("SetOcspReqExtensions"); 06042 06043 if (nonce == NULL || nonceSz == 0) return 0; 06044 06045 seqArray[0][0] = ASN_OCTET_STRING; 06046 seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]); 06047 06048 seqArray[1][0] = ASN_OBJECT_ID; 06049 seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]); 06050 06051 totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId); 06052 06053 seqSz[2] = SetSequence(totalSz, seqArray[2]); 06054 totalSz += seqSz[2]; 06055 06056 seqSz[3] = SetSequence(totalSz, seqArray[3]); 06057 totalSz += seqSz[3]; 06058 06059 seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2); 06060 seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]); 06061 totalSz += seqSz[4]; 06062 06063 if (totalSz < extSz) 06064 { 06065 totalSz = 0; 06066 XMEMCPY(output + totalSz, seqArray[4], seqSz[4]); 06067 totalSz += seqSz[4]; 06068 XMEMCPY(output + totalSz, seqArray[3], seqSz[3]); 06069 totalSz += seqSz[3]; 06070 XMEMCPY(output + totalSz, seqArray[2], seqSz[2]); 06071 totalSz += seqSz[2]; 06072 XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); 06073 totalSz += seqSz[1]; 06074 XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId)); 06075 totalSz += (word32)sizeof(NonceObjId); 06076 XMEMCPY(output + totalSz, seqArray[0], seqSz[0]); 06077 totalSz += seqSz[0]; 06078 XMEMCPY(output + totalSz, nonce, nonceSz); 06079 totalSz += nonceSz; 06080 } 06081 06082 return totalSz; 06083 } 06084 06085 06086 int EncodeOcspRequest(OcspRequest* req) 06087 { 06088 byte seqArray[5][MAX_SEQ_SZ]; 06089 /* The ASN.1 of the OCSP Request is an onion of sequences */ 06090 byte algoArray[MAX_ALGO_SZ]; 06091 byte issuerArray[MAX_ENCODED_DIG_SZ]; 06092 byte issuerKeyArray[MAX_ENCODED_DIG_SZ]; 06093 byte snArray[MAX_SN_SZ]; 06094 byte extArray[MAX_OCSP_EXT_SZ]; 06095 byte* output = req->dest; 06096 word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; 06097 int i; 06098 06099 CYASSL_ENTER("EncodeOcspRequest"); 06100 06101 algoSz = SetAlgoID(SHAh, algoArray, hashType, 0); 06102 06103 req->issuerHash = req->cert->issuerHash; 06104 issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray); 06105 06106 req->issuerKeyHash = req->cert->issuerKeyHash; 06107 issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray); 06108 06109 req->serial = req->cert->serial; 06110 req->serialSz = req->cert->serialSz; 06111 snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); 06112 06113 extSz = 0; 06114 if (req->useNonce) { 06115 RNG rng; 06116 if (InitRng(&rng) != 0) { 06117 CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); 06118 } else { 06119 req->nonceSz = MAX_OCSP_NONCE_SZ; 06120 RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); 06121 extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, 06122 req->nonce, req->nonceSz); 06123 } 06124 } 06125 06126 totalSz = algoSz + issuerSz + issuerKeySz + snSz; 06127 06128 for (i = 4; i >= 0; i--) { 06129 seqSz[i] = SetSequence(totalSz, seqArray[i]); 06130 totalSz += seqSz[i]; 06131 if (i == 2) totalSz += extSz; 06132 } 06133 totalSz = 0; 06134 for (i = 0; i < 5; i++) { 06135 XMEMCPY(output + totalSz, seqArray[i], seqSz[i]); 06136 totalSz += seqSz[i]; 06137 } 06138 XMEMCPY(output + totalSz, algoArray, algoSz); 06139 totalSz += algoSz; 06140 XMEMCPY(output + totalSz, issuerArray, issuerSz); 06141 totalSz += issuerSz; 06142 XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz); 06143 totalSz += issuerKeySz; 06144 XMEMCPY(output + totalSz, snArray, snSz); 06145 totalSz += snSz; 06146 if (extSz != 0) { 06147 XMEMCPY(output + totalSz, extArray, extSz); 06148 totalSz += extSz; 06149 } 06150 06151 return totalSz; 06152 } 06153 06154 06155 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, 06156 byte* dest, word32 destSz) 06157 { 06158 CYASSL_ENTER("InitOcspRequest"); 06159 06160 req->cert = cert; 06161 req->useNonce = useNonce; 06162 req->nonceSz = 0; 06163 req->issuerHash = NULL; 06164 req->issuerKeyHash = NULL; 06165 req->serial = NULL; 06166 req->dest = dest; 06167 req->destSz = destSz; 06168 } 06169 06170 06171 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) 06172 { 06173 int cmp; 06174 06175 CYASSL_ENTER("CompareOcspReqResp"); 06176 06177 if (req == NULL) 06178 { 06179 CYASSL_MSG("\tReq missing"); 06180 return -1; 06181 } 06182 06183 if (resp == NULL) 06184 { 06185 CYASSL_MSG("\tResp missing"); 06186 return 1; 06187 } 06188 06189 /* Nonces are not critical. The responder may not necessarily add 06190 * the nonce to the response. */ 06191 if (req->useNonce && resp->nonceSz != 0) { 06192 cmp = req->nonceSz - resp->nonceSz; 06193 if (cmp != 0) 06194 { 06195 CYASSL_MSG("\tnonceSz mismatch"); 06196 return cmp; 06197 } 06198 06199 cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); 06200 if (cmp != 0) 06201 { 06202 CYASSL_MSG("\tnonce mismatch"); 06203 return cmp; 06204 } 06205 } 06206 06207 cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE); 06208 if (cmp != 0) 06209 { 06210 CYASSL_MSG("\tissuerHash mismatch"); 06211 return cmp; 06212 } 06213 06214 cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE); 06215 if (cmp != 0) 06216 { 06217 CYASSL_MSG("\tissuerKeyHash mismatch"); 06218 return cmp; 06219 } 06220 06221 cmp = req->serialSz - resp->status->serialSz; 06222 if (cmp != 0) 06223 { 06224 CYASSL_MSG("\tserialSz mismatch"); 06225 return cmp; 06226 } 06227 06228 cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz); 06229 if (cmp != 0) 06230 { 06231 CYASSL_MSG("\tserial mismatch"); 06232 return cmp; 06233 } 06234 06235 return 0; 06236 } 06237 06238 #endif 06239 06240 06241 /* store SHA1 hash of NAME */ 06242 CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, 06243 int maxIdx) 06244 { 06245 Sha sha; 06246 int length; /* length of all distinguished names */ 06247 int ret = 0; 06248 word32 dummy; 06249 06250 CYASSL_ENTER("GetNameHash"); 06251 06252 if (source[*idx] == ASN_OBJECT_ID) { 06253 CYASSL_MSG("Trying optional prefix..."); 06254 06255 if (GetLength(source, idx, &length, maxIdx) < 0) 06256 return ASN_PARSE_E; 06257 06258 *idx += length; 06259 CYASSL_MSG("Got optional prefix"); 06260 } 06261 06262 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be 06263 * calculated over the entire DER encoding of the Name field, including 06264 * the tag and length. */ 06265 dummy = *idx; 06266 if (GetSequence(source, idx, &length, maxIdx) < 0) 06267 return ASN_PARSE_E; 06268 06269 ret = InitSha(&sha); 06270 if (ret != 0) 06271 return ret; 06272 ShaUpdate(&sha, source + dummy, length + *idx - dummy); 06273 ShaFinal(&sha, hash); 06274 06275 *idx += length; 06276 06277 return 0; 06278 } 06279 06280 06281 #ifdef HAVE_CRL 06282 06283 /* initialize decoded CRL */ 06284 void InitDecodedCRL(DecodedCRL* dcrl) 06285 { 06286 CYASSL_MSG("InitDecodedCRL"); 06287 06288 dcrl->certBegin = 0; 06289 dcrl->sigIndex = 0; 06290 dcrl->sigLength = 0; 06291 dcrl->signatureOID = 0; 06292 dcrl->certs = NULL; 06293 dcrl->totalCerts = 0; 06294 } 06295 06296 06297 /* free decoded CRL resources */ 06298 void FreeDecodedCRL(DecodedCRL* dcrl) 06299 { 06300 RevokedCert* tmp = dcrl->certs; 06301 06302 CYASSL_MSG("FreeDecodedCRL"); 06303 06304 while(tmp) { 06305 RevokedCert* next = tmp->next; 06306 XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); 06307 tmp = next; 06308 } 06309 } 06310 06311 06312 /* Get Revoked Cert list, 0 on success */ 06313 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, 06314 int maxIdx) 06315 { 06316 int len; 06317 word32 end; 06318 byte b; 06319 RevokedCert* rc; 06320 06321 CYASSL_ENTER("GetRevoked"); 06322 06323 if (GetSequence(buff, idx, &len, maxIdx) < 0) 06324 return ASN_PARSE_E; 06325 06326 end = *idx + len; 06327 06328 /* get serial number */ 06329 b = buff[*idx]; 06330 *idx += 1; 06331 06332 if (b != ASN_INTEGER) { 06333 CYASSL_MSG("Expecting Integer"); 06334 return ASN_PARSE_E; 06335 } 06336 06337 if (GetLength(buff, idx, &len, maxIdx) < 0) 06338 return ASN_PARSE_E; 06339 06340 if (len > EXTERNAL_SERIAL_SIZE) { 06341 CYASSL_MSG("Serial Size too big"); 06342 return ASN_PARSE_E; 06343 } 06344 06345 rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL); 06346 if (rc == NULL) { 06347 CYASSL_MSG("Alloc Revoked Cert failed"); 06348 return MEMORY_E; 06349 } 06350 06351 XMEMCPY(rc->serialNumber, &buff[*idx], len); 06352 rc->serialSz = len; 06353 06354 /* add to list */ 06355 rc->next = dcrl->certs; 06356 dcrl->certs = rc; 06357 dcrl->totalCerts++; 06358 06359 *idx += len; 06360 06361 /* get date */ 06362 b = buff[*idx]; 06363 *idx += 1; 06364 06365 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) { 06366 CYASSL_MSG("Expecting Date"); 06367 return ASN_PARSE_E; 06368 } 06369 06370 if (GetLength(buff, idx, &len, maxIdx) < 0) 06371 return ASN_PARSE_E; 06372 06373 /* skip for now */ 06374 *idx += len; 06375 06376 if (*idx != end) /* skip extensions */ 06377 *idx = end; 06378 06379 return 0; 06380 } 06381 06382 06383 /* Get CRL Signature, 0 on success */ 06384 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl, 06385 int maxIdx) 06386 { 06387 int length; 06388 byte b; 06389 06390 CYASSL_ENTER("GetCRL_Signature"); 06391 06392 b = source[*idx]; 06393 *idx += 1; 06394 if (b != ASN_BIT_STRING) 06395 return ASN_BITSTR_E; 06396 06397 if (GetLength(source, idx, &length, maxIdx) < 0) 06398 return ASN_PARSE_E; 06399 06400 dcrl->sigLength = length; 06401 06402 b = source[*idx]; 06403 *idx += 1; 06404 if (b != 0x00) 06405 return ASN_EXPECT_0_E; 06406 06407 dcrl->sigLength--; 06408 dcrl->signature = (byte*)&source[*idx]; 06409 06410 *idx += dcrl->sigLength; 06411 06412 return 0; 06413 } 06414 06415 06416 /* prase crl buffer into decoded state, 0 on success */ 06417 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) 06418 { 06419 int version, len; 06420 word32 oid, idx = 0; 06421 Signer* ca = NULL; 06422 06423 CYASSL_MSG("ParseCRL"); 06424 06425 /* raw crl hash */ 06426 /* hash here if needed for optimized comparisons 06427 * Sha sha; 06428 * InitSha(&sha); 06429 * ShaUpdate(&sha, buff, sz); 06430 * ShaFinal(&sha, dcrl->crlHash); */ 06431 06432 if (GetSequence(buff, &idx, &len, sz) < 0) 06433 return ASN_PARSE_E; 06434 06435 dcrl->certBegin = idx; 06436 06437 if (GetSequence(buff, &idx, &len, sz) < 0) 06438 return ASN_PARSE_E; 06439 dcrl->sigIndex = len + idx; 06440 06441 /* may have version */ 06442 if (buff[idx] == ASN_INTEGER) { 06443 if (GetMyVersion(buff, &idx, &version) < 0) 06444 return ASN_PARSE_E; 06445 } 06446 06447 if (GetAlgoId(buff, &idx, &oid, sz) < 0) 06448 return ASN_PARSE_E; 06449 06450 if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) 06451 return ASN_PARSE_E; 06452 06453 if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) 06454 return ASN_PARSE_E; 06455 06456 if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) 06457 return ASN_PARSE_E; 06458 06459 if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) { 06460 CYASSL_MSG("CRL after date is no longer valid"); 06461 return ASN_AFTER_DATE_E; 06462 } 06463 06464 if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) { 06465 if (GetSequence(buff, &idx, &len, sz) < 0) 06466 return ASN_PARSE_E; 06467 06468 len += idx; 06469 06470 while (idx < (word32)len) { 06471 if (GetRevoked(buff, &idx, dcrl, sz) < 0) 06472 return ASN_PARSE_E; 06473 } 06474 } 06475 06476 if (idx != dcrl->sigIndex) 06477 idx = dcrl->sigIndex; /* skip extensions */ 06478 06479 if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0) 06480 return ASN_PARSE_E; 06481 06482 if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0) 06483 return ASN_PARSE_E; 06484 06485 /* openssl doesn't add skid by default for CRLs cause firefox chokes 06486 we're not assuming it's available yet */ 06487 #if !defined(NO_SKID) && defined(CRL_SKID_READY) 06488 if (dcrl->extAuthKeyIdSet) 06489 ca = GetCA(cm, dcrl->extAuthKeyId); 06490 if (ca == NULL) 06491 ca = GetCAByName(cm, dcrl->issuerHash); 06492 #else /* NO_SKID */ 06493 ca = GetCA(cm, dcrl->issuerHash); 06494 #endif /* NO_SKID */ 06495 CYASSL_MSG("About to verify CRL signature"); 06496 06497 if (ca) { 06498 CYASSL_MSG("Found CRL issuer CA"); 06499 /* try to confirm/verify signature */ 06500 if (!ConfirmSignature(buff + dcrl->certBegin, 06501 dcrl->sigIndex - dcrl->certBegin, 06502 ca->publicKey, ca->pubKeySize, ca->keyOID, 06503 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) { 06504 CYASSL_MSG("CRL Confirm signature failed"); 06505 return ASN_CRL_CONFIRM_E; 06506 } 06507 } 06508 else { 06509 CYASSL_MSG("Did NOT find CRL issuer CA"); 06510 return ASN_CRL_NO_SIGNER_E; 06511 } 06512 06513 return 0; 06514 } 06515 06516 #endif /* HAVE_CRL */ 06517 #endif 06518 06519 #ifdef CYASSL_SEP 06520 06521 06522 06523 #endif /* CYASSL_SEP */ 06524
Generated on Tue Jul 12 2022 20:12:50 by
