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