A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Vanger
Date:
Mon Jan 19 21:45:42 2015 +0000
Revision:
0:b86d15c6ba29
Child:
1:561bad221c72
Child:
2:dc991c4ab35e
Updated CyaSSL Library to 3.3.0. Changed Settings and functions to be implemented for mbed platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vanger 0:b86d15c6ba29 1 /* asn.c
Vanger 0:b86d15c6ba29 2 *
Vanger 0:b86d15c6ba29 3 * Copyright (C) 2006-2014 wolfSSL Inc.
Vanger 0:b86d15c6ba29 4 *
Vanger 0:b86d15c6ba29 5 * This file is part of CyaSSL.
Vanger 0:b86d15c6ba29 6 *
Vanger 0:b86d15c6ba29 7 * CyaSSL is free software; you can redistribute it and/or modify
Vanger 0:b86d15c6ba29 8 * it under the terms of the GNU General Public License as published by
Vanger 0:b86d15c6ba29 9 * the Free Software Foundation; either version 2 of the License, or
Vanger 0:b86d15c6ba29 10 * (at your option) any later version.
Vanger 0:b86d15c6ba29 11 *
Vanger 0:b86d15c6ba29 12 * CyaSSL is distributed in the hope that it will be useful,
Vanger 0:b86d15c6ba29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Vanger 0:b86d15c6ba29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Vanger 0:b86d15c6ba29 15 * GNU General Public License for more details.
Vanger 0:b86d15c6ba29 16 *
Vanger 0:b86d15c6ba29 17 * You should have received a copy of the GNU General Public License
Vanger 0:b86d15c6ba29 18 * along with this program; if not, write to the Free Software
Vanger 0:b86d15c6ba29 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Vanger 0:b86d15c6ba29 20 */
Vanger 0:b86d15c6ba29 21
Vanger 0:b86d15c6ba29 22 #ifdef HAVE_CONFIG_H
Vanger 0:b86d15c6ba29 23 #include <config.h>
Vanger 0:b86d15c6ba29 24 #endif
Vanger 0:b86d15c6ba29 25
Vanger 0:b86d15c6ba29 26 #include <cyassl/ctaocrypt/settings.h>
Vanger 0:b86d15c6ba29 27
Vanger 0:b86d15c6ba29 28 #ifndef NO_ASN
Vanger 0:b86d15c6ba29 29
Vanger 0:b86d15c6ba29 30 #ifdef HAVE_RTP_SYS
Vanger 0:b86d15c6ba29 31 #include "os.h" /* dc_rtc_api needs */
Vanger 0:b86d15c6ba29 32 #include "dc_rtc_api.h" /* to get current time */
Vanger 0:b86d15c6ba29 33 #endif
Vanger 0:b86d15c6ba29 34
Vanger 0:b86d15c6ba29 35 #include <cyassl/ctaocrypt/integer.h>
Vanger 0:b86d15c6ba29 36 #include <cyassl/ctaocrypt/asn.h>
Vanger 0:b86d15c6ba29 37 #include <cyassl/ctaocrypt/coding.h>
Vanger 0:b86d15c6ba29 38 #include <cyassl/ctaocrypt/md2.h>
Vanger 0:b86d15c6ba29 39 #include <cyassl/ctaocrypt/hmac.h>
Vanger 0:b86d15c6ba29 40 #include <cyassl/ctaocrypt/error-crypt.h>
Vanger 0:b86d15c6ba29 41 #include <cyassl/ctaocrypt/pwdbased.h>
Vanger 0:b86d15c6ba29 42 #include <cyassl/ctaocrypt/des3.h>
Vanger 0:b86d15c6ba29 43 #include <cyassl/ctaocrypt/logging.h>
Vanger 0:b86d15c6ba29 44
Vanger 0:b86d15c6ba29 45 #include <cyassl/ctaocrypt/random.h>
Vanger 0:b86d15c6ba29 46
Vanger 0:b86d15c6ba29 47
Vanger 0:b86d15c6ba29 48 #ifndef NO_RC4
Vanger 0:b86d15c6ba29 49 #include <cyassl/ctaocrypt/arc4.h>
Vanger 0:b86d15c6ba29 50 #endif
Vanger 0:b86d15c6ba29 51
Vanger 0:b86d15c6ba29 52 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 53 #include "ntru_crypto.h"
Vanger 0:b86d15c6ba29 54 #endif
Vanger 0:b86d15c6ba29 55
Vanger 0:b86d15c6ba29 56 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 57 #include <cyassl/ctaocrypt/ecc.h>
Vanger 0:b86d15c6ba29 58 #endif
Vanger 0:b86d15c6ba29 59
Vanger 0:b86d15c6ba29 60 #ifdef CYASSL_DEBUG_ENCODING
Vanger 0:b86d15c6ba29 61 #ifdef FREESCALE_MQX
Vanger 0:b86d15c6ba29 62 #include <fio.h>
Vanger 0:b86d15c6ba29 63 #else
Vanger 0:b86d15c6ba29 64 #include <stdio.h>
Vanger 0:b86d15c6ba29 65 #endif
Vanger 0:b86d15c6ba29 66 #endif
Vanger 0:b86d15c6ba29 67
Vanger 0:b86d15c6ba29 68 #ifdef _MSC_VER
Vanger 0:b86d15c6ba29 69 /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
Vanger 0:b86d15c6ba29 70 #pragma warning(disable: 4996)
Vanger 0:b86d15c6ba29 71 #endif
Vanger 0:b86d15c6ba29 72
Vanger 0:b86d15c6ba29 73
Vanger 0:b86d15c6ba29 74 #ifndef TRUE
Vanger 0:b86d15c6ba29 75 #define TRUE 1
Vanger 0:b86d15c6ba29 76 #endif
Vanger 0:b86d15c6ba29 77 #ifndef FALSE
Vanger 0:b86d15c6ba29 78 #define FALSE 0
Vanger 0:b86d15c6ba29 79 #endif
Vanger 0:b86d15c6ba29 80
Vanger 0:b86d15c6ba29 81
Vanger 0:b86d15c6ba29 82 #ifdef HAVE_RTP_SYS
Vanger 0:b86d15c6ba29 83 /* uses parital <time.h> structures */
Vanger 0:b86d15c6ba29 84 #define XTIME(tl) (0)
Vanger 0:b86d15c6ba29 85 #define XGMTIME(c) my_gmtime((c))
Vanger 0:b86d15c6ba29 86 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 87 #elif defined(MICRIUM)
Vanger 0:b86d15c6ba29 88 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
Vanger 0:b86d15c6ba29 89 #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t))
Vanger 0:b86d15c6ba29 90 #else
Vanger 0:b86d15c6ba29 91 #define XVALIDATE_DATE(d, f, t) (0)
Vanger 0:b86d15c6ba29 92 #endif
Vanger 0:b86d15c6ba29 93 #define NO_TIME_H
Vanger 0:b86d15c6ba29 94 /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
Vanger 0:b86d15c6ba29 95 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
Vanger 0:b86d15c6ba29 96 #include <time.h>
Vanger 0:b86d15c6ba29 97 #define XTIME(t1) pic32_time((t1))
Vanger 0:b86d15c6ba29 98 #define XGMTIME(c) gmtime((c))
Vanger 0:b86d15c6ba29 99 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 100 #elif defined(FREESCALE_MQX)
Vanger 0:b86d15c6ba29 101 #define XTIME(t1) mqx_time((t1))
Vanger 0:b86d15c6ba29 102 #define XGMTIME(c) mqx_gmtime((c))
Vanger 0:b86d15c6ba29 103 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 104 #elif defined(CYASSL_MDK_ARM)
Vanger 0:b86d15c6ba29 105 #if defined(CYASSL_MDK5)
Vanger 0:b86d15c6ba29 106 #include "cmsis_os.h"
Vanger 0:b86d15c6ba29 107 #else
Vanger 0:b86d15c6ba29 108 #include <rtl.h>
Vanger 0:b86d15c6ba29 109 #endif
Vanger 0:b86d15c6ba29 110 #undef RNG
Vanger 0:b86d15c6ba29 111 #include "cyassl_MDK_ARM.h"
Vanger 0:b86d15c6ba29 112 #undef RNG
Vanger 0:b86d15c6ba29 113 #define RNG CyaSSL_RNG /*for avoiding name conflict in "stm32f2xx.h" */
Vanger 0:b86d15c6ba29 114 #define XTIME(tl) (0)
Vanger 0:b86d15c6ba29 115 #define XGMTIME(c) Cyassl_MDK_gmtime((c))
Vanger 0:b86d15c6ba29 116 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 117 #elif defined(USER_TIME)
Vanger 0:b86d15c6ba29 118 /* user time, and gmtime compatible functions, there is a gmtime
Vanger 0:b86d15c6ba29 119 implementation here that WINCE uses, so really just need some ticks
Vanger 0:b86d15c6ba29 120 since the EPOCH
Vanger 0:b86d15c6ba29 121 */
Vanger 0:b86d15c6ba29 122
Vanger 0:b86d15c6ba29 123 struct tm {
Vanger 0:b86d15c6ba29 124 int tm_sec; /* seconds after the minute [0-60] */
Vanger 0:b86d15c6ba29 125 int tm_min; /* minutes after the hour [0-59] */
Vanger 0:b86d15c6ba29 126 int tm_hour; /* hours since midnight [0-23] */
Vanger 0:b86d15c6ba29 127 int tm_mday; /* day of the month [1-31] */
Vanger 0:b86d15c6ba29 128 int tm_mon; /* months since January [0-11] */
Vanger 0:b86d15c6ba29 129 int tm_year; /* years since 1900 */
Vanger 0:b86d15c6ba29 130 int tm_wday; /* days since Sunday [0-6] */
Vanger 0:b86d15c6ba29 131 int tm_yday; /* days since January 1 [0-365] */
Vanger 0:b86d15c6ba29 132 int tm_isdst; /* Daylight Savings Time flag */
Vanger 0:b86d15c6ba29 133 long tm_gmtoff; /* offset from CUT in seconds */
Vanger 0:b86d15c6ba29 134 char *tm_zone; /* timezone abbreviation */
Vanger 0:b86d15c6ba29 135 };
Vanger 0:b86d15c6ba29 136 typedef long time_t;
Vanger 0:b86d15c6ba29 137
Vanger 0:b86d15c6ba29 138 /* forward declaration */
Vanger 0:b86d15c6ba29 139 struct tm* gmtime(const time_t* timer);
Vanger 0:b86d15c6ba29 140 time_t XTIME(time_t * timer){
Vanger 0:b86d15c6ba29 141 return time(timer);
Vanger 0:b86d15c6ba29 142 }
Vanger 0:b86d15c6ba29 143
Vanger 0:b86d15c6ba29 144 #define XGMTIME(c) gmtime((c))
Vanger 0:b86d15c6ba29 145 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 146
Vanger 0:b86d15c6ba29 147 #ifdef STACK_TRAP
Vanger 0:b86d15c6ba29 148 /* for stack trap tracking, don't call os gmtime on OS X/linux,
Vanger 0:b86d15c6ba29 149 uses a lot of stack spce */
Vanger 0:b86d15c6ba29 150 extern time_t time(time_t * timer);
Vanger 0:b86d15c6ba29 151 #define XTIME(tl) time((tl))
Vanger 0:b86d15c6ba29 152 #endif /* STACK_TRAP */
Vanger 0:b86d15c6ba29 153
Vanger 0:b86d15c6ba29 154 #else
Vanger 0:b86d15c6ba29 155 /* default */
Vanger 0:b86d15c6ba29 156 /* uses complete <time.h> facility */
Vanger 0:b86d15c6ba29 157 #include <time.h>
Vanger 0:b86d15c6ba29 158 #define XTIME(tl) time((tl))
Vanger 0:b86d15c6ba29 159 #define XGMTIME(c) gmtime((c))
Vanger 0:b86d15c6ba29 160 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
Vanger 0:b86d15c6ba29 161 #endif
Vanger 0:b86d15c6ba29 162
Vanger 0:b86d15c6ba29 163
Vanger 0:b86d15c6ba29 164 #ifdef _WIN32_WCE
Vanger 0:b86d15c6ba29 165 /* no time() or gmtime() even though in time.h header?? */
Vanger 0:b86d15c6ba29 166
Vanger 0:b86d15c6ba29 167 #include <windows.h>
Vanger 0:b86d15c6ba29 168
Vanger 0:b86d15c6ba29 169
Vanger 0:b86d15c6ba29 170 time_t time(time_t* timer)
Vanger 0:b86d15c6ba29 171 {
Vanger 0:b86d15c6ba29 172 SYSTEMTIME sysTime;
Vanger 0:b86d15c6ba29 173 FILETIME fTime;
Vanger 0:b86d15c6ba29 174 ULARGE_INTEGER intTime;
Vanger 0:b86d15c6ba29 175 time_t localTime;
Vanger 0:b86d15c6ba29 176
Vanger 0:b86d15c6ba29 177 if (timer == NULL)
Vanger 0:b86d15c6ba29 178 timer = &localTime;
Vanger 0:b86d15c6ba29 179
Vanger 0:b86d15c6ba29 180 GetSystemTime(&sysTime);
Vanger 0:b86d15c6ba29 181 SystemTimeToFileTime(&sysTime, &fTime);
Vanger 0:b86d15c6ba29 182
Vanger 0:b86d15c6ba29 183 XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
Vanger 0:b86d15c6ba29 184 /* subtract EPOCH */
Vanger 0:b86d15c6ba29 185 intTime.QuadPart -= 0x19db1ded53e8000;
Vanger 0:b86d15c6ba29 186 /* to secs */
Vanger 0:b86d15c6ba29 187 intTime.QuadPart /= 10000000;
Vanger 0:b86d15c6ba29 188 *timer = (time_t)intTime.QuadPart;
Vanger 0:b86d15c6ba29 189
Vanger 0:b86d15c6ba29 190 return *timer;
Vanger 0:b86d15c6ba29 191 }
Vanger 0:b86d15c6ba29 192
Vanger 0:b86d15c6ba29 193 #endif /* _WIN32_WCE */
Vanger 0:b86d15c6ba29 194 #if defined( _WIN32_WCE ) || defined( USER_TIME )
Vanger 0:b86d15c6ba29 195
Vanger 0:b86d15c6ba29 196 struct tm* gmtime(const time_t* timer)
Vanger 0:b86d15c6ba29 197 {
Vanger 0:b86d15c6ba29 198 #define YEAR0 1900
Vanger 0:b86d15c6ba29 199 #define EPOCH_YEAR 1970
Vanger 0:b86d15c6ba29 200 #define SECS_DAY (24L * 60L * 60L)
Vanger 0:b86d15c6ba29 201 #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
Vanger 0:b86d15c6ba29 202 #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
Vanger 0:b86d15c6ba29 203
Vanger 0:b86d15c6ba29 204 static const int _ytab[2][12] =
Vanger 0:b86d15c6ba29 205 {
Vanger 0:b86d15c6ba29 206 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
Vanger 0:b86d15c6ba29 207 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
Vanger 0:b86d15c6ba29 208 };
Vanger 0:b86d15c6ba29 209
Vanger 0:b86d15c6ba29 210 static struct tm st_time;
Vanger 0:b86d15c6ba29 211 struct tm* ret = &st_time;
Vanger 0:b86d15c6ba29 212 time_t secs = *timer;
Vanger 0:b86d15c6ba29 213 unsigned long dayclock, dayno;
Vanger 0:b86d15c6ba29 214 int year = EPOCH_YEAR;
Vanger 0:b86d15c6ba29 215
Vanger 0:b86d15c6ba29 216 dayclock = (unsigned long)secs % SECS_DAY;
Vanger 0:b86d15c6ba29 217 dayno = (unsigned long)secs / SECS_DAY;
Vanger 0:b86d15c6ba29 218
Vanger 0:b86d15c6ba29 219 ret->tm_sec = (int) dayclock % 60;
Vanger 0:b86d15c6ba29 220 ret->tm_min = (int)(dayclock % 3600) / 60;
Vanger 0:b86d15c6ba29 221 ret->tm_hour = (int) dayclock / 3600;
Vanger 0:b86d15c6ba29 222 ret->tm_wday = (int) (dayno + 4) % 7; /* day 0 a Thursday */
Vanger 0:b86d15c6ba29 223
Vanger 0:b86d15c6ba29 224 while(dayno >= (unsigned long)YEARSIZE(year)) {
Vanger 0:b86d15c6ba29 225 dayno -= YEARSIZE(year);
Vanger 0:b86d15c6ba29 226 year++;
Vanger 0:b86d15c6ba29 227 }
Vanger 0:b86d15c6ba29 228
Vanger 0:b86d15c6ba29 229 ret->tm_year = year - YEAR0;
Vanger 0:b86d15c6ba29 230 ret->tm_yday = (int)dayno;
Vanger 0:b86d15c6ba29 231 ret->tm_mon = 0;
Vanger 0:b86d15c6ba29 232
Vanger 0:b86d15c6ba29 233 while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
Vanger 0:b86d15c6ba29 234 dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
Vanger 0:b86d15c6ba29 235 ret->tm_mon++;
Vanger 0:b86d15c6ba29 236 }
Vanger 0:b86d15c6ba29 237
Vanger 0:b86d15c6ba29 238 ret->tm_mday = (int)++dayno;
Vanger 0:b86d15c6ba29 239 ret->tm_isdst = 0;
Vanger 0:b86d15c6ba29 240
Vanger 0:b86d15c6ba29 241 return ret;
Vanger 0:b86d15c6ba29 242 }
Vanger 0:b86d15c6ba29 243
Vanger 0:b86d15c6ba29 244 #endif /* _WIN32_WCE || USER_TIME */
Vanger 0:b86d15c6ba29 245
Vanger 0:b86d15c6ba29 246
Vanger 0:b86d15c6ba29 247 #ifdef HAVE_RTP_SYS
Vanger 0:b86d15c6ba29 248
Vanger 0:b86d15c6ba29 249 #define YEAR0 1900
Vanger 0:b86d15c6ba29 250
Vanger 0:b86d15c6ba29 251 struct tm* my_gmtime(const time_t* timer) /* has a gmtime() but hangs */
Vanger 0:b86d15c6ba29 252 {
Vanger 0:b86d15c6ba29 253 static struct tm st_time;
Vanger 0:b86d15c6ba29 254 struct tm* ret = &st_time;
Vanger 0:b86d15c6ba29 255
Vanger 0:b86d15c6ba29 256 DC_RTC_CALENDAR cal;
Vanger 0:b86d15c6ba29 257 dc_rtc_time_get(&cal, TRUE);
Vanger 0:b86d15c6ba29 258
Vanger 0:b86d15c6ba29 259 ret->tm_year = cal.year - YEAR0; /* gm starts at 1900 */
Vanger 0:b86d15c6ba29 260 ret->tm_mon = cal.month - 1; /* gm starts at 0 */
Vanger 0:b86d15c6ba29 261 ret->tm_mday = cal.day;
Vanger 0:b86d15c6ba29 262 ret->tm_hour = cal.hour;
Vanger 0:b86d15c6ba29 263 ret->tm_min = cal.minute;
Vanger 0:b86d15c6ba29 264 ret->tm_sec = cal.second;
Vanger 0:b86d15c6ba29 265
Vanger 0:b86d15c6ba29 266 return ret;
Vanger 0:b86d15c6ba29 267 }
Vanger 0:b86d15c6ba29 268
Vanger 0:b86d15c6ba29 269 #endif /* HAVE_RTP_SYS */
Vanger 0:b86d15c6ba29 270
Vanger 0:b86d15c6ba29 271
Vanger 0:b86d15c6ba29 272 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
Vanger 0:b86d15c6ba29 273
Vanger 0:b86d15c6ba29 274 /*
Vanger 0:b86d15c6ba29 275 * time() is just a stub in Microchip libraries. We need our own
Vanger 0:b86d15c6ba29 276 * implementation. Use SNTP client to get seconds since epoch.
Vanger 0:b86d15c6ba29 277 */
Vanger 0:b86d15c6ba29 278 time_t pic32_time(time_t* timer)
Vanger 0:b86d15c6ba29 279 {
Vanger 0:b86d15c6ba29 280 #ifdef MICROCHIP_TCPIP_V5
Vanger 0:b86d15c6ba29 281 DWORD sec = 0;
Vanger 0:b86d15c6ba29 282 #else
Vanger 0:b86d15c6ba29 283 uint32_t sec = 0;
Vanger 0:b86d15c6ba29 284 #endif
Vanger 0:b86d15c6ba29 285 time_t localTime;
Vanger 0:b86d15c6ba29 286
Vanger 0:b86d15c6ba29 287 if (timer == NULL)
Vanger 0:b86d15c6ba29 288 timer = &localTime;
Vanger 0:b86d15c6ba29 289
Vanger 0:b86d15c6ba29 290 #ifdef MICROCHIP_MPLAB_HARMONY
Vanger 0:b86d15c6ba29 291 sec = TCPIP_SNTP_UTCSecondsGet();
Vanger 0:b86d15c6ba29 292 #else
Vanger 0:b86d15c6ba29 293 sec = SNTPGetUTCSeconds();
Vanger 0:b86d15c6ba29 294 #endif
Vanger 0:b86d15c6ba29 295 *timer = (time_t) sec;
Vanger 0:b86d15c6ba29 296
Vanger 0:b86d15c6ba29 297 return *timer;
Vanger 0:b86d15c6ba29 298 }
Vanger 0:b86d15c6ba29 299
Vanger 0:b86d15c6ba29 300 #endif /* MICROCHIP_TCPIP */
Vanger 0:b86d15c6ba29 301
Vanger 0:b86d15c6ba29 302
Vanger 0:b86d15c6ba29 303 #ifdef FREESCALE_MQX
Vanger 0:b86d15c6ba29 304
Vanger 0:b86d15c6ba29 305 time_t mqx_time(time_t* timer)
Vanger 0:b86d15c6ba29 306 {
Vanger 0:b86d15c6ba29 307 time_t localTime;
Vanger 0:b86d15c6ba29 308 TIME_STRUCT time_s;
Vanger 0:b86d15c6ba29 309
Vanger 0:b86d15c6ba29 310 if (timer == NULL)
Vanger 0:b86d15c6ba29 311 timer = &localTime;
Vanger 0:b86d15c6ba29 312
Vanger 0:b86d15c6ba29 313 _time_get(&time_s);
Vanger 0:b86d15c6ba29 314 *timer = (time_t) time_s.SECONDS;
Vanger 0:b86d15c6ba29 315
Vanger 0:b86d15c6ba29 316 return *timer;
Vanger 0:b86d15c6ba29 317 }
Vanger 0:b86d15c6ba29 318
Vanger 0:b86d15c6ba29 319 /* CodeWarrior GCC toolchain only has gmtime_r(), no gmtime() */
Vanger 0:b86d15c6ba29 320 struct tm* mqx_gmtime(const time_t* clock)
Vanger 0:b86d15c6ba29 321 {
Vanger 0:b86d15c6ba29 322 struct tm tmpTime;
Vanger 0:b86d15c6ba29 323
Vanger 0:b86d15c6ba29 324 return gmtime_r(clock, &tmpTime);
Vanger 0:b86d15c6ba29 325 }
Vanger 0:b86d15c6ba29 326
Vanger 0:b86d15c6ba29 327 #endif /* FREESCALE_MQX */
Vanger 0:b86d15c6ba29 328
Vanger 0:b86d15c6ba29 329 #ifdef CYASSL_TIRTOS
Vanger 0:b86d15c6ba29 330
Vanger 0:b86d15c6ba29 331 time_t XTIME(time_t * timer)
Vanger 0:b86d15c6ba29 332 {
Vanger 0:b86d15c6ba29 333 time_t sec = 0;
Vanger 0:b86d15c6ba29 334
Vanger 0:b86d15c6ba29 335 sec = (time_t) MYTIME_gettime();
Vanger 0:b86d15c6ba29 336
Vanger 0:b86d15c6ba29 337 if (timer != NULL)
Vanger 0:b86d15c6ba29 338 *timer = sec;
Vanger 0:b86d15c6ba29 339
Vanger 0:b86d15c6ba29 340 return sec;
Vanger 0:b86d15c6ba29 341 }
Vanger 0:b86d15c6ba29 342
Vanger 0:b86d15c6ba29 343 #endif /* CYASSL_TIRTOS */
Vanger 0:b86d15c6ba29 344
Vanger 0:b86d15c6ba29 345 static INLINE word32 btoi(byte b)
Vanger 0:b86d15c6ba29 346 {
Vanger 0:b86d15c6ba29 347 return b - 0x30;
Vanger 0:b86d15c6ba29 348 }
Vanger 0:b86d15c6ba29 349
Vanger 0:b86d15c6ba29 350
Vanger 0:b86d15c6ba29 351 /* two byte date/time, add to value */
Vanger 0:b86d15c6ba29 352 static INLINE void GetTime(int* value, const byte* date, int* idx)
Vanger 0:b86d15c6ba29 353 {
Vanger 0:b86d15c6ba29 354 int i = *idx;
Vanger 0:b86d15c6ba29 355
Vanger 0:b86d15c6ba29 356 *value += btoi(date[i++]) * 10;
Vanger 0:b86d15c6ba29 357 *value += btoi(date[i++]);
Vanger 0:b86d15c6ba29 358
Vanger 0:b86d15c6ba29 359 *idx = i;
Vanger 0:b86d15c6ba29 360 }
Vanger 0:b86d15c6ba29 361
Vanger 0:b86d15c6ba29 362
Vanger 0:b86d15c6ba29 363 #if defined(MICRIUM)
Vanger 0:b86d15c6ba29 364
Vanger 0:b86d15c6ba29 365 CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format,
Vanger 0:b86d15c6ba29 366 CPU_INT08U dateType)
Vanger 0:b86d15c6ba29 367 {
Vanger 0:b86d15c6ba29 368 CPU_BOOLEAN rtn_code;
Vanger 0:b86d15c6ba29 369 CPU_INT32S i;
Vanger 0:b86d15c6ba29 370 CPU_INT32S val;
Vanger 0:b86d15c6ba29 371 CPU_INT16U year;
Vanger 0:b86d15c6ba29 372 CPU_INT08U month;
Vanger 0:b86d15c6ba29 373 CPU_INT16U day;
Vanger 0:b86d15c6ba29 374 CPU_INT08U hour;
Vanger 0:b86d15c6ba29 375 CPU_INT08U min;
Vanger 0:b86d15c6ba29 376 CPU_INT08U sec;
Vanger 0:b86d15c6ba29 377
Vanger 0:b86d15c6ba29 378 i = 0;
Vanger 0:b86d15c6ba29 379 year = 0u;
Vanger 0:b86d15c6ba29 380
Vanger 0:b86d15c6ba29 381 if (format == ASN_UTC_TIME) {
Vanger 0:b86d15c6ba29 382 if (btoi(date[0]) >= 5)
Vanger 0:b86d15c6ba29 383 year = 1900;
Vanger 0:b86d15c6ba29 384 else
Vanger 0:b86d15c6ba29 385 year = 2000;
Vanger 0:b86d15c6ba29 386 }
Vanger 0:b86d15c6ba29 387 else { /* format == GENERALIZED_TIME */
Vanger 0:b86d15c6ba29 388 year += btoi(date[i++]) * 1000;
Vanger 0:b86d15c6ba29 389 year += btoi(date[i++]) * 100;
Vanger 0:b86d15c6ba29 390 }
Vanger 0:b86d15c6ba29 391
Vanger 0:b86d15c6ba29 392 val = year;
Vanger 0:b86d15c6ba29 393 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 394 year = (CPU_INT16U)val;
Vanger 0:b86d15c6ba29 395
Vanger 0:b86d15c6ba29 396 val = 0;
Vanger 0:b86d15c6ba29 397 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 398 month = (CPU_INT08U)val;
Vanger 0:b86d15c6ba29 399
Vanger 0:b86d15c6ba29 400 val = 0;
Vanger 0:b86d15c6ba29 401 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 402 day = (CPU_INT16U)val;
Vanger 0:b86d15c6ba29 403
Vanger 0:b86d15c6ba29 404 val = 0;
Vanger 0:b86d15c6ba29 405 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 406 hour = (CPU_INT08U)val;
Vanger 0:b86d15c6ba29 407
Vanger 0:b86d15c6ba29 408 val = 0;
Vanger 0:b86d15c6ba29 409 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 410 min = (CPU_INT08U)val;
Vanger 0:b86d15c6ba29 411
Vanger 0:b86d15c6ba29 412 val = 0;
Vanger 0:b86d15c6ba29 413 GetTime(&val, date, &i);
Vanger 0:b86d15c6ba29 414 sec = (CPU_INT08U)val;
Vanger 0:b86d15c6ba29 415
Vanger 0:b86d15c6ba29 416 return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType);
Vanger 0:b86d15c6ba29 417 }
Vanger 0:b86d15c6ba29 418
Vanger 0:b86d15c6ba29 419 #endif /* MICRIUM */
Vanger 0:b86d15c6ba29 420
Vanger 0:b86d15c6ba29 421
Vanger 0:b86d15c6ba29 422 CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
Vanger 0:b86d15c6ba29 423 word32 maxIdx)
Vanger 0:b86d15c6ba29 424 {
Vanger 0:b86d15c6ba29 425 int length = 0;
Vanger 0:b86d15c6ba29 426 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 427 byte b;
Vanger 0:b86d15c6ba29 428
Vanger 0:b86d15c6ba29 429 *len = 0; /* default length */
Vanger 0:b86d15c6ba29 430
Vanger 0:b86d15c6ba29 431 if ( (i+1) > maxIdx) { /* for first read */
Vanger 0:b86d15c6ba29 432 CYASSL_MSG("GetLength bad index on input");
Vanger 0:b86d15c6ba29 433 return BUFFER_E;
Vanger 0:b86d15c6ba29 434 }
Vanger 0:b86d15c6ba29 435
Vanger 0:b86d15c6ba29 436 b = input[i++];
Vanger 0:b86d15c6ba29 437 if (b >= ASN_LONG_LENGTH) {
Vanger 0:b86d15c6ba29 438 word32 bytes = b & 0x7F;
Vanger 0:b86d15c6ba29 439
Vanger 0:b86d15c6ba29 440 if ( (i+bytes) > maxIdx) { /* for reading bytes */
Vanger 0:b86d15c6ba29 441 CYASSL_MSG("GetLength bad long length");
Vanger 0:b86d15c6ba29 442 return BUFFER_E;
Vanger 0:b86d15c6ba29 443 }
Vanger 0:b86d15c6ba29 444
Vanger 0:b86d15c6ba29 445 while (bytes--) {
Vanger 0:b86d15c6ba29 446 b = input[i++];
Vanger 0:b86d15c6ba29 447 length = (length << 8) | b;
Vanger 0:b86d15c6ba29 448 }
Vanger 0:b86d15c6ba29 449 }
Vanger 0:b86d15c6ba29 450 else
Vanger 0:b86d15c6ba29 451 length = b;
Vanger 0:b86d15c6ba29 452
Vanger 0:b86d15c6ba29 453 if ( (i+length) > maxIdx) { /* for user of length */
Vanger 0:b86d15c6ba29 454 CYASSL_MSG("GetLength value exceeds buffer length");
Vanger 0:b86d15c6ba29 455 return BUFFER_E;
Vanger 0:b86d15c6ba29 456 }
Vanger 0:b86d15c6ba29 457
Vanger 0:b86d15c6ba29 458 *inOutIdx = i;
Vanger 0:b86d15c6ba29 459 if (length > 0)
Vanger 0:b86d15c6ba29 460 *len = length;
Vanger 0:b86d15c6ba29 461
Vanger 0:b86d15c6ba29 462 return length;
Vanger 0:b86d15c6ba29 463 }
Vanger 0:b86d15c6ba29 464
Vanger 0:b86d15c6ba29 465
Vanger 0:b86d15c6ba29 466 CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
Vanger 0:b86d15c6ba29 467 word32 maxIdx)
Vanger 0:b86d15c6ba29 468 {
Vanger 0:b86d15c6ba29 469 int length = -1;
Vanger 0:b86d15c6ba29 470 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 471
Vanger 0:b86d15c6ba29 472 if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
Vanger 0:b86d15c6ba29 473 GetLength(input, &idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 474 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 475
Vanger 0:b86d15c6ba29 476 *len = length;
Vanger 0:b86d15c6ba29 477 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 478
Vanger 0:b86d15c6ba29 479 return length;
Vanger 0:b86d15c6ba29 480 }
Vanger 0:b86d15c6ba29 481
Vanger 0:b86d15c6ba29 482
Vanger 0:b86d15c6ba29 483 CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
Vanger 0:b86d15c6ba29 484 word32 maxIdx)
Vanger 0:b86d15c6ba29 485 {
Vanger 0:b86d15c6ba29 486 int length = -1;
Vanger 0:b86d15c6ba29 487 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 488
Vanger 0:b86d15c6ba29 489 if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
Vanger 0:b86d15c6ba29 490 GetLength(input, &idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 491 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 492
Vanger 0:b86d15c6ba29 493 *len = length;
Vanger 0:b86d15c6ba29 494 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 495
Vanger 0:b86d15c6ba29 496 return length;
Vanger 0:b86d15c6ba29 497 }
Vanger 0:b86d15c6ba29 498
Vanger 0:b86d15c6ba29 499
Vanger 0:b86d15c6ba29 500 /* windows header clash for WinCE using GetVersion */
Vanger 0:b86d15c6ba29 501 CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
Vanger 0:b86d15c6ba29 502 {
Vanger 0:b86d15c6ba29 503 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 504
Vanger 0:b86d15c6ba29 505 CYASSL_ENTER("GetMyVersion");
Vanger 0:b86d15c6ba29 506
Vanger 0:b86d15c6ba29 507 if (input[idx++] != ASN_INTEGER)
Vanger 0:b86d15c6ba29 508 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 509
Vanger 0:b86d15c6ba29 510 if (input[idx++] != 0x01)
Vanger 0:b86d15c6ba29 511 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 512
Vanger 0:b86d15c6ba29 513 *version = input[idx++];
Vanger 0:b86d15c6ba29 514 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 515 return *version;
Vanger 0:b86d15c6ba29 516 }
Vanger 0:b86d15c6ba29 517
Vanger 0:b86d15c6ba29 518
Vanger 0:b86d15c6ba29 519 #ifndef NO_PWDBASED
Vanger 0:b86d15c6ba29 520 /* Get small count integer, 32 bits or less */
Vanger 0:b86d15c6ba29 521 static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
Vanger 0:b86d15c6ba29 522 {
Vanger 0:b86d15c6ba29 523 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 524 word32 len;
Vanger 0:b86d15c6ba29 525
Vanger 0:b86d15c6ba29 526 *number = 0;
Vanger 0:b86d15c6ba29 527
Vanger 0:b86d15c6ba29 528 if (input[idx++] != ASN_INTEGER)
Vanger 0:b86d15c6ba29 529 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 530
Vanger 0:b86d15c6ba29 531 len = input[idx++];
Vanger 0:b86d15c6ba29 532 if (len > 4)
Vanger 0:b86d15c6ba29 533 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 534
Vanger 0:b86d15c6ba29 535 while (len--) {
Vanger 0:b86d15c6ba29 536 *number = *number << 8 | input[idx++];
Vanger 0:b86d15c6ba29 537 }
Vanger 0:b86d15c6ba29 538
Vanger 0:b86d15c6ba29 539 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 540
Vanger 0:b86d15c6ba29 541 return *number;
Vanger 0:b86d15c6ba29 542 }
Vanger 0:b86d15c6ba29 543 #endif /* !NO_PWDBASED */
Vanger 0:b86d15c6ba29 544
Vanger 0:b86d15c6ba29 545
Vanger 0:b86d15c6ba29 546 /* May not have one, not an error */
Vanger 0:b86d15c6ba29 547 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
Vanger 0:b86d15c6ba29 548 {
Vanger 0:b86d15c6ba29 549 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 550
Vanger 0:b86d15c6ba29 551 CYASSL_ENTER("GetExplicitVersion");
Vanger 0:b86d15c6ba29 552 if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
Vanger 0:b86d15c6ba29 553 *inOutIdx = ++idx; /* eat header */
Vanger 0:b86d15c6ba29 554 return GetMyVersion(input, inOutIdx, version);
Vanger 0:b86d15c6ba29 555 }
Vanger 0:b86d15c6ba29 556
Vanger 0:b86d15c6ba29 557 /* go back as is */
Vanger 0:b86d15c6ba29 558 *version = 0;
Vanger 0:b86d15c6ba29 559
Vanger 0:b86d15c6ba29 560 return 0;
Vanger 0:b86d15c6ba29 561 }
Vanger 0:b86d15c6ba29 562
Vanger 0:b86d15c6ba29 563
Vanger 0:b86d15c6ba29 564 CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 565 word32 maxIdx)
Vanger 0:b86d15c6ba29 566 {
Vanger 0:b86d15c6ba29 567 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 568 byte b = input[i++];
Vanger 0:b86d15c6ba29 569 int length;
Vanger 0:b86d15c6ba29 570
Vanger 0:b86d15c6ba29 571 if (b != ASN_INTEGER)
Vanger 0:b86d15c6ba29 572 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 573
Vanger 0:b86d15c6ba29 574 if (GetLength(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 575 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 576
Vanger 0:b86d15c6ba29 577 if ( (b = input[i++]) == 0x00)
Vanger 0:b86d15c6ba29 578 length--;
Vanger 0:b86d15c6ba29 579 else
Vanger 0:b86d15c6ba29 580 i--;
Vanger 0:b86d15c6ba29 581
Vanger 0:b86d15c6ba29 582 if (mp_init(mpi) != MP_OKAY)
Vanger 0:b86d15c6ba29 583 return MP_INIT_E;
Vanger 0:b86d15c6ba29 584
Vanger 0:b86d15c6ba29 585 if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
Vanger 0:b86d15c6ba29 586 mp_clear(mpi);
Vanger 0:b86d15c6ba29 587 return ASN_GETINT_E;
Vanger 0:b86d15c6ba29 588 }
Vanger 0:b86d15c6ba29 589
Vanger 0:b86d15c6ba29 590 *inOutIdx = i + length;
Vanger 0:b86d15c6ba29 591 return 0;
Vanger 0:b86d15c6ba29 592 }
Vanger 0:b86d15c6ba29 593
Vanger 0:b86d15c6ba29 594
Vanger 0:b86d15c6ba29 595 static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
Vanger 0:b86d15c6ba29 596 word32 maxIdx)
Vanger 0:b86d15c6ba29 597 {
Vanger 0:b86d15c6ba29 598 int length;
Vanger 0:b86d15c6ba29 599 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 600 byte b;
Vanger 0:b86d15c6ba29 601 *oid = 0;
Vanger 0:b86d15c6ba29 602
Vanger 0:b86d15c6ba29 603 b = input[i++];
Vanger 0:b86d15c6ba29 604 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 605 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 606
Vanger 0:b86d15c6ba29 607 if (GetLength(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 608 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 609
Vanger 0:b86d15c6ba29 610 while(length--)
Vanger 0:b86d15c6ba29 611 *oid += input[i++];
Vanger 0:b86d15c6ba29 612 /* just sum it up for now */
Vanger 0:b86d15c6ba29 613
Vanger 0:b86d15c6ba29 614 *inOutIdx = i;
Vanger 0:b86d15c6ba29 615
Vanger 0:b86d15c6ba29 616 return 0;
Vanger 0:b86d15c6ba29 617 }
Vanger 0:b86d15c6ba29 618
Vanger 0:b86d15c6ba29 619
Vanger 0:b86d15c6ba29 620 CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
Vanger 0:b86d15c6ba29 621 word32 maxIdx)
Vanger 0:b86d15c6ba29 622 {
Vanger 0:b86d15c6ba29 623 int length;
Vanger 0:b86d15c6ba29 624 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 625 byte b;
Vanger 0:b86d15c6ba29 626 *oid = 0;
Vanger 0:b86d15c6ba29 627
Vanger 0:b86d15c6ba29 628 CYASSL_ENTER("GetAlgoId");
Vanger 0:b86d15c6ba29 629
Vanger 0:b86d15c6ba29 630 if (GetSequence(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 631 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 632
Vanger 0:b86d15c6ba29 633 b = input[i++];
Vanger 0:b86d15c6ba29 634 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 635 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 636
Vanger 0:b86d15c6ba29 637 if (GetLength(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 638 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 639
Vanger 0:b86d15c6ba29 640 while(length--) {
Vanger 0:b86d15c6ba29 641 /* odd HC08 compiler behavior here when input[i++] */
Vanger 0:b86d15c6ba29 642 *oid += input[i];
Vanger 0:b86d15c6ba29 643 i++;
Vanger 0:b86d15c6ba29 644 }
Vanger 0:b86d15c6ba29 645 /* just sum it up for now */
Vanger 0:b86d15c6ba29 646
Vanger 0:b86d15c6ba29 647 /* could have NULL tag and 0 terminator, but may not */
Vanger 0:b86d15c6ba29 648 b = input[i++];
Vanger 0:b86d15c6ba29 649
Vanger 0:b86d15c6ba29 650 if (b == ASN_TAG_NULL) {
Vanger 0:b86d15c6ba29 651 b = input[i++];
Vanger 0:b86d15c6ba29 652 if (b != 0)
Vanger 0:b86d15c6ba29 653 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 654 }
Vanger 0:b86d15c6ba29 655 else
Vanger 0:b86d15c6ba29 656 /* go back, didn't have it */
Vanger 0:b86d15c6ba29 657 i--;
Vanger 0:b86d15c6ba29 658
Vanger 0:b86d15c6ba29 659 *inOutIdx = i;
Vanger 0:b86d15c6ba29 660
Vanger 0:b86d15c6ba29 661 return 0;
Vanger 0:b86d15c6ba29 662 }
Vanger 0:b86d15c6ba29 663
Vanger 0:b86d15c6ba29 664 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 665
Vanger 0:b86d15c6ba29 666
Vanger 0:b86d15c6ba29 667 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 668
Vanger 0:b86d15c6ba29 669 static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input,
Vanger 0:b86d15c6ba29 670 word32* inOutIdx, word32 maxIdx, void* heap)
Vanger 0:b86d15c6ba29 671 {
Vanger 0:b86d15c6ba29 672 word32 i = *inOutIdx;
Vanger 0:b86d15c6ba29 673 byte b = input[i++];
Vanger 0:b86d15c6ba29 674 int length;
Vanger 0:b86d15c6ba29 675
Vanger 0:b86d15c6ba29 676 if (b != ASN_INTEGER)
Vanger 0:b86d15c6ba29 677 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 678
Vanger 0:b86d15c6ba29 679 if (GetLength(input, &i, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 680 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 681
Vanger 0:b86d15c6ba29 682 if ( (b = input[i++]) == 0x00)
Vanger 0:b86d15c6ba29 683 length--;
Vanger 0:b86d15c6ba29 684 else
Vanger 0:b86d15c6ba29 685 i--;
Vanger 0:b86d15c6ba29 686
Vanger 0:b86d15c6ba29 687 *buffSz = (word16)length;
Vanger 0:b86d15c6ba29 688 *buff = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA);
Vanger 0:b86d15c6ba29 689 if (*buff == NULL)
Vanger 0:b86d15c6ba29 690 return MEMORY_E;
Vanger 0:b86d15c6ba29 691
Vanger 0:b86d15c6ba29 692 XMEMCPY(*buff, input + i, *buffSz);
Vanger 0:b86d15c6ba29 693
Vanger 0:b86d15c6ba29 694 *inOutIdx = i + length;
Vanger 0:b86d15c6ba29 695 return 0;
Vanger 0:b86d15c6ba29 696 }
Vanger 0:b86d15c6ba29 697
Vanger 0:b86d15c6ba29 698 static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
Vanger 0:b86d15c6ba29 699 RsaKey* key, word32 inSz)
Vanger 0:b86d15c6ba29 700 {
Vanger 0:b86d15c6ba29 701 int version, length;
Vanger 0:b86d15c6ba29 702 void* h = key->heap;
Vanger 0:b86d15c6ba29 703
Vanger 0:b86d15c6ba29 704 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 705 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 706
Vanger 0:b86d15c6ba29 707 if (GetMyVersion(input, inOutIdx, &version) < 0)
Vanger 0:b86d15c6ba29 708 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 709
Vanger 0:b86d15c6ba29 710 key->type = RSA_PRIVATE;
Vanger 0:b86d15c6ba29 711
Vanger 0:b86d15c6ba29 712 if (GetCaviumInt(&key->c_n, &key->c_nSz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 713 GetCaviumInt(&key->c_e, &key->c_eSz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 714 GetCaviumInt(&key->c_d, &key->c_dSz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 715 GetCaviumInt(&key->c_p, &key->c_pSz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 716 GetCaviumInt(&key->c_q, &key->c_qSz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 717 GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 718 GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 ||
Vanger 0:b86d15c6ba29 719 GetCaviumInt(&key->c_u, &key->c_uSz, input, inOutIdx, inSz, h) < 0 )
Vanger 0:b86d15c6ba29 720 return ASN_RSA_KEY_E;
Vanger 0:b86d15c6ba29 721
Vanger 0:b86d15c6ba29 722 return 0;
Vanger 0:b86d15c6ba29 723 }
Vanger 0:b86d15c6ba29 724
Vanger 0:b86d15c6ba29 725
Vanger 0:b86d15c6ba29 726 #endif /* HAVE_CAVIUM */
Vanger 0:b86d15c6ba29 727
Vanger 0:b86d15c6ba29 728 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
Vanger 0:b86d15c6ba29 729 word32 inSz)
Vanger 0:b86d15c6ba29 730 {
Vanger 0:b86d15c6ba29 731 int version, length;
Vanger 0:b86d15c6ba29 732
Vanger 0:b86d15c6ba29 733 #ifdef HAVE_CAVIUM
Vanger 0:b86d15c6ba29 734 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
Vanger 0:b86d15c6ba29 735 return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz);
Vanger 0:b86d15c6ba29 736 #endif
Vanger 0:b86d15c6ba29 737
Vanger 0:b86d15c6ba29 738 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 739 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 740
Vanger 0:b86d15c6ba29 741 if (GetMyVersion(input, inOutIdx, &version) < 0)
Vanger 0:b86d15c6ba29 742 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 743
Vanger 0:b86d15c6ba29 744 key->type = RSA_PRIVATE;
Vanger 0:b86d15c6ba29 745
Vanger 0:b86d15c6ba29 746 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 747 GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 748 GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 749 GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 750 GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 751 GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 752 GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 753 GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
Vanger 0:b86d15c6ba29 754
Vanger 0:b86d15c6ba29 755 return 0;
Vanger 0:b86d15c6ba29 756 }
Vanger 0:b86d15c6ba29 757
Vanger 0:b86d15c6ba29 758 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 759
Vanger 0:b86d15c6ba29 760 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
Vanger 0:b86d15c6ba29 761 int ToTraditional(byte* input, word32 sz)
Vanger 0:b86d15c6ba29 762 {
Vanger 0:b86d15c6ba29 763 word32 inOutIdx = 0, oid;
Vanger 0:b86d15c6ba29 764 int version, length;
Vanger 0:b86d15c6ba29 765
Vanger 0:b86d15c6ba29 766 if (GetSequence(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 767 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 768
Vanger 0:b86d15c6ba29 769 if (GetMyVersion(input, &inOutIdx, &version) < 0)
Vanger 0:b86d15c6ba29 770 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 771
Vanger 0:b86d15c6ba29 772 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 773 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 774
Vanger 0:b86d15c6ba29 775 if (input[inOutIdx] == ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 776 /* pkcs8 ecc uses slightly different format */
Vanger 0:b86d15c6ba29 777 inOutIdx++; /* past id */
Vanger 0:b86d15c6ba29 778 if (GetLength(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 779 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 780 inOutIdx += length; /* over sub id, key input will verify */
Vanger 0:b86d15c6ba29 781 }
Vanger 0:b86d15c6ba29 782
Vanger 0:b86d15c6ba29 783 if (input[inOutIdx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 784 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 785
Vanger 0:b86d15c6ba29 786 if (GetLength(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 787 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 788
Vanger 0:b86d15c6ba29 789 XMEMMOVE(input, input + inOutIdx, length);
Vanger 0:b86d15c6ba29 790
Vanger 0:b86d15c6ba29 791 return length;
Vanger 0:b86d15c6ba29 792 }
Vanger 0:b86d15c6ba29 793
Vanger 0:b86d15c6ba29 794
Vanger 0:b86d15c6ba29 795 #ifndef NO_PWDBASED
Vanger 0:b86d15c6ba29 796
Vanger 0:b86d15c6ba29 797 /* Check To see if PKCS version algo is supported, set id if it is return 0
Vanger 0:b86d15c6ba29 798 < 0 on error */
Vanger 0:b86d15c6ba29 799 static int CheckAlgo(int first, int second, int* id, int* version)
Vanger 0:b86d15c6ba29 800 {
Vanger 0:b86d15c6ba29 801 *id = ALGO_ID_E;
Vanger 0:b86d15c6ba29 802 *version = PKCS5; /* default */
Vanger 0:b86d15c6ba29 803
Vanger 0:b86d15c6ba29 804 if (first == 1) {
Vanger 0:b86d15c6ba29 805 switch (second) {
Vanger 0:b86d15c6ba29 806 case 1:
Vanger 0:b86d15c6ba29 807 *id = PBE_SHA1_RC4_128;
Vanger 0:b86d15c6ba29 808 *version = PKCS12;
Vanger 0:b86d15c6ba29 809 return 0;
Vanger 0:b86d15c6ba29 810 case 3:
Vanger 0:b86d15c6ba29 811 *id = PBE_SHA1_DES3;
Vanger 0:b86d15c6ba29 812 *version = PKCS12;
Vanger 0:b86d15c6ba29 813 return 0;
Vanger 0:b86d15c6ba29 814 default:
Vanger 0:b86d15c6ba29 815 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 816 }
Vanger 0:b86d15c6ba29 817 }
Vanger 0:b86d15c6ba29 818
Vanger 0:b86d15c6ba29 819 if (first != PKCS5)
Vanger 0:b86d15c6ba29 820 return ASN_INPUT_E; /* VERSION ERROR */
Vanger 0:b86d15c6ba29 821
Vanger 0:b86d15c6ba29 822 if (second == PBES2) {
Vanger 0:b86d15c6ba29 823 *version = PKCS5v2;
Vanger 0:b86d15c6ba29 824 return 0;
Vanger 0:b86d15c6ba29 825 }
Vanger 0:b86d15c6ba29 826
Vanger 0:b86d15c6ba29 827 switch (second) {
Vanger 0:b86d15c6ba29 828 case 3: /* see RFC 2898 for ids */
Vanger 0:b86d15c6ba29 829 *id = PBE_MD5_DES;
Vanger 0:b86d15c6ba29 830 return 0;
Vanger 0:b86d15c6ba29 831 case 10:
Vanger 0:b86d15c6ba29 832 *id = PBE_SHA1_DES;
Vanger 0:b86d15c6ba29 833 return 0;
Vanger 0:b86d15c6ba29 834 default:
Vanger 0:b86d15c6ba29 835 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 836
Vanger 0:b86d15c6ba29 837 }
Vanger 0:b86d15c6ba29 838 }
Vanger 0:b86d15c6ba29 839
Vanger 0:b86d15c6ba29 840
Vanger 0:b86d15c6ba29 841 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
Vanger 0:b86d15c6ba29 842 < 0 on error */
Vanger 0:b86d15c6ba29 843 static int CheckAlgoV2(int oid, int* id)
Vanger 0:b86d15c6ba29 844 {
Vanger 0:b86d15c6ba29 845 switch (oid) {
Vanger 0:b86d15c6ba29 846 case 69:
Vanger 0:b86d15c6ba29 847 *id = PBE_SHA1_DES;
Vanger 0:b86d15c6ba29 848 return 0;
Vanger 0:b86d15c6ba29 849 case 652:
Vanger 0:b86d15c6ba29 850 *id = PBE_SHA1_DES3;
Vanger 0:b86d15c6ba29 851 return 0;
Vanger 0:b86d15c6ba29 852 default:
Vanger 0:b86d15c6ba29 853 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 854
Vanger 0:b86d15c6ba29 855 }
Vanger 0:b86d15c6ba29 856 }
Vanger 0:b86d15c6ba29 857
Vanger 0:b86d15c6ba29 858
Vanger 0:b86d15c6ba29 859 /* Decrypt intput in place from parameters based on id */
Vanger 0:b86d15c6ba29 860 static int DecryptKey(const char* password, int passwordSz, byte* salt,
Vanger 0:b86d15c6ba29 861 int saltSz, int iterations, int id, byte* input,
Vanger 0:b86d15c6ba29 862 int length, int version, byte* cbcIv)
Vanger 0:b86d15c6ba29 863 {
Vanger 0:b86d15c6ba29 864 int typeH;
Vanger 0:b86d15c6ba29 865 int derivedLen;
Vanger 0:b86d15c6ba29 866 int decryptionType;
Vanger 0:b86d15c6ba29 867 int ret = 0;
Vanger 0:b86d15c6ba29 868 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 869 byte* key;
Vanger 0:b86d15c6ba29 870 #else
Vanger 0:b86d15c6ba29 871 byte key[MAX_KEY_SIZE];
Vanger 0:b86d15c6ba29 872 #endif
Vanger 0:b86d15c6ba29 873
Vanger 0:b86d15c6ba29 874 switch (id) {
Vanger 0:b86d15c6ba29 875 case PBE_MD5_DES:
Vanger 0:b86d15c6ba29 876 typeH = MD5;
Vanger 0:b86d15c6ba29 877 derivedLen = 16; /* may need iv for v1.5 */
Vanger 0:b86d15c6ba29 878 decryptionType = DES_TYPE;
Vanger 0:b86d15c6ba29 879 break;
Vanger 0:b86d15c6ba29 880
Vanger 0:b86d15c6ba29 881 case PBE_SHA1_DES:
Vanger 0:b86d15c6ba29 882 typeH = SHA;
Vanger 0:b86d15c6ba29 883 derivedLen = 16; /* may need iv for v1.5 */
Vanger 0:b86d15c6ba29 884 decryptionType = DES_TYPE;
Vanger 0:b86d15c6ba29 885 break;
Vanger 0:b86d15c6ba29 886
Vanger 0:b86d15c6ba29 887 case PBE_SHA1_DES3:
Vanger 0:b86d15c6ba29 888 typeH = SHA;
Vanger 0:b86d15c6ba29 889 derivedLen = 32; /* may need iv for v1.5 */
Vanger 0:b86d15c6ba29 890 decryptionType = DES3_TYPE;
Vanger 0:b86d15c6ba29 891 break;
Vanger 0:b86d15c6ba29 892
Vanger 0:b86d15c6ba29 893 case PBE_SHA1_RC4_128:
Vanger 0:b86d15c6ba29 894 typeH = SHA;
Vanger 0:b86d15c6ba29 895 derivedLen = 16;
Vanger 0:b86d15c6ba29 896 decryptionType = RC4_TYPE;
Vanger 0:b86d15c6ba29 897 break;
Vanger 0:b86d15c6ba29 898
Vanger 0:b86d15c6ba29 899 default:
Vanger 0:b86d15c6ba29 900 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 901 }
Vanger 0:b86d15c6ba29 902
Vanger 0:b86d15c6ba29 903 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 904 key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 905 if (key == NULL)
Vanger 0:b86d15c6ba29 906 return MEMORY_E;
Vanger 0:b86d15c6ba29 907 #endif
Vanger 0:b86d15c6ba29 908
Vanger 0:b86d15c6ba29 909 if (version == PKCS5v2)
Vanger 0:b86d15c6ba29 910 ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations,
Vanger 0:b86d15c6ba29 911 derivedLen, typeH);
Vanger 0:b86d15c6ba29 912 else if (version == PKCS5)
Vanger 0:b86d15c6ba29 913 ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
Vanger 0:b86d15c6ba29 914 derivedLen, typeH);
Vanger 0:b86d15c6ba29 915 else if (version == PKCS12) {
Vanger 0:b86d15c6ba29 916 int i, idx = 0;
Vanger 0:b86d15c6ba29 917 byte unicodePasswd[MAX_UNICODE_SZ];
Vanger 0:b86d15c6ba29 918
Vanger 0:b86d15c6ba29 919 if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
Vanger 0:b86d15c6ba29 920 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 921 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 922 #endif
Vanger 0:b86d15c6ba29 923 return UNICODE_SIZE_E;
Vanger 0:b86d15c6ba29 924 }
Vanger 0:b86d15c6ba29 925
Vanger 0:b86d15c6ba29 926 for (i = 0; i < passwordSz; i++) {
Vanger 0:b86d15c6ba29 927 unicodePasswd[idx++] = 0x00;
Vanger 0:b86d15c6ba29 928 unicodePasswd[idx++] = (byte)password[i];
Vanger 0:b86d15c6ba29 929 }
Vanger 0:b86d15c6ba29 930 /* add trailing NULL */
Vanger 0:b86d15c6ba29 931 unicodePasswd[idx++] = 0x00;
Vanger 0:b86d15c6ba29 932 unicodePasswd[idx++] = 0x00;
Vanger 0:b86d15c6ba29 933
Vanger 0:b86d15c6ba29 934 ret = PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
Vanger 0:b86d15c6ba29 935 iterations, derivedLen, typeH, 1);
Vanger 0:b86d15c6ba29 936 if (decryptionType != RC4_TYPE)
Vanger 0:b86d15c6ba29 937 ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
Vanger 0:b86d15c6ba29 938 iterations, 8, typeH, 2);
Vanger 0:b86d15c6ba29 939 }
Vanger 0:b86d15c6ba29 940 else {
Vanger 0:b86d15c6ba29 941 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 942 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 943 #endif
Vanger 0:b86d15c6ba29 944 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 945 }
Vanger 0:b86d15c6ba29 946
Vanger 0:b86d15c6ba29 947 if (ret != 0) {
Vanger 0:b86d15c6ba29 948 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 949 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 950 #endif
Vanger 0:b86d15c6ba29 951 return ret;
Vanger 0:b86d15c6ba29 952 }
Vanger 0:b86d15c6ba29 953
Vanger 0:b86d15c6ba29 954 switch (decryptionType) {
Vanger 0:b86d15c6ba29 955 #ifndef NO_DES3
Vanger 0:b86d15c6ba29 956 case DES_TYPE:
Vanger 0:b86d15c6ba29 957 {
Vanger 0:b86d15c6ba29 958 Des dec;
Vanger 0:b86d15c6ba29 959 byte* desIv = key + 8;
Vanger 0:b86d15c6ba29 960
Vanger 0:b86d15c6ba29 961 if (version == PKCS5v2 || version == PKCS12)
Vanger 0:b86d15c6ba29 962 desIv = cbcIv;
Vanger 0:b86d15c6ba29 963
Vanger 0:b86d15c6ba29 964 ret = Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
Vanger 0:b86d15c6ba29 965 if (ret != 0) {
Vanger 0:b86d15c6ba29 966 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 967 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 968 #endif
Vanger 0:b86d15c6ba29 969 return ret;
Vanger 0:b86d15c6ba29 970 }
Vanger 0:b86d15c6ba29 971
Vanger 0:b86d15c6ba29 972 Des_CbcDecrypt(&dec, input, input, length);
Vanger 0:b86d15c6ba29 973 break;
Vanger 0:b86d15c6ba29 974 }
Vanger 0:b86d15c6ba29 975
Vanger 0:b86d15c6ba29 976 case DES3_TYPE:
Vanger 0:b86d15c6ba29 977 {
Vanger 0:b86d15c6ba29 978 Des3 dec;
Vanger 0:b86d15c6ba29 979 byte* desIv = key + 24;
Vanger 0:b86d15c6ba29 980
Vanger 0:b86d15c6ba29 981 if (version == PKCS5v2 || version == PKCS12)
Vanger 0:b86d15c6ba29 982 desIv = cbcIv;
Vanger 0:b86d15c6ba29 983 ret = Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
Vanger 0:b86d15c6ba29 984 if (ret != 0) {
Vanger 0:b86d15c6ba29 985 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 986 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 987 #endif
Vanger 0:b86d15c6ba29 988 return ret;
Vanger 0:b86d15c6ba29 989 }
Vanger 0:b86d15c6ba29 990 ret = Des3_CbcDecrypt(&dec, input, input, length);
Vanger 0:b86d15c6ba29 991 if (ret != 0) {
Vanger 0:b86d15c6ba29 992 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 993 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 994 #endif
Vanger 0:b86d15c6ba29 995 return ret;
Vanger 0:b86d15c6ba29 996 }
Vanger 0:b86d15c6ba29 997 break;
Vanger 0:b86d15c6ba29 998 }
Vanger 0:b86d15c6ba29 999 #endif
Vanger 0:b86d15c6ba29 1000 #ifndef NO_RC4
Vanger 0:b86d15c6ba29 1001 case RC4_TYPE:
Vanger 0:b86d15c6ba29 1002 {
Vanger 0:b86d15c6ba29 1003 Arc4 dec;
Vanger 0:b86d15c6ba29 1004
Vanger 0:b86d15c6ba29 1005 Arc4SetKey(&dec, key, derivedLen);
Vanger 0:b86d15c6ba29 1006 Arc4Process(&dec, input, input, length);
Vanger 0:b86d15c6ba29 1007 break;
Vanger 0:b86d15c6ba29 1008 }
Vanger 0:b86d15c6ba29 1009 #endif
Vanger 0:b86d15c6ba29 1010
Vanger 0:b86d15c6ba29 1011 default:
Vanger 0:b86d15c6ba29 1012 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1013 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1014 #endif
Vanger 0:b86d15c6ba29 1015 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1016 }
Vanger 0:b86d15c6ba29 1017
Vanger 0:b86d15c6ba29 1018 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1019 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1020 #endif
Vanger 0:b86d15c6ba29 1021
Vanger 0:b86d15c6ba29 1022 return 0;
Vanger 0:b86d15c6ba29 1023 }
Vanger 0:b86d15c6ba29 1024
Vanger 0:b86d15c6ba29 1025
Vanger 0:b86d15c6ba29 1026 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
Vanger 0:b86d15c6ba29 1027 of input */
Vanger 0:b86d15c6ba29 1028 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
Vanger 0:b86d15c6ba29 1029 {
Vanger 0:b86d15c6ba29 1030 word32 inOutIdx = 0, oid;
Vanger 0:b86d15c6ba29 1031 int first, second, length, version, saltSz, id;
Vanger 0:b86d15c6ba29 1032 int iterations = 0;
Vanger 0:b86d15c6ba29 1033 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1034 byte* salt = NULL;
Vanger 0:b86d15c6ba29 1035 byte* cbcIv = NULL;
Vanger 0:b86d15c6ba29 1036 #else
Vanger 0:b86d15c6ba29 1037 byte salt[MAX_SALT_SIZE];
Vanger 0:b86d15c6ba29 1038 byte cbcIv[MAX_IV_SIZE];
Vanger 0:b86d15c6ba29 1039 #endif
Vanger 0:b86d15c6ba29 1040
Vanger 0:b86d15c6ba29 1041 if (GetSequence(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 1042 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1043
Vanger 0:b86d15c6ba29 1044 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 1045 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1046
Vanger 0:b86d15c6ba29 1047 first = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */
Vanger 0:b86d15c6ba29 1048 second = input[inOutIdx - 1]; /* version.algo, algo id last byte */
Vanger 0:b86d15c6ba29 1049
Vanger 0:b86d15c6ba29 1050 if (CheckAlgo(first, second, &id, &version) < 0)
Vanger 0:b86d15c6ba29 1051 return ASN_INPUT_E; /* Algo ID error */
Vanger 0:b86d15c6ba29 1052
Vanger 0:b86d15c6ba29 1053 if (version == PKCS5v2) {
Vanger 0:b86d15c6ba29 1054
Vanger 0:b86d15c6ba29 1055 if (GetSequence(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 1056 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1057
Vanger 0:b86d15c6ba29 1058 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 1059 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1060
Vanger 0:b86d15c6ba29 1061 if (oid != PBKDF2_OID)
Vanger 0:b86d15c6ba29 1062 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1063 }
Vanger 0:b86d15c6ba29 1064
Vanger 0:b86d15c6ba29 1065 if (GetSequence(input, &inOutIdx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 1066 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1067
Vanger 0:b86d15c6ba29 1068 if (input[inOutIdx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 1069 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1070
Vanger 0:b86d15c6ba29 1071 if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
Vanger 0:b86d15c6ba29 1072 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1073
Vanger 0:b86d15c6ba29 1074 if (saltSz > MAX_SALT_SIZE)
Vanger 0:b86d15c6ba29 1075 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1076
Vanger 0:b86d15c6ba29 1077 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1078 salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1079 if (salt == NULL)
Vanger 0:b86d15c6ba29 1080 return MEMORY_E;
Vanger 0:b86d15c6ba29 1081 #endif
Vanger 0:b86d15c6ba29 1082
Vanger 0:b86d15c6ba29 1083 XMEMCPY(salt, &input[inOutIdx], saltSz);
Vanger 0:b86d15c6ba29 1084 inOutIdx += saltSz;
Vanger 0:b86d15c6ba29 1085
Vanger 0:b86d15c6ba29 1086 if (GetShortInt(input, &inOutIdx, &iterations) < 0) {
Vanger 0:b86d15c6ba29 1087 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1088 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1089 #endif
Vanger 0:b86d15c6ba29 1090 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1091 }
Vanger 0:b86d15c6ba29 1092
Vanger 0:b86d15c6ba29 1093 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1094 cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1095 if (cbcIv == NULL) {
Vanger 0:b86d15c6ba29 1096 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1097 return MEMORY_E;
Vanger 0:b86d15c6ba29 1098 }
Vanger 0:b86d15c6ba29 1099 #endif
Vanger 0:b86d15c6ba29 1100
Vanger 0:b86d15c6ba29 1101 if (version == PKCS5v2) {
Vanger 0:b86d15c6ba29 1102 /* get encryption algo */
Vanger 0:b86d15c6ba29 1103 if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) {
Vanger 0:b86d15c6ba29 1104 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1105 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1106 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1107 #endif
Vanger 0:b86d15c6ba29 1108 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1109 }
Vanger 0:b86d15c6ba29 1110
Vanger 0:b86d15c6ba29 1111 if (CheckAlgoV2(oid, &id) < 0) {
Vanger 0:b86d15c6ba29 1112 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1113 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1114 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1115 #endif
Vanger 0:b86d15c6ba29 1116 return ASN_PARSE_E; /* PKCS v2 algo id error */
Vanger 0:b86d15c6ba29 1117 }
Vanger 0:b86d15c6ba29 1118
Vanger 0:b86d15c6ba29 1119 if (input[inOutIdx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 1120 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1121 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1122 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1123 #endif
Vanger 0:b86d15c6ba29 1124 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1125 }
Vanger 0:b86d15c6ba29 1126
Vanger 0:b86d15c6ba29 1127 if (GetLength(input, &inOutIdx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 1128 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1129 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1130 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1131 #endif
Vanger 0:b86d15c6ba29 1132 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1133 }
Vanger 0:b86d15c6ba29 1134
Vanger 0:b86d15c6ba29 1135 XMEMCPY(cbcIv, &input[inOutIdx], length);
Vanger 0:b86d15c6ba29 1136 inOutIdx += length;
Vanger 0:b86d15c6ba29 1137 }
Vanger 0:b86d15c6ba29 1138
Vanger 0:b86d15c6ba29 1139 if (input[inOutIdx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 1140 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1141 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1142 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1143 #endif
Vanger 0:b86d15c6ba29 1144 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1145 }
Vanger 0:b86d15c6ba29 1146
Vanger 0:b86d15c6ba29 1147 if (GetLength(input, &inOutIdx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 1148 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1149 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1150 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1151 #endif
Vanger 0:b86d15c6ba29 1152 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1153 }
Vanger 0:b86d15c6ba29 1154
Vanger 0:b86d15c6ba29 1155 if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
Vanger 0:b86d15c6ba29 1156 input + inOutIdx, length, version, cbcIv) < 0) {
Vanger 0:b86d15c6ba29 1157 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1158 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1159 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1160 #endif
Vanger 0:b86d15c6ba29 1161 return ASN_INPUT_E; /* decrypt failure */
Vanger 0:b86d15c6ba29 1162 }
Vanger 0:b86d15c6ba29 1163
Vanger 0:b86d15c6ba29 1164 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1165 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1166 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1167 #endif
Vanger 0:b86d15c6ba29 1168
Vanger 0:b86d15c6ba29 1169 XMEMMOVE(input, input + inOutIdx, length);
Vanger 0:b86d15c6ba29 1170 return ToTraditional(input, length);
Vanger 0:b86d15c6ba29 1171 }
Vanger 0:b86d15c6ba29 1172
Vanger 0:b86d15c6ba29 1173 #endif /* NO_PWDBASED */
Vanger 0:b86d15c6ba29 1174
Vanger 0:b86d15c6ba29 1175 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1176
Vanger 0:b86d15c6ba29 1177 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
Vanger 0:b86d15c6ba29 1178 word32 inSz)
Vanger 0:b86d15c6ba29 1179 {
Vanger 0:b86d15c6ba29 1180 int length;
Vanger 0:b86d15c6ba29 1181
Vanger 0:b86d15c6ba29 1182 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1183 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1184
Vanger 0:b86d15c6ba29 1185 key->type = RSA_PUBLIC;
Vanger 0:b86d15c6ba29 1186
Vanger 0:b86d15c6ba29 1187 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
Vanger 0:b86d15c6ba29 1188 {
Vanger 0:b86d15c6ba29 1189 byte b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 1190 if (b != ASN_INTEGER) {
Vanger 0:b86d15c6ba29 1191 /* not from decoded cert, will have algo id, skip past */
Vanger 0:b86d15c6ba29 1192 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1193 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1194
Vanger 0:b86d15c6ba29 1195 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 1196 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 1197 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 1198
Vanger 0:b86d15c6ba29 1199 if (GetLength(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1200 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1201
Vanger 0:b86d15c6ba29 1202 *inOutIdx += length; /* skip past */
Vanger 0:b86d15c6ba29 1203
Vanger 0:b86d15c6ba29 1204 /* could have NULL tag and 0 terminator, but may not */
Vanger 0:b86d15c6ba29 1205 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 1206
Vanger 0:b86d15c6ba29 1207 if (b == ASN_TAG_NULL) {
Vanger 0:b86d15c6ba29 1208 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 1209 if (b != 0)
Vanger 0:b86d15c6ba29 1210 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 1211 }
Vanger 0:b86d15c6ba29 1212 else
Vanger 0:b86d15c6ba29 1213 /* go back, didn't have it */
Vanger 0:b86d15c6ba29 1214 (*inOutIdx)--;
Vanger 0:b86d15c6ba29 1215
Vanger 0:b86d15c6ba29 1216 /* should have bit tag length and seq next */
Vanger 0:b86d15c6ba29 1217 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 1218 if (b != ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 1219 return ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 1220
Vanger 0:b86d15c6ba29 1221 if (GetLength(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1222 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1223
Vanger 0:b86d15c6ba29 1224 /* could have 0 */
Vanger 0:b86d15c6ba29 1225 b = input[(*inOutIdx)++];
Vanger 0:b86d15c6ba29 1226 if (b != 0)
Vanger 0:b86d15c6ba29 1227 (*inOutIdx)--;
Vanger 0:b86d15c6ba29 1228
Vanger 0:b86d15c6ba29 1229 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1230 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1231 } /* end if */
Vanger 0:b86d15c6ba29 1232 } /* openssl var block */
Vanger 0:b86d15c6ba29 1233 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1234
Vanger 0:b86d15c6ba29 1235 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1236 GetInt(&key->e, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
Vanger 0:b86d15c6ba29 1237
Vanger 0:b86d15c6ba29 1238 return 0;
Vanger 0:b86d15c6ba29 1239 }
Vanger 0:b86d15c6ba29 1240
Vanger 0:b86d15c6ba29 1241 int RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz,
Vanger 0:b86d15c6ba29 1242 RsaKey* key)
Vanger 0:b86d15c6ba29 1243 {
Vanger 0:b86d15c6ba29 1244 if (n == NULL || e == NULL || key == NULL)
Vanger 0:b86d15c6ba29 1245 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1246
Vanger 0:b86d15c6ba29 1247 key->type = RSA_PUBLIC;
Vanger 0:b86d15c6ba29 1248
Vanger 0:b86d15c6ba29 1249 if (mp_init(&key->n) != MP_OKAY)
Vanger 0:b86d15c6ba29 1250 return MP_INIT_E;
Vanger 0:b86d15c6ba29 1251
Vanger 0:b86d15c6ba29 1252 if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
Vanger 0:b86d15c6ba29 1253 mp_clear(&key->n);
Vanger 0:b86d15c6ba29 1254 return ASN_GETINT_E;
Vanger 0:b86d15c6ba29 1255 }
Vanger 0:b86d15c6ba29 1256
Vanger 0:b86d15c6ba29 1257 if (mp_init(&key->e) != MP_OKAY) {
Vanger 0:b86d15c6ba29 1258 mp_clear(&key->n);
Vanger 0:b86d15c6ba29 1259 return MP_INIT_E;
Vanger 0:b86d15c6ba29 1260 }
Vanger 0:b86d15c6ba29 1261
Vanger 0:b86d15c6ba29 1262 if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
Vanger 0:b86d15c6ba29 1263 mp_clear(&key->n);
Vanger 0:b86d15c6ba29 1264 mp_clear(&key->e);
Vanger 0:b86d15c6ba29 1265 return ASN_GETINT_E;
Vanger 0:b86d15c6ba29 1266 }
Vanger 0:b86d15c6ba29 1267
Vanger 0:b86d15c6ba29 1268 return 0;
Vanger 0:b86d15c6ba29 1269 }
Vanger 0:b86d15c6ba29 1270
Vanger 0:b86d15c6ba29 1271 #endif
Vanger 0:b86d15c6ba29 1272
Vanger 0:b86d15c6ba29 1273 #ifndef NO_DH
Vanger 0:b86d15c6ba29 1274
Vanger 0:b86d15c6ba29 1275 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
Vanger 0:b86d15c6ba29 1276 {
Vanger 0:b86d15c6ba29 1277 int length;
Vanger 0:b86d15c6ba29 1278
Vanger 0:b86d15c6ba29 1279 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1280 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1281
Vanger 0:b86d15c6ba29 1282 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1283 GetInt(&key->g, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E;
Vanger 0:b86d15c6ba29 1284
Vanger 0:b86d15c6ba29 1285 return 0;
Vanger 0:b86d15c6ba29 1286 }
Vanger 0:b86d15c6ba29 1287
Vanger 0:b86d15c6ba29 1288 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
Vanger 0:b86d15c6ba29 1289 {
Vanger 0:b86d15c6ba29 1290 if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0)
Vanger 0:b86d15c6ba29 1291 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 1292
Vanger 0:b86d15c6ba29 1293 /* may have leading 0 */
Vanger 0:b86d15c6ba29 1294 if (p[0] == 0) {
Vanger 0:b86d15c6ba29 1295 pSz--; p++;
Vanger 0:b86d15c6ba29 1296 }
Vanger 0:b86d15c6ba29 1297
Vanger 0:b86d15c6ba29 1298 if (g[0] == 0) {
Vanger 0:b86d15c6ba29 1299 gSz--; g++;
Vanger 0:b86d15c6ba29 1300 }
Vanger 0:b86d15c6ba29 1301
Vanger 0:b86d15c6ba29 1302 if (mp_init(&key->p) != MP_OKAY)
Vanger 0:b86d15c6ba29 1303 return MP_INIT_E;
Vanger 0:b86d15c6ba29 1304 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
Vanger 0:b86d15c6ba29 1305 mp_clear(&key->p);
Vanger 0:b86d15c6ba29 1306 return ASN_DH_KEY_E;
Vanger 0:b86d15c6ba29 1307 }
Vanger 0:b86d15c6ba29 1308
Vanger 0:b86d15c6ba29 1309 if (mp_init(&key->g) != MP_OKAY) {
Vanger 0:b86d15c6ba29 1310 mp_clear(&key->p);
Vanger 0:b86d15c6ba29 1311 return MP_INIT_E;
Vanger 0:b86d15c6ba29 1312 }
Vanger 0:b86d15c6ba29 1313 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
Vanger 0:b86d15c6ba29 1314 mp_clear(&key->g);
Vanger 0:b86d15c6ba29 1315 mp_clear(&key->p);
Vanger 0:b86d15c6ba29 1316 return ASN_DH_KEY_E;
Vanger 0:b86d15c6ba29 1317 }
Vanger 0:b86d15c6ba29 1318
Vanger 0:b86d15c6ba29 1319 return 0;
Vanger 0:b86d15c6ba29 1320 }
Vanger 0:b86d15c6ba29 1321
Vanger 0:b86d15c6ba29 1322
Vanger 0:b86d15c6ba29 1323 int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
Vanger 0:b86d15c6ba29 1324 byte* g, word32* gInOutSz)
Vanger 0:b86d15c6ba29 1325 {
Vanger 0:b86d15c6ba29 1326 word32 i = 0;
Vanger 0:b86d15c6ba29 1327 byte b;
Vanger 0:b86d15c6ba29 1328 int length;
Vanger 0:b86d15c6ba29 1329
Vanger 0:b86d15c6ba29 1330 if (GetSequence(input, &i, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1331 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1332
Vanger 0:b86d15c6ba29 1333 b = input[i++];
Vanger 0:b86d15c6ba29 1334 if (b != ASN_INTEGER)
Vanger 0:b86d15c6ba29 1335 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1336
Vanger 0:b86d15c6ba29 1337 if (GetLength(input, &i, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1338 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1339
Vanger 0:b86d15c6ba29 1340 if ( (b = input[i++]) == 0x00)
Vanger 0:b86d15c6ba29 1341 length--;
Vanger 0:b86d15c6ba29 1342 else
Vanger 0:b86d15c6ba29 1343 i--;
Vanger 0:b86d15c6ba29 1344
Vanger 0:b86d15c6ba29 1345 if (length <= (int)*pInOutSz) {
Vanger 0:b86d15c6ba29 1346 XMEMCPY(p, &input[i], length);
Vanger 0:b86d15c6ba29 1347 *pInOutSz = length;
Vanger 0:b86d15c6ba29 1348 }
Vanger 0:b86d15c6ba29 1349 else
Vanger 0:b86d15c6ba29 1350 return BUFFER_E;
Vanger 0:b86d15c6ba29 1351
Vanger 0:b86d15c6ba29 1352 i += length;
Vanger 0:b86d15c6ba29 1353
Vanger 0:b86d15c6ba29 1354 b = input[i++];
Vanger 0:b86d15c6ba29 1355 if (b != ASN_INTEGER)
Vanger 0:b86d15c6ba29 1356 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1357
Vanger 0:b86d15c6ba29 1358 if (GetLength(input, &i, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1359 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1360
Vanger 0:b86d15c6ba29 1361 if (length <= (int)*gInOutSz) {
Vanger 0:b86d15c6ba29 1362 XMEMCPY(g, &input[i], length);
Vanger 0:b86d15c6ba29 1363 *gInOutSz = length;
Vanger 0:b86d15c6ba29 1364 }
Vanger 0:b86d15c6ba29 1365 else
Vanger 0:b86d15c6ba29 1366 return BUFFER_E;
Vanger 0:b86d15c6ba29 1367
Vanger 0:b86d15c6ba29 1368 return 0;
Vanger 0:b86d15c6ba29 1369 }
Vanger 0:b86d15c6ba29 1370
Vanger 0:b86d15c6ba29 1371 #endif /* NO_DH */
Vanger 0:b86d15c6ba29 1372
Vanger 0:b86d15c6ba29 1373
Vanger 0:b86d15c6ba29 1374 #ifndef NO_DSA
Vanger 0:b86d15c6ba29 1375
Vanger 0:b86d15c6ba29 1376 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
Vanger 0:b86d15c6ba29 1377 word32 inSz)
Vanger 0:b86d15c6ba29 1378 {
Vanger 0:b86d15c6ba29 1379 int length;
Vanger 0:b86d15c6ba29 1380
Vanger 0:b86d15c6ba29 1381 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1382 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1383
Vanger 0:b86d15c6ba29 1384 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1385 GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1386 GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1387 GetInt(&key->y, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E;
Vanger 0:b86d15c6ba29 1388
Vanger 0:b86d15c6ba29 1389 key->type = DSA_PUBLIC;
Vanger 0:b86d15c6ba29 1390 return 0;
Vanger 0:b86d15c6ba29 1391 }
Vanger 0:b86d15c6ba29 1392
Vanger 0:b86d15c6ba29 1393
Vanger 0:b86d15c6ba29 1394 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
Vanger 0:b86d15c6ba29 1395 word32 inSz)
Vanger 0:b86d15c6ba29 1396 {
Vanger 0:b86d15c6ba29 1397 int length, version;
Vanger 0:b86d15c6ba29 1398
Vanger 0:b86d15c6ba29 1399 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 1400 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1401
Vanger 0:b86d15c6ba29 1402 if (GetMyVersion(input, inOutIdx, &version) < 0)
Vanger 0:b86d15c6ba29 1403 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1404
Vanger 0:b86d15c6ba29 1405 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1406 GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1407 GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1408 GetInt(&key->y, input, inOutIdx, inSz) < 0 ||
Vanger 0:b86d15c6ba29 1409 GetInt(&key->x, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E;
Vanger 0:b86d15c6ba29 1410
Vanger 0:b86d15c6ba29 1411 key->type = DSA_PRIVATE;
Vanger 0:b86d15c6ba29 1412 return 0;
Vanger 0:b86d15c6ba29 1413 }
Vanger 0:b86d15c6ba29 1414
Vanger 0:b86d15c6ba29 1415 #endif /* NO_DSA */
Vanger 0:b86d15c6ba29 1416
Vanger 0:b86d15c6ba29 1417
Vanger 0:b86d15c6ba29 1418 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
Vanger 0:b86d15c6ba29 1419 {
Vanger 0:b86d15c6ba29 1420 cert->publicKey = 0;
Vanger 0:b86d15c6ba29 1421 cert->pubKeySize = 0;
Vanger 0:b86d15c6ba29 1422 cert->pubKeyStored = 0;
Vanger 0:b86d15c6ba29 1423 cert->version = 0;
Vanger 0:b86d15c6ba29 1424 cert->signature = 0;
Vanger 0:b86d15c6ba29 1425 cert->subjectCN = 0;
Vanger 0:b86d15c6ba29 1426 cert->subjectCNLen = 0;
Vanger 0:b86d15c6ba29 1427 cert->subjectCNEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1428 cert->subjectCNStored = 0;
Vanger 0:b86d15c6ba29 1429 cert->altNames = NULL;
Vanger 0:b86d15c6ba29 1430 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 1431 cert->altEmailNames = NULL;
Vanger 0:b86d15c6ba29 1432 cert->permittedNames = NULL;
Vanger 0:b86d15c6ba29 1433 cert->excludedNames = NULL;
Vanger 0:b86d15c6ba29 1434 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 1435 cert->issuer[0] = '\0';
Vanger 0:b86d15c6ba29 1436 cert->subject[0] = '\0';
Vanger 0:b86d15c6ba29 1437 cert->source = source; /* don't own */
Vanger 0:b86d15c6ba29 1438 cert->srcIdx = 0;
Vanger 0:b86d15c6ba29 1439 cert->maxIdx = inSz; /* can't go over this index */
Vanger 0:b86d15c6ba29 1440 cert->heap = heap;
Vanger 0:b86d15c6ba29 1441 XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 1442 cert->serialSz = 0;
Vanger 0:b86d15c6ba29 1443 cert->extensions = 0;
Vanger 0:b86d15c6ba29 1444 cert->extensionsSz = 0;
Vanger 0:b86d15c6ba29 1445 cert->extensionsIdx = 0;
Vanger 0:b86d15c6ba29 1446 cert->extAuthInfo = NULL;
Vanger 0:b86d15c6ba29 1447 cert->extAuthInfoSz = 0;
Vanger 0:b86d15c6ba29 1448 cert->extCrlInfo = NULL;
Vanger 0:b86d15c6ba29 1449 cert->extCrlInfoSz = 0;
Vanger 0:b86d15c6ba29 1450 XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE);
Vanger 0:b86d15c6ba29 1451 cert->extSubjKeyIdSet = 0;
Vanger 0:b86d15c6ba29 1452 XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE);
Vanger 0:b86d15c6ba29 1453 cert->extAuthKeyIdSet = 0;
Vanger 0:b86d15c6ba29 1454 cert->extKeyUsageSet = 0;
Vanger 0:b86d15c6ba29 1455 cert->extKeyUsage = 0;
Vanger 0:b86d15c6ba29 1456 cert->extExtKeyUsageSet = 0;
Vanger 0:b86d15c6ba29 1457 cert->extExtKeyUsage = 0;
Vanger 0:b86d15c6ba29 1458 cert->isCA = 0;
Vanger 0:b86d15c6ba29 1459 #ifdef HAVE_PKCS7
Vanger 0:b86d15c6ba29 1460 cert->issuerRaw = NULL;
Vanger 0:b86d15c6ba29 1461 cert->issuerRawLen = 0;
Vanger 0:b86d15c6ba29 1462 #endif
Vanger 0:b86d15c6ba29 1463 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 1464 cert->subjectSN = 0;
Vanger 0:b86d15c6ba29 1465 cert->subjectSNLen = 0;
Vanger 0:b86d15c6ba29 1466 cert->subjectSNEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1467 cert->subjectC = 0;
Vanger 0:b86d15c6ba29 1468 cert->subjectCLen = 0;
Vanger 0:b86d15c6ba29 1469 cert->subjectCEnc = CTC_PRINTABLE;
Vanger 0:b86d15c6ba29 1470 cert->subjectL = 0;
Vanger 0:b86d15c6ba29 1471 cert->subjectLLen = 0;
Vanger 0:b86d15c6ba29 1472 cert->subjectLEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1473 cert->subjectST = 0;
Vanger 0:b86d15c6ba29 1474 cert->subjectSTLen = 0;
Vanger 0:b86d15c6ba29 1475 cert->subjectSTEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1476 cert->subjectO = 0;
Vanger 0:b86d15c6ba29 1477 cert->subjectOLen = 0;
Vanger 0:b86d15c6ba29 1478 cert->subjectOEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1479 cert->subjectOU = 0;
Vanger 0:b86d15c6ba29 1480 cert->subjectOULen = 0;
Vanger 0:b86d15c6ba29 1481 cert->subjectOUEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 1482 cert->subjectEmail = 0;
Vanger 0:b86d15c6ba29 1483 cert->subjectEmailLen = 0;
Vanger 0:b86d15c6ba29 1484 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 1485 cert->beforeDate = NULL;
Vanger 0:b86d15c6ba29 1486 cert->beforeDateLen = 0;
Vanger 0:b86d15c6ba29 1487 cert->afterDate = NULL;
Vanger 0:b86d15c6ba29 1488 cert->afterDateLen = 0;
Vanger 0:b86d15c6ba29 1489 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1490 XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
Vanger 0:b86d15c6ba29 1491 XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
Vanger 0:b86d15c6ba29 1492 cert->extBasicConstSet = 0;
Vanger 0:b86d15c6ba29 1493 cert->extBasicConstCrit = 0;
Vanger 0:b86d15c6ba29 1494 cert->extBasicConstPlSet = 0;
Vanger 0:b86d15c6ba29 1495 cert->pathLength = 0;
Vanger 0:b86d15c6ba29 1496 cert->extSubjAltNameSet = 0;
Vanger 0:b86d15c6ba29 1497 cert->extSubjAltNameCrit = 0;
Vanger 0:b86d15c6ba29 1498 cert->extAuthKeyIdCrit = 0;
Vanger 0:b86d15c6ba29 1499 cert->extSubjKeyIdCrit = 0;
Vanger 0:b86d15c6ba29 1500 cert->extKeyUsageCrit = 0;
Vanger 0:b86d15c6ba29 1501 cert->extExtKeyUsageCrit = 0;
Vanger 0:b86d15c6ba29 1502 cert->extExtKeyUsageSrc = NULL;
Vanger 0:b86d15c6ba29 1503 cert->extExtKeyUsageSz = 0;
Vanger 0:b86d15c6ba29 1504 cert->extExtKeyUsageCount = 0;
Vanger 0:b86d15c6ba29 1505 cert->extAuthKeyIdSrc = NULL;
Vanger 0:b86d15c6ba29 1506 cert->extAuthKeyIdSz = 0;
Vanger 0:b86d15c6ba29 1507 cert->extSubjKeyIdSrc = NULL;
Vanger 0:b86d15c6ba29 1508 cert->extSubjKeyIdSz = 0;
Vanger 0:b86d15c6ba29 1509 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1510 #if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS)
Vanger 0:b86d15c6ba29 1511 cert->extNameConstraintSet = 0;
Vanger 0:b86d15c6ba29 1512 #endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 1513 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1514 cert->pkCurveOID = 0;
Vanger 0:b86d15c6ba29 1515 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1516 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 1517 cert->deviceTypeSz = 0;
Vanger 0:b86d15c6ba29 1518 cert->deviceType = NULL;
Vanger 0:b86d15c6ba29 1519 cert->hwTypeSz = 0;
Vanger 0:b86d15c6ba29 1520 cert->hwType = NULL;
Vanger 0:b86d15c6ba29 1521 cert->hwSerialNumSz = 0;
Vanger 0:b86d15c6ba29 1522 cert->hwSerialNum = NULL;
Vanger 0:b86d15c6ba29 1523 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1524 cert->extCertPolicySet = 0;
Vanger 0:b86d15c6ba29 1525 cert->extCertPolicyCrit = 0;
Vanger 0:b86d15c6ba29 1526 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1527 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 1528 }
Vanger 0:b86d15c6ba29 1529
Vanger 0:b86d15c6ba29 1530
Vanger 0:b86d15c6ba29 1531 void FreeAltNames(DNS_entry* altNames, void* heap)
Vanger 0:b86d15c6ba29 1532 {
Vanger 0:b86d15c6ba29 1533 (void)heap;
Vanger 0:b86d15c6ba29 1534
Vanger 0:b86d15c6ba29 1535 while (altNames) {
Vanger 0:b86d15c6ba29 1536 DNS_entry* tmp = altNames->next;
Vanger 0:b86d15c6ba29 1537
Vanger 0:b86d15c6ba29 1538 XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 1539 XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 1540 altNames = tmp;
Vanger 0:b86d15c6ba29 1541 }
Vanger 0:b86d15c6ba29 1542 }
Vanger 0:b86d15c6ba29 1543
Vanger 0:b86d15c6ba29 1544 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 1545
Vanger 0:b86d15c6ba29 1546 void FreeNameSubtrees(Base_entry* names, void* heap)
Vanger 0:b86d15c6ba29 1547 {
Vanger 0:b86d15c6ba29 1548 (void)heap;
Vanger 0:b86d15c6ba29 1549
Vanger 0:b86d15c6ba29 1550 while (names) {
Vanger 0:b86d15c6ba29 1551 Base_entry* tmp = names->next;
Vanger 0:b86d15c6ba29 1552
Vanger 0:b86d15c6ba29 1553 XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 1554 XFREE(names, heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 1555 names = tmp;
Vanger 0:b86d15c6ba29 1556 }
Vanger 0:b86d15c6ba29 1557 }
Vanger 0:b86d15c6ba29 1558
Vanger 0:b86d15c6ba29 1559 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 1560
Vanger 0:b86d15c6ba29 1561 void FreeDecodedCert(DecodedCert* cert)
Vanger 0:b86d15c6ba29 1562 {
Vanger 0:b86d15c6ba29 1563 if (cert->subjectCNStored == 1)
Vanger 0:b86d15c6ba29 1564 XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
Vanger 0:b86d15c6ba29 1565 if (cert->pubKeyStored == 1)
Vanger 0:b86d15c6ba29 1566 XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 1567 if (cert->altNames)
Vanger 0:b86d15c6ba29 1568 FreeAltNames(cert->altNames, cert->heap);
Vanger 0:b86d15c6ba29 1569 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 1570 if (cert->altEmailNames)
Vanger 0:b86d15c6ba29 1571 FreeAltNames(cert->altEmailNames, cert->heap);
Vanger 0:b86d15c6ba29 1572 if (cert->permittedNames)
Vanger 0:b86d15c6ba29 1573 FreeNameSubtrees(cert->permittedNames, cert->heap);
Vanger 0:b86d15c6ba29 1574 if (cert->excludedNames)
Vanger 0:b86d15c6ba29 1575 FreeNameSubtrees(cert->excludedNames, cert->heap);
Vanger 0:b86d15c6ba29 1576 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 1577 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 1578 XFREE(cert->deviceType, cert->heap, 0);
Vanger 0:b86d15c6ba29 1579 XFREE(cert->hwType, cert->heap, 0);
Vanger 0:b86d15c6ba29 1580 XFREE(cert->hwSerialNum, cert->heap, 0);
Vanger 0:b86d15c6ba29 1581 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 1582 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1583 if (cert->issuerName.fullName != NULL)
Vanger 0:b86d15c6ba29 1584 XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 1585 if (cert->subjectName.fullName != NULL)
Vanger 0:b86d15c6ba29 1586 XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 1587 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1588 }
Vanger 0:b86d15c6ba29 1589
Vanger 0:b86d15c6ba29 1590
Vanger 0:b86d15c6ba29 1591 static int GetCertHeader(DecodedCert* cert)
Vanger 0:b86d15c6ba29 1592 {
Vanger 0:b86d15c6ba29 1593 int ret = 0, len;
Vanger 0:b86d15c6ba29 1594 byte serialTmp[EXTERNAL_SERIAL_SIZE];
Vanger 0:b86d15c6ba29 1595 #if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH)
Vanger 0:b86d15c6ba29 1596 mp_int* mpi = NULL;
Vanger 0:b86d15c6ba29 1597 #else
Vanger 0:b86d15c6ba29 1598 mp_int stack_mpi;
Vanger 0:b86d15c6ba29 1599 mp_int* mpi = &stack_mpi;
Vanger 0:b86d15c6ba29 1600 #endif
Vanger 0:b86d15c6ba29 1601
Vanger 0:b86d15c6ba29 1602 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1603 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1604
Vanger 0:b86d15c6ba29 1605 cert->certBegin = cert->srcIdx;
Vanger 0:b86d15c6ba29 1606
Vanger 0:b86d15c6ba29 1607 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1608 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1609 cert->sigIndex = len + cert->srcIdx;
Vanger 0:b86d15c6ba29 1610
Vanger 0:b86d15c6ba29 1611 if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
Vanger 0:b86d15c6ba29 1612 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1613
Vanger 0:b86d15c6ba29 1614 #if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH)
Vanger 0:b86d15c6ba29 1615 mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1616 if (mpi == NULL)
Vanger 0:b86d15c6ba29 1617 return MEMORY_E;
Vanger 0:b86d15c6ba29 1618 #endif
Vanger 0:b86d15c6ba29 1619
Vanger 0:b86d15c6ba29 1620 if (GetInt(mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 1621 #if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH)
Vanger 0:b86d15c6ba29 1622 XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1623 #endif
Vanger 0:b86d15c6ba29 1624 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1625 }
Vanger 0:b86d15c6ba29 1626
Vanger 0:b86d15c6ba29 1627 len = mp_unsigned_bin_size(mpi);
Vanger 0:b86d15c6ba29 1628 if (len < (int)sizeof(serialTmp)) {
Vanger 0:b86d15c6ba29 1629 if ( (ret = mp_to_unsigned_bin(mpi, serialTmp)) == MP_OKAY) {
Vanger 0:b86d15c6ba29 1630 XMEMCPY(cert->serial, serialTmp, len);
Vanger 0:b86d15c6ba29 1631 cert->serialSz = len;
Vanger 0:b86d15c6ba29 1632 }
Vanger 0:b86d15c6ba29 1633 }
Vanger 0:b86d15c6ba29 1634 mp_clear(mpi);
Vanger 0:b86d15c6ba29 1635
Vanger 0:b86d15c6ba29 1636 #if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH)
Vanger 0:b86d15c6ba29 1637 XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1638 #endif
Vanger 0:b86d15c6ba29 1639
Vanger 0:b86d15c6ba29 1640 return ret;
Vanger 0:b86d15c6ba29 1641 }
Vanger 0:b86d15c6ba29 1642
Vanger 0:b86d15c6ba29 1643 #if !defined(NO_RSA)
Vanger 0:b86d15c6ba29 1644 /* Store Rsa Key, may save later, Dsa could use in future */
Vanger 0:b86d15c6ba29 1645 static int StoreRsaKey(DecodedCert* cert)
Vanger 0:b86d15c6ba29 1646 {
Vanger 0:b86d15c6ba29 1647 int length;
Vanger 0:b86d15c6ba29 1648 word32 recvd = cert->srcIdx;
Vanger 0:b86d15c6ba29 1649
Vanger 0:b86d15c6ba29 1650 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1651 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1652
Vanger 0:b86d15c6ba29 1653 recvd = cert->srcIdx - recvd;
Vanger 0:b86d15c6ba29 1654 length += recvd;
Vanger 0:b86d15c6ba29 1655
Vanger 0:b86d15c6ba29 1656 while (recvd--)
Vanger 0:b86d15c6ba29 1657 cert->srcIdx--;
Vanger 0:b86d15c6ba29 1658
Vanger 0:b86d15c6ba29 1659 cert->pubKeySize = length;
Vanger 0:b86d15c6ba29 1660 cert->publicKey = cert->source + cert->srcIdx;
Vanger 0:b86d15c6ba29 1661 cert->srcIdx += length;
Vanger 0:b86d15c6ba29 1662
Vanger 0:b86d15c6ba29 1663 return 0;
Vanger 0:b86d15c6ba29 1664 }
Vanger 0:b86d15c6ba29 1665 #endif
Vanger 0:b86d15c6ba29 1666
Vanger 0:b86d15c6ba29 1667
Vanger 0:b86d15c6ba29 1668 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1669
Vanger 0:b86d15c6ba29 1670 /* return 0 on sucess if the ECC curve oid sum is supported */
Vanger 0:b86d15c6ba29 1671 static int CheckCurve(word32 oid)
Vanger 0:b86d15c6ba29 1672 {
Vanger 0:b86d15c6ba29 1673 if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid !=
Vanger 0:b86d15c6ba29 1674 ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1)
Vanger 0:b86d15c6ba29 1675 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 1676
Vanger 0:b86d15c6ba29 1677 return 0;
Vanger 0:b86d15c6ba29 1678 }
Vanger 0:b86d15c6ba29 1679
Vanger 0:b86d15c6ba29 1680 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1681
Vanger 0:b86d15c6ba29 1682
Vanger 0:b86d15c6ba29 1683 static int GetKey(DecodedCert* cert)
Vanger 0:b86d15c6ba29 1684 {
Vanger 0:b86d15c6ba29 1685 int length;
Vanger 0:b86d15c6ba29 1686 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 1687 int tmpIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1688 #endif
Vanger 0:b86d15c6ba29 1689
Vanger 0:b86d15c6ba29 1690 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1691 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1692
Vanger 0:b86d15c6ba29 1693 if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1694 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1695
Vanger 0:b86d15c6ba29 1696 switch (cert->keyOID) {
Vanger 0:b86d15c6ba29 1697 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 1698 case RSAk:
Vanger 0:b86d15c6ba29 1699 {
Vanger 0:b86d15c6ba29 1700 byte b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1701 if (b != ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 1702 return ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 1703
Vanger 0:b86d15c6ba29 1704 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1705 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1706 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1707 if (b != 0x00)
Vanger 0:b86d15c6ba29 1708 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 1709
Vanger 0:b86d15c6ba29 1710 return StoreRsaKey(cert);
Vanger 0:b86d15c6ba29 1711 }
Vanger 0:b86d15c6ba29 1712
Vanger 0:b86d15c6ba29 1713 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 1714 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 1715 case NTRUk:
Vanger 0:b86d15c6ba29 1716 {
Vanger 0:b86d15c6ba29 1717 const byte* key = &cert->source[tmpIdx];
Vanger 0:b86d15c6ba29 1718 byte* next = (byte*)key;
Vanger 0:b86d15c6ba29 1719 word16 keyLen;
Vanger 0:b86d15c6ba29 1720 word32 rc;
Vanger 0:b86d15c6ba29 1721 word32 remaining = cert->maxIdx - cert->srcIdx;
Vanger 0:b86d15c6ba29 1722 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1723 byte* keyBlob = NULL;
Vanger 0:b86d15c6ba29 1724 #else
Vanger 0:b86d15c6ba29 1725 byte keyBlob[MAX_NTRU_KEY_SZ];
Vanger 0:b86d15c6ba29 1726 #endif
Vanger 0:b86d15c6ba29 1727 rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
Vanger 0:b86d15c6ba29 1728 &keyLen, NULL, &next, &remaining);
Vanger 0:b86d15c6ba29 1729 if (rc != NTRU_OK)
Vanger 0:b86d15c6ba29 1730 return ASN_NTRU_KEY_E;
Vanger 0:b86d15c6ba29 1731 if (keyLen > MAX_NTRU_KEY_SZ)
Vanger 0:b86d15c6ba29 1732 return ASN_NTRU_KEY_E;
Vanger 0:b86d15c6ba29 1733
Vanger 0:b86d15c6ba29 1734 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1735 keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
Vanger 0:b86d15c6ba29 1736 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1737 if (keyBlob == NULL)
Vanger 0:b86d15c6ba29 1738 return MEMORY_E;
Vanger 0:b86d15c6ba29 1739 #endif
Vanger 0:b86d15c6ba29 1740
Vanger 0:b86d15c6ba29 1741 rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
Vanger 0:b86d15c6ba29 1742 &keyLen, keyBlob, &next, &remaining);
Vanger 0:b86d15c6ba29 1743 if (rc != NTRU_OK) {
Vanger 0:b86d15c6ba29 1744 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1745 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1746 #endif
Vanger 0:b86d15c6ba29 1747 return ASN_NTRU_KEY_E;
Vanger 0:b86d15c6ba29 1748 }
Vanger 0:b86d15c6ba29 1749
Vanger 0:b86d15c6ba29 1750 if ( (next - key) < 0) {
Vanger 0:b86d15c6ba29 1751 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1752 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1753 #endif
Vanger 0:b86d15c6ba29 1754 return ASN_NTRU_KEY_E;
Vanger 0:b86d15c6ba29 1755 }
Vanger 0:b86d15c6ba29 1756
Vanger 0:b86d15c6ba29 1757 cert->srcIdx = tmpIdx + (int)(next - key);
Vanger 0:b86d15c6ba29 1758
Vanger 0:b86d15c6ba29 1759 cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
Vanger 0:b86d15c6ba29 1760 DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 1761 if (cert->publicKey == NULL) {
Vanger 0:b86d15c6ba29 1762 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1763 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1764 #endif
Vanger 0:b86d15c6ba29 1765 return MEMORY_E;
Vanger 0:b86d15c6ba29 1766 }
Vanger 0:b86d15c6ba29 1767 XMEMCPY(cert->publicKey, keyBlob, keyLen);
Vanger 0:b86d15c6ba29 1768 cert->pubKeyStored = 1;
Vanger 0:b86d15c6ba29 1769 cert->pubKeySize = keyLen;
Vanger 0:b86d15c6ba29 1770
Vanger 0:b86d15c6ba29 1771 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 1772 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 1773 #endif
Vanger 0:b86d15c6ba29 1774
Vanger 0:b86d15c6ba29 1775 return 0;
Vanger 0:b86d15c6ba29 1776 }
Vanger 0:b86d15c6ba29 1777 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 1778 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 1779 case ECDSAk:
Vanger 0:b86d15c6ba29 1780 {
Vanger 0:b86d15c6ba29 1781 int oidSz = 0;
Vanger 0:b86d15c6ba29 1782 byte b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1783
Vanger 0:b86d15c6ba29 1784 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 1785 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 1786
Vanger 0:b86d15c6ba29 1787 if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1788 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1789
Vanger 0:b86d15c6ba29 1790 while(oidSz--)
Vanger 0:b86d15c6ba29 1791 cert->pkCurveOID += cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1792
Vanger 0:b86d15c6ba29 1793 if (CheckCurve(cert->pkCurveOID) < 0)
Vanger 0:b86d15c6ba29 1794 return ECC_CURVE_OID_E;
Vanger 0:b86d15c6ba29 1795
Vanger 0:b86d15c6ba29 1796 /* key header */
Vanger 0:b86d15c6ba29 1797 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1798 if (b != ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 1799 return ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 1800
Vanger 0:b86d15c6ba29 1801 if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1802 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1803 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1804 if (b != 0x00)
Vanger 0:b86d15c6ba29 1805 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 1806
Vanger 0:b86d15c6ba29 1807 /* actual key, use length - 1 since ate preceding 0 */
Vanger 0:b86d15c6ba29 1808 length -= 1;
Vanger 0:b86d15c6ba29 1809
Vanger 0:b86d15c6ba29 1810 cert->publicKey = (byte*) XMALLOC(length, cert->heap,
Vanger 0:b86d15c6ba29 1811 DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 1812 if (cert->publicKey == NULL)
Vanger 0:b86d15c6ba29 1813 return MEMORY_E;
Vanger 0:b86d15c6ba29 1814 XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
Vanger 0:b86d15c6ba29 1815 cert->pubKeyStored = 1;
Vanger 0:b86d15c6ba29 1816 cert->pubKeySize = length;
Vanger 0:b86d15c6ba29 1817
Vanger 0:b86d15c6ba29 1818 cert->srcIdx += length;
Vanger 0:b86d15c6ba29 1819
Vanger 0:b86d15c6ba29 1820 return 0;
Vanger 0:b86d15c6ba29 1821 }
Vanger 0:b86d15c6ba29 1822 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 1823 default:
Vanger 0:b86d15c6ba29 1824 return ASN_UNKNOWN_OID_E;
Vanger 0:b86d15c6ba29 1825 }
Vanger 0:b86d15c6ba29 1826 }
Vanger 0:b86d15c6ba29 1827
Vanger 0:b86d15c6ba29 1828
Vanger 0:b86d15c6ba29 1829 /* process NAME, either issuer or subject */
Vanger 0:b86d15c6ba29 1830 static int GetName(DecodedCert* cert, int nameType)
Vanger 0:b86d15c6ba29 1831 {
Vanger 0:b86d15c6ba29 1832 Sha sha; /* MUST have SHA-1 hash for cert names */
Vanger 0:b86d15c6ba29 1833 int length; /* length of all distinguished names */
Vanger 0:b86d15c6ba29 1834 int dummy;
Vanger 0:b86d15c6ba29 1835 int ret;
Vanger 0:b86d15c6ba29 1836 char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
Vanger 0:b86d15c6ba29 1837 word32 idx;
Vanger 0:b86d15c6ba29 1838 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1839 DecodedName* dName =
Vanger 0:b86d15c6ba29 1840 (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
Vanger 0:b86d15c6ba29 1841 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1842
Vanger 0:b86d15c6ba29 1843 CYASSL_MSG("Getting Cert Name");
Vanger 0:b86d15c6ba29 1844
Vanger 0:b86d15c6ba29 1845 if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 1846 CYASSL_MSG("Trying optional prefix...");
Vanger 0:b86d15c6ba29 1847
Vanger 0:b86d15c6ba29 1848 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1849 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1850
Vanger 0:b86d15c6ba29 1851 cert->srcIdx += length;
Vanger 0:b86d15c6ba29 1852 CYASSL_MSG("Got optional prefix");
Vanger 0:b86d15c6ba29 1853 }
Vanger 0:b86d15c6ba29 1854
Vanger 0:b86d15c6ba29 1855 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
Vanger 0:b86d15c6ba29 1856 * calculated over the entire DER encoding of the Name field, including
Vanger 0:b86d15c6ba29 1857 * the tag and length. */
Vanger 0:b86d15c6ba29 1858 idx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1859 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1860 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1861
Vanger 0:b86d15c6ba29 1862 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 1863 if (ret != 0)
Vanger 0:b86d15c6ba29 1864 return ret;
Vanger 0:b86d15c6ba29 1865 ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx);
Vanger 0:b86d15c6ba29 1866 if (nameType == ISSUER)
Vanger 0:b86d15c6ba29 1867 ShaFinal(&sha, cert->issuerHash);
Vanger 0:b86d15c6ba29 1868 else
Vanger 0:b86d15c6ba29 1869 ShaFinal(&sha, cert->subjectHash);
Vanger 0:b86d15c6ba29 1870
Vanger 0:b86d15c6ba29 1871 length += cert->srcIdx;
Vanger 0:b86d15c6ba29 1872 idx = 0;
Vanger 0:b86d15c6ba29 1873
Vanger 0:b86d15c6ba29 1874 #ifdef HAVE_PKCS7
Vanger 0:b86d15c6ba29 1875 /* store pointer to raw issuer */
Vanger 0:b86d15c6ba29 1876 if (nameType == ISSUER) {
Vanger 0:b86d15c6ba29 1877 cert->issuerRaw = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1878 cert->issuerRawLen = length - cert->srcIdx;
Vanger 0:b86d15c6ba29 1879 }
Vanger 0:b86d15c6ba29 1880 #endif
Vanger 0:b86d15c6ba29 1881 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 1882 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 1883 cert->subjectRaw = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1884 cert->subjectRawLen = length - cert->srcIdx;
Vanger 0:b86d15c6ba29 1885 }
Vanger 0:b86d15c6ba29 1886 #endif
Vanger 0:b86d15c6ba29 1887
Vanger 0:b86d15c6ba29 1888 while (cert->srcIdx < (word32)length) {
Vanger 0:b86d15c6ba29 1889 byte b;
Vanger 0:b86d15c6ba29 1890 byte joint[2];
Vanger 0:b86d15c6ba29 1891 byte tooBig = FALSE;
Vanger 0:b86d15c6ba29 1892 int oidSz;
Vanger 0:b86d15c6ba29 1893
Vanger 0:b86d15c6ba29 1894 if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 1895 CYASSL_MSG("Cert name lacks set header, trying sequence");
Vanger 0:b86d15c6ba29 1896 }
Vanger 0:b86d15c6ba29 1897
Vanger 0:b86d15c6ba29 1898 if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1899 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1900
Vanger 0:b86d15c6ba29 1901 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1902 if (b != ASN_OBJECT_ID)
Vanger 0:b86d15c6ba29 1903 return ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 1904
Vanger 0:b86d15c6ba29 1905 if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1906 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1907
Vanger 0:b86d15c6ba29 1908 XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
Vanger 0:b86d15c6ba29 1909
Vanger 0:b86d15c6ba29 1910 /* v1 name types */
Vanger 0:b86d15c6ba29 1911 if (joint[0] == 0x55 && joint[1] == 0x04) {
Vanger 0:b86d15c6ba29 1912 byte id;
Vanger 0:b86d15c6ba29 1913 byte copy = FALSE;
Vanger 0:b86d15c6ba29 1914 int strLen;
Vanger 0:b86d15c6ba29 1915
Vanger 0:b86d15c6ba29 1916 cert->srcIdx += 2;
Vanger 0:b86d15c6ba29 1917 id = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 1918 b = cert->source[cert->srcIdx++]; /* encoding */
Vanger 0:b86d15c6ba29 1919
Vanger 0:b86d15c6ba29 1920 if (GetLength(cert->source, &cert->srcIdx, &strLen,
Vanger 0:b86d15c6ba29 1921 cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 1922 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 1923
Vanger 0:b86d15c6ba29 1924 if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
Vanger 0:b86d15c6ba29 1925 /* include biggest pre fix header too 4 = "/serialNumber=" */
Vanger 0:b86d15c6ba29 1926 CYASSL_MSG("ASN Name too big, skipping");
Vanger 0:b86d15c6ba29 1927 tooBig = TRUE;
Vanger 0:b86d15c6ba29 1928 }
Vanger 0:b86d15c6ba29 1929
Vanger 0:b86d15c6ba29 1930 if (id == ASN_COMMON_NAME) {
Vanger 0:b86d15c6ba29 1931 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 1932 cert->subjectCN = (char *)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1933 cert->subjectCNLen = strLen;
Vanger 0:b86d15c6ba29 1934 cert->subjectCNEnc = b;
Vanger 0:b86d15c6ba29 1935 }
Vanger 0:b86d15c6ba29 1936
Vanger 0:b86d15c6ba29 1937 if (!tooBig) {
Vanger 0:b86d15c6ba29 1938 XMEMCPY(&full[idx], "/CN=", 4);
Vanger 0:b86d15c6ba29 1939 idx += 4;
Vanger 0:b86d15c6ba29 1940 copy = TRUE;
Vanger 0:b86d15c6ba29 1941 }
Vanger 0:b86d15c6ba29 1942 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1943 dName->cnIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1944 dName->cnLen = strLen;
Vanger 0:b86d15c6ba29 1945 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1946 }
Vanger 0:b86d15c6ba29 1947 else if (id == ASN_SUR_NAME) {
Vanger 0:b86d15c6ba29 1948 if (!tooBig) {
Vanger 0:b86d15c6ba29 1949 XMEMCPY(&full[idx], "/SN=", 4);
Vanger 0:b86d15c6ba29 1950 idx += 4;
Vanger 0:b86d15c6ba29 1951 copy = TRUE;
Vanger 0:b86d15c6ba29 1952 }
Vanger 0:b86d15c6ba29 1953 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 1954 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 1955 cert->subjectSN = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1956 cert->subjectSNLen = strLen;
Vanger 0:b86d15c6ba29 1957 cert->subjectSNEnc = b;
Vanger 0:b86d15c6ba29 1958 }
Vanger 0:b86d15c6ba29 1959 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 1960 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1961 dName->snIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1962 dName->snLen = strLen;
Vanger 0:b86d15c6ba29 1963 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1964 }
Vanger 0:b86d15c6ba29 1965 else if (id == ASN_COUNTRY_NAME) {
Vanger 0:b86d15c6ba29 1966 if (!tooBig) {
Vanger 0:b86d15c6ba29 1967 XMEMCPY(&full[idx], "/C=", 3);
Vanger 0:b86d15c6ba29 1968 idx += 3;
Vanger 0:b86d15c6ba29 1969 copy = TRUE;
Vanger 0:b86d15c6ba29 1970 }
Vanger 0:b86d15c6ba29 1971 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 1972 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 1973 cert->subjectC = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1974 cert->subjectCLen = strLen;
Vanger 0:b86d15c6ba29 1975 cert->subjectCEnc = b;
Vanger 0:b86d15c6ba29 1976 }
Vanger 0:b86d15c6ba29 1977 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 1978 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1979 dName->cIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1980 dName->cLen = strLen;
Vanger 0:b86d15c6ba29 1981 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 1982 }
Vanger 0:b86d15c6ba29 1983 else if (id == ASN_LOCALITY_NAME) {
Vanger 0:b86d15c6ba29 1984 if (!tooBig) {
Vanger 0:b86d15c6ba29 1985 XMEMCPY(&full[idx], "/L=", 3);
Vanger 0:b86d15c6ba29 1986 idx += 3;
Vanger 0:b86d15c6ba29 1987 copy = TRUE;
Vanger 0:b86d15c6ba29 1988 }
Vanger 0:b86d15c6ba29 1989 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 1990 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 1991 cert->subjectL = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 1992 cert->subjectLLen = strLen;
Vanger 0:b86d15c6ba29 1993 cert->subjectLEnc = b;
Vanger 0:b86d15c6ba29 1994 }
Vanger 0:b86d15c6ba29 1995 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 1996 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 1997 dName->lIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 1998 dName->lLen = strLen;
Vanger 0:b86d15c6ba29 1999 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2000 }
Vanger 0:b86d15c6ba29 2001 else if (id == ASN_STATE_NAME) {
Vanger 0:b86d15c6ba29 2002 if (!tooBig) {
Vanger 0:b86d15c6ba29 2003 XMEMCPY(&full[idx], "/ST=", 4);
Vanger 0:b86d15c6ba29 2004 idx += 4;
Vanger 0:b86d15c6ba29 2005 copy = TRUE;
Vanger 0:b86d15c6ba29 2006 }
Vanger 0:b86d15c6ba29 2007 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 2008 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 2009 cert->subjectST = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2010 cert->subjectSTLen = strLen;
Vanger 0:b86d15c6ba29 2011 cert->subjectSTEnc = b;
Vanger 0:b86d15c6ba29 2012 }
Vanger 0:b86d15c6ba29 2013 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 2014 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2015 dName->stIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2016 dName->stLen = strLen;
Vanger 0:b86d15c6ba29 2017 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2018 }
Vanger 0:b86d15c6ba29 2019 else if (id == ASN_ORG_NAME) {
Vanger 0:b86d15c6ba29 2020 if (!tooBig) {
Vanger 0:b86d15c6ba29 2021 XMEMCPY(&full[idx], "/O=", 3);
Vanger 0:b86d15c6ba29 2022 idx += 3;
Vanger 0:b86d15c6ba29 2023 copy = TRUE;
Vanger 0:b86d15c6ba29 2024 }
Vanger 0:b86d15c6ba29 2025 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 2026 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 2027 cert->subjectO = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2028 cert->subjectOLen = strLen;
Vanger 0:b86d15c6ba29 2029 cert->subjectOEnc = b;
Vanger 0:b86d15c6ba29 2030 }
Vanger 0:b86d15c6ba29 2031 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 2032 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2033 dName->oIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2034 dName->oLen = strLen;
Vanger 0:b86d15c6ba29 2035 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2036 }
Vanger 0:b86d15c6ba29 2037 else if (id == ASN_ORGUNIT_NAME) {
Vanger 0:b86d15c6ba29 2038 if (!tooBig) {
Vanger 0:b86d15c6ba29 2039 XMEMCPY(&full[idx], "/OU=", 4);
Vanger 0:b86d15c6ba29 2040 idx += 4;
Vanger 0:b86d15c6ba29 2041 copy = TRUE;
Vanger 0:b86d15c6ba29 2042 }
Vanger 0:b86d15c6ba29 2043 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 2044 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 2045 cert->subjectOU = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2046 cert->subjectOULen = strLen;
Vanger 0:b86d15c6ba29 2047 cert->subjectOUEnc = b;
Vanger 0:b86d15c6ba29 2048 }
Vanger 0:b86d15c6ba29 2049 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 2050 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2051 dName->ouIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2052 dName->ouLen = strLen;
Vanger 0:b86d15c6ba29 2053 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2054 }
Vanger 0:b86d15c6ba29 2055 else if (id == ASN_SERIAL_NUMBER) {
Vanger 0:b86d15c6ba29 2056 if (!tooBig) {
Vanger 0:b86d15c6ba29 2057 XMEMCPY(&full[idx], "/serialNumber=", 14);
Vanger 0:b86d15c6ba29 2058 idx += 14;
Vanger 0:b86d15c6ba29 2059 copy = TRUE;
Vanger 0:b86d15c6ba29 2060 }
Vanger 0:b86d15c6ba29 2061 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2062 dName->snIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2063 dName->snLen = strLen;
Vanger 0:b86d15c6ba29 2064 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2065 }
Vanger 0:b86d15c6ba29 2066
Vanger 0:b86d15c6ba29 2067 if (copy && !tooBig) {
Vanger 0:b86d15c6ba29 2068 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
Vanger 0:b86d15c6ba29 2069 idx += strLen;
Vanger 0:b86d15c6ba29 2070 }
Vanger 0:b86d15c6ba29 2071
Vanger 0:b86d15c6ba29 2072 cert->srcIdx += strLen;
Vanger 0:b86d15c6ba29 2073 }
Vanger 0:b86d15c6ba29 2074 else {
Vanger 0:b86d15c6ba29 2075 /* skip */
Vanger 0:b86d15c6ba29 2076 byte email = FALSE;
Vanger 0:b86d15c6ba29 2077 byte uid = FALSE;
Vanger 0:b86d15c6ba29 2078 int adv;
Vanger 0:b86d15c6ba29 2079
Vanger 0:b86d15c6ba29 2080 if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */
Vanger 0:b86d15c6ba29 2081 email = TRUE;
Vanger 0:b86d15c6ba29 2082
Vanger 0:b86d15c6ba29 2083 if (joint[0] == 0x9 && joint[1] == 0x92) /* uid id hdr */
Vanger 0:b86d15c6ba29 2084 uid = TRUE;
Vanger 0:b86d15c6ba29 2085
Vanger 0:b86d15c6ba29 2086 cert->srcIdx += oidSz + 1;
Vanger 0:b86d15c6ba29 2087
Vanger 0:b86d15c6ba29 2088 if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 2089 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 2090
Vanger 0:b86d15c6ba29 2091 if (adv > (int)(ASN_NAME_MAX - idx)) {
Vanger 0:b86d15c6ba29 2092 CYASSL_MSG("ASN name too big, skipping");
Vanger 0:b86d15c6ba29 2093 tooBig = TRUE;
Vanger 0:b86d15c6ba29 2094 }
Vanger 0:b86d15c6ba29 2095
Vanger 0:b86d15c6ba29 2096 if (email) {
Vanger 0:b86d15c6ba29 2097 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
Vanger 0:b86d15c6ba29 2098 CYASSL_MSG("ASN name too big, skipping");
Vanger 0:b86d15c6ba29 2099 tooBig = TRUE;
Vanger 0:b86d15c6ba29 2100 }
Vanger 0:b86d15c6ba29 2101 if (!tooBig) {
Vanger 0:b86d15c6ba29 2102 XMEMCPY(&full[idx], "/emailAddress=", 14);
Vanger 0:b86d15c6ba29 2103 idx += 14;
Vanger 0:b86d15c6ba29 2104 }
Vanger 0:b86d15c6ba29 2105
Vanger 0:b86d15c6ba29 2106 #ifdef CYASSL_CERT_GEN
Vanger 0:b86d15c6ba29 2107 if (nameType == SUBJECT) {
Vanger 0:b86d15c6ba29 2108 cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2109 cert->subjectEmailLen = adv;
Vanger 0:b86d15c6ba29 2110 }
Vanger 0:b86d15c6ba29 2111 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 2112 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2113 dName->emailIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2114 dName->emailLen = adv;
Vanger 0:b86d15c6ba29 2115 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2116 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 2117 {
Vanger 0:b86d15c6ba29 2118 DNS_entry* emailName = NULL;
Vanger 0:b86d15c6ba29 2119
Vanger 0:b86d15c6ba29 2120 emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
Vanger 0:b86d15c6ba29 2121 cert->heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 2122 if (emailName == NULL) {
Vanger 0:b86d15c6ba29 2123 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 2124 return MEMORY_E;
Vanger 0:b86d15c6ba29 2125 }
Vanger 0:b86d15c6ba29 2126 emailName->name = (char*)XMALLOC(adv + 1,
Vanger 0:b86d15c6ba29 2127 cert->heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 2128 if (emailName->name == NULL) {
Vanger 0:b86d15c6ba29 2129 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 2130 return MEMORY_E;
Vanger 0:b86d15c6ba29 2131 }
Vanger 0:b86d15c6ba29 2132 XMEMCPY(emailName->name,
Vanger 0:b86d15c6ba29 2133 &cert->source[cert->srcIdx], adv);
Vanger 0:b86d15c6ba29 2134 emailName->name[adv] = 0;
Vanger 0:b86d15c6ba29 2135
Vanger 0:b86d15c6ba29 2136 emailName->next = cert->altEmailNames;
Vanger 0:b86d15c6ba29 2137 cert->altEmailNames = emailName;
Vanger 0:b86d15c6ba29 2138 }
Vanger 0:b86d15c6ba29 2139 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 2140 if (!tooBig) {
Vanger 0:b86d15c6ba29 2141 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
Vanger 0:b86d15c6ba29 2142 idx += adv;
Vanger 0:b86d15c6ba29 2143 }
Vanger 0:b86d15c6ba29 2144 }
Vanger 0:b86d15c6ba29 2145
Vanger 0:b86d15c6ba29 2146 if (uid) {
Vanger 0:b86d15c6ba29 2147 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
Vanger 0:b86d15c6ba29 2148 CYASSL_MSG("ASN name too big, skipping");
Vanger 0:b86d15c6ba29 2149 tooBig = TRUE;
Vanger 0:b86d15c6ba29 2150 }
Vanger 0:b86d15c6ba29 2151 if (!tooBig) {
Vanger 0:b86d15c6ba29 2152 XMEMCPY(&full[idx], "/UID=", 5);
Vanger 0:b86d15c6ba29 2153 idx += 5;
Vanger 0:b86d15c6ba29 2154
Vanger 0:b86d15c6ba29 2155 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
Vanger 0:b86d15c6ba29 2156 idx += adv;
Vanger 0:b86d15c6ba29 2157 }
Vanger 0:b86d15c6ba29 2158 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2159 dName->uidIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2160 dName->uidLen = adv;
Vanger 0:b86d15c6ba29 2161 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2162 }
Vanger 0:b86d15c6ba29 2163
Vanger 0:b86d15c6ba29 2164 cert->srcIdx += adv;
Vanger 0:b86d15c6ba29 2165 }
Vanger 0:b86d15c6ba29 2166 }
Vanger 0:b86d15c6ba29 2167 full[idx++] = 0;
Vanger 0:b86d15c6ba29 2168
Vanger 0:b86d15c6ba29 2169 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 2170 {
Vanger 0:b86d15c6ba29 2171 int totalLen = 0;
Vanger 0:b86d15c6ba29 2172
Vanger 0:b86d15c6ba29 2173 if (dName->cnLen != 0)
Vanger 0:b86d15c6ba29 2174 totalLen += dName->cnLen + 4;
Vanger 0:b86d15c6ba29 2175 if (dName->snLen != 0)
Vanger 0:b86d15c6ba29 2176 totalLen += dName->snLen + 4;
Vanger 0:b86d15c6ba29 2177 if (dName->cLen != 0)
Vanger 0:b86d15c6ba29 2178 totalLen += dName->cLen + 3;
Vanger 0:b86d15c6ba29 2179 if (dName->lLen != 0)
Vanger 0:b86d15c6ba29 2180 totalLen += dName->lLen + 3;
Vanger 0:b86d15c6ba29 2181 if (dName->stLen != 0)
Vanger 0:b86d15c6ba29 2182 totalLen += dName->stLen + 4;
Vanger 0:b86d15c6ba29 2183 if (dName->oLen != 0)
Vanger 0:b86d15c6ba29 2184 totalLen += dName->oLen + 3;
Vanger 0:b86d15c6ba29 2185 if (dName->ouLen != 0)
Vanger 0:b86d15c6ba29 2186 totalLen += dName->ouLen + 4;
Vanger 0:b86d15c6ba29 2187 if (dName->emailLen != 0)
Vanger 0:b86d15c6ba29 2188 totalLen += dName->emailLen + 14;
Vanger 0:b86d15c6ba29 2189 if (dName->uidLen != 0)
Vanger 0:b86d15c6ba29 2190 totalLen += dName->uidLen + 5;
Vanger 0:b86d15c6ba29 2191 if (dName->serialLen != 0)
Vanger 0:b86d15c6ba29 2192 totalLen += dName->serialLen + 14;
Vanger 0:b86d15c6ba29 2193
Vanger 0:b86d15c6ba29 2194 dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
Vanger 0:b86d15c6ba29 2195 if (dName->fullName != NULL) {
Vanger 0:b86d15c6ba29 2196 idx = 0;
Vanger 0:b86d15c6ba29 2197
Vanger 0:b86d15c6ba29 2198 if (dName->cnLen != 0) {
Vanger 0:b86d15c6ba29 2199 dName->entryCount++;
Vanger 0:b86d15c6ba29 2200 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
Vanger 0:b86d15c6ba29 2201 idx += 4;
Vanger 0:b86d15c6ba29 2202 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2203 &cert->source[dName->cnIdx], dName->cnLen);
Vanger 0:b86d15c6ba29 2204 dName->cnIdx = idx;
Vanger 0:b86d15c6ba29 2205 idx += dName->cnLen;
Vanger 0:b86d15c6ba29 2206 }
Vanger 0:b86d15c6ba29 2207 if (dName->snLen != 0) {
Vanger 0:b86d15c6ba29 2208 dName->entryCount++;
Vanger 0:b86d15c6ba29 2209 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
Vanger 0:b86d15c6ba29 2210 idx += 4;
Vanger 0:b86d15c6ba29 2211 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2212 &cert->source[dName->snIdx], dName->snLen);
Vanger 0:b86d15c6ba29 2213 dName->snIdx = idx;
Vanger 0:b86d15c6ba29 2214 idx += dName->snLen;
Vanger 0:b86d15c6ba29 2215 }
Vanger 0:b86d15c6ba29 2216 if (dName->cLen != 0) {
Vanger 0:b86d15c6ba29 2217 dName->entryCount++;
Vanger 0:b86d15c6ba29 2218 XMEMCPY(&dName->fullName[idx], "/C=", 3);
Vanger 0:b86d15c6ba29 2219 idx += 3;
Vanger 0:b86d15c6ba29 2220 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2221 &cert->source[dName->cIdx], dName->cLen);
Vanger 0:b86d15c6ba29 2222 dName->cIdx = idx;
Vanger 0:b86d15c6ba29 2223 idx += dName->cLen;
Vanger 0:b86d15c6ba29 2224 }
Vanger 0:b86d15c6ba29 2225 if (dName->lLen != 0) {
Vanger 0:b86d15c6ba29 2226 dName->entryCount++;
Vanger 0:b86d15c6ba29 2227 XMEMCPY(&dName->fullName[idx], "/L=", 3);
Vanger 0:b86d15c6ba29 2228 idx += 3;
Vanger 0:b86d15c6ba29 2229 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2230 &cert->source[dName->lIdx], dName->lLen);
Vanger 0:b86d15c6ba29 2231 dName->lIdx = idx;
Vanger 0:b86d15c6ba29 2232 idx += dName->lLen;
Vanger 0:b86d15c6ba29 2233 }
Vanger 0:b86d15c6ba29 2234 if (dName->stLen != 0) {
Vanger 0:b86d15c6ba29 2235 dName->entryCount++;
Vanger 0:b86d15c6ba29 2236 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
Vanger 0:b86d15c6ba29 2237 idx += 4;
Vanger 0:b86d15c6ba29 2238 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2239 &cert->source[dName->stIdx], dName->stLen);
Vanger 0:b86d15c6ba29 2240 dName->stIdx = idx;
Vanger 0:b86d15c6ba29 2241 idx += dName->stLen;
Vanger 0:b86d15c6ba29 2242 }
Vanger 0:b86d15c6ba29 2243 if (dName->oLen != 0) {
Vanger 0:b86d15c6ba29 2244 dName->entryCount++;
Vanger 0:b86d15c6ba29 2245 XMEMCPY(&dName->fullName[idx], "/O=", 3);
Vanger 0:b86d15c6ba29 2246 idx += 3;
Vanger 0:b86d15c6ba29 2247 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2248 &cert->source[dName->oIdx], dName->oLen);
Vanger 0:b86d15c6ba29 2249 dName->oIdx = idx;
Vanger 0:b86d15c6ba29 2250 idx += dName->oLen;
Vanger 0:b86d15c6ba29 2251 }
Vanger 0:b86d15c6ba29 2252 if (dName->ouLen != 0) {
Vanger 0:b86d15c6ba29 2253 dName->entryCount++;
Vanger 0:b86d15c6ba29 2254 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
Vanger 0:b86d15c6ba29 2255 idx += 4;
Vanger 0:b86d15c6ba29 2256 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2257 &cert->source[dName->ouIdx], dName->ouLen);
Vanger 0:b86d15c6ba29 2258 dName->ouIdx = idx;
Vanger 0:b86d15c6ba29 2259 idx += dName->ouLen;
Vanger 0:b86d15c6ba29 2260 }
Vanger 0:b86d15c6ba29 2261 if (dName->emailLen != 0) {
Vanger 0:b86d15c6ba29 2262 dName->entryCount++;
Vanger 0:b86d15c6ba29 2263 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
Vanger 0:b86d15c6ba29 2264 idx += 14;
Vanger 0:b86d15c6ba29 2265 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2266 &cert->source[dName->emailIdx], dName->emailLen);
Vanger 0:b86d15c6ba29 2267 dName->emailIdx = idx;
Vanger 0:b86d15c6ba29 2268 idx += dName->emailLen;
Vanger 0:b86d15c6ba29 2269 }
Vanger 0:b86d15c6ba29 2270 if (dName->uidLen != 0) {
Vanger 0:b86d15c6ba29 2271 dName->entryCount++;
Vanger 0:b86d15c6ba29 2272 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
Vanger 0:b86d15c6ba29 2273 idx += 5;
Vanger 0:b86d15c6ba29 2274 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2275 &cert->source[dName->uidIdx], dName->uidLen);
Vanger 0:b86d15c6ba29 2276 dName->uidIdx = idx;
Vanger 0:b86d15c6ba29 2277 idx += dName->uidLen;
Vanger 0:b86d15c6ba29 2278 }
Vanger 0:b86d15c6ba29 2279 if (dName->serialLen != 0) {
Vanger 0:b86d15c6ba29 2280 dName->entryCount++;
Vanger 0:b86d15c6ba29 2281 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
Vanger 0:b86d15c6ba29 2282 idx += 14;
Vanger 0:b86d15c6ba29 2283 XMEMCPY(&dName->fullName[idx],
Vanger 0:b86d15c6ba29 2284 &cert->source[dName->serialIdx], dName->serialLen);
Vanger 0:b86d15c6ba29 2285 dName->serialIdx = idx;
Vanger 0:b86d15c6ba29 2286 idx += dName->serialLen;
Vanger 0:b86d15c6ba29 2287 }
Vanger 0:b86d15c6ba29 2288 dName->fullName[idx] = '\0';
Vanger 0:b86d15c6ba29 2289 dName->fullNameLen = totalLen;
Vanger 0:b86d15c6ba29 2290 }
Vanger 0:b86d15c6ba29 2291 }
Vanger 0:b86d15c6ba29 2292 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 2293
Vanger 0:b86d15c6ba29 2294 return 0;
Vanger 0:b86d15c6ba29 2295 }
Vanger 0:b86d15c6ba29 2296
Vanger 0:b86d15c6ba29 2297
Vanger 0:b86d15c6ba29 2298 #ifndef NO_TIME_H
Vanger 0:b86d15c6ba29 2299
Vanger 0:b86d15c6ba29 2300 /* to the second */
Vanger 0:b86d15c6ba29 2301 static int DateGreaterThan(const struct tm* a, const struct tm* b)
Vanger 0:b86d15c6ba29 2302 {
Vanger 0:b86d15c6ba29 2303 if (a->tm_year > b->tm_year)
Vanger 0:b86d15c6ba29 2304 return 1;
Vanger 0:b86d15c6ba29 2305
Vanger 0:b86d15c6ba29 2306 if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
Vanger 0:b86d15c6ba29 2307 return 1;
Vanger 0:b86d15c6ba29 2308
Vanger 0:b86d15c6ba29 2309 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
Vanger 0:b86d15c6ba29 2310 a->tm_mday > b->tm_mday)
Vanger 0:b86d15c6ba29 2311 return 1;
Vanger 0:b86d15c6ba29 2312
Vanger 0:b86d15c6ba29 2313 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
Vanger 0:b86d15c6ba29 2314 a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
Vanger 0:b86d15c6ba29 2315 return 1;
Vanger 0:b86d15c6ba29 2316
Vanger 0:b86d15c6ba29 2317 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
Vanger 0:b86d15c6ba29 2318 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
Vanger 0:b86d15c6ba29 2319 a->tm_min > b->tm_min)
Vanger 0:b86d15c6ba29 2320 return 1;
Vanger 0:b86d15c6ba29 2321
Vanger 0:b86d15c6ba29 2322 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
Vanger 0:b86d15c6ba29 2323 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
Vanger 0:b86d15c6ba29 2324 a->tm_min == b->tm_min && a->tm_sec > b->tm_sec)
Vanger 0:b86d15c6ba29 2325 return 1;
Vanger 0:b86d15c6ba29 2326
Vanger 0:b86d15c6ba29 2327 return 0; /* false */
Vanger 0:b86d15c6ba29 2328 }
Vanger 0:b86d15c6ba29 2329
Vanger 0:b86d15c6ba29 2330
Vanger 0:b86d15c6ba29 2331 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
Vanger 0:b86d15c6ba29 2332 {
Vanger 0:b86d15c6ba29 2333 return DateGreaterThan(b,a);
Vanger 0:b86d15c6ba29 2334 }
Vanger 0:b86d15c6ba29 2335
Vanger 0:b86d15c6ba29 2336
Vanger 0:b86d15c6ba29 2337 /* like atoi but only use first byte */
Vanger 0:b86d15c6ba29 2338 /* Make sure before and after dates are valid */
Vanger 0:b86d15c6ba29 2339 int ValidateDate(const byte* date, byte format, int dateType)
Vanger 0:b86d15c6ba29 2340 {
Vanger 0:b86d15c6ba29 2341 time_t ltime;
Vanger 0:b86d15c6ba29 2342 struct tm certTime;
Vanger 0:b86d15c6ba29 2343 struct tm* localTime;
Vanger 0:b86d15c6ba29 2344 int i = 0;
Vanger 0:b86d15c6ba29 2345
Vanger 0:b86d15c6ba29 2346 ltime = XTIME(0);
Vanger 0:b86d15c6ba29 2347 XMEMSET(&certTime, 0, sizeof(certTime));
Vanger 0:b86d15c6ba29 2348
Vanger 0:b86d15c6ba29 2349 if (format == ASN_UTC_TIME) {
Vanger 0:b86d15c6ba29 2350 if (btoi(date[0]) >= 5)
Vanger 0:b86d15c6ba29 2351 certTime.tm_year = 1900;
Vanger 0:b86d15c6ba29 2352 else
Vanger 0:b86d15c6ba29 2353 certTime.tm_year = 2000;
Vanger 0:b86d15c6ba29 2354 }
Vanger 0:b86d15c6ba29 2355 else { /* format == GENERALIZED_TIME */
Vanger 0:b86d15c6ba29 2356 certTime.tm_year += btoi(date[i++]) * 1000;
Vanger 0:b86d15c6ba29 2357 certTime.tm_year += btoi(date[i++]) * 100;
Vanger 0:b86d15c6ba29 2358 }
Vanger 0:b86d15c6ba29 2359
Vanger 0:b86d15c6ba29 2360 /* adjust tm_year, tm_mon */
Vanger 0:b86d15c6ba29 2361 GetTime((int*)&certTime.tm_year, date, &i); certTime.tm_year -= 1900;
Vanger 0:b86d15c6ba29 2362 GetTime((int*)&certTime.tm_mon, date, &i); certTime.tm_mon -= 1;
Vanger 0:b86d15c6ba29 2363 GetTime((int*)&certTime.tm_mday, date, &i);
Vanger 0:b86d15c6ba29 2364 GetTime((int*)&certTime.tm_hour, date, &i);
Vanger 0:b86d15c6ba29 2365 GetTime((int*)&certTime.tm_min, date, &i);
Vanger 0:b86d15c6ba29 2366 GetTime((int*)&certTime.tm_sec, date, &i);
Vanger 0:b86d15c6ba29 2367
Vanger 0:b86d15c6ba29 2368 if (date[i] != 'Z') { /* only Zulu supported for this profile */
Vanger 0:b86d15c6ba29 2369 CYASSL_MSG("Only Zulu time supported for this profile");
Vanger 0:b86d15c6ba29 2370 return 0;
Vanger 0:b86d15c6ba29 2371 }
Vanger 0:b86d15c6ba29 2372
Vanger 0:b86d15c6ba29 2373 localTime = XGMTIME(&ltime);
Vanger 0:b86d15c6ba29 2374
Vanger 0:b86d15c6ba29 2375 if (dateType == BEFORE) {
Vanger 0:b86d15c6ba29 2376 if (DateLessThan(localTime, &certTime))
Vanger 0:b86d15c6ba29 2377 return 0;
Vanger 0:b86d15c6ba29 2378 }
Vanger 0:b86d15c6ba29 2379 else
Vanger 0:b86d15c6ba29 2380 if (DateGreaterThan(localTime, &certTime))
Vanger 0:b86d15c6ba29 2381 return 0;
Vanger 0:b86d15c6ba29 2382
Vanger 0:b86d15c6ba29 2383 return 1;
Vanger 0:b86d15c6ba29 2384 }
Vanger 0:b86d15c6ba29 2385
Vanger 0:b86d15c6ba29 2386 #endif /* NO_TIME_H */
Vanger 0:b86d15c6ba29 2387
Vanger 0:b86d15c6ba29 2388
Vanger 0:b86d15c6ba29 2389 static int GetDate(DecodedCert* cert, int dateType)
Vanger 0:b86d15c6ba29 2390 {
Vanger 0:b86d15c6ba29 2391 int length;
Vanger 0:b86d15c6ba29 2392 byte date[MAX_DATE_SIZE];
Vanger 0:b86d15c6ba29 2393 byte b;
Vanger 0:b86d15c6ba29 2394 word32 startIdx = 0;
Vanger 0:b86d15c6ba29 2395
Vanger 0:b86d15c6ba29 2396 if (dateType == BEFORE)
Vanger 0:b86d15c6ba29 2397 cert->beforeDate = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2398 else
Vanger 0:b86d15c6ba29 2399 cert->afterDate = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2400 startIdx = cert->srcIdx;
Vanger 0:b86d15c6ba29 2401
Vanger 0:b86d15c6ba29 2402 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 2403 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
Vanger 0:b86d15c6ba29 2404 return ASN_TIME_E;
Vanger 0:b86d15c6ba29 2405
Vanger 0:b86d15c6ba29 2406 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 2407 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 2408
Vanger 0:b86d15c6ba29 2409 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
Vanger 0:b86d15c6ba29 2410 return ASN_DATE_SZ_E;
Vanger 0:b86d15c6ba29 2411
Vanger 0:b86d15c6ba29 2412 XMEMCPY(date, &cert->source[cert->srcIdx], length);
Vanger 0:b86d15c6ba29 2413 cert->srcIdx += length;
Vanger 0:b86d15c6ba29 2414
Vanger 0:b86d15c6ba29 2415 if (dateType == BEFORE)
Vanger 0:b86d15c6ba29 2416 cert->beforeDateLen = cert->srcIdx - startIdx;
Vanger 0:b86d15c6ba29 2417 else
Vanger 0:b86d15c6ba29 2418 cert->afterDateLen = cert->srcIdx - startIdx;
Vanger 0:b86d15c6ba29 2419
Vanger 0:b86d15c6ba29 2420 if (!XVALIDATE_DATE(date, b, dateType)) {
Vanger 0:b86d15c6ba29 2421 if (dateType == BEFORE)
Vanger 0:b86d15c6ba29 2422 return ASN_BEFORE_DATE_E;
Vanger 0:b86d15c6ba29 2423 else
Vanger 0:b86d15c6ba29 2424 return ASN_AFTER_DATE_E;
Vanger 0:b86d15c6ba29 2425 }
Vanger 0:b86d15c6ba29 2426
Vanger 0:b86d15c6ba29 2427 return 0;
Vanger 0:b86d15c6ba29 2428 }
Vanger 0:b86d15c6ba29 2429
Vanger 0:b86d15c6ba29 2430
Vanger 0:b86d15c6ba29 2431 static int GetValidity(DecodedCert* cert, int verify)
Vanger 0:b86d15c6ba29 2432 {
Vanger 0:b86d15c6ba29 2433 int length;
Vanger 0:b86d15c6ba29 2434 int badDate = 0;
Vanger 0:b86d15c6ba29 2435
Vanger 0:b86d15c6ba29 2436 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 2437 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 2438
Vanger 0:b86d15c6ba29 2439 if (GetDate(cert, BEFORE) < 0 && verify)
Vanger 0:b86d15c6ba29 2440 badDate = ASN_BEFORE_DATE_E; /* continue parsing */
Vanger 0:b86d15c6ba29 2441
Vanger 0:b86d15c6ba29 2442 if (GetDate(cert, AFTER) < 0 && verify)
Vanger 0:b86d15c6ba29 2443 return ASN_AFTER_DATE_E;
Vanger 0:b86d15c6ba29 2444
Vanger 0:b86d15c6ba29 2445 if (badDate != 0)
Vanger 0:b86d15c6ba29 2446 return badDate;
Vanger 0:b86d15c6ba29 2447
Vanger 0:b86d15c6ba29 2448 return 0;
Vanger 0:b86d15c6ba29 2449 }
Vanger 0:b86d15c6ba29 2450
Vanger 0:b86d15c6ba29 2451
Vanger 0:b86d15c6ba29 2452 int DecodeToKey(DecodedCert* cert, int verify)
Vanger 0:b86d15c6ba29 2453 {
Vanger 0:b86d15c6ba29 2454 int badDate = 0;
Vanger 0:b86d15c6ba29 2455 int ret;
Vanger 0:b86d15c6ba29 2456
Vanger 0:b86d15c6ba29 2457 if ( (ret = GetCertHeader(cert)) < 0)
Vanger 0:b86d15c6ba29 2458 return ret;
Vanger 0:b86d15c6ba29 2459
Vanger 0:b86d15c6ba29 2460 CYASSL_MSG("Got Cert Header");
Vanger 0:b86d15c6ba29 2461
Vanger 0:b86d15c6ba29 2462 if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
Vanger 0:b86d15c6ba29 2463 cert->maxIdx)) < 0)
Vanger 0:b86d15c6ba29 2464 return ret;
Vanger 0:b86d15c6ba29 2465
Vanger 0:b86d15c6ba29 2466 CYASSL_MSG("Got Algo ID");
Vanger 0:b86d15c6ba29 2467
Vanger 0:b86d15c6ba29 2468 if ( (ret = GetName(cert, ISSUER)) < 0)
Vanger 0:b86d15c6ba29 2469 return ret;
Vanger 0:b86d15c6ba29 2470
Vanger 0:b86d15c6ba29 2471 if ( (ret = GetValidity(cert, verify)) < 0)
Vanger 0:b86d15c6ba29 2472 badDate = ret;
Vanger 0:b86d15c6ba29 2473
Vanger 0:b86d15c6ba29 2474 if ( (ret = GetName(cert, SUBJECT)) < 0)
Vanger 0:b86d15c6ba29 2475 return ret;
Vanger 0:b86d15c6ba29 2476
Vanger 0:b86d15c6ba29 2477 CYASSL_MSG("Got Subject Name");
Vanger 0:b86d15c6ba29 2478
Vanger 0:b86d15c6ba29 2479 if ( (ret = GetKey(cert)) < 0)
Vanger 0:b86d15c6ba29 2480 return ret;
Vanger 0:b86d15c6ba29 2481
Vanger 0:b86d15c6ba29 2482 CYASSL_MSG("Got Key");
Vanger 0:b86d15c6ba29 2483
Vanger 0:b86d15c6ba29 2484 if (badDate != 0)
Vanger 0:b86d15c6ba29 2485 return badDate;
Vanger 0:b86d15c6ba29 2486
Vanger 0:b86d15c6ba29 2487 return ret;
Vanger 0:b86d15c6ba29 2488 }
Vanger 0:b86d15c6ba29 2489
Vanger 0:b86d15c6ba29 2490
Vanger 0:b86d15c6ba29 2491 static int GetSignature(DecodedCert* cert)
Vanger 0:b86d15c6ba29 2492 {
Vanger 0:b86d15c6ba29 2493 int length;
Vanger 0:b86d15c6ba29 2494 byte b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 2495
Vanger 0:b86d15c6ba29 2496 if (b != ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 2497 return ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 2498
Vanger 0:b86d15c6ba29 2499 if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
Vanger 0:b86d15c6ba29 2500 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 2501
Vanger 0:b86d15c6ba29 2502 cert->sigLength = length;
Vanger 0:b86d15c6ba29 2503
Vanger 0:b86d15c6ba29 2504 b = cert->source[cert->srcIdx++];
Vanger 0:b86d15c6ba29 2505 if (b != 0x00)
Vanger 0:b86d15c6ba29 2506 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 2507
Vanger 0:b86d15c6ba29 2508 cert->sigLength--;
Vanger 0:b86d15c6ba29 2509 cert->signature = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 2510 cert->srcIdx += cert->sigLength;
Vanger 0:b86d15c6ba29 2511
Vanger 0:b86d15c6ba29 2512 return 0;
Vanger 0:b86d15c6ba29 2513 }
Vanger 0:b86d15c6ba29 2514
Vanger 0:b86d15c6ba29 2515
Vanger 0:b86d15c6ba29 2516 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
Vanger 0:b86d15c6ba29 2517 {
Vanger 0:b86d15c6ba29 2518 output[0] = ASN_OCTET_STRING;
Vanger 0:b86d15c6ba29 2519 output[1] = (byte)digSz;
Vanger 0:b86d15c6ba29 2520 XMEMCPY(&output[2], digest, digSz);
Vanger 0:b86d15c6ba29 2521
Vanger 0:b86d15c6ba29 2522 return digSz + 2;
Vanger 0:b86d15c6ba29 2523 }
Vanger 0:b86d15c6ba29 2524
Vanger 0:b86d15c6ba29 2525
Vanger 0:b86d15c6ba29 2526 static word32 BytePrecision(word32 value)
Vanger 0:b86d15c6ba29 2527 {
Vanger 0:b86d15c6ba29 2528 word32 i;
Vanger 0:b86d15c6ba29 2529 for (i = sizeof(value); i; --i)
Vanger 0:b86d15c6ba29 2530 if (value >> ((i - 1) * CYASSL_BIT_SIZE))
Vanger 0:b86d15c6ba29 2531 break;
Vanger 0:b86d15c6ba29 2532
Vanger 0:b86d15c6ba29 2533 return i;
Vanger 0:b86d15c6ba29 2534 }
Vanger 0:b86d15c6ba29 2535
Vanger 0:b86d15c6ba29 2536
Vanger 0:b86d15c6ba29 2537 CYASSL_LOCAL word32 SetLength(word32 length, byte* output)
Vanger 0:b86d15c6ba29 2538 {
Vanger 0:b86d15c6ba29 2539 word32 i = 0, j;
Vanger 0:b86d15c6ba29 2540
Vanger 0:b86d15c6ba29 2541 if (length < ASN_LONG_LENGTH)
Vanger 0:b86d15c6ba29 2542 output[i++] = (byte)length;
Vanger 0:b86d15c6ba29 2543 else {
Vanger 0:b86d15c6ba29 2544 output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
Vanger 0:b86d15c6ba29 2545
Vanger 0:b86d15c6ba29 2546 for (j = BytePrecision(length); j; --j) {
Vanger 0:b86d15c6ba29 2547 output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE));
Vanger 0:b86d15c6ba29 2548 i++;
Vanger 0:b86d15c6ba29 2549 }
Vanger 0:b86d15c6ba29 2550 }
Vanger 0:b86d15c6ba29 2551
Vanger 0:b86d15c6ba29 2552 return i;
Vanger 0:b86d15c6ba29 2553 }
Vanger 0:b86d15c6ba29 2554
Vanger 0:b86d15c6ba29 2555
Vanger 0:b86d15c6ba29 2556 CYASSL_LOCAL word32 SetSequence(word32 len, byte* output)
Vanger 0:b86d15c6ba29 2557 {
Vanger 0:b86d15c6ba29 2558 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
Vanger 0:b86d15c6ba29 2559 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 2560 }
Vanger 0:b86d15c6ba29 2561
Vanger 0:b86d15c6ba29 2562 CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output)
Vanger 0:b86d15c6ba29 2563 {
Vanger 0:b86d15c6ba29 2564 output[0] = ASN_OCTET_STRING;
Vanger 0:b86d15c6ba29 2565 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 2566 }
Vanger 0:b86d15c6ba29 2567
Vanger 0:b86d15c6ba29 2568 /* Write a set header to output */
Vanger 0:b86d15c6ba29 2569 CYASSL_LOCAL word32 SetSet(word32 len, byte* output)
Vanger 0:b86d15c6ba29 2570 {
Vanger 0:b86d15c6ba29 2571 output[0] = ASN_SET | ASN_CONSTRUCTED;
Vanger 0:b86d15c6ba29 2572 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 2573 }
Vanger 0:b86d15c6ba29 2574
Vanger 0:b86d15c6ba29 2575 CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
Vanger 0:b86d15c6ba29 2576 {
Vanger 0:b86d15c6ba29 2577
Vanger 0:b86d15c6ba29 2578 output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
Vanger 0:b86d15c6ba29 2579 | ASN_CONTEXT_SPECIFIC | number;
Vanger 0:b86d15c6ba29 2580 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 2581 }
Vanger 0:b86d15c6ba29 2582
Vanger 0:b86d15c6ba29 2583 CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
Vanger 0:b86d15c6ba29 2584 {
Vanger 0:b86d15c6ba29 2585 output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
Vanger 0:b86d15c6ba29 2586 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 2587 }
Vanger 0:b86d15c6ba29 2588
Vanger 0:b86d15c6ba29 2589
Vanger 0:b86d15c6ba29 2590 #if defined(HAVE_ECC) && (defined(CYASSL_CERT_GEN) || defined(CYASSL_KEY_GEN))
Vanger 0:b86d15c6ba29 2591
Vanger 0:b86d15c6ba29 2592 static word32 SetCurve(ecc_key* key, byte* output)
Vanger 0:b86d15c6ba29 2593 {
Vanger 0:b86d15c6ba29 2594
Vanger 0:b86d15c6ba29 2595 /* curve types */
Vanger 0:b86d15c6ba29 2596 static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
Vanger 0:b86d15c6ba29 2597 0x03, 0x01, 0x01};
Vanger 0:b86d15c6ba29 2598 static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
Vanger 0:b86d15c6ba29 2599 0x03, 0x01, 0x07};
Vanger 0:b86d15c6ba29 2600 static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
Vanger 0:b86d15c6ba29 2601 0x02};
Vanger 0:b86d15c6ba29 2602 static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
Vanger 0:b86d15c6ba29 2603 0x21};
Vanger 0:b86d15c6ba29 2604 static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
Vanger 0:b86d15c6ba29 2605 0x22};
Vanger 0:b86d15c6ba29 2606 static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00,
Vanger 0:b86d15c6ba29 2607 0x23};
Vanger 0:b86d15c6ba29 2608
Vanger 0:b86d15c6ba29 2609 int oidSz = 0;
Vanger 0:b86d15c6ba29 2610 int idx = 0;
Vanger 0:b86d15c6ba29 2611 int lenSz = 0;
Vanger 0:b86d15c6ba29 2612 const byte* oid = 0;
Vanger 0:b86d15c6ba29 2613
Vanger 0:b86d15c6ba29 2614 output[0] = ASN_OBJECT_ID;
Vanger 0:b86d15c6ba29 2615 idx++;
Vanger 0:b86d15c6ba29 2616
Vanger 0:b86d15c6ba29 2617 switch (key->dp->size) {
Vanger 0:b86d15c6ba29 2618 case 20:
Vanger 0:b86d15c6ba29 2619 oidSz = sizeof(ECC_160r1_AlgoID);
Vanger 0:b86d15c6ba29 2620 oid = ECC_160r1_AlgoID;
Vanger 0:b86d15c6ba29 2621 break;
Vanger 0:b86d15c6ba29 2622
Vanger 0:b86d15c6ba29 2623 case 24:
Vanger 0:b86d15c6ba29 2624 oidSz = sizeof(ECC_192v1_AlgoID);
Vanger 0:b86d15c6ba29 2625 oid = ECC_192v1_AlgoID;
Vanger 0:b86d15c6ba29 2626 break;
Vanger 0:b86d15c6ba29 2627
Vanger 0:b86d15c6ba29 2628 case 28:
Vanger 0:b86d15c6ba29 2629 oidSz = sizeof(ECC_224r1_AlgoID);
Vanger 0:b86d15c6ba29 2630 oid = ECC_224r1_AlgoID;
Vanger 0:b86d15c6ba29 2631 break;
Vanger 0:b86d15c6ba29 2632
Vanger 0:b86d15c6ba29 2633 case 32:
Vanger 0:b86d15c6ba29 2634 oidSz = sizeof(ECC_256v1_AlgoID);
Vanger 0:b86d15c6ba29 2635 oid = ECC_256v1_AlgoID;
Vanger 0:b86d15c6ba29 2636 break;
Vanger 0:b86d15c6ba29 2637
Vanger 0:b86d15c6ba29 2638 case 48:
Vanger 0:b86d15c6ba29 2639 oidSz = sizeof(ECC_384r1_AlgoID);
Vanger 0:b86d15c6ba29 2640 oid = ECC_384r1_AlgoID;
Vanger 0:b86d15c6ba29 2641 break;
Vanger 0:b86d15c6ba29 2642
Vanger 0:b86d15c6ba29 2643 case 66:
Vanger 0:b86d15c6ba29 2644 oidSz = sizeof(ECC_521r1_AlgoID);
Vanger 0:b86d15c6ba29 2645 oid = ECC_521r1_AlgoID;
Vanger 0:b86d15c6ba29 2646 break;
Vanger 0:b86d15c6ba29 2647
Vanger 0:b86d15c6ba29 2648 default:
Vanger 0:b86d15c6ba29 2649 return ASN_UNKNOWN_OID_E;
Vanger 0:b86d15c6ba29 2650 }
Vanger 0:b86d15c6ba29 2651 lenSz = SetLength(oidSz, output+idx);
Vanger 0:b86d15c6ba29 2652 idx += lenSz;
Vanger 0:b86d15c6ba29 2653
Vanger 0:b86d15c6ba29 2654 XMEMCPY(output+idx, oid, oidSz);
Vanger 0:b86d15c6ba29 2655 idx += oidSz;
Vanger 0:b86d15c6ba29 2656
Vanger 0:b86d15c6ba29 2657 return idx;
Vanger 0:b86d15c6ba29 2658 }
Vanger 0:b86d15c6ba29 2659
Vanger 0:b86d15c6ba29 2660 #endif /* HAVE_ECC && CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 2661
Vanger 0:b86d15c6ba29 2662
Vanger 0:b86d15c6ba29 2663 CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
Vanger 0:b86d15c6ba29 2664 {
Vanger 0:b86d15c6ba29 2665 /* adding TAG_NULL and 0 to end */
Vanger 0:b86d15c6ba29 2666
Vanger 0:b86d15c6ba29 2667 /* hashTypes */
Vanger 0:b86d15c6ba29 2668 static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
Vanger 0:b86d15c6ba29 2669 0x05, 0x00 };
Vanger 0:b86d15c6ba29 2670 static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
Vanger 0:b86d15c6ba29 2671 0x04, 0x02, 0x01, 0x05, 0x00 };
Vanger 0:b86d15c6ba29 2672 static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
Vanger 0:b86d15c6ba29 2673 0x04, 0x02, 0x02, 0x05, 0x00 };
Vanger 0:b86d15c6ba29 2674 static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
Vanger 0:b86d15c6ba29 2675 0x04, 0x02, 0x03, 0x05, 0x00 };
Vanger 0:b86d15c6ba29 2676 static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
Vanger 0:b86d15c6ba29 2677 0x02, 0x05, 0x05, 0x00 };
Vanger 0:b86d15c6ba29 2678 static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
Vanger 0:b86d15c6ba29 2679 0x02, 0x02, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2680
Vanger 0:b86d15c6ba29 2681 /* blkTypes, no NULL tags because IV is there instead */
Vanger 0:b86d15c6ba29 2682 static const byte desCbcAlgoID[] = { 0x2B, 0x0E, 0x03, 0x02, 0x07 };
Vanger 0:b86d15c6ba29 2683 static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
Vanger 0:b86d15c6ba29 2684 0x0D, 0x03, 0x07 };
Vanger 0:b86d15c6ba29 2685
Vanger 0:b86d15c6ba29 2686 /* RSA sigTypes */
Vanger 0:b86d15c6ba29 2687 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2688 static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
Vanger 0:b86d15c6ba29 2689 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2690 static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
Vanger 0:b86d15c6ba29 2691 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2692 static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
Vanger 0:b86d15c6ba29 2693 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2694 static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
Vanger 0:b86d15c6ba29 2695 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2696 static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
Vanger 0:b86d15c6ba29 2697 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2698 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2699
Vanger 0:b86d15c6ba29 2700 /* ECDSA sigTypes */
Vanger 0:b86d15c6ba29 2701 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2702 static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
Vanger 0:b86d15c6ba29 2703 0x04, 0x01, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2704 static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
Vanger 0:b86d15c6ba29 2705 0x04, 0x03, 0x02, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2706 static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
Vanger 0:b86d15c6ba29 2707 0x04, 0x03, 0x03, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2708 static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
Vanger 0:b86d15c6ba29 2709 0x04, 0x03, 0x04, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2710 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2711
Vanger 0:b86d15c6ba29 2712 /* RSA keyType */
Vanger 0:b86d15c6ba29 2713 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2714 static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
Vanger 0:b86d15c6ba29 2715 0x01, 0x01, 0x01, 0x05, 0x00};
Vanger 0:b86d15c6ba29 2716 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2717
Vanger 0:b86d15c6ba29 2718 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2719 /* ECC keyType */
Vanger 0:b86d15c6ba29 2720 /* no tags, so set tagSz smaller later */
Vanger 0:b86d15c6ba29 2721 static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
Vanger 0:b86d15c6ba29 2722 0x02, 0x01};
Vanger 0:b86d15c6ba29 2723 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2724
Vanger 0:b86d15c6ba29 2725 int algoSz = 0;
Vanger 0:b86d15c6ba29 2726 int tagSz = 2; /* tag null and terminator */
Vanger 0:b86d15c6ba29 2727 word32 idSz, seqSz;
Vanger 0:b86d15c6ba29 2728 const byte* algoName = 0;
Vanger 0:b86d15c6ba29 2729 byte ID_Length[MAX_LENGTH_SZ];
Vanger 0:b86d15c6ba29 2730 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
Vanger 0:b86d15c6ba29 2731
Vanger 0:b86d15c6ba29 2732 if (type == hashType) {
Vanger 0:b86d15c6ba29 2733 switch (algoOID) {
Vanger 0:b86d15c6ba29 2734 case SHAh:
Vanger 0:b86d15c6ba29 2735 algoSz = sizeof(shaAlgoID);
Vanger 0:b86d15c6ba29 2736 algoName = shaAlgoID;
Vanger 0:b86d15c6ba29 2737 break;
Vanger 0:b86d15c6ba29 2738
Vanger 0:b86d15c6ba29 2739 case SHA256h:
Vanger 0:b86d15c6ba29 2740 algoSz = sizeof(sha256AlgoID);
Vanger 0:b86d15c6ba29 2741 algoName = sha256AlgoID;
Vanger 0:b86d15c6ba29 2742 break;
Vanger 0:b86d15c6ba29 2743
Vanger 0:b86d15c6ba29 2744 case SHA384h:
Vanger 0:b86d15c6ba29 2745 algoSz = sizeof(sha384AlgoID);
Vanger 0:b86d15c6ba29 2746 algoName = sha384AlgoID;
Vanger 0:b86d15c6ba29 2747 break;
Vanger 0:b86d15c6ba29 2748
Vanger 0:b86d15c6ba29 2749 case SHA512h:
Vanger 0:b86d15c6ba29 2750 algoSz = sizeof(sha512AlgoID);
Vanger 0:b86d15c6ba29 2751 algoName = sha512AlgoID;
Vanger 0:b86d15c6ba29 2752 break;
Vanger 0:b86d15c6ba29 2753
Vanger 0:b86d15c6ba29 2754 case MD2h:
Vanger 0:b86d15c6ba29 2755 algoSz = sizeof(md2AlgoID);
Vanger 0:b86d15c6ba29 2756 algoName = md2AlgoID;
Vanger 0:b86d15c6ba29 2757 break;
Vanger 0:b86d15c6ba29 2758
Vanger 0:b86d15c6ba29 2759 case MD5h:
Vanger 0:b86d15c6ba29 2760 algoSz = sizeof(md5AlgoID);
Vanger 0:b86d15c6ba29 2761 algoName = md5AlgoID;
Vanger 0:b86d15c6ba29 2762 break;
Vanger 0:b86d15c6ba29 2763
Vanger 0:b86d15c6ba29 2764 default:
Vanger 0:b86d15c6ba29 2765 CYASSL_MSG("Unknown Hash Algo");
Vanger 0:b86d15c6ba29 2766 return 0; /* UNKOWN_HASH_E; */
Vanger 0:b86d15c6ba29 2767 }
Vanger 0:b86d15c6ba29 2768 }
Vanger 0:b86d15c6ba29 2769 else if (type == blkType) {
Vanger 0:b86d15c6ba29 2770 switch (algoOID) {
Vanger 0:b86d15c6ba29 2771 case DESb:
Vanger 0:b86d15c6ba29 2772 algoSz = sizeof(desCbcAlgoID);
Vanger 0:b86d15c6ba29 2773 algoName = desCbcAlgoID;
Vanger 0:b86d15c6ba29 2774 tagSz = 0;
Vanger 0:b86d15c6ba29 2775 break;
Vanger 0:b86d15c6ba29 2776 case DES3b:
Vanger 0:b86d15c6ba29 2777 algoSz = sizeof(des3CbcAlgoID);
Vanger 0:b86d15c6ba29 2778 algoName = des3CbcAlgoID;
Vanger 0:b86d15c6ba29 2779 tagSz = 0;
Vanger 0:b86d15c6ba29 2780 break;
Vanger 0:b86d15c6ba29 2781 default:
Vanger 0:b86d15c6ba29 2782 CYASSL_MSG("Unknown Block Algo");
Vanger 0:b86d15c6ba29 2783 return 0;
Vanger 0:b86d15c6ba29 2784 }
Vanger 0:b86d15c6ba29 2785 }
Vanger 0:b86d15c6ba29 2786 else if (type == sigType) { /* sigType */
Vanger 0:b86d15c6ba29 2787 switch (algoOID) {
Vanger 0:b86d15c6ba29 2788 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2789 case CTC_MD5wRSA:
Vanger 0:b86d15c6ba29 2790 algoSz = sizeof(md5wRSA_AlgoID);
Vanger 0:b86d15c6ba29 2791 algoName = md5wRSA_AlgoID;
Vanger 0:b86d15c6ba29 2792 break;
Vanger 0:b86d15c6ba29 2793
Vanger 0:b86d15c6ba29 2794 case CTC_SHAwRSA:
Vanger 0:b86d15c6ba29 2795 algoSz = sizeof(shawRSA_AlgoID);
Vanger 0:b86d15c6ba29 2796 algoName = shawRSA_AlgoID;
Vanger 0:b86d15c6ba29 2797 break;
Vanger 0:b86d15c6ba29 2798
Vanger 0:b86d15c6ba29 2799 case CTC_SHA256wRSA:
Vanger 0:b86d15c6ba29 2800 algoSz = sizeof(sha256wRSA_AlgoID);
Vanger 0:b86d15c6ba29 2801 algoName = sha256wRSA_AlgoID;
Vanger 0:b86d15c6ba29 2802 break;
Vanger 0:b86d15c6ba29 2803
Vanger 0:b86d15c6ba29 2804 case CTC_SHA384wRSA:
Vanger 0:b86d15c6ba29 2805 algoSz = sizeof(sha384wRSA_AlgoID);
Vanger 0:b86d15c6ba29 2806 algoName = sha384wRSA_AlgoID;
Vanger 0:b86d15c6ba29 2807 break;
Vanger 0:b86d15c6ba29 2808
Vanger 0:b86d15c6ba29 2809 case CTC_SHA512wRSA:
Vanger 0:b86d15c6ba29 2810 algoSz = sizeof(sha512wRSA_AlgoID);
Vanger 0:b86d15c6ba29 2811 algoName = sha512wRSA_AlgoID;
Vanger 0:b86d15c6ba29 2812 break;
Vanger 0:b86d15c6ba29 2813 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2814 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2815 case CTC_SHAwECDSA:
Vanger 0:b86d15c6ba29 2816 algoSz = sizeof(shawECDSA_AlgoID);
Vanger 0:b86d15c6ba29 2817 algoName = shawECDSA_AlgoID;
Vanger 0:b86d15c6ba29 2818 break;
Vanger 0:b86d15c6ba29 2819
Vanger 0:b86d15c6ba29 2820 case CTC_SHA256wECDSA:
Vanger 0:b86d15c6ba29 2821 algoSz = sizeof(sha256wECDSA_AlgoID);
Vanger 0:b86d15c6ba29 2822 algoName = sha256wECDSA_AlgoID;
Vanger 0:b86d15c6ba29 2823 break;
Vanger 0:b86d15c6ba29 2824
Vanger 0:b86d15c6ba29 2825 case CTC_SHA384wECDSA:
Vanger 0:b86d15c6ba29 2826 algoSz = sizeof(sha384wECDSA_AlgoID);
Vanger 0:b86d15c6ba29 2827 algoName = sha384wECDSA_AlgoID;
Vanger 0:b86d15c6ba29 2828 break;
Vanger 0:b86d15c6ba29 2829
Vanger 0:b86d15c6ba29 2830 case CTC_SHA512wECDSA:
Vanger 0:b86d15c6ba29 2831 algoSz = sizeof(sha512wECDSA_AlgoID);
Vanger 0:b86d15c6ba29 2832 algoName = sha512wECDSA_AlgoID;
Vanger 0:b86d15c6ba29 2833 break;
Vanger 0:b86d15c6ba29 2834 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2835 default:
Vanger 0:b86d15c6ba29 2836 CYASSL_MSG("Unknown Signature Algo");
Vanger 0:b86d15c6ba29 2837 return 0;
Vanger 0:b86d15c6ba29 2838 }
Vanger 0:b86d15c6ba29 2839 }
Vanger 0:b86d15c6ba29 2840 else if (type == keyType) { /* keyType */
Vanger 0:b86d15c6ba29 2841 switch (algoOID) {
Vanger 0:b86d15c6ba29 2842 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 2843 case RSAk:
Vanger 0:b86d15c6ba29 2844 algoSz = sizeof(RSA_AlgoID);
Vanger 0:b86d15c6ba29 2845 algoName = RSA_AlgoID;
Vanger 0:b86d15c6ba29 2846 break;
Vanger 0:b86d15c6ba29 2847 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 2848 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 2849 case ECDSAk:
Vanger 0:b86d15c6ba29 2850 algoSz = sizeof(ECC_AlgoID);
Vanger 0:b86d15c6ba29 2851 algoName = ECC_AlgoID;
Vanger 0:b86d15c6ba29 2852 tagSz = 0;
Vanger 0:b86d15c6ba29 2853 break;
Vanger 0:b86d15c6ba29 2854 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 2855 default:
Vanger 0:b86d15c6ba29 2856 CYASSL_MSG("Unknown Key Algo");
Vanger 0:b86d15c6ba29 2857 return 0;
Vanger 0:b86d15c6ba29 2858 }
Vanger 0:b86d15c6ba29 2859 }
Vanger 0:b86d15c6ba29 2860 else {
Vanger 0:b86d15c6ba29 2861 CYASSL_MSG("Unknown Algo type");
Vanger 0:b86d15c6ba29 2862 return 0;
Vanger 0:b86d15c6ba29 2863 }
Vanger 0:b86d15c6ba29 2864
Vanger 0:b86d15c6ba29 2865 idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
Vanger 0:b86d15c6ba29 2866 seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray);
Vanger 0:b86d15c6ba29 2867 /* +1 for object id, curveID of curveSz follows for ecc */
Vanger 0:b86d15c6ba29 2868 seqArray[seqSz++] = ASN_OBJECT_ID;
Vanger 0:b86d15c6ba29 2869
Vanger 0:b86d15c6ba29 2870 XMEMCPY(output, seqArray, seqSz);
Vanger 0:b86d15c6ba29 2871 XMEMCPY(output + seqSz, ID_Length, idSz);
Vanger 0:b86d15c6ba29 2872 XMEMCPY(output + seqSz + idSz, algoName, algoSz);
Vanger 0:b86d15c6ba29 2873
Vanger 0:b86d15c6ba29 2874 return seqSz + idSz + algoSz;
Vanger 0:b86d15c6ba29 2875
Vanger 0:b86d15c6ba29 2876 }
Vanger 0:b86d15c6ba29 2877
Vanger 0:b86d15c6ba29 2878
Vanger 0:b86d15c6ba29 2879 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
Vanger 0:b86d15c6ba29 2880 {
Vanger 0:b86d15c6ba29 2881 byte digArray[MAX_ENCODED_DIG_SZ];
Vanger 0:b86d15c6ba29 2882 byte algoArray[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 2883 byte seqArray[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 2884 word32 encDigSz, algoSz, seqSz;
Vanger 0:b86d15c6ba29 2885
Vanger 0:b86d15c6ba29 2886 encDigSz = SetDigest(digest, digSz, digArray);
Vanger 0:b86d15c6ba29 2887 algoSz = SetAlgoID(hashOID, algoArray, hashType, 0);
Vanger 0:b86d15c6ba29 2888 seqSz = SetSequence(encDigSz + algoSz, seqArray);
Vanger 0:b86d15c6ba29 2889
Vanger 0:b86d15c6ba29 2890 XMEMCPY(out, seqArray, seqSz);
Vanger 0:b86d15c6ba29 2891 XMEMCPY(out + seqSz, algoArray, algoSz);
Vanger 0:b86d15c6ba29 2892 XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
Vanger 0:b86d15c6ba29 2893
Vanger 0:b86d15c6ba29 2894 return encDigSz + algoSz + seqSz;
Vanger 0:b86d15c6ba29 2895 }
Vanger 0:b86d15c6ba29 2896
Vanger 0:b86d15c6ba29 2897
Vanger 0:b86d15c6ba29 2898 int GetCTC_HashOID(int type)
Vanger 0:b86d15c6ba29 2899 {
Vanger 0:b86d15c6ba29 2900 switch (type) {
Vanger 0:b86d15c6ba29 2901 #ifdef CYASSL_MD2
Vanger 0:b86d15c6ba29 2902 case MD2:
Vanger 0:b86d15c6ba29 2903 return MD2h;
Vanger 0:b86d15c6ba29 2904 #endif
Vanger 0:b86d15c6ba29 2905 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 2906 case MD5:
Vanger 0:b86d15c6ba29 2907 return MD5h;
Vanger 0:b86d15c6ba29 2908 #endif
Vanger 0:b86d15c6ba29 2909 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 2910 case SHA:
Vanger 0:b86d15c6ba29 2911 return SHAh;
Vanger 0:b86d15c6ba29 2912 #endif
Vanger 0:b86d15c6ba29 2913 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 2914 case SHA256:
Vanger 0:b86d15c6ba29 2915 return SHA256h;
Vanger 0:b86d15c6ba29 2916 #endif
Vanger 0:b86d15c6ba29 2917 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 2918 case SHA384:
Vanger 0:b86d15c6ba29 2919 return SHA384h;
Vanger 0:b86d15c6ba29 2920 #endif
Vanger 0:b86d15c6ba29 2921 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 2922 case SHA512:
Vanger 0:b86d15c6ba29 2923 return SHA512h;
Vanger 0:b86d15c6ba29 2924 #endif
Vanger 0:b86d15c6ba29 2925 default:
Vanger 0:b86d15c6ba29 2926 return 0;
Vanger 0:b86d15c6ba29 2927 };
Vanger 0:b86d15c6ba29 2928 }
Vanger 0:b86d15c6ba29 2929
Vanger 0:b86d15c6ba29 2930
Vanger 0:b86d15c6ba29 2931 /* return true (1) or false (0) for Confirmation */
Vanger 0:b86d15c6ba29 2932 static int ConfirmSignature(const byte* buf, word32 bufSz,
Vanger 0:b86d15c6ba29 2933 const byte* key, word32 keySz, word32 keyOID,
Vanger 0:b86d15c6ba29 2934 const byte* sig, word32 sigSz, word32 sigOID,
Vanger 0:b86d15c6ba29 2935 void* heap)
Vanger 0:b86d15c6ba29 2936 {
Vanger 0:b86d15c6ba29 2937 int typeH = 0, digestSz = 0, ret = 0;
Vanger 0:b86d15c6ba29 2938 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 2939 byte* digest;
Vanger 0:b86d15c6ba29 2940 #else
Vanger 0:b86d15c6ba29 2941 byte digest[MAX_DIGEST_SIZE];
Vanger 0:b86d15c6ba29 2942 #endif
Vanger 0:b86d15c6ba29 2943
Vanger 0:b86d15c6ba29 2944 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 2945 digest = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 2946 if (digest == NULL)
Vanger 0:b86d15c6ba29 2947 return 0; /* not confirmed */
Vanger 0:b86d15c6ba29 2948 #endif
Vanger 0:b86d15c6ba29 2949
Vanger 0:b86d15c6ba29 2950 (void)key;
Vanger 0:b86d15c6ba29 2951 (void)keySz;
Vanger 0:b86d15c6ba29 2952 (void)sig;
Vanger 0:b86d15c6ba29 2953 (void)sigSz;
Vanger 0:b86d15c6ba29 2954 (void)heap;
Vanger 0:b86d15c6ba29 2955
Vanger 0:b86d15c6ba29 2956 switch (sigOID) {
Vanger 0:b86d15c6ba29 2957 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 2958 case CTC_MD5wRSA:
Vanger 0:b86d15c6ba29 2959 if (Md5Hash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 2960 typeH = MD5h;
Vanger 0:b86d15c6ba29 2961 digestSz = MD5_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 2962 }
Vanger 0:b86d15c6ba29 2963 break;
Vanger 0:b86d15c6ba29 2964 #endif
Vanger 0:b86d15c6ba29 2965 #if defined(CYASSL_MD2)
Vanger 0:b86d15c6ba29 2966 case CTC_MD2wRSA:
Vanger 0:b86d15c6ba29 2967 if (Md2Hash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 2968 typeH = MD2h;
Vanger 0:b86d15c6ba29 2969 digestSz = MD2_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 2970 }
Vanger 0:b86d15c6ba29 2971 break;
Vanger 0:b86d15c6ba29 2972 #endif
Vanger 0:b86d15c6ba29 2973 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 2974 case CTC_SHAwRSA:
Vanger 0:b86d15c6ba29 2975 case CTC_SHAwDSA:
Vanger 0:b86d15c6ba29 2976 case CTC_SHAwECDSA:
Vanger 0:b86d15c6ba29 2977 if (ShaHash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 2978 typeH = SHAh;
Vanger 0:b86d15c6ba29 2979 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 2980 }
Vanger 0:b86d15c6ba29 2981 break;
Vanger 0:b86d15c6ba29 2982 #endif
Vanger 0:b86d15c6ba29 2983 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 2984 case CTC_SHA256wRSA:
Vanger 0:b86d15c6ba29 2985 case CTC_SHA256wECDSA:
Vanger 0:b86d15c6ba29 2986 if (Sha256Hash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 2987 typeH = SHA256h;
Vanger 0:b86d15c6ba29 2988 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 2989 }
Vanger 0:b86d15c6ba29 2990 break;
Vanger 0:b86d15c6ba29 2991 #endif
Vanger 0:b86d15c6ba29 2992 #ifdef CYASSL_SHA512
Vanger 0:b86d15c6ba29 2993 case CTC_SHA512wRSA:
Vanger 0:b86d15c6ba29 2994 case CTC_SHA512wECDSA:
Vanger 0:b86d15c6ba29 2995 if (Sha512Hash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 2996 typeH = SHA512h;
Vanger 0:b86d15c6ba29 2997 digestSz = SHA512_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 2998 }
Vanger 0:b86d15c6ba29 2999 break;
Vanger 0:b86d15c6ba29 3000 #endif
Vanger 0:b86d15c6ba29 3001 #ifdef CYASSL_SHA384
Vanger 0:b86d15c6ba29 3002 case CTC_SHA384wRSA:
Vanger 0:b86d15c6ba29 3003 case CTC_SHA384wECDSA:
Vanger 0:b86d15c6ba29 3004 if (Sha384Hash(buf, bufSz, digest) == 0) {
Vanger 0:b86d15c6ba29 3005 typeH = SHA384h;
Vanger 0:b86d15c6ba29 3006 digestSz = SHA384_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 3007 }
Vanger 0:b86d15c6ba29 3008 break;
Vanger 0:b86d15c6ba29 3009 #endif
Vanger 0:b86d15c6ba29 3010 default:
Vanger 0:b86d15c6ba29 3011 CYASSL_MSG("Verify Signautre has unsupported type");
Vanger 0:b86d15c6ba29 3012 }
Vanger 0:b86d15c6ba29 3013
Vanger 0:b86d15c6ba29 3014 if (typeH == 0) {
Vanger 0:b86d15c6ba29 3015 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3016 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3017 #endif
Vanger 0:b86d15c6ba29 3018 return 0; /* not confirmed */
Vanger 0:b86d15c6ba29 3019 }
Vanger 0:b86d15c6ba29 3020
Vanger 0:b86d15c6ba29 3021 switch (keyOID) {
Vanger 0:b86d15c6ba29 3022 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 3023 case RSAk:
Vanger 0:b86d15c6ba29 3024 {
Vanger 0:b86d15c6ba29 3025 word32 idx = 0;
Vanger 0:b86d15c6ba29 3026 int encodedSigSz, verifySz;
Vanger 0:b86d15c6ba29 3027 byte* out;
Vanger 0:b86d15c6ba29 3028 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3029 RsaKey* pubKey;
Vanger 0:b86d15c6ba29 3030 byte* plain;
Vanger 0:b86d15c6ba29 3031 byte* encodedSig;
Vanger 0:b86d15c6ba29 3032 #else
Vanger 0:b86d15c6ba29 3033 RsaKey pubKey[1];
Vanger 0:b86d15c6ba29 3034 byte plain[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 3035 byte encodedSig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 3036 #endif
Vanger 0:b86d15c6ba29 3037
Vanger 0:b86d15c6ba29 3038 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3039 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
Vanger 0:b86d15c6ba29 3040 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3041 plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 3042 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3043 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
Vanger 0:b86d15c6ba29 3044 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3045
Vanger 0:b86d15c6ba29 3046 if (pubKey == NULL || plain == NULL || encodedSig == NULL) {
Vanger 0:b86d15c6ba29 3047 CYASSL_MSG("Failed to allocate memory at ConfirmSignature");
Vanger 0:b86d15c6ba29 3048
Vanger 0:b86d15c6ba29 3049 if (pubKey)
Vanger 0:b86d15c6ba29 3050 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3051 if (plain)
Vanger 0:b86d15c6ba29 3052 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3053 if (encodedSig)
Vanger 0:b86d15c6ba29 3054 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3055
Vanger 0:b86d15c6ba29 3056 break; /* not confirmed */
Vanger 0:b86d15c6ba29 3057 }
Vanger 0:b86d15c6ba29 3058 #endif
Vanger 0:b86d15c6ba29 3059
Vanger 0:b86d15c6ba29 3060 if (sigSz > MAX_ENCODED_SIG_SZ) {
Vanger 0:b86d15c6ba29 3061 CYASSL_MSG("Verify Signautre is too big");
Vanger 0:b86d15c6ba29 3062 }
Vanger 0:b86d15c6ba29 3063 else if (InitRsaKey(pubKey, heap) != 0) {
Vanger 0:b86d15c6ba29 3064 CYASSL_MSG("InitRsaKey failed");
Vanger 0:b86d15c6ba29 3065 }
Vanger 0:b86d15c6ba29 3066 else if (RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) {
Vanger 0:b86d15c6ba29 3067 CYASSL_MSG("ASN Key decode error RSA");
Vanger 0:b86d15c6ba29 3068 }
Vanger 0:b86d15c6ba29 3069 else {
Vanger 0:b86d15c6ba29 3070 XMEMCPY(plain, sig, sigSz);
Vanger 0:b86d15c6ba29 3071
Vanger 0:b86d15c6ba29 3072 if ((verifySz = RsaSSL_VerifyInline(plain, sigSz, &out,
Vanger 0:b86d15c6ba29 3073 pubKey)) < 0) {
Vanger 0:b86d15c6ba29 3074 CYASSL_MSG("Rsa SSL verify error");
Vanger 0:b86d15c6ba29 3075 }
Vanger 0:b86d15c6ba29 3076 else {
Vanger 0:b86d15c6ba29 3077 /* make sure we're right justified */
Vanger 0:b86d15c6ba29 3078 encodedSigSz =
Vanger 0:b86d15c6ba29 3079 EncodeSignature(encodedSig, digest, digestSz, typeH);
Vanger 0:b86d15c6ba29 3080 if (encodedSigSz != verifySz ||
Vanger 0:b86d15c6ba29 3081 XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
Vanger 0:b86d15c6ba29 3082 CYASSL_MSG("Rsa SSL verify match encode error");
Vanger 0:b86d15c6ba29 3083 }
Vanger 0:b86d15c6ba29 3084 else
Vanger 0:b86d15c6ba29 3085 ret = 1; /* match */
Vanger 0:b86d15c6ba29 3086
Vanger 0:b86d15c6ba29 3087 #ifdef CYASSL_DEBUG_ENCODING
Vanger 0:b86d15c6ba29 3088 {
Vanger 0:b86d15c6ba29 3089 int x;
Vanger 0:b86d15c6ba29 3090
Vanger 0:b86d15c6ba29 3091 printf("cyassl encodedSig:\n");
Vanger 0:b86d15c6ba29 3092
Vanger 0:b86d15c6ba29 3093 for (x = 0; x < encodedSigSz; x++) {
Vanger 0:b86d15c6ba29 3094 printf("%02x ", encodedSig[x]);
Vanger 0:b86d15c6ba29 3095 if ( (x % 16) == 15)
Vanger 0:b86d15c6ba29 3096 printf("\n");
Vanger 0:b86d15c6ba29 3097 }
Vanger 0:b86d15c6ba29 3098
Vanger 0:b86d15c6ba29 3099 printf("\n");
Vanger 0:b86d15c6ba29 3100 printf("actual digest:\n");
Vanger 0:b86d15c6ba29 3101
Vanger 0:b86d15c6ba29 3102 for (x = 0; x < verifySz; x++) {
Vanger 0:b86d15c6ba29 3103 printf("%02x ", out[x]);
Vanger 0:b86d15c6ba29 3104 if ( (x % 16) == 15)
Vanger 0:b86d15c6ba29 3105 printf("\n");
Vanger 0:b86d15c6ba29 3106 }
Vanger 0:b86d15c6ba29 3107
Vanger 0:b86d15c6ba29 3108 printf("\n");
Vanger 0:b86d15c6ba29 3109 }
Vanger 0:b86d15c6ba29 3110 #endif /* CYASSL_DEBUG_ENCODING */
Vanger 0:b86d15c6ba29 3111
Vanger 0:b86d15c6ba29 3112 }
Vanger 0:b86d15c6ba29 3113
Vanger 0:b86d15c6ba29 3114 }
Vanger 0:b86d15c6ba29 3115
Vanger 0:b86d15c6ba29 3116 FreeRsaKey(pubKey);
Vanger 0:b86d15c6ba29 3117
Vanger 0:b86d15c6ba29 3118 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3119 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3120 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3121 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3122 #endif
Vanger 0:b86d15c6ba29 3123 break;
Vanger 0:b86d15c6ba29 3124 }
Vanger 0:b86d15c6ba29 3125
Vanger 0:b86d15c6ba29 3126 #endif /* NO_RSA */
Vanger 0:b86d15c6ba29 3127 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 3128 case ECDSAk:
Vanger 0:b86d15c6ba29 3129 {
Vanger 0:b86d15c6ba29 3130 int verify = 0;
Vanger 0:b86d15c6ba29 3131 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3132 ecc_key* pubKey;
Vanger 0:b86d15c6ba29 3133 #else
Vanger 0:b86d15c6ba29 3134 ecc_key pubKey[1];
Vanger 0:b86d15c6ba29 3135 #endif
Vanger 0:b86d15c6ba29 3136
Vanger 0:b86d15c6ba29 3137 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3138 pubKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL,
Vanger 0:b86d15c6ba29 3139 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3140 if (pubKey == NULL) {
Vanger 0:b86d15c6ba29 3141 CYASSL_MSG("Failed to allocate pubKey");
Vanger 0:b86d15c6ba29 3142 break; /* not confirmed */
Vanger 0:b86d15c6ba29 3143 }
Vanger 0:b86d15c6ba29 3144 #endif
Vanger 0:b86d15c6ba29 3145
Vanger 0:b86d15c6ba29 3146 if (ecc_import_x963(key, keySz, pubKey) < 0) {
Vanger 0:b86d15c6ba29 3147 CYASSL_MSG("ASN Key import error ECC");
Vanger 0:b86d15c6ba29 3148 }
Vanger 0:b86d15c6ba29 3149 else {
Vanger 0:b86d15c6ba29 3150 if (ecc_verify_hash(sig, sigSz, digest, digestSz, &verify,
Vanger 0:b86d15c6ba29 3151 pubKey) != 0) {
Vanger 0:b86d15c6ba29 3152 CYASSL_MSG("ECC verify hash error");
Vanger 0:b86d15c6ba29 3153 }
Vanger 0:b86d15c6ba29 3154 else if (1 != verify) {
Vanger 0:b86d15c6ba29 3155 CYASSL_MSG("ECC Verify didn't match");
Vanger 0:b86d15c6ba29 3156 } else
Vanger 0:b86d15c6ba29 3157 ret = 1; /* match */
Vanger 0:b86d15c6ba29 3158
Vanger 0:b86d15c6ba29 3159 ecc_free(pubKey);
Vanger 0:b86d15c6ba29 3160 }
Vanger 0:b86d15c6ba29 3161 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3162 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3163 #endif
Vanger 0:b86d15c6ba29 3164 break;
Vanger 0:b86d15c6ba29 3165 }
Vanger 0:b86d15c6ba29 3166 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 3167 default:
Vanger 0:b86d15c6ba29 3168 CYASSL_MSG("Verify Key type unknown");
Vanger 0:b86d15c6ba29 3169 }
Vanger 0:b86d15c6ba29 3170
Vanger 0:b86d15c6ba29 3171 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 3172 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 3173 #endif
Vanger 0:b86d15c6ba29 3174
Vanger 0:b86d15c6ba29 3175 return ret;
Vanger 0:b86d15c6ba29 3176 }
Vanger 0:b86d15c6ba29 3177
Vanger 0:b86d15c6ba29 3178
Vanger 0:b86d15c6ba29 3179 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 3180
Vanger 0:b86d15c6ba29 3181 static int MatchBaseName(int type, const char* name, int nameSz,
Vanger 0:b86d15c6ba29 3182 const char* base, int baseSz)
Vanger 0:b86d15c6ba29 3183 {
Vanger 0:b86d15c6ba29 3184 if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
Vanger 0:b86d15c6ba29 3185 name[0] == '.' || nameSz < baseSz ||
Vanger 0:b86d15c6ba29 3186 (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
Vanger 0:b86d15c6ba29 3187 return 0;
Vanger 0:b86d15c6ba29 3188
Vanger 0:b86d15c6ba29 3189 /* If an email type, handle special cases where the base is only
Vanger 0:b86d15c6ba29 3190 * a domain, or is an email address itself. */
Vanger 0:b86d15c6ba29 3191 if (type == ASN_RFC822_TYPE) {
Vanger 0:b86d15c6ba29 3192 const char* p = NULL;
Vanger 0:b86d15c6ba29 3193 int count = 0;
Vanger 0:b86d15c6ba29 3194
Vanger 0:b86d15c6ba29 3195 if (base[0] != '.') {
Vanger 0:b86d15c6ba29 3196 p = base;
Vanger 0:b86d15c6ba29 3197 count = 0;
Vanger 0:b86d15c6ba29 3198
Vanger 0:b86d15c6ba29 3199 /* find the '@' in the base */
Vanger 0:b86d15c6ba29 3200 while (*p != '@' && count < baseSz) {
Vanger 0:b86d15c6ba29 3201 count++;
Vanger 0:b86d15c6ba29 3202 p++;
Vanger 0:b86d15c6ba29 3203 }
Vanger 0:b86d15c6ba29 3204
Vanger 0:b86d15c6ba29 3205 /* No '@' in base, reset p to NULL */
Vanger 0:b86d15c6ba29 3206 if (count >= baseSz)
Vanger 0:b86d15c6ba29 3207 p = NULL;
Vanger 0:b86d15c6ba29 3208 }
Vanger 0:b86d15c6ba29 3209
Vanger 0:b86d15c6ba29 3210 if (p == NULL) {
Vanger 0:b86d15c6ba29 3211 /* Base isn't an email address, it is a domain name,
Vanger 0:b86d15c6ba29 3212 * wind the name forward one character past its '@'. */
Vanger 0:b86d15c6ba29 3213 p = name;
Vanger 0:b86d15c6ba29 3214 count = 0;
Vanger 0:b86d15c6ba29 3215 while (*p != '@' && count < baseSz) {
Vanger 0:b86d15c6ba29 3216 count++;
Vanger 0:b86d15c6ba29 3217 p++;
Vanger 0:b86d15c6ba29 3218 }
Vanger 0:b86d15c6ba29 3219
Vanger 0:b86d15c6ba29 3220 if (count < baseSz && *p == '@') {
Vanger 0:b86d15c6ba29 3221 name = p + 1;
Vanger 0:b86d15c6ba29 3222 nameSz -= count + 1;
Vanger 0:b86d15c6ba29 3223 }
Vanger 0:b86d15c6ba29 3224 }
Vanger 0:b86d15c6ba29 3225 }
Vanger 0:b86d15c6ba29 3226
Vanger 0:b86d15c6ba29 3227 if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
Vanger 0:b86d15c6ba29 3228 int szAdjust = nameSz - baseSz;
Vanger 0:b86d15c6ba29 3229 name += szAdjust;
Vanger 0:b86d15c6ba29 3230 nameSz -= szAdjust;
Vanger 0:b86d15c6ba29 3231 }
Vanger 0:b86d15c6ba29 3232
Vanger 0:b86d15c6ba29 3233 while (nameSz > 0) {
Vanger 0:b86d15c6ba29 3234 if (XTOLOWER(*name++) != XTOLOWER(*base++))
Vanger 0:b86d15c6ba29 3235 return 0;
Vanger 0:b86d15c6ba29 3236 nameSz--;
Vanger 0:b86d15c6ba29 3237 }
Vanger 0:b86d15c6ba29 3238
Vanger 0:b86d15c6ba29 3239 return 1;
Vanger 0:b86d15c6ba29 3240 }
Vanger 0:b86d15c6ba29 3241
Vanger 0:b86d15c6ba29 3242
Vanger 0:b86d15c6ba29 3243 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3244 {
Vanger 0:b86d15c6ba29 3245 if (signer == NULL || cert == NULL)
Vanger 0:b86d15c6ba29 3246 return 0;
Vanger 0:b86d15c6ba29 3247
Vanger 0:b86d15c6ba29 3248 /* Check against the excluded list */
Vanger 0:b86d15c6ba29 3249 if (signer->excludedNames) {
Vanger 0:b86d15c6ba29 3250 Base_entry* base = signer->excludedNames;
Vanger 0:b86d15c6ba29 3251
Vanger 0:b86d15c6ba29 3252 while (base != NULL) {
Vanger 0:b86d15c6ba29 3253 if (base->type == ASN_DNS_TYPE) {
Vanger 0:b86d15c6ba29 3254 DNS_entry* name = cert->altNames;
Vanger 0:b86d15c6ba29 3255 while (name != NULL) {
Vanger 0:b86d15c6ba29 3256 if (MatchBaseName(ASN_DNS_TYPE,
Vanger 0:b86d15c6ba29 3257 name->name, (int)XSTRLEN(name->name),
Vanger 0:b86d15c6ba29 3258 base->name, base->nameSz))
Vanger 0:b86d15c6ba29 3259 return 0;
Vanger 0:b86d15c6ba29 3260 name = name->next;
Vanger 0:b86d15c6ba29 3261 }
Vanger 0:b86d15c6ba29 3262 }
Vanger 0:b86d15c6ba29 3263 else if (base->type == ASN_RFC822_TYPE) {
Vanger 0:b86d15c6ba29 3264 DNS_entry* name = cert->altEmailNames;
Vanger 0:b86d15c6ba29 3265 while (name != NULL) {
Vanger 0:b86d15c6ba29 3266 if (MatchBaseName(ASN_RFC822_TYPE,
Vanger 0:b86d15c6ba29 3267 name->name, (int)XSTRLEN(name->name),
Vanger 0:b86d15c6ba29 3268 base->name, base->nameSz))
Vanger 0:b86d15c6ba29 3269 return 0;
Vanger 0:b86d15c6ba29 3270
Vanger 0:b86d15c6ba29 3271 name = name->next;
Vanger 0:b86d15c6ba29 3272 }
Vanger 0:b86d15c6ba29 3273 }
Vanger 0:b86d15c6ba29 3274 else if (base->type == ASN_DIR_TYPE) {
Vanger 0:b86d15c6ba29 3275 if (cert->subjectRawLen == base->nameSz &&
Vanger 0:b86d15c6ba29 3276 XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
Vanger 0:b86d15c6ba29 3277
Vanger 0:b86d15c6ba29 3278 return 0;
Vanger 0:b86d15c6ba29 3279 }
Vanger 0:b86d15c6ba29 3280 }
Vanger 0:b86d15c6ba29 3281 base = base->next;
Vanger 0:b86d15c6ba29 3282 }
Vanger 0:b86d15c6ba29 3283 }
Vanger 0:b86d15c6ba29 3284
Vanger 0:b86d15c6ba29 3285 /* Check against the permitted list */
Vanger 0:b86d15c6ba29 3286 if (signer->permittedNames != NULL) {
Vanger 0:b86d15c6ba29 3287 int needDns = 0;
Vanger 0:b86d15c6ba29 3288 int matchDns = 0;
Vanger 0:b86d15c6ba29 3289 int needEmail = 0;
Vanger 0:b86d15c6ba29 3290 int matchEmail = 0;
Vanger 0:b86d15c6ba29 3291 int needDir = 0;
Vanger 0:b86d15c6ba29 3292 int matchDir = 0;
Vanger 0:b86d15c6ba29 3293 Base_entry* base = signer->permittedNames;
Vanger 0:b86d15c6ba29 3294
Vanger 0:b86d15c6ba29 3295 while (base != NULL) {
Vanger 0:b86d15c6ba29 3296 if (base->type == ASN_DNS_TYPE) {
Vanger 0:b86d15c6ba29 3297 DNS_entry* name = cert->altNames;
Vanger 0:b86d15c6ba29 3298
Vanger 0:b86d15c6ba29 3299 if (name != NULL)
Vanger 0:b86d15c6ba29 3300 needDns = 1;
Vanger 0:b86d15c6ba29 3301
Vanger 0:b86d15c6ba29 3302 while (name != NULL) {
Vanger 0:b86d15c6ba29 3303 matchDns = MatchBaseName(ASN_DNS_TYPE,
Vanger 0:b86d15c6ba29 3304 name->name, (int)XSTRLEN(name->name),
Vanger 0:b86d15c6ba29 3305 base->name, base->nameSz);
Vanger 0:b86d15c6ba29 3306 name = name->next;
Vanger 0:b86d15c6ba29 3307 }
Vanger 0:b86d15c6ba29 3308 }
Vanger 0:b86d15c6ba29 3309 else if (base->type == ASN_RFC822_TYPE) {
Vanger 0:b86d15c6ba29 3310 DNS_entry* name = cert->altEmailNames;
Vanger 0:b86d15c6ba29 3311
Vanger 0:b86d15c6ba29 3312 if (name != NULL)
Vanger 0:b86d15c6ba29 3313 needEmail = 1;
Vanger 0:b86d15c6ba29 3314
Vanger 0:b86d15c6ba29 3315 while (name != NULL) {
Vanger 0:b86d15c6ba29 3316 matchEmail = MatchBaseName(ASN_DNS_TYPE,
Vanger 0:b86d15c6ba29 3317 name->name, (int)XSTRLEN(name->name),
Vanger 0:b86d15c6ba29 3318 base->name, base->nameSz);
Vanger 0:b86d15c6ba29 3319 name = name->next;
Vanger 0:b86d15c6ba29 3320 }
Vanger 0:b86d15c6ba29 3321 }
Vanger 0:b86d15c6ba29 3322 else if (base->type == ASN_DIR_TYPE) {
Vanger 0:b86d15c6ba29 3323 needDir = 1;
Vanger 0:b86d15c6ba29 3324 if (cert->subjectRaw != NULL &&
Vanger 0:b86d15c6ba29 3325 cert->subjectRawLen == base->nameSz &&
Vanger 0:b86d15c6ba29 3326 XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) {
Vanger 0:b86d15c6ba29 3327
Vanger 0:b86d15c6ba29 3328 matchDir = 1;
Vanger 0:b86d15c6ba29 3329 }
Vanger 0:b86d15c6ba29 3330 }
Vanger 0:b86d15c6ba29 3331 base = base->next;
Vanger 0:b86d15c6ba29 3332 }
Vanger 0:b86d15c6ba29 3333
Vanger 0:b86d15c6ba29 3334 if ((needDns && !matchDns) || (needEmail && !matchEmail) ||
Vanger 0:b86d15c6ba29 3335 (needDir && !matchDir)) {
Vanger 0:b86d15c6ba29 3336
Vanger 0:b86d15c6ba29 3337 return 0;
Vanger 0:b86d15c6ba29 3338 }
Vanger 0:b86d15c6ba29 3339 }
Vanger 0:b86d15c6ba29 3340
Vanger 0:b86d15c6ba29 3341 return 1;
Vanger 0:b86d15c6ba29 3342 }
Vanger 0:b86d15c6ba29 3343
Vanger 0:b86d15c6ba29 3344 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 3345
Vanger 0:b86d15c6ba29 3346
Vanger 0:b86d15c6ba29 3347 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3348 {
Vanger 0:b86d15c6ba29 3349 word32 idx = 0;
Vanger 0:b86d15c6ba29 3350 int length = 0;
Vanger 0:b86d15c6ba29 3351
Vanger 0:b86d15c6ba29 3352 CYASSL_ENTER("DecodeAltNames");
Vanger 0:b86d15c6ba29 3353
Vanger 0:b86d15c6ba29 3354 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3355 CYASSL_MSG("\tBad Sequence");
Vanger 0:b86d15c6ba29 3356 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3357 }
Vanger 0:b86d15c6ba29 3358
Vanger 0:b86d15c6ba29 3359 while (length > 0) {
Vanger 0:b86d15c6ba29 3360 byte b = input[idx++];
Vanger 0:b86d15c6ba29 3361
Vanger 0:b86d15c6ba29 3362 length--;
Vanger 0:b86d15c6ba29 3363
Vanger 0:b86d15c6ba29 3364 /* Save DNS Type names in the altNames list. */
Vanger 0:b86d15c6ba29 3365 /* Save Other Type names in the cert's OidMap */
Vanger 0:b86d15c6ba29 3366 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
Vanger 0:b86d15c6ba29 3367 DNS_entry* dnsEntry;
Vanger 0:b86d15c6ba29 3368 int strLen;
Vanger 0:b86d15c6ba29 3369 word32 lenStartIdx = idx;
Vanger 0:b86d15c6ba29 3370
Vanger 0:b86d15c6ba29 3371 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3372 CYASSL_MSG("\tfail: str length");
Vanger 0:b86d15c6ba29 3373 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3374 }
Vanger 0:b86d15c6ba29 3375 length -= (idx - lenStartIdx);
Vanger 0:b86d15c6ba29 3376
Vanger 0:b86d15c6ba29 3377 dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
Vanger 0:b86d15c6ba29 3378 DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3379 if (dnsEntry == NULL) {
Vanger 0:b86d15c6ba29 3380 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3381 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3382 }
Vanger 0:b86d15c6ba29 3383
Vanger 0:b86d15c6ba29 3384 dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
Vanger 0:b86d15c6ba29 3385 DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3386 if (dnsEntry->name == NULL) {
Vanger 0:b86d15c6ba29 3387 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3388 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3389 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3390 }
Vanger 0:b86d15c6ba29 3391
Vanger 0:b86d15c6ba29 3392 XMEMCPY(dnsEntry->name, &input[idx], strLen);
Vanger 0:b86d15c6ba29 3393 dnsEntry->name[strLen] = '\0';
Vanger 0:b86d15c6ba29 3394
Vanger 0:b86d15c6ba29 3395 dnsEntry->next = cert->altNames;
Vanger 0:b86d15c6ba29 3396 cert->altNames = dnsEntry;
Vanger 0:b86d15c6ba29 3397
Vanger 0:b86d15c6ba29 3398 length -= strLen;
Vanger 0:b86d15c6ba29 3399 idx += strLen;
Vanger 0:b86d15c6ba29 3400 }
Vanger 0:b86d15c6ba29 3401 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 3402 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
Vanger 0:b86d15c6ba29 3403 DNS_entry* emailEntry;
Vanger 0:b86d15c6ba29 3404 int strLen;
Vanger 0:b86d15c6ba29 3405 word32 lenStartIdx = idx;
Vanger 0:b86d15c6ba29 3406
Vanger 0:b86d15c6ba29 3407 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3408 CYASSL_MSG("\tfail: str length");
Vanger 0:b86d15c6ba29 3409 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3410 }
Vanger 0:b86d15c6ba29 3411 length -= (idx - lenStartIdx);
Vanger 0:b86d15c6ba29 3412
Vanger 0:b86d15c6ba29 3413 emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
Vanger 0:b86d15c6ba29 3414 DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3415 if (emailEntry == NULL) {
Vanger 0:b86d15c6ba29 3416 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3417 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3418 }
Vanger 0:b86d15c6ba29 3419
Vanger 0:b86d15c6ba29 3420 emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
Vanger 0:b86d15c6ba29 3421 DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3422 if (emailEntry->name == NULL) {
Vanger 0:b86d15c6ba29 3423 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3424 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3425 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3426 }
Vanger 0:b86d15c6ba29 3427
Vanger 0:b86d15c6ba29 3428 XMEMCPY(emailEntry->name, &input[idx], strLen);
Vanger 0:b86d15c6ba29 3429 emailEntry->name[strLen] = '\0';
Vanger 0:b86d15c6ba29 3430
Vanger 0:b86d15c6ba29 3431 emailEntry->next = cert->altEmailNames;
Vanger 0:b86d15c6ba29 3432 cert->altEmailNames = emailEntry;
Vanger 0:b86d15c6ba29 3433
Vanger 0:b86d15c6ba29 3434 length -= strLen;
Vanger 0:b86d15c6ba29 3435 idx += strLen;
Vanger 0:b86d15c6ba29 3436 }
Vanger 0:b86d15c6ba29 3437 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 3438 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 3439 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
Vanger 0:b86d15c6ba29 3440 {
Vanger 0:b86d15c6ba29 3441 int strLen;
Vanger 0:b86d15c6ba29 3442 word32 lenStartIdx = idx;
Vanger 0:b86d15c6ba29 3443 word32 oid = 0;
Vanger 0:b86d15c6ba29 3444
Vanger 0:b86d15c6ba29 3445 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3446 CYASSL_MSG("\tfail: other name length");
Vanger 0:b86d15c6ba29 3447 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3448 }
Vanger 0:b86d15c6ba29 3449 /* Consume the rest of this sequence. */
Vanger 0:b86d15c6ba29 3450 length -= (strLen + idx - lenStartIdx);
Vanger 0:b86d15c6ba29 3451
Vanger 0:b86d15c6ba29 3452 if (GetObjectId(input, &idx, &oid, sz) < 0) {
Vanger 0:b86d15c6ba29 3453 CYASSL_MSG("\tbad OID");
Vanger 0:b86d15c6ba29 3454 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3455 }
Vanger 0:b86d15c6ba29 3456
Vanger 0:b86d15c6ba29 3457 if (oid != HW_NAME_OID) {
Vanger 0:b86d15c6ba29 3458 CYASSL_MSG("\tincorrect OID");
Vanger 0:b86d15c6ba29 3459 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3460 }
Vanger 0:b86d15c6ba29 3461
Vanger 0:b86d15c6ba29 3462 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
Vanger 0:b86d15c6ba29 3463 CYASSL_MSG("\twrong type");
Vanger 0:b86d15c6ba29 3464 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3465 }
Vanger 0:b86d15c6ba29 3466
Vanger 0:b86d15c6ba29 3467 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3468 CYASSL_MSG("\tfail: str len");
Vanger 0:b86d15c6ba29 3469 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3470 }
Vanger 0:b86d15c6ba29 3471
Vanger 0:b86d15c6ba29 3472 if (GetSequence(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3473 CYASSL_MSG("\tBad Sequence");
Vanger 0:b86d15c6ba29 3474 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3475 }
Vanger 0:b86d15c6ba29 3476
Vanger 0:b86d15c6ba29 3477 if (input[idx++] != ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 3478 CYASSL_MSG("\texpected OID");
Vanger 0:b86d15c6ba29 3479 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3480 }
Vanger 0:b86d15c6ba29 3481
Vanger 0:b86d15c6ba29 3482 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3483 CYASSL_MSG("\tfailed: str len");
Vanger 0:b86d15c6ba29 3484 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3485 }
Vanger 0:b86d15c6ba29 3486
Vanger 0:b86d15c6ba29 3487 cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0);
Vanger 0:b86d15c6ba29 3488 if (cert->hwType == NULL) {
Vanger 0:b86d15c6ba29 3489 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3490 return MEMORY_E;
Vanger 0:b86d15c6ba29 3491 }
Vanger 0:b86d15c6ba29 3492
Vanger 0:b86d15c6ba29 3493 XMEMCPY(cert->hwType, &input[idx], strLen);
Vanger 0:b86d15c6ba29 3494 cert->hwTypeSz = strLen;
Vanger 0:b86d15c6ba29 3495 idx += strLen;
Vanger 0:b86d15c6ba29 3496
Vanger 0:b86d15c6ba29 3497 if (input[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 3498 CYASSL_MSG("\texpected Octet String");
Vanger 0:b86d15c6ba29 3499 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3500 }
Vanger 0:b86d15c6ba29 3501
Vanger 0:b86d15c6ba29 3502 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3503 CYASSL_MSG("\tfailed: str len");
Vanger 0:b86d15c6ba29 3504 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3505 }
Vanger 0:b86d15c6ba29 3506
Vanger 0:b86d15c6ba29 3507 cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0);
Vanger 0:b86d15c6ba29 3508 if (cert->hwSerialNum == NULL) {
Vanger 0:b86d15c6ba29 3509 CYASSL_MSG("\tOut of Memory");
Vanger 0:b86d15c6ba29 3510 return MEMORY_E;
Vanger 0:b86d15c6ba29 3511 }
Vanger 0:b86d15c6ba29 3512
Vanger 0:b86d15c6ba29 3513 XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
Vanger 0:b86d15c6ba29 3514 cert->hwSerialNum[strLen] = '\0';
Vanger 0:b86d15c6ba29 3515 cert->hwSerialNumSz = strLen;
Vanger 0:b86d15c6ba29 3516 idx += strLen;
Vanger 0:b86d15c6ba29 3517 }
Vanger 0:b86d15c6ba29 3518 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 3519 else {
Vanger 0:b86d15c6ba29 3520 int strLen;
Vanger 0:b86d15c6ba29 3521 word32 lenStartIdx = idx;
Vanger 0:b86d15c6ba29 3522
Vanger 0:b86d15c6ba29 3523 CYASSL_MSG("\tUnsupported name type, skipping");
Vanger 0:b86d15c6ba29 3524
Vanger 0:b86d15c6ba29 3525 if (GetLength(input, &idx, &strLen, sz) < 0) {
Vanger 0:b86d15c6ba29 3526 CYASSL_MSG("\tfail: unsupported name length");
Vanger 0:b86d15c6ba29 3527 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3528 }
Vanger 0:b86d15c6ba29 3529 length -= (strLen + idx - lenStartIdx);
Vanger 0:b86d15c6ba29 3530 idx += strLen;
Vanger 0:b86d15c6ba29 3531 }
Vanger 0:b86d15c6ba29 3532 }
Vanger 0:b86d15c6ba29 3533 return 0;
Vanger 0:b86d15c6ba29 3534 }
Vanger 0:b86d15c6ba29 3535
Vanger 0:b86d15c6ba29 3536
Vanger 0:b86d15c6ba29 3537 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3538 {
Vanger 0:b86d15c6ba29 3539 word32 idx = 0;
Vanger 0:b86d15c6ba29 3540 int length = 0;
Vanger 0:b86d15c6ba29 3541
Vanger 0:b86d15c6ba29 3542 CYASSL_ENTER("DecodeBasicCaConstraint");
Vanger 0:b86d15c6ba29 3543 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3544 CYASSL_MSG("\tfail: bad SEQUENCE");
Vanger 0:b86d15c6ba29 3545 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3546 }
Vanger 0:b86d15c6ba29 3547
Vanger 0:b86d15c6ba29 3548 if (length == 0)
Vanger 0:b86d15c6ba29 3549 return 0;
Vanger 0:b86d15c6ba29 3550
Vanger 0:b86d15c6ba29 3551 /* If the basic ca constraint is false, this extension may be named, but
Vanger 0:b86d15c6ba29 3552 * left empty. So, if the length is 0, just return. */
Vanger 0:b86d15c6ba29 3553
Vanger 0:b86d15c6ba29 3554 if (input[idx++] != ASN_BOOLEAN)
Vanger 0:b86d15c6ba29 3555 {
Vanger 0:b86d15c6ba29 3556 CYASSL_MSG("\tfail: constraint not BOOLEAN");
Vanger 0:b86d15c6ba29 3557 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3558 }
Vanger 0:b86d15c6ba29 3559
Vanger 0:b86d15c6ba29 3560 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3561 {
Vanger 0:b86d15c6ba29 3562 CYASSL_MSG("\tfail: length");
Vanger 0:b86d15c6ba29 3563 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3564 }
Vanger 0:b86d15c6ba29 3565
Vanger 0:b86d15c6ba29 3566 if (input[idx++])
Vanger 0:b86d15c6ba29 3567 cert->isCA = 1;
Vanger 0:b86d15c6ba29 3568
Vanger 0:b86d15c6ba29 3569 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3570 /* If there isn't any more data, return. */
Vanger 0:b86d15c6ba29 3571 if (idx >= (word32)sz)
Vanger 0:b86d15c6ba29 3572 return 0;
Vanger 0:b86d15c6ba29 3573
Vanger 0:b86d15c6ba29 3574 /* Anything left should be the optional pathlength */
Vanger 0:b86d15c6ba29 3575 if (input[idx++] != ASN_INTEGER) {
Vanger 0:b86d15c6ba29 3576 CYASSL_MSG("\tfail: pathlen not INTEGER");
Vanger 0:b86d15c6ba29 3577 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3578 }
Vanger 0:b86d15c6ba29 3579
Vanger 0:b86d15c6ba29 3580 if (input[idx++] != 1) {
Vanger 0:b86d15c6ba29 3581 CYASSL_MSG("\tfail: pathlen too long");
Vanger 0:b86d15c6ba29 3582 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3583 }
Vanger 0:b86d15c6ba29 3584
Vanger 0:b86d15c6ba29 3585 cert->pathLength = input[idx];
Vanger 0:b86d15c6ba29 3586 cert->extBasicConstPlSet = 1;
Vanger 0:b86d15c6ba29 3587 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 3588
Vanger 0:b86d15c6ba29 3589 return 0;
Vanger 0:b86d15c6ba29 3590 }
Vanger 0:b86d15c6ba29 3591
Vanger 0:b86d15c6ba29 3592
Vanger 0:b86d15c6ba29 3593 #define CRLDP_FULL_NAME 0
Vanger 0:b86d15c6ba29 3594 /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
Vanger 0:b86d15c6ba29 3595 #define GENERALNAME_URI 6
Vanger 0:b86d15c6ba29 3596 /* From RFC3280 SS4.2.1.7, GeneralName */
Vanger 0:b86d15c6ba29 3597
Vanger 0:b86d15c6ba29 3598 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3599 {
Vanger 0:b86d15c6ba29 3600 word32 idx = 0;
Vanger 0:b86d15c6ba29 3601 int length = 0;
Vanger 0:b86d15c6ba29 3602
Vanger 0:b86d15c6ba29 3603 CYASSL_ENTER("DecodeCrlDist");
Vanger 0:b86d15c6ba29 3604
Vanger 0:b86d15c6ba29 3605 /* Unwrap the list of Distribution Points*/
Vanger 0:b86d15c6ba29 3606 if (GetSequence(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3607 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3608
Vanger 0:b86d15c6ba29 3609 /* Unwrap a single Distribution Point */
Vanger 0:b86d15c6ba29 3610 if (GetSequence(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3611 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3612
Vanger 0:b86d15c6ba29 3613 /* The Distribution Point has three explicit optional members
Vanger 0:b86d15c6ba29 3614 * First check for a DistributionPointName
Vanger 0:b86d15c6ba29 3615 */
Vanger 0:b86d15c6ba29 3616 if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
Vanger 0:b86d15c6ba29 3617 {
Vanger 0:b86d15c6ba29 3618 idx++;
Vanger 0:b86d15c6ba29 3619 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3620 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3621
Vanger 0:b86d15c6ba29 3622 if (input[idx] ==
Vanger 0:b86d15c6ba29 3623 (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
Vanger 0:b86d15c6ba29 3624 {
Vanger 0:b86d15c6ba29 3625 idx++;
Vanger 0:b86d15c6ba29 3626 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3627 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3628
Vanger 0:b86d15c6ba29 3629 if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
Vanger 0:b86d15c6ba29 3630 {
Vanger 0:b86d15c6ba29 3631 idx++;
Vanger 0:b86d15c6ba29 3632 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3633 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3634
Vanger 0:b86d15c6ba29 3635 cert->extCrlInfoSz = length;
Vanger 0:b86d15c6ba29 3636 cert->extCrlInfo = input + idx;
Vanger 0:b86d15c6ba29 3637 idx += length;
Vanger 0:b86d15c6ba29 3638 }
Vanger 0:b86d15c6ba29 3639 else
Vanger 0:b86d15c6ba29 3640 /* This isn't a URI, skip it. */
Vanger 0:b86d15c6ba29 3641 idx += length;
Vanger 0:b86d15c6ba29 3642 }
Vanger 0:b86d15c6ba29 3643 else
Vanger 0:b86d15c6ba29 3644 /* This isn't a FULLNAME, skip it. */
Vanger 0:b86d15c6ba29 3645 idx += length;
Vanger 0:b86d15c6ba29 3646 }
Vanger 0:b86d15c6ba29 3647
Vanger 0:b86d15c6ba29 3648 /* Check for reasonFlags */
Vanger 0:b86d15c6ba29 3649 if (idx < (word32)sz &&
Vanger 0:b86d15c6ba29 3650 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
Vanger 0:b86d15c6ba29 3651 {
Vanger 0:b86d15c6ba29 3652 idx++;
Vanger 0:b86d15c6ba29 3653 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3654 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3655 idx += length;
Vanger 0:b86d15c6ba29 3656 }
Vanger 0:b86d15c6ba29 3657
Vanger 0:b86d15c6ba29 3658 /* Check for cRLIssuer */
Vanger 0:b86d15c6ba29 3659 if (idx < (word32)sz &&
Vanger 0:b86d15c6ba29 3660 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
Vanger 0:b86d15c6ba29 3661 {
Vanger 0:b86d15c6ba29 3662 idx++;
Vanger 0:b86d15c6ba29 3663 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3664 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3665 idx += length;
Vanger 0:b86d15c6ba29 3666 }
Vanger 0:b86d15c6ba29 3667
Vanger 0:b86d15c6ba29 3668 if (idx < (word32)sz)
Vanger 0:b86d15c6ba29 3669 {
Vanger 0:b86d15c6ba29 3670 CYASSL_MSG("\tThere are more CRL Distribution Point records, "
Vanger 0:b86d15c6ba29 3671 "but we only use the first one.");
Vanger 0:b86d15c6ba29 3672 }
Vanger 0:b86d15c6ba29 3673
Vanger 0:b86d15c6ba29 3674 return 0;
Vanger 0:b86d15c6ba29 3675 }
Vanger 0:b86d15c6ba29 3676
Vanger 0:b86d15c6ba29 3677
Vanger 0:b86d15c6ba29 3678 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3679 /*
Vanger 0:b86d15c6ba29 3680 * Read the first of the Authority Information Access records. If there are
Vanger 0:b86d15c6ba29 3681 * any issues, return without saving the record.
Vanger 0:b86d15c6ba29 3682 */
Vanger 0:b86d15c6ba29 3683 {
Vanger 0:b86d15c6ba29 3684 word32 idx = 0;
Vanger 0:b86d15c6ba29 3685 int length = 0;
Vanger 0:b86d15c6ba29 3686 byte b;
Vanger 0:b86d15c6ba29 3687 word32 oid;
Vanger 0:b86d15c6ba29 3688
Vanger 0:b86d15c6ba29 3689 CYASSL_ENTER("DecodeAuthInfo");
Vanger 0:b86d15c6ba29 3690
Vanger 0:b86d15c6ba29 3691 /* Unwrap the list of AIAs */
Vanger 0:b86d15c6ba29 3692 if (GetSequence(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3693 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3694
Vanger 0:b86d15c6ba29 3695 while (idx < (word32)sz) {
Vanger 0:b86d15c6ba29 3696 /* Unwrap a single AIA */
Vanger 0:b86d15c6ba29 3697 if (GetSequence(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3698 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3699
Vanger 0:b86d15c6ba29 3700 oid = 0;
Vanger 0:b86d15c6ba29 3701 if (GetObjectId(input, &idx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 3702 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3703
Vanger 0:b86d15c6ba29 3704 /* Only supporting URIs right now. */
Vanger 0:b86d15c6ba29 3705 b = input[idx++];
Vanger 0:b86d15c6ba29 3706 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 3707 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3708
Vanger 0:b86d15c6ba29 3709 if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
Vanger 0:b86d15c6ba29 3710 oid == AIA_OCSP_OID)
Vanger 0:b86d15c6ba29 3711 {
Vanger 0:b86d15c6ba29 3712 cert->extAuthInfoSz = length;
Vanger 0:b86d15c6ba29 3713 cert->extAuthInfo = input + idx;
Vanger 0:b86d15c6ba29 3714 break;
Vanger 0:b86d15c6ba29 3715 }
Vanger 0:b86d15c6ba29 3716 idx += length;
Vanger 0:b86d15c6ba29 3717 }
Vanger 0:b86d15c6ba29 3718
Vanger 0:b86d15c6ba29 3719 return 0;
Vanger 0:b86d15c6ba29 3720 }
Vanger 0:b86d15c6ba29 3721
Vanger 0:b86d15c6ba29 3722
Vanger 0:b86d15c6ba29 3723 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3724 {
Vanger 0:b86d15c6ba29 3725 word32 idx = 0;
Vanger 0:b86d15c6ba29 3726 int length = 0, ret = 0;
Vanger 0:b86d15c6ba29 3727
Vanger 0:b86d15c6ba29 3728 CYASSL_ENTER("DecodeAuthKeyId");
Vanger 0:b86d15c6ba29 3729
Vanger 0:b86d15c6ba29 3730 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3731 CYASSL_MSG("\tfail: should be a SEQUENCE\n");
Vanger 0:b86d15c6ba29 3732 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3733 }
Vanger 0:b86d15c6ba29 3734
Vanger 0:b86d15c6ba29 3735 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
Vanger 0:b86d15c6ba29 3736 CYASSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
Vanger 0:b86d15c6ba29 3737 return 0;
Vanger 0:b86d15c6ba29 3738 }
Vanger 0:b86d15c6ba29 3739
Vanger 0:b86d15c6ba29 3740 if (GetLength(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3741 CYASSL_MSG("\tfail: extension data length");
Vanger 0:b86d15c6ba29 3742 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3743 }
Vanger 0:b86d15c6ba29 3744
Vanger 0:b86d15c6ba29 3745 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3746 cert->extAuthKeyIdSrc = &input[idx];
Vanger 0:b86d15c6ba29 3747 cert->extAuthKeyIdSz = length;
Vanger 0:b86d15c6ba29 3748 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 3749
Vanger 0:b86d15c6ba29 3750 if (length == SHA_SIZE) {
Vanger 0:b86d15c6ba29 3751 XMEMCPY(cert->extAuthKeyId, input + idx, length);
Vanger 0:b86d15c6ba29 3752 }
Vanger 0:b86d15c6ba29 3753 else {
Vanger 0:b86d15c6ba29 3754 Sha sha;
Vanger 0:b86d15c6ba29 3755 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 3756 if (ret != 0)
Vanger 0:b86d15c6ba29 3757 return ret;
Vanger 0:b86d15c6ba29 3758 ShaUpdate(&sha, input + idx, length);
Vanger 0:b86d15c6ba29 3759 ShaFinal(&sha, cert->extAuthKeyId);
Vanger 0:b86d15c6ba29 3760 }
Vanger 0:b86d15c6ba29 3761
Vanger 0:b86d15c6ba29 3762 return 0;
Vanger 0:b86d15c6ba29 3763 }
Vanger 0:b86d15c6ba29 3764
Vanger 0:b86d15c6ba29 3765
Vanger 0:b86d15c6ba29 3766 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3767 {
Vanger 0:b86d15c6ba29 3768 word32 idx = 0;
Vanger 0:b86d15c6ba29 3769 int length = 0, ret = 0;
Vanger 0:b86d15c6ba29 3770
Vanger 0:b86d15c6ba29 3771 CYASSL_ENTER("DecodeSubjKeyId");
Vanger 0:b86d15c6ba29 3772
Vanger 0:b86d15c6ba29 3773 if (input[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 3774 CYASSL_MSG("\tfail: should be an OCTET STRING");
Vanger 0:b86d15c6ba29 3775 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3776 }
Vanger 0:b86d15c6ba29 3777
Vanger 0:b86d15c6ba29 3778 if (GetLength(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3779 CYASSL_MSG("\tfail: extension data length");
Vanger 0:b86d15c6ba29 3780 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3781 }
Vanger 0:b86d15c6ba29 3782
Vanger 0:b86d15c6ba29 3783 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3784 cert->extSubjKeyIdSrc = &input[idx];
Vanger 0:b86d15c6ba29 3785 cert->extSubjKeyIdSz = length;
Vanger 0:b86d15c6ba29 3786 #endif /* OPENSSL_EXTRA */
Vanger 0:b86d15c6ba29 3787
Vanger 0:b86d15c6ba29 3788 if (length == SIGNER_DIGEST_SIZE) {
Vanger 0:b86d15c6ba29 3789 XMEMCPY(cert->extSubjKeyId, input + idx, length);
Vanger 0:b86d15c6ba29 3790 }
Vanger 0:b86d15c6ba29 3791 else {
Vanger 0:b86d15c6ba29 3792 Sha sha;
Vanger 0:b86d15c6ba29 3793 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 3794 if (ret != 0)
Vanger 0:b86d15c6ba29 3795 return ret;
Vanger 0:b86d15c6ba29 3796 ShaUpdate(&sha, input + idx, length);
Vanger 0:b86d15c6ba29 3797 ShaFinal(&sha, cert->extSubjKeyId);
Vanger 0:b86d15c6ba29 3798 }
Vanger 0:b86d15c6ba29 3799
Vanger 0:b86d15c6ba29 3800 return ret;
Vanger 0:b86d15c6ba29 3801 }
Vanger 0:b86d15c6ba29 3802
Vanger 0:b86d15c6ba29 3803
Vanger 0:b86d15c6ba29 3804 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3805 {
Vanger 0:b86d15c6ba29 3806 word32 idx = 0;
Vanger 0:b86d15c6ba29 3807 int length;
Vanger 0:b86d15c6ba29 3808 byte unusedBits;
Vanger 0:b86d15c6ba29 3809 CYASSL_ENTER("DecodeKeyUsage");
Vanger 0:b86d15c6ba29 3810
Vanger 0:b86d15c6ba29 3811 if (input[idx++] != ASN_BIT_STRING) {
Vanger 0:b86d15c6ba29 3812 CYASSL_MSG("\tfail: key usage expected bit string");
Vanger 0:b86d15c6ba29 3813 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3814 }
Vanger 0:b86d15c6ba29 3815
Vanger 0:b86d15c6ba29 3816 if (GetLength(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3817 CYASSL_MSG("\tfail: key usage bad length");
Vanger 0:b86d15c6ba29 3818 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3819 }
Vanger 0:b86d15c6ba29 3820
Vanger 0:b86d15c6ba29 3821 unusedBits = input[idx++];
Vanger 0:b86d15c6ba29 3822 length--;
Vanger 0:b86d15c6ba29 3823
Vanger 0:b86d15c6ba29 3824 if (length == 2) {
Vanger 0:b86d15c6ba29 3825 cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]);
Vanger 0:b86d15c6ba29 3826 cert->extKeyUsage >>= unusedBits;
Vanger 0:b86d15c6ba29 3827 }
Vanger 0:b86d15c6ba29 3828 else if (length == 1)
Vanger 0:b86d15c6ba29 3829 cert->extKeyUsage = (word16)(input[idx] << 1);
Vanger 0:b86d15c6ba29 3830
Vanger 0:b86d15c6ba29 3831 return 0;
Vanger 0:b86d15c6ba29 3832 }
Vanger 0:b86d15c6ba29 3833
Vanger 0:b86d15c6ba29 3834
Vanger 0:b86d15c6ba29 3835 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3836 {
Vanger 0:b86d15c6ba29 3837 word32 idx = 0, oid;
Vanger 0:b86d15c6ba29 3838 int length;
Vanger 0:b86d15c6ba29 3839
Vanger 0:b86d15c6ba29 3840 CYASSL_ENTER("DecodeExtKeyUsage");
Vanger 0:b86d15c6ba29 3841
Vanger 0:b86d15c6ba29 3842 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3843 CYASSL_MSG("\tfail: should be a SEQUENCE");
Vanger 0:b86d15c6ba29 3844 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3845 }
Vanger 0:b86d15c6ba29 3846
Vanger 0:b86d15c6ba29 3847 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3848 cert->extExtKeyUsageSrc = input + idx;
Vanger 0:b86d15c6ba29 3849 cert->extExtKeyUsageSz = length;
Vanger 0:b86d15c6ba29 3850 #endif
Vanger 0:b86d15c6ba29 3851
Vanger 0:b86d15c6ba29 3852 while (idx < (word32)sz) {
Vanger 0:b86d15c6ba29 3853 if (GetObjectId(input, &idx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 3854 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3855
Vanger 0:b86d15c6ba29 3856 switch (oid) {
Vanger 0:b86d15c6ba29 3857 case EKU_ANY_OID:
Vanger 0:b86d15c6ba29 3858 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
Vanger 0:b86d15c6ba29 3859 break;
Vanger 0:b86d15c6ba29 3860 case EKU_SERVER_AUTH_OID:
Vanger 0:b86d15c6ba29 3861 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
Vanger 0:b86d15c6ba29 3862 break;
Vanger 0:b86d15c6ba29 3863 case EKU_CLIENT_AUTH_OID:
Vanger 0:b86d15c6ba29 3864 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
Vanger 0:b86d15c6ba29 3865 break;
Vanger 0:b86d15c6ba29 3866 case EKU_OCSP_SIGN_OID:
Vanger 0:b86d15c6ba29 3867 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
Vanger 0:b86d15c6ba29 3868 break;
Vanger 0:b86d15c6ba29 3869 }
Vanger 0:b86d15c6ba29 3870
Vanger 0:b86d15c6ba29 3871 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 3872 cert->extExtKeyUsageCount++;
Vanger 0:b86d15c6ba29 3873 #endif
Vanger 0:b86d15c6ba29 3874 }
Vanger 0:b86d15c6ba29 3875
Vanger 0:b86d15c6ba29 3876 return 0;
Vanger 0:b86d15c6ba29 3877 }
Vanger 0:b86d15c6ba29 3878
Vanger 0:b86d15c6ba29 3879
Vanger 0:b86d15c6ba29 3880 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 3881 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
Vanger 0:b86d15c6ba29 3882 {
Vanger 0:b86d15c6ba29 3883 word32 idx = 0;
Vanger 0:b86d15c6ba29 3884
Vanger 0:b86d15c6ba29 3885 (void)heap;
Vanger 0:b86d15c6ba29 3886
Vanger 0:b86d15c6ba29 3887 while (idx < (word32)sz) {
Vanger 0:b86d15c6ba29 3888 int seqLength, strLength;
Vanger 0:b86d15c6ba29 3889 word32 nameIdx;
Vanger 0:b86d15c6ba29 3890 byte b;
Vanger 0:b86d15c6ba29 3891
Vanger 0:b86d15c6ba29 3892 if (GetSequence(input, &idx, &seqLength, sz) < 0) {
Vanger 0:b86d15c6ba29 3893 CYASSL_MSG("\tfail: should be a SEQUENCE");
Vanger 0:b86d15c6ba29 3894 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3895 }
Vanger 0:b86d15c6ba29 3896
Vanger 0:b86d15c6ba29 3897 nameIdx = idx;
Vanger 0:b86d15c6ba29 3898 b = input[nameIdx++];
Vanger 0:b86d15c6ba29 3899 if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
Vanger 0:b86d15c6ba29 3900 CYASSL_MSG("\tinvalid length");
Vanger 0:b86d15c6ba29 3901 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3902 }
Vanger 0:b86d15c6ba29 3903
Vanger 0:b86d15c6ba29 3904 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
Vanger 0:b86d15c6ba29 3905 b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
Vanger 0:b86d15c6ba29 3906 b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
Vanger 0:b86d15c6ba29 3907
Vanger 0:b86d15c6ba29 3908 Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry),
Vanger 0:b86d15c6ba29 3909 heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3910
Vanger 0:b86d15c6ba29 3911 if (entry == NULL) {
Vanger 0:b86d15c6ba29 3912 CYASSL_MSG("allocate error");
Vanger 0:b86d15c6ba29 3913 return MEMORY_E;
Vanger 0:b86d15c6ba29 3914 }
Vanger 0:b86d15c6ba29 3915
Vanger 0:b86d15c6ba29 3916 entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
Vanger 0:b86d15c6ba29 3917 if (entry->name == NULL) {
Vanger 0:b86d15c6ba29 3918 CYASSL_MSG("allocate error");
Vanger 0:b86d15c6ba29 3919 return MEMORY_E;
Vanger 0:b86d15c6ba29 3920 }
Vanger 0:b86d15c6ba29 3921
Vanger 0:b86d15c6ba29 3922 XMEMCPY(entry->name, &input[nameIdx], strLength);
Vanger 0:b86d15c6ba29 3923 entry->nameSz = strLength;
Vanger 0:b86d15c6ba29 3924 entry->type = b & 0x0F;
Vanger 0:b86d15c6ba29 3925
Vanger 0:b86d15c6ba29 3926 entry->next = *head;
Vanger 0:b86d15c6ba29 3927 *head = entry;
Vanger 0:b86d15c6ba29 3928 }
Vanger 0:b86d15c6ba29 3929
Vanger 0:b86d15c6ba29 3930 idx += seqLength;
Vanger 0:b86d15c6ba29 3931 }
Vanger 0:b86d15c6ba29 3932
Vanger 0:b86d15c6ba29 3933 return 0;
Vanger 0:b86d15c6ba29 3934 }
Vanger 0:b86d15c6ba29 3935
Vanger 0:b86d15c6ba29 3936
Vanger 0:b86d15c6ba29 3937 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3938 {
Vanger 0:b86d15c6ba29 3939 word32 idx = 0;
Vanger 0:b86d15c6ba29 3940 int length = 0;
Vanger 0:b86d15c6ba29 3941
Vanger 0:b86d15c6ba29 3942 CYASSL_ENTER("DecodeNameConstraints");
Vanger 0:b86d15c6ba29 3943
Vanger 0:b86d15c6ba29 3944 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3945 CYASSL_MSG("\tfail: should be a SEQUENCE");
Vanger 0:b86d15c6ba29 3946 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3947 }
Vanger 0:b86d15c6ba29 3948
Vanger 0:b86d15c6ba29 3949 while (idx < (word32)sz) {
Vanger 0:b86d15c6ba29 3950 byte b = input[idx++];
Vanger 0:b86d15c6ba29 3951 Base_entry** subtree = NULL;
Vanger 0:b86d15c6ba29 3952
Vanger 0:b86d15c6ba29 3953 if (GetLength(input, &idx, &length, sz) <= 0) {
Vanger 0:b86d15c6ba29 3954 CYASSL_MSG("\tinvalid length");
Vanger 0:b86d15c6ba29 3955 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3956 }
Vanger 0:b86d15c6ba29 3957
Vanger 0:b86d15c6ba29 3958 if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
Vanger 0:b86d15c6ba29 3959 subtree = &cert->permittedNames;
Vanger 0:b86d15c6ba29 3960 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
Vanger 0:b86d15c6ba29 3961 subtree = &cert->excludedNames;
Vanger 0:b86d15c6ba29 3962 else {
Vanger 0:b86d15c6ba29 3963 CYASSL_MSG("\tinvalid subtree");
Vanger 0:b86d15c6ba29 3964 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3965 }
Vanger 0:b86d15c6ba29 3966
Vanger 0:b86d15c6ba29 3967 DecodeSubtree(input + idx, length, subtree, cert->heap);
Vanger 0:b86d15c6ba29 3968
Vanger 0:b86d15c6ba29 3969 idx += length;
Vanger 0:b86d15c6ba29 3970 }
Vanger 0:b86d15c6ba29 3971
Vanger 0:b86d15c6ba29 3972 return 0;
Vanger 0:b86d15c6ba29 3973 }
Vanger 0:b86d15c6ba29 3974 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 3975
Vanger 0:b86d15c6ba29 3976
Vanger 0:b86d15c6ba29 3977 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 3978 static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
Vanger 0:b86d15c6ba29 3979 {
Vanger 0:b86d15c6ba29 3980 word32 idx = 0;
Vanger 0:b86d15c6ba29 3981 int length = 0;
Vanger 0:b86d15c6ba29 3982
Vanger 0:b86d15c6ba29 3983 CYASSL_ENTER("DecodeCertPolicy");
Vanger 0:b86d15c6ba29 3984
Vanger 0:b86d15c6ba29 3985 /* Unwrap certificatePolicies */
Vanger 0:b86d15c6ba29 3986 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3987 CYASSL_MSG("\tdeviceType isn't OID");
Vanger 0:b86d15c6ba29 3988 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3989 }
Vanger 0:b86d15c6ba29 3990
Vanger 0:b86d15c6ba29 3991 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 3992 CYASSL_MSG("\tdeviceType isn't OID");
Vanger 0:b86d15c6ba29 3993 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3994 }
Vanger 0:b86d15c6ba29 3995
Vanger 0:b86d15c6ba29 3996 if (input[idx++] != ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 3997 CYASSL_MSG("\tdeviceType isn't OID");
Vanger 0:b86d15c6ba29 3998 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 3999 }
Vanger 0:b86d15c6ba29 4000
Vanger 0:b86d15c6ba29 4001 if (GetLength(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 4002 CYASSL_MSG("\tCouldn't read length of deviceType");
Vanger 0:b86d15c6ba29 4003 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4004 }
Vanger 0:b86d15c6ba29 4005
Vanger 0:b86d15c6ba29 4006 if (length > 0) {
Vanger 0:b86d15c6ba29 4007 cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0);
Vanger 0:b86d15c6ba29 4008 if (cert->deviceType == NULL) {
Vanger 0:b86d15c6ba29 4009 CYASSL_MSG("\tCouldn't alloc memory for deviceType");
Vanger 0:b86d15c6ba29 4010 return MEMORY_E;
Vanger 0:b86d15c6ba29 4011 }
Vanger 0:b86d15c6ba29 4012 cert->deviceTypeSz = length;
Vanger 0:b86d15c6ba29 4013 XMEMCPY(cert->deviceType, input + idx, length);
Vanger 0:b86d15c6ba29 4014 }
Vanger 0:b86d15c6ba29 4015
Vanger 0:b86d15c6ba29 4016 CYASSL_LEAVE("DecodeCertPolicy", 0);
Vanger 0:b86d15c6ba29 4017 return 0;
Vanger 0:b86d15c6ba29 4018 }
Vanger 0:b86d15c6ba29 4019 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 4020
Vanger 0:b86d15c6ba29 4021
Vanger 0:b86d15c6ba29 4022 static int DecodeCertExtensions(DecodedCert* cert)
Vanger 0:b86d15c6ba29 4023 /*
Vanger 0:b86d15c6ba29 4024 * Processing the Certificate Extensions. This does not modify the current
Vanger 0:b86d15c6ba29 4025 * index. It is works starting with the recorded extensions pointer.
Vanger 0:b86d15c6ba29 4026 */
Vanger 0:b86d15c6ba29 4027 {
Vanger 0:b86d15c6ba29 4028 word32 idx = 0;
Vanger 0:b86d15c6ba29 4029 int sz = cert->extensionsSz;
Vanger 0:b86d15c6ba29 4030 byte* input = cert->extensions;
Vanger 0:b86d15c6ba29 4031 int length;
Vanger 0:b86d15c6ba29 4032 word32 oid;
Vanger 0:b86d15c6ba29 4033 byte critical = 0;
Vanger 0:b86d15c6ba29 4034 byte criticalFail = 0;
Vanger 0:b86d15c6ba29 4035
Vanger 0:b86d15c6ba29 4036 CYASSL_ENTER("DecodeCertExtensions");
Vanger 0:b86d15c6ba29 4037
Vanger 0:b86d15c6ba29 4038 if (input == NULL || sz == 0)
Vanger 0:b86d15c6ba29 4039 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4040
Vanger 0:b86d15c6ba29 4041 if (input[idx++] != ASN_EXTENSIONS)
Vanger 0:b86d15c6ba29 4042 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4043
Vanger 0:b86d15c6ba29 4044 if (GetLength(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 4045 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4046
Vanger 0:b86d15c6ba29 4047 if (GetSequence(input, &idx, &length, sz) < 0)
Vanger 0:b86d15c6ba29 4048 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4049
Vanger 0:b86d15c6ba29 4050 while (idx < (word32)sz) {
Vanger 0:b86d15c6ba29 4051 if (GetSequence(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 4052 CYASSL_MSG("\tfail: should be a SEQUENCE");
Vanger 0:b86d15c6ba29 4053 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4054 }
Vanger 0:b86d15c6ba29 4055
Vanger 0:b86d15c6ba29 4056 oid = 0;
Vanger 0:b86d15c6ba29 4057 if (GetObjectId(input, &idx, &oid, sz) < 0) {
Vanger 0:b86d15c6ba29 4058 CYASSL_MSG("\tfail: OBJECT ID");
Vanger 0:b86d15c6ba29 4059 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4060 }
Vanger 0:b86d15c6ba29 4061
Vanger 0:b86d15c6ba29 4062 /* check for critical flag */
Vanger 0:b86d15c6ba29 4063 critical = 0;
Vanger 0:b86d15c6ba29 4064 if (input[idx] == ASN_BOOLEAN) {
Vanger 0:b86d15c6ba29 4065 int boolLength = 0;
Vanger 0:b86d15c6ba29 4066 idx++;
Vanger 0:b86d15c6ba29 4067 if (GetLength(input, &idx, &boolLength, sz) < 0) {
Vanger 0:b86d15c6ba29 4068 CYASSL_MSG("\tfail: critical boolean length");
Vanger 0:b86d15c6ba29 4069 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4070 }
Vanger 0:b86d15c6ba29 4071 if (input[idx++])
Vanger 0:b86d15c6ba29 4072 critical = 1;
Vanger 0:b86d15c6ba29 4073 }
Vanger 0:b86d15c6ba29 4074
Vanger 0:b86d15c6ba29 4075 /* process the extension based on the OID */
Vanger 0:b86d15c6ba29 4076 if (input[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 4077 CYASSL_MSG("\tfail: should be an OCTET STRING");
Vanger 0:b86d15c6ba29 4078 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4079 }
Vanger 0:b86d15c6ba29 4080
Vanger 0:b86d15c6ba29 4081 if (GetLength(input, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 4082 CYASSL_MSG("\tfail: extension data length");
Vanger 0:b86d15c6ba29 4083 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4084 }
Vanger 0:b86d15c6ba29 4085
Vanger 0:b86d15c6ba29 4086 switch (oid) {
Vanger 0:b86d15c6ba29 4087 case BASIC_CA_OID:
Vanger 0:b86d15c6ba29 4088 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4089 cert->extBasicConstSet = 1;
Vanger 0:b86d15c6ba29 4090 cert->extBasicConstCrit = critical;
Vanger 0:b86d15c6ba29 4091 #endif
Vanger 0:b86d15c6ba29 4092 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4093 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4094 break;
Vanger 0:b86d15c6ba29 4095
Vanger 0:b86d15c6ba29 4096 case CRL_DIST_OID:
Vanger 0:b86d15c6ba29 4097 if (DecodeCrlDist(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4098 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4099 break;
Vanger 0:b86d15c6ba29 4100
Vanger 0:b86d15c6ba29 4101 case AUTH_INFO_OID:
Vanger 0:b86d15c6ba29 4102 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4103 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4104 break;
Vanger 0:b86d15c6ba29 4105
Vanger 0:b86d15c6ba29 4106 case ALT_NAMES_OID:
Vanger 0:b86d15c6ba29 4107 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4108 cert->extSubjAltNameSet = 1;
Vanger 0:b86d15c6ba29 4109 cert->extSubjAltNameCrit = critical;
Vanger 0:b86d15c6ba29 4110 #endif
Vanger 0:b86d15c6ba29 4111 if (DecodeAltNames(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4112 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4113 break;
Vanger 0:b86d15c6ba29 4114
Vanger 0:b86d15c6ba29 4115 case AUTH_KEY_OID:
Vanger 0:b86d15c6ba29 4116 cert->extAuthKeyIdSet = 1;
Vanger 0:b86d15c6ba29 4117 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4118 cert->extAuthKeyIdCrit = critical;
Vanger 0:b86d15c6ba29 4119 #endif
Vanger 0:b86d15c6ba29 4120 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4121 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4122 break;
Vanger 0:b86d15c6ba29 4123
Vanger 0:b86d15c6ba29 4124 case SUBJ_KEY_OID:
Vanger 0:b86d15c6ba29 4125 cert->extSubjKeyIdSet = 1;
Vanger 0:b86d15c6ba29 4126 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4127 cert->extSubjKeyIdCrit = critical;
Vanger 0:b86d15c6ba29 4128 #endif
Vanger 0:b86d15c6ba29 4129 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4130 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4131 break;
Vanger 0:b86d15c6ba29 4132
Vanger 0:b86d15c6ba29 4133 case CERT_POLICY_OID:
Vanger 0:b86d15c6ba29 4134 CYASSL_MSG("Certificate Policy extension not supported yet.");
Vanger 0:b86d15c6ba29 4135 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 4136 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4137 cert->extCertPolicySet = 1;
Vanger 0:b86d15c6ba29 4138 cert->extCertPolicyCrit = critical;
Vanger 0:b86d15c6ba29 4139 #endif
Vanger 0:b86d15c6ba29 4140 if (DecodeCertPolicy(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4141 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4142 #endif
Vanger 0:b86d15c6ba29 4143 break;
Vanger 0:b86d15c6ba29 4144
Vanger 0:b86d15c6ba29 4145 case KEY_USAGE_OID:
Vanger 0:b86d15c6ba29 4146 cert->extKeyUsageSet = 1;
Vanger 0:b86d15c6ba29 4147 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4148 cert->extKeyUsageCrit = critical;
Vanger 0:b86d15c6ba29 4149 #endif
Vanger 0:b86d15c6ba29 4150 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4151 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4152 break;
Vanger 0:b86d15c6ba29 4153
Vanger 0:b86d15c6ba29 4154 case EXT_KEY_USAGE_OID:
Vanger 0:b86d15c6ba29 4155 cert->extExtKeyUsageSet = 1;
Vanger 0:b86d15c6ba29 4156 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4157 cert->extExtKeyUsageCrit = critical;
Vanger 0:b86d15c6ba29 4158 #endif
Vanger 0:b86d15c6ba29 4159 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4160 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4161 break;
Vanger 0:b86d15c6ba29 4162
Vanger 0:b86d15c6ba29 4163 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 4164 case NAME_CONS_OID:
Vanger 0:b86d15c6ba29 4165 cert->extNameConstraintSet = 1;
Vanger 0:b86d15c6ba29 4166 #ifdef OPENSSL_EXTRA
Vanger 0:b86d15c6ba29 4167 cert->extNameConstraintCrit = critical;
Vanger 0:b86d15c6ba29 4168 #endif
Vanger 0:b86d15c6ba29 4169 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
Vanger 0:b86d15c6ba29 4170 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 4171 break;
Vanger 0:b86d15c6ba29 4172 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 4173
Vanger 0:b86d15c6ba29 4174 case INHIBIT_ANY_OID:
Vanger 0:b86d15c6ba29 4175 CYASSL_MSG("Inhibit anyPolicy extension not supported yet.");
Vanger 0:b86d15c6ba29 4176 break;
Vanger 0:b86d15c6ba29 4177
Vanger 0:b86d15c6ba29 4178 default:
Vanger 0:b86d15c6ba29 4179 /* While it is a failure to not support critical extensions,
Vanger 0:b86d15c6ba29 4180 * still parse the certificate ignoring the unsupported
Vanger 0:b86d15c6ba29 4181 * extention to allow caller to accept it with the verify
Vanger 0:b86d15c6ba29 4182 * callback. */
Vanger 0:b86d15c6ba29 4183 if (critical)
Vanger 0:b86d15c6ba29 4184 criticalFail = 1;
Vanger 0:b86d15c6ba29 4185 break;
Vanger 0:b86d15c6ba29 4186 }
Vanger 0:b86d15c6ba29 4187 idx += length;
Vanger 0:b86d15c6ba29 4188 }
Vanger 0:b86d15c6ba29 4189
Vanger 0:b86d15c6ba29 4190 return criticalFail ? ASN_CRIT_EXT_E : 0;
Vanger 0:b86d15c6ba29 4191 }
Vanger 0:b86d15c6ba29 4192
Vanger 0:b86d15c6ba29 4193
Vanger 0:b86d15c6ba29 4194 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
Vanger 0:b86d15c6ba29 4195 {
Vanger 0:b86d15c6ba29 4196 int ret;
Vanger 0:b86d15c6ba29 4197 char* ptr;
Vanger 0:b86d15c6ba29 4198
Vanger 0:b86d15c6ba29 4199 ret = ParseCertRelative(cert, type, verify, cm);
Vanger 0:b86d15c6ba29 4200 if (ret < 0)
Vanger 0:b86d15c6ba29 4201 return ret;
Vanger 0:b86d15c6ba29 4202
Vanger 0:b86d15c6ba29 4203 if (cert->subjectCNLen > 0) {
Vanger 0:b86d15c6ba29 4204 ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
Vanger 0:b86d15c6ba29 4205 DYNAMIC_TYPE_SUBJECT_CN);
Vanger 0:b86d15c6ba29 4206 if (ptr == NULL)
Vanger 0:b86d15c6ba29 4207 return MEMORY_E;
Vanger 0:b86d15c6ba29 4208 XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
Vanger 0:b86d15c6ba29 4209 ptr[cert->subjectCNLen] = '\0';
Vanger 0:b86d15c6ba29 4210 cert->subjectCN = ptr;
Vanger 0:b86d15c6ba29 4211 cert->subjectCNStored = 1;
Vanger 0:b86d15c6ba29 4212 }
Vanger 0:b86d15c6ba29 4213
Vanger 0:b86d15c6ba29 4214 if (cert->keyOID == RSAk &&
Vanger 0:b86d15c6ba29 4215 cert->publicKey != NULL && cert->pubKeySize > 0) {
Vanger 0:b86d15c6ba29 4216 ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
Vanger 0:b86d15c6ba29 4217 DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 4218 if (ptr == NULL)
Vanger 0:b86d15c6ba29 4219 return MEMORY_E;
Vanger 0:b86d15c6ba29 4220 XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
Vanger 0:b86d15c6ba29 4221 cert->publicKey = (byte *)ptr;
Vanger 0:b86d15c6ba29 4222 cert->pubKeyStored = 1;
Vanger 0:b86d15c6ba29 4223 }
Vanger 0:b86d15c6ba29 4224
Vanger 0:b86d15c6ba29 4225 return ret;
Vanger 0:b86d15c6ba29 4226 }
Vanger 0:b86d15c6ba29 4227
Vanger 0:b86d15c6ba29 4228
Vanger 0:b86d15c6ba29 4229 /* from SSL proper, for locking can't do find here anymore */
Vanger 0:b86d15c6ba29 4230 #ifdef __cplusplus
Vanger 0:b86d15c6ba29 4231 extern "C" {
Vanger 0:b86d15c6ba29 4232 #endif
Vanger 0:b86d15c6ba29 4233 CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
Vanger 0:b86d15c6ba29 4234 #ifndef NO_SKID
Vanger 0:b86d15c6ba29 4235 CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
Vanger 0:b86d15c6ba29 4236 #endif
Vanger 0:b86d15c6ba29 4237 #ifdef __cplusplus
Vanger 0:b86d15c6ba29 4238 }
Vanger 0:b86d15c6ba29 4239 #endif
Vanger 0:b86d15c6ba29 4240
Vanger 0:b86d15c6ba29 4241
Vanger 0:b86d15c6ba29 4242 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
Vanger 0:b86d15c6ba29 4243 {
Vanger 0:b86d15c6ba29 4244 word32 confirmOID;
Vanger 0:b86d15c6ba29 4245 int ret;
Vanger 0:b86d15c6ba29 4246 int badDate = 0;
Vanger 0:b86d15c6ba29 4247 int criticalExt = 0;
Vanger 0:b86d15c6ba29 4248
Vanger 0:b86d15c6ba29 4249 if ((ret = DecodeToKey(cert, verify)) < 0) {
Vanger 0:b86d15c6ba29 4250 if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
Vanger 0:b86d15c6ba29 4251 badDate = ret;
Vanger 0:b86d15c6ba29 4252 else
Vanger 0:b86d15c6ba29 4253 return ret;
Vanger 0:b86d15c6ba29 4254 }
Vanger 0:b86d15c6ba29 4255
Vanger 0:b86d15c6ba29 4256 CYASSL_MSG("Parsed Past Key");
Vanger 0:b86d15c6ba29 4257
Vanger 0:b86d15c6ba29 4258 if (cert->srcIdx < cert->sigIndex) {
Vanger 0:b86d15c6ba29 4259 #ifndef ALLOW_V1_EXTENSIONS
Vanger 0:b86d15c6ba29 4260 if (cert->version < 2) {
Vanger 0:b86d15c6ba29 4261 CYASSL_MSG(" v1 and v2 certs not allowed extensions");
Vanger 0:b86d15c6ba29 4262 return ASN_VERSION_E;
Vanger 0:b86d15c6ba29 4263 }
Vanger 0:b86d15c6ba29 4264 #endif
Vanger 0:b86d15c6ba29 4265 /* save extensions */
Vanger 0:b86d15c6ba29 4266 cert->extensions = &cert->source[cert->srcIdx];
Vanger 0:b86d15c6ba29 4267 cert->extensionsSz = cert->sigIndex - cert->srcIdx;
Vanger 0:b86d15c6ba29 4268 cert->extensionsIdx = cert->srcIdx; /* for potential later use */
Vanger 0:b86d15c6ba29 4269
Vanger 0:b86d15c6ba29 4270 if ((ret = DecodeCertExtensions(cert)) < 0) {
Vanger 0:b86d15c6ba29 4271 if (ret == ASN_CRIT_EXT_E)
Vanger 0:b86d15c6ba29 4272 criticalExt = ret;
Vanger 0:b86d15c6ba29 4273 else
Vanger 0:b86d15c6ba29 4274 return ret;
Vanger 0:b86d15c6ba29 4275 }
Vanger 0:b86d15c6ba29 4276
Vanger 0:b86d15c6ba29 4277 /* advance past extensions */
Vanger 0:b86d15c6ba29 4278 cert->srcIdx = cert->sigIndex;
Vanger 0:b86d15c6ba29 4279 }
Vanger 0:b86d15c6ba29 4280
Vanger 0:b86d15c6ba29 4281 if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
Vanger 0:b86d15c6ba29 4282 cert->maxIdx)) < 0)
Vanger 0:b86d15c6ba29 4283 return ret;
Vanger 0:b86d15c6ba29 4284
Vanger 0:b86d15c6ba29 4285 if ((ret = GetSignature(cert)) < 0)
Vanger 0:b86d15c6ba29 4286 return ret;
Vanger 0:b86d15c6ba29 4287
Vanger 0:b86d15c6ba29 4288 if (confirmOID != cert->signatureOID)
Vanger 0:b86d15c6ba29 4289 return ASN_SIG_OID_E;
Vanger 0:b86d15c6ba29 4290
Vanger 0:b86d15c6ba29 4291 #ifndef NO_SKID
Vanger 0:b86d15c6ba29 4292 if (cert->extSubjKeyIdSet == 0
Vanger 0:b86d15c6ba29 4293 && cert->publicKey != NULL && cert->pubKeySize > 0) {
Vanger 0:b86d15c6ba29 4294 Sha sha;
Vanger 0:b86d15c6ba29 4295 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 4296 if (ret != 0)
Vanger 0:b86d15c6ba29 4297 return ret;
Vanger 0:b86d15c6ba29 4298 ShaUpdate(&sha, cert->publicKey, cert->pubKeySize);
Vanger 0:b86d15c6ba29 4299 ShaFinal(&sha, cert->extSubjKeyId);
Vanger 0:b86d15c6ba29 4300 }
Vanger 0:b86d15c6ba29 4301 #endif
Vanger 0:b86d15c6ba29 4302 if (verify && type != CA_TYPE) {
Vanger 0:b86d15c6ba29 4303 Signer* ca = NULL;
Vanger 0:b86d15c6ba29 4304 #ifndef NO_SKID
Vanger 0:b86d15c6ba29 4305 if (cert->extAuthKeyIdSet)
Vanger 0:b86d15c6ba29 4306 ca = GetCA(cm, cert->extAuthKeyId);
Vanger 0:b86d15c6ba29 4307 if (ca == NULL)
Vanger 0:b86d15c6ba29 4308 ca = GetCAByName(cm, cert->issuerHash);
Vanger 0:b86d15c6ba29 4309 #else /* NO_SKID */
Vanger 0:b86d15c6ba29 4310 ca = GetCA(cm, cert->issuerHash);
Vanger 0:b86d15c6ba29 4311 #endif /* NO SKID */
Vanger 0:b86d15c6ba29 4312 CYASSL_MSG("About to verify certificate signature");
Vanger 0:b86d15c6ba29 4313 if (ca) {
Vanger 0:b86d15c6ba29 4314 #ifdef HAVE_OCSP
Vanger 0:b86d15c6ba29 4315 /* Need the ca's public key hash for OCSP */
Vanger 0:b86d15c6ba29 4316 {
Vanger 0:b86d15c6ba29 4317 Sha sha;
Vanger 0:b86d15c6ba29 4318 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 4319 if (ret != 0)
Vanger 0:b86d15c6ba29 4320 return ret;
Vanger 0:b86d15c6ba29 4321 ShaUpdate(&sha, ca->publicKey, ca->pubKeySize);
Vanger 0:b86d15c6ba29 4322 ShaFinal(&sha, cert->issuerKeyHash);
Vanger 0:b86d15c6ba29 4323 }
Vanger 0:b86d15c6ba29 4324 #endif /* HAVE_OCSP */
Vanger 0:b86d15c6ba29 4325 /* try to confirm/verify signature */
Vanger 0:b86d15c6ba29 4326 if (!ConfirmSignature(cert->source + cert->certBegin,
Vanger 0:b86d15c6ba29 4327 cert->sigIndex - cert->certBegin,
Vanger 0:b86d15c6ba29 4328 ca->publicKey, ca->pubKeySize, ca->keyOID,
Vanger 0:b86d15c6ba29 4329 cert->signature, cert->sigLength, cert->signatureOID,
Vanger 0:b86d15c6ba29 4330 cert->heap)) {
Vanger 0:b86d15c6ba29 4331 CYASSL_MSG("Confirm signature failed");
Vanger 0:b86d15c6ba29 4332 return ASN_SIG_CONFIRM_E;
Vanger 0:b86d15c6ba29 4333 }
Vanger 0:b86d15c6ba29 4334 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 4335 /* check that this cert's name is permitted by the signer's
Vanger 0:b86d15c6ba29 4336 * name constraints */
Vanger 0:b86d15c6ba29 4337 if (!ConfirmNameConstraints(ca, cert)) {
Vanger 0:b86d15c6ba29 4338 CYASSL_MSG("Confirm name constraint failed");
Vanger 0:b86d15c6ba29 4339 return ASN_NAME_INVALID_E;
Vanger 0:b86d15c6ba29 4340 }
Vanger 0:b86d15c6ba29 4341 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 4342 }
Vanger 0:b86d15c6ba29 4343 else {
Vanger 0:b86d15c6ba29 4344 /* no signer */
Vanger 0:b86d15c6ba29 4345 CYASSL_MSG("No CA signer to verify with");
Vanger 0:b86d15c6ba29 4346 return ASN_NO_SIGNER_E;
Vanger 0:b86d15c6ba29 4347 }
Vanger 0:b86d15c6ba29 4348 }
Vanger 0:b86d15c6ba29 4349
Vanger 0:b86d15c6ba29 4350 if (badDate != 0)
Vanger 0:b86d15c6ba29 4351 return badDate;
Vanger 0:b86d15c6ba29 4352
Vanger 0:b86d15c6ba29 4353 if (criticalExt != 0)
Vanger 0:b86d15c6ba29 4354 return criticalExt;
Vanger 0:b86d15c6ba29 4355
Vanger 0:b86d15c6ba29 4356 return 0;
Vanger 0:b86d15c6ba29 4357 }
Vanger 0:b86d15c6ba29 4358
Vanger 0:b86d15c6ba29 4359
Vanger 0:b86d15c6ba29 4360 /* Create and init an new signer */
Vanger 0:b86d15c6ba29 4361 Signer* MakeSigner(void* heap)
Vanger 0:b86d15c6ba29 4362 {
Vanger 0:b86d15c6ba29 4363 Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
Vanger 0:b86d15c6ba29 4364 DYNAMIC_TYPE_SIGNER);
Vanger 0:b86d15c6ba29 4365 if (signer) {
Vanger 0:b86d15c6ba29 4366 signer->pubKeySize = 0;
Vanger 0:b86d15c6ba29 4367 signer->keyOID = 0;
Vanger 0:b86d15c6ba29 4368 signer->publicKey = NULL;
Vanger 0:b86d15c6ba29 4369 signer->nameLen = 0;
Vanger 0:b86d15c6ba29 4370 signer->name = NULL;
Vanger 0:b86d15c6ba29 4371 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 4372 signer->permittedNames = NULL;
Vanger 0:b86d15c6ba29 4373 signer->excludedNames = NULL;
Vanger 0:b86d15c6ba29 4374 #endif /* IGNORE_NAME_CONSTRAINTS */
Vanger 0:b86d15c6ba29 4375 signer->next = NULL;
Vanger 0:b86d15c6ba29 4376 }
Vanger 0:b86d15c6ba29 4377 (void)heap;
Vanger 0:b86d15c6ba29 4378
Vanger 0:b86d15c6ba29 4379 return signer;
Vanger 0:b86d15c6ba29 4380 }
Vanger 0:b86d15c6ba29 4381
Vanger 0:b86d15c6ba29 4382
Vanger 0:b86d15c6ba29 4383 /* Free an individual signer */
Vanger 0:b86d15c6ba29 4384 void FreeSigner(Signer* signer, void* heap)
Vanger 0:b86d15c6ba29 4385 {
Vanger 0:b86d15c6ba29 4386 XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
Vanger 0:b86d15c6ba29 4387 XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
Vanger 0:b86d15c6ba29 4388 #ifndef IGNORE_NAME_CONSTRAINTS
Vanger 0:b86d15c6ba29 4389 if (signer->permittedNames)
Vanger 0:b86d15c6ba29 4390 FreeNameSubtrees(signer->permittedNames, heap);
Vanger 0:b86d15c6ba29 4391 if (signer->excludedNames)
Vanger 0:b86d15c6ba29 4392 FreeNameSubtrees(signer->excludedNames, heap);
Vanger 0:b86d15c6ba29 4393 #endif
Vanger 0:b86d15c6ba29 4394 XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
Vanger 0:b86d15c6ba29 4395
Vanger 0:b86d15c6ba29 4396 (void)heap;
Vanger 0:b86d15c6ba29 4397 }
Vanger 0:b86d15c6ba29 4398
Vanger 0:b86d15c6ba29 4399
Vanger 0:b86d15c6ba29 4400 /* Free the whole singer table with number of rows */
Vanger 0:b86d15c6ba29 4401 void FreeSignerTable(Signer** table, int rows, void* heap)
Vanger 0:b86d15c6ba29 4402 {
Vanger 0:b86d15c6ba29 4403 int i;
Vanger 0:b86d15c6ba29 4404
Vanger 0:b86d15c6ba29 4405 for (i = 0; i < rows; i++) {
Vanger 0:b86d15c6ba29 4406 Signer* signer = table[i];
Vanger 0:b86d15c6ba29 4407 while (signer) {
Vanger 0:b86d15c6ba29 4408 Signer* next = signer->next;
Vanger 0:b86d15c6ba29 4409 FreeSigner(signer, heap);
Vanger 0:b86d15c6ba29 4410 signer = next;
Vanger 0:b86d15c6ba29 4411 }
Vanger 0:b86d15c6ba29 4412 table[i] = NULL;
Vanger 0:b86d15c6ba29 4413 }
Vanger 0:b86d15c6ba29 4414 }
Vanger 0:b86d15c6ba29 4415
Vanger 0:b86d15c6ba29 4416
Vanger 0:b86d15c6ba29 4417 CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
Vanger 0:b86d15c6ba29 4418 {
Vanger 0:b86d15c6ba29 4419 int i = 0;
Vanger 0:b86d15c6ba29 4420
Vanger 0:b86d15c6ba29 4421 if (header) {
Vanger 0:b86d15c6ba29 4422 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
Vanger 0:b86d15c6ba29 4423 output[i++] = ASN_BIT_STRING;
Vanger 0:b86d15c6ba29 4424 }
Vanger 0:b86d15c6ba29 4425 output[i++] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 4426 output[i++] = 0x01;
Vanger 0:b86d15c6ba29 4427 output[i++] = (byte)version;
Vanger 0:b86d15c6ba29 4428
Vanger 0:b86d15c6ba29 4429 return i;
Vanger 0:b86d15c6ba29 4430 }
Vanger 0:b86d15c6ba29 4431
Vanger 0:b86d15c6ba29 4432
Vanger 0:b86d15c6ba29 4433 CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
Vanger 0:b86d15c6ba29 4434 {
Vanger 0:b86d15c6ba29 4435 int result = 0;
Vanger 0:b86d15c6ba29 4436
Vanger 0:b86d15c6ba29 4437 CYASSL_ENTER("SetSerialNumber");
Vanger 0:b86d15c6ba29 4438
Vanger 0:b86d15c6ba29 4439 if (snSz <= EXTERNAL_SERIAL_SIZE) {
Vanger 0:b86d15c6ba29 4440 output[0] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 4441 /* The serial number is always positive. When encoding the
Vanger 0:b86d15c6ba29 4442 * INTEGER, if the MSB is 1, add a padding zero to keep the
Vanger 0:b86d15c6ba29 4443 * number positive. */
Vanger 0:b86d15c6ba29 4444 if (sn[0] & 0x80) {
Vanger 0:b86d15c6ba29 4445 output[1] = (byte)snSz + 1;
Vanger 0:b86d15c6ba29 4446 output[2] = 0;
Vanger 0:b86d15c6ba29 4447 XMEMCPY(&output[3], sn, snSz);
Vanger 0:b86d15c6ba29 4448 result = snSz + 3;
Vanger 0:b86d15c6ba29 4449 }
Vanger 0:b86d15c6ba29 4450 else {
Vanger 0:b86d15c6ba29 4451 output[1] = (byte)snSz;
Vanger 0:b86d15c6ba29 4452 XMEMCPY(&output[2], sn, snSz);
Vanger 0:b86d15c6ba29 4453 result = snSz + 2;
Vanger 0:b86d15c6ba29 4454 }
Vanger 0:b86d15c6ba29 4455 }
Vanger 0:b86d15c6ba29 4456 return result;
Vanger 0:b86d15c6ba29 4457 }
Vanger 0:b86d15c6ba29 4458
Vanger 0:b86d15c6ba29 4459
Vanger 0:b86d15c6ba29 4460
Vanger 0:b86d15c6ba29 4461
Vanger 0:b86d15c6ba29 4462 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
Vanger 0:b86d15c6ba29 4463
Vanger 0:b86d15c6ba29 4464 /* convert der buffer to pem into output, can't do inplace, der and output
Vanger 0:b86d15c6ba29 4465 need to be different */
Vanger 0:b86d15c6ba29 4466 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
Vanger 0:b86d15c6ba29 4467 int type)
Vanger 0:b86d15c6ba29 4468 {
Vanger 0:b86d15c6ba29 4469 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4470 char* header = NULL;
Vanger 0:b86d15c6ba29 4471 char* footer = NULL;
Vanger 0:b86d15c6ba29 4472 #else
Vanger 0:b86d15c6ba29 4473 char header[80];
Vanger 0:b86d15c6ba29 4474 char footer[80];
Vanger 0:b86d15c6ba29 4475 #endif
Vanger 0:b86d15c6ba29 4476
Vanger 0:b86d15c6ba29 4477 int headerLen = 80;
Vanger 0:b86d15c6ba29 4478 int footerLen = 80;
Vanger 0:b86d15c6ba29 4479 int i;
Vanger 0:b86d15c6ba29 4480 int err;
Vanger 0:b86d15c6ba29 4481 int outLen; /* return length or error */
Vanger 0:b86d15c6ba29 4482
Vanger 0:b86d15c6ba29 4483 if (der == output) /* no in place conversion */
Vanger 0:b86d15c6ba29 4484 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4485
Vanger 0:b86d15c6ba29 4486 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4487 header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4488 if (header == NULL)
Vanger 0:b86d15c6ba29 4489 return MEMORY_E;
Vanger 0:b86d15c6ba29 4490
Vanger 0:b86d15c6ba29 4491 footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4492 if (footer == NULL) {
Vanger 0:b86d15c6ba29 4493 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4494 return MEMORY_E;
Vanger 0:b86d15c6ba29 4495 }
Vanger 0:b86d15c6ba29 4496 #endif
Vanger 0:b86d15c6ba29 4497
Vanger 0:b86d15c6ba29 4498 if (type == CERT_TYPE) {
Vanger 0:b86d15c6ba29 4499 XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", headerLen);
Vanger 0:b86d15c6ba29 4500 XSTRNCPY(footer, "-----END CERTIFICATE-----\n", footerLen);
Vanger 0:b86d15c6ba29 4501 }
Vanger 0:b86d15c6ba29 4502 else if (type == PRIVATEKEY_TYPE) {
Vanger 0:b86d15c6ba29 4503 XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", headerLen);
Vanger 0:b86d15c6ba29 4504 XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", footerLen);
Vanger 0:b86d15c6ba29 4505 }
Vanger 0:b86d15c6ba29 4506 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 4507 else if (type == ECC_PRIVATEKEY_TYPE) {
Vanger 0:b86d15c6ba29 4508 XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", headerLen);
Vanger 0:b86d15c6ba29 4509 XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", footerLen);
Vanger 0:b86d15c6ba29 4510 }
Vanger 0:b86d15c6ba29 4511 #endif
Vanger 0:b86d15c6ba29 4512 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 4513 else if (type == CERTREQ_TYPE)
Vanger 0:b86d15c6ba29 4514 {
Vanger 0:b86d15c6ba29 4515 XSTRNCPY(header,
Vanger 0:b86d15c6ba29 4516 "-----BEGIN CERTIFICATE REQUEST-----\n", headerLen);
Vanger 0:b86d15c6ba29 4517 XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", footerLen);
Vanger 0:b86d15c6ba29 4518 }
Vanger 0:b86d15c6ba29 4519 #endif
Vanger 0:b86d15c6ba29 4520 else {
Vanger 0:b86d15c6ba29 4521 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4522 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4523 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4524 #endif
Vanger 0:b86d15c6ba29 4525 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4526 }
Vanger 0:b86d15c6ba29 4527
Vanger 0:b86d15c6ba29 4528 headerLen = (int)XSTRLEN(header);
Vanger 0:b86d15c6ba29 4529 footerLen = (int)XSTRLEN(footer);
Vanger 0:b86d15c6ba29 4530
Vanger 0:b86d15c6ba29 4531 if (!der || !output) {
Vanger 0:b86d15c6ba29 4532 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4533 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4534 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4535 #endif
Vanger 0:b86d15c6ba29 4536 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4537 }
Vanger 0:b86d15c6ba29 4538
Vanger 0:b86d15c6ba29 4539 /* don't even try if outSz too short */
Vanger 0:b86d15c6ba29 4540 if (outSz < headerLen + footerLen + derSz) {
Vanger 0:b86d15c6ba29 4541 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4542 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4543 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4544 #endif
Vanger 0:b86d15c6ba29 4545 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4546 }
Vanger 0:b86d15c6ba29 4547
Vanger 0:b86d15c6ba29 4548 /* header */
Vanger 0:b86d15c6ba29 4549 XMEMCPY(output, header, headerLen);
Vanger 0:b86d15c6ba29 4550 i = headerLen;
Vanger 0:b86d15c6ba29 4551
Vanger 0:b86d15c6ba29 4552 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4553 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4554 #endif
Vanger 0:b86d15c6ba29 4555
Vanger 0:b86d15c6ba29 4556 /* body */
Vanger 0:b86d15c6ba29 4557 outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */
Vanger 0:b86d15c6ba29 4558 if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
Vanger 0:b86d15c6ba29 4559 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4560 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4561 #endif
Vanger 0:b86d15c6ba29 4562 return err;
Vanger 0:b86d15c6ba29 4563 }
Vanger 0:b86d15c6ba29 4564 i += outLen;
Vanger 0:b86d15c6ba29 4565
Vanger 0:b86d15c6ba29 4566 /* footer */
Vanger 0:b86d15c6ba29 4567 if ( (i + footerLen) > (int)outSz) {
Vanger 0:b86d15c6ba29 4568 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4569 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4570 #endif
Vanger 0:b86d15c6ba29 4571 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4572 }
Vanger 0:b86d15c6ba29 4573 XMEMCPY(output + i, footer, footerLen);
Vanger 0:b86d15c6ba29 4574
Vanger 0:b86d15c6ba29 4575 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4576 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4577 #endif
Vanger 0:b86d15c6ba29 4578
Vanger 0:b86d15c6ba29 4579 return outLen + headerLen + footerLen;
Vanger 0:b86d15c6ba29 4580 }
Vanger 0:b86d15c6ba29 4581
Vanger 0:b86d15c6ba29 4582
Vanger 0:b86d15c6ba29 4583 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 4584
Vanger 0:b86d15c6ba29 4585
Vanger 0:b86d15c6ba29 4586 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA)
Vanger 0:b86d15c6ba29 4587
Vanger 0:b86d15c6ba29 4588
Vanger 0:b86d15c6ba29 4589 static mp_int* GetRsaInt(RsaKey* key, int idx)
Vanger 0:b86d15c6ba29 4590 {
Vanger 0:b86d15c6ba29 4591 if (idx == 0)
Vanger 0:b86d15c6ba29 4592 return &key->n;
Vanger 0:b86d15c6ba29 4593 if (idx == 1)
Vanger 0:b86d15c6ba29 4594 return &key->e;
Vanger 0:b86d15c6ba29 4595 if (idx == 2)
Vanger 0:b86d15c6ba29 4596 return &key->d;
Vanger 0:b86d15c6ba29 4597 if (idx == 3)
Vanger 0:b86d15c6ba29 4598 return &key->p;
Vanger 0:b86d15c6ba29 4599 if (idx == 4)
Vanger 0:b86d15c6ba29 4600 return &key->q;
Vanger 0:b86d15c6ba29 4601 if (idx == 5)
Vanger 0:b86d15c6ba29 4602 return &key->dP;
Vanger 0:b86d15c6ba29 4603 if (idx == 6)
Vanger 0:b86d15c6ba29 4604 return &key->dQ;
Vanger 0:b86d15c6ba29 4605 if (idx == 7)
Vanger 0:b86d15c6ba29 4606 return &key->u;
Vanger 0:b86d15c6ba29 4607
Vanger 0:b86d15c6ba29 4608 return NULL;
Vanger 0:b86d15c6ba29 4609 }
Vanger 0:b86d15c6ba29 4610
Vanger 0:b86d15c6ba29 4611
Vanger 0:b86d15c6ba29 4612 /* Release Tmp RSA resources */
Vanger 0:b86d15c6ba29 4613 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
Vanger 0:b86d15c6ba29 4614 {
Vanger 0:b86d15c6ba29 4615 int i;
Vanger 0:b86d15c6ba29 4616
Vanger 0:b86d15c6ba29 4617 (void)heap;
Vanger 0:b86d15c6ba29 4618
Vanger 0:b86d15c6ba29 4619 for (i = 0; i < RSA_INTS; i++)
Vanger 0:b86d15c6ba29 4620 XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 4621 }
Vanger 0:b86d15c6ba29 4622
Vanger 0:b86d15c6ba29 4623
Vanger 0:b86d15c6ba29 4624 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
Vanger 0:b86d15c6ba29 4625 written */
Vanger 0:b86d15c6ba29 4626 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
Vanger 0:b86d15c6ba29 4627 {
Vanger 0:b86d15c6ba29 4628 word32 seqSz, verSz, rawLen, intTotalLen = 0;
Vanger 0:b86d15c6ba29 4629 word32 sizes[RSA_INTS];
Vanger 0:b86d15c6ba29 4630 int i, j, outLen, ret = 0;
Vanger 0:b86d15c6ba29 4631
Vanger 0:b86d15c6ba29 4632 byte seq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 4633 byte ver[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 4634 byte* tmps[RSA_INTS];
Vanger 0:b86d15c6ba29 4635
Vanger 0:b86d15c6ba29 4636 if (!key || !output)
Vanger 0:b86d15c6ba29 4637 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4638
Vanger 0:b86d15c6ba29 4639 if (key->type != RSA_PRIVATE)
Vanger 0:b86d15c6ba29 4640 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4641
Vanger 0:b86d15c6ba29 4642 for (i = 0; i < RSA_INTS; i++)
Vanger 0:b86d15c6ba29 4643 tmps[i] = NULL;
Vanger 0:b86d15c6ba29 4644
Vanger 0:b86d15c6ba29 4645 /* write all big ints from key to DER tmps */
Vanger 0:b86d15c6ba29 4646 for (i = 0; i < RSA_INTS; i++) {
Vanger 0:b86d15c6ba29 4647 mp_int* keyInt = GetRsaInt(key, i);
Vanger 0:b86d15c6ba29 4648 rawLen = mp_unsigned_bin_size(keyInt);
Vanger 0:b86d15c6ba29 4649 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
Vanger 0:b86d15c6ba29 4650 DYNAMIC_TYPE_RSA);
Vanger 0:b86d15c6ba29 4651 if (tmps[i] == NULL) {
Vanger 0:b86d15c6ba29 4652 ret = MEMORY_E;
Vanger 0:b86d15c6ba29 4653 break;
Vanger 0:b86d15c6ba29 4654 }
Vanger 0:b86d15c6ba29 4655
Vanger 0:b86d15c6ba29 4656 tmps[i][0] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 4657 sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */
Vanger 0:b86d15c6ba29 4658
Vanger 0:b86d15c6ba29 4659 if (sizes[i] <= MAX_SEQ_SZ) {
Vanger 0:b86d15c6ba29 4660 int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
Vanger 0:b86d15c6ba29 4661 if (err == MP_OKAY) {
Vanger 0:b86d15c6ba29 4662 sizes[i] += rawLen;
Vanger 0:b86d15c6ba29 4663 intTotalLen += sizes[i];
Vanger 0:b86d15c6ba29 4664 }
Vanger 0:b86d15c6ba29 4665 else {
Vanger 0:b86d15c6ba29 4666 ret = err;
Vanger 0:b86d15c6ba29 4667 break;
Vanger 0:b86d15c6ba29 4668 }
Vanger 0:b86d15c6ba29 4669 }
Vanger 0:b86d15c6ba29 4670 else {
Vanger 0:b86d15c6ba29 4671 ret = ASN_INPUT_E;
Vanger 0:b86d15c6ba29 4672 break;
Vanger 0:b86d15c6ba29 4673 }
Vanger 0:b86d15c6ba29 4674 }
Vanger 0:b86d15c6ba29 4675
Vanger 0:b86d15c6ba29 4676 if (ret != 0) {
Vanger 0:b86d15c6ba29 4677 FreeTmpRsas(tmps, key->heap);
Vanger 0:b86d15c6ba29 4678 return ret;
Vanger 0:b86d15c6ba29 4679 }
Vanger 0:b86d15c6ba29 4680
Vanger 0:b86d15c6ba29 4681 /* make headers */
Vanger 0:b86d15c6ba29 4682 verSz = SetMyVersion(0, ver, FALSE);
Vanger 0:b86d15c6ba29 4683 seqSz = SetSequence(verSz + intTotalLen, seq);
Vanger 0:b86d15c6ba29 4684
Vanger 0:b86d15c6ba29 4685 outLen = seqSz + verSz + intTotalLen;
Vanger 0:b86d15c6ba29 4686 if (outLen > (int)inLen)
Vanger 0:b86d15c6ba29 4687 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 4688
Vanger 0:b86d15c6ba29 4689 /* write to output */
Vanger 0:b86d15c6ba29 4690 XMEMCPY(output, seq, seqSz);
Vanger 0:b86d15c6ba29 4691 j = seqSz;
Vanger 0:b86d15c6ba29 4692 XMEMCPY(output + j, ver, verSz);
Vanger 0:b86d15c6ba29 4693 j += verSz;
Vanger 0:b86d15c6ba29 4694
Vanger 0:b86d15c6ba29 4695 for (i = 0; i < RSA_INTS; i++) {
Vanger 0:b86d15c6ba29 4696 XMEMCPY(output + j, tmps[i], sizes[i]);
Vanger 0:b86d15c6ba29 4697 j += sizes[i];
Vanger 0:b86d15c6ba29 4698 }
Vanger 0:b86d15c6ba29 4699 FreeTmpRsas(tmps, key->heap);
Vanger 0:b86d15c6ba29 4700
Vanger 0:b86d15c6ba29 4701 return outLen;
Vanger 0:b86d15c6ba29 4702 }
Vanger 0:b86d15c6ba29 4703
Vanger 0:b86d15c6ba29 4704 #endif /* CYASSL_KEY_GEN && !NO_RSA */
Vanger 0:b86d15c6ba29 4705
Vanger 0:b86d15c6ba29 4706
Vanger 0:b86d15c6ba29 4707 #if defined(CYASSL_CERT_GEN) && !defined(NO_RSA)
Vanger 0:b86d15c6ba29 4708
Vanger 0:b86d15c6ba29 4709
Vanger 0:b86d15c6ba29 4710 #ifndef min
Vanger 0:b86d15c6ba29 4711
Vanger 0:b86d15c6ba29 4712 static INLINE word32 min(word32 a, word32 b)
Vanger 0:b86d15c6ba29 4713 {
Vanger 0:b86d15c6ba29 4714 return a > b ? b : a;
Vanger 0:b86d15c6ba29 4715 }
Vanger 0:b86d15c6ba29 4716
Vanger 0:b86d15c6ba29 4717 #endif /* min */
Vanger 0:b86d15c6ba29 4718
Vanger 0:b86d15c6ba29 4719
Vanger 0:b86d15c6ba29 4720 /* Initialize and Set Certficate defaults:
Vanger 0:b86d15c6ba29 4721 version = 3 (0x2)
Vanger 0:b86d15c6ba29 4722 serial = 0
Vanger 0:b86d15c6ba29 4723 sigType = SHA_WITH_RSA
Vanger 0:b86d15c6ba29 4724 issuer = blank
Vanger 0:b86d15c6ba29 4725 daysValid = 500
Vanger 0:b86d15c6ba29 4726 selfSigned = 1 (true) use subject as issuer
Vanger 0:b86d15c6ba29 4727 subject = blank
Vanger 0:b86d15c6ba29 4728 */
Vanger 0:b86d15c6ba29 4729 void InitCert(Cert* cert)
Vanger 0:b86d15c6ba29 4730 {
Vanger 0:b86d15c6ba29 4731 cert->version = 2; /* version 3 is hex 2 */
Vanger 0:b86d15c6ba29 4732 cert->sigType = CTC_SHAwRSA;
Vanger 0:b86d15c6ba29 4733 cert->daysValid = 500;
Vanger 0:b86d15c6ba29 4734 cert->selfSigned = 1;
Vanger 0:b86d15c6ba29 4735 cert->isCA = 0;
Vanger 0:b86d15c6ba29 4736 cert->bodySz = 0;
Vanger 0:b86d15c6ba29 4737 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 4738 cert->altNamesSz = 0;
Vanger 0:b86d15c6ba29 4739 cert->beforeDateSz = 0;
Vanger 0:b86d15c6ba29 4740 cert->afterDateSz = 0;
Vanger 0:b86d15c6ba29 4741 #endif
Vanger 0:b86d15c6ba29 4742 cert->keyType = RSA_KEY;
Vanger 0:b86d15c6ba29 4743 XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 4744
Vanger 0:b86d15c6ba29 4745 cert->issuer.country[0] = '\0';
Vanger 0:b86d15c6ba29 4746 cert->issuer.countryEnc = CTC_PRINTABLE;
Vanger 0:b86d15c6ba29 4747 cert->issuer.state[0] = '\0';
Vanger 0:b86d15c6ba29 4748 cert->issuer.stateEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4749 cert->issuer.locality[0] = '\0';
Vanger 0:b86d15c6ba29 4750 cert->issuer.localityEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4751 cert->issuer.sur[0] = '\0';
Vanger 0:b86d15c6ba29 4752 cert->issuer.surEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4753 cert->issuer.org[0] = '\0';
Vanger 0:b86d15c6ba29 4754 cert->issuer.orgEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4755 cert->issuer.unit[0] = '\0';
Vanger 0:b86d15c6ba29 4756 cert->issuer.unitEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4757 cert->issuer.commonName[0] = '\0';
Vanger 0:b86d15c6ba29 4758 cert->issuer.commonNameEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4759 cert->issuer.email[0] = '\0';
Vanger 0:b86d15c6ba29 4760
Vanger 0:b86d15c6ba29 4761 cert->subject.country[0] = '\0';
Vanger 0:b86d15c6ba29 4762 cert->subject.countryEnc = CTC_PRINTABLE;
Vanger 0:b86d15c6ba29 4763 cert->subject.state[0] = '\0';
Vanger 0:b86d15c6ba29 4764 cert->subject.stateEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4765 cert->subject.locality[0] = '\0';
Vanger 0:b86d15c6ba29 4766 cert->subject.localityEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4767 cert->subject.sur[0] = '\0';
Vanger 0:b86d15c6ba29 4768 cert->subject.surEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4769 cert->subject.org[0] = '\0';
Vanger 0:b86d15c6ba29 4770 cert->subject.orgEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4771 cert->subject.unit[0] = '\0';
Vanger 0:b86d15c6ba29 4772 cert->subject.unitEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4773 cert->subject.commonName[0] = '\0';
Vanger 0:b86d15c6ba29 4774 cert->subject.commonNameEnc = CTC_UTF8;
Vanger 0:b86d15c6ba29 4775 cert->subject.email[0] = '\0';
Vanger 0:b86d15c6ba29 4776
Vanger 0:b86d15c6ba29 4777 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 4778 cert->challengePw[0] ='\0';
Vanger 0:b86d15c6ba29 4779 #endif
Vanger 0:b86d15c6ba29 4780 }
Vanger 0:b86d15c6ba29 4781
Vanger 0:b86d15c6ba29 4782
Vanger 0:b86d15c6ba29 4783 /* DER encoded x509 Certificate */
Vanger 0:b86d15c6ba29 4784 typedef struct DerCert {
Vanger 0:b86d15c6ba29 4785 byte size[MAX_LENGTH_SZ]; /* length encoded */
Vanger 0:b86d15c6ba29 4786 byte version[MAX_VERSION_SZ]; /* version encoded */
Vanger 0:b86d15c6ba29 4787 byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
Vanger 0:b86d15c6ba29 4788 byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */
Vanger 0:b86d15c6ba29 4789 byte issuer[ASN_NAME_MAX]; /* issuer encoded */
Vanger 0:b86d15c6ba29 4790 byte subject[ASN_NAME_MAX]; /* subject encoded */
Vanger 0:b86d15c6ba29 4791 byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */
Vanger 0:b86d15c6ba29 4792 byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
Vanger 0:b86d15c6ba29 4793 byte ca[MAX_CA_SZ]; /* basic constraint CA true size */
Vanger 0:b86d15c6ba29 4794 byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
Vanger 0:b86d15c6ba29 4795 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 4796 byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */
Vanger 0:b86d15c6ba29 4797 #endif
Vanger 0:b86d15c6ba29 4798 int sizeSz; /* encoded size length */
Vanger 0:b86d15c6ba29 4799 int versionSz; /* encoded version length */
Vanger 0:b86d15c6ba29 4800 int serialSz; /* encoded serial length */
Vanger 0:b86d15c6ba29 4801 int sigAlgoSz; /* enocded sig alog length */
Vanger 0:b86d15c6ba29 4802 int issuerSz; /* encoded issuer length */
Vanger 0:b86d15c6ba29 4803 int subjectSz; /* encoded subject length */
Vanger 0:b86d15c6ba29 4804 int validitySz; /* encoded validity length */
Vanger 0:b86d15c6ba29 4805 int publicKeySz; /* encoded public key length */
Vanger 0:b86d15c6ba29 4806 int caSz; /* encoded CA extension length */
Vanger 0:b86d15c6ba29 4807 int extensionsSz; /* encoded extensions total length */
Vanger 0:b86d15c6ba29 4808 int total; /* total encoded lengths */
Vanger 0:b86d15c6ba29 4809 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 4810 int attribSz;
Vanger 0:b86d15c6ba29 4811 #endif
Vanger 0:b86d15c6ba29 4812 } DerCert;
Vanger 0:b86d15c6ba29 4813
Vanger 0:b86d15c6ba29 4814
Vanger 0:b86d15c6ba29 4815 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 4816
Vanger 0:b86d15c6ba29 4817 /* Write a set header to output */
Vanger 0:b86d15c6ba29 4818 static word32 SetUTF8String(word32 len, byte* output)
Vanger 0:b86d15c6ba29 4819 {
Vanger 0:b86d15c6ba29 4820 output[0] = ASN_UTF8STRING;
Vanger 0:b86d15c6ba29 4821 return SetLength(len, output + 1) + 1;
Vanger 0:b86d15c6ba29 4822 }
Vanger 0:b86d15c6ba29 4823
Vanger 0:b86d15c6ba29 4824 #endif /* CYASSL_CERT_REQ */
Vanger 0:b86d15c6ba29 4825
Vanger 0:b86d15c6ba29 4826
Vanger 0:b86d15c6ba29 4827 /* Write a serial number to output */
Vanger 0:b86d15c6ba29 4828 static int SetSerial(const byte* serial, byte* output)
Vanger 0:b86d15c6ba29 4829 {
Vanger 0:b86d15c6ba29 4830 int length = 0;
Vanger 0:b86d15c6ba29 4831
Vanger 0:b86d15c6ba29 4832 output[length++] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 4833 length += SetLength(CTC_SERIAL_SIZE, &output[length]);
Vanger 0:b86d15c6ba29 4834 XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 4835
Vanger 0:b86d15c6ba29 4836 return length + CTC_SERIAL_SIZE;
Vanger 0:b86d15c6ba29 4837 }
Vanger 0:b86d15c6ba29 4838
Vanger 0:b86d15c6ba29 4839
Vanger 0:b86d15c6ba29 4840 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 4841
Vanger 0:b86d15c6ba29 4842
Vanger 0:b86d15c6ba29 4843 /* Write a public ECC key to output */
Vanger 0:b86d15c6ba29 4844 static int SetEccPublicKey(byte* output, ecc_key* key)
Vanger 0:b86d15c6ba29 4845 {
Vanger 0:b86d15c6ba29 4846 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
Vanger 0:b86d15c6ba29 4847 int algoSz;
Vanger 0:b86d15c6ba29 4848 int curveSz;
Vanger 0:b86d15c6ba29 4849 int lenSz;
Vanger 0:b86d15c6ba29 4850 int idx;
Vanger 0:b86d15c6ba29 4851 word32 pubSz = ECC_BUFSIZE;
Vanger 0:b86d15c6ba29 4852 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4853 byte* algo = NULL;
Vanger 0:b86d15c6ba29 4854 byte* curve = NULL;
Vanger 0:b86d15c6ba29 4855 byte* pub = NULL;
Vanger 0:b86d15c6ba29 4856 #else
Vanger 0:b86d15c6ba29 4857 byte algo[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 4858 byte curve[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 4859 byte pub[ECC_BUFSIZE];
Vanger 0:b86d15c6ba29 4860 #endif
Vanger 0:b86d15c6ba29 4861
Vanger 0:b86d15c6ba29 4862 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4863 pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4864 if (pub == NULL)
Vanger 0:b86d15c6ba29 4865 return MEMORY_E;
Vanger 0:b86d15c6ba29 4866 #endif
Vanger 0:b86d15c6ba29 4867
Vanger 0:b86d15c6ba29 4868 int ret = ecc_export_x963(key, pub, &pubSz);
Vanger 0:b86d15c6ba29 4869 if (ret != 0) {
Vanger 0:b86d15c6ba29 4870 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4871 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4872 #endif
Vanger 0:b86d15c6ba29 4873 return ret;
Vanger 0:b86d15c6ba29 4874 }
Vanger 0:b86d15c6ba29 4875
Vanger 0:b86d15c6ba29 4876 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4877 curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4878 if (curve == NULL) {
Vanger 0:b86d15c6ba29 4879 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4880 return MEMORY_E;
Vanger 0:b86d15c6ba29 4881 }
Vanger 0:b86d15c6ba29 4882 #endif
Vanger 0:b86d15c6ba29 4883
Vanger 0:b86d15c6ba29 4884 /* headers */
Vanger 0:b86d15c6ba29 4885 curveSz = SetCurve(key, curve);
Vanger 0:b86d15c6ba29 4886 if (curveSz <= 0) {
Vanger 0:b86d15c6ba29 4887 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4888 XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4889 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4890 #endif
Vanger 0:b86d15c6ba29 4891 return curveSz;
Vanger 0:b86d15c6ba29 4892 }
Vanger 0:b86d15c6ba29 4893
Vanger 0:b86d15c6ba29 4894 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4895 algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4896 if (algo == NULL) {
Vanger 0:b86d15c6ba29 4897 XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4898 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4899 return MEMORY_E;
Vanger 0:b86d15c6ba29 4900 }
Vanger 0:b86d15c6ba29 4901 #endif
Vanger 0:b86d15c6ba29 4902
Vanger 0:b86d15c6ba29 4903 algoSz = SetAlgoID(ECDSAk, algo, keyType, curveSz);
Vanger 0:b86d15c6ba29 4904 lenSz = SetLength(pubSz + 1, len);
Vanger 0:b86d15c6ba29 4905 len[lenSz++] = 0; /* trailing 0 */
Vanger 0:b86d15c6ba29 4906
Vanger 0:b86d15c6ba29 4907 /* write */
Vanger 0:b86d15c6ba29 4908 idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output);
Vanger 0:b86d15c6ba29 4909 /* 1 is for ASN_BIT_STRING */
Vanger 0:b86d15c6ba29 4910 /* algo */
Vanger 0:b86d15c6ba29 4911 XMEMCPY(output + idx, algo, algoSz);
Vanger 0:b86d15c6ba29 4912 idx += algoSz;
Vanger 0:b86d15c6ba29 4913 /* curve */
Vanger 0:b86d15c6ba29 4914 XMEMCPY(output + idx, curve, curveSz);
Vanger 0:b86d15c6ba29 4915 idx += curveSz;
Vanger 0:b86d15c6ba29 4916 /* bit string */
Vanger 0:b86d15c6ba29 4917 output[idx++] = ASN_BIT_STRING;
Vanger 0:b86d15c6ba29 4918 /* length */
Vanger 0:b86d15c6ba29 4919 XMEMCPY(output + idx, len, lenSz);
Vanger 0:b86d15c6ba29 4920 idx += lenSz;
Vanger 0:b86d15c6ba29 4921 /* pub */
Vanger 0:b86d15c6ba29 4922 XMEMCPY(output + idx, pub, pubSz);
Vanger 0:b86d15c6ba29 4923 idx += pubSz;
Vanger 0:b86d15c6ba29 4924
Vanger 0:b86d15c6ba29 4925 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4926 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4927 XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4928 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4929 #endif
Vanger 0:b86d15c6ba29 4930
Vanger 0:b86d15c6ba29 4931 return idx;
Vanger 0:b86d15c6ba29 4932 }
Vanger 0:b86d15c6ba29 4933
Vanger 0:b86d15c6ba29 4934
Vanger 0:b86d15c6ba29 4935 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 4936
Vanger 0:b86d15c6ba29 4937
Vanger 0:b86d15c6ba29 4938 /* Write a public RSA key to output */
Vanger 0:b86d15c6ba29 4939 static int SetRsaPublicKey(byte* output, RsaKey* key)
Vanger 0:b86d15c6ba29 4940 {
Vanger 0:b86d15c6ba29 4941 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4942 byte* n = NULL;
Vanger 0:b86d15c6ba29 4943 byte* e = NULL;
Vanger 0:b86d15c6ba29 4944 byte* algo = NULL;
Vanger 0:b86d15c6ba29 4945 #else
Vanger 0:b86d15c6ba29 4946 byte n[MAX_RSA_INT_SZ];
Vanger 0:b86d15c6ba29 4947 byte e[MAX_RSA_E_SZ];
Vanger 0:b86d15c6ba29 4948 byte algo[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 4949 #endif
Vanger 0:b86d15c6ba29 4950 byte seq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 4951 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
Vanger 0:b86d15c6ba29 4952 int nSz;
Vanger 0:b86d15c6ba29 4953 int eSz;
Vanger 0:b86d15c6ba29 4954 int algoSz;
Vanger 0:b86d15c6ba29 4955 int seqSz;
Vanger 0:b86d15c6ba29 4956 int lenSz;
Vanger 0:b86d15c6ba29 4957 int idx;
Vanger 0:b86d15c6ba29 4958 int rawLen;
Vanger 0:b86d15c6ba29 4959 int leadingBit;
Vanger 0:b86d15c6ba29 4960 int err;
Vanger 0:b86d15c6ba29 4961
Vanger 0:b86d15c6ba29 4962 /* n */
Vanger 0:b86d15c6ba29 4963 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4964 n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4965 if (n == NULL)
Vanger 0:b86d15c6ba29 4966 return MEMORY_E;
Vanger 0:b86d15c6ba29 4967 #endif
Vanger 0:b86d15c6ba29 4968
Vanger 0:b86d15c6ba29 4969 leadingBit = mp_leading_bit(&key->n);
Vanger 0:b86d15c6ba29 4970 rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
Vanger 0:b86d15c6ba29 4971 n[0] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 4972 nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
Vanger 0:b86d15c6ba29 4973
Vanger 0:b86d15c6ba29 4974 if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
Vanger 0:b86d15c6ba29 4975 if (leadingBit)
Vanger 0:b86d15c6ba29 4976 n[nSz] = 0;
Vanger 0:b86d15c6ba29 4977 err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
Vanger 0:b86d15c6ba29 4978 if (err == MP_OKAY)
Vanger 0:b86d15c6ba29 4979 nSz += rawLen;
Vanger 0:b86d15c6ba29 4980 else {
Vanger 0:b86d15c6ba29 4981 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4982 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4983 #endif
Vanger 0:b86d15c6ba29 4984 return MP_TO_E;
Vanger 0:b86d15c6ba29 4985 }
Vanger 0:b86d15c6ba29 4986 }
Vanger 0:b86d15c6ba29 4987 else {
Vanger 0:b86d15c6ba29 4988 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4989 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4990 #endif
Vanger 0:b86d15c6ba29 4991 return BUFFER_E;
Vanger 0:b86d15c6ba29 4992 }
Vanger 0:b86d15c6ba29 4993
Vanger 0:b86d15c6ba29 4994 /* e */
Vanger 0:b86d15c6ba29 4995 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4996 e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 4997 if (e == NULL) {
Vanger 0:b86d15c6ba29 4998 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 4999 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5000 #endif
Vanger 0:b86d15c6ba29 5001 return MEMORY_E;
Vanger 0:b86d15c6ba29 5002 }
Vanger 0:b86d15c6ba29 5003 #endif
Vanger 0:b86d15c6ba29 5004
Vanger 0:b86d15c6ba29 5005 leadingBit = mp_leading_bit(&key->e);
Vanger 0:b86d15c6ba29 5006 rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
Vanger 0:b86d15c6ba29 5007 e[0] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 5008 eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
Vanger 0:b86d15c6ba29 5009
Vanger 0:b86d15c6ba29 5010 if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
Vanger 0:b86d15c6ba29 5011 if (leadingBit)
Vanger 0:b86d15c6ba29 5012 e[eSz] = 0;
Vanger 0:b86d15c6ba29 5013 err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
Vanger 0:b86d15c6ba29 5014 if (err == MP_OKAY)
Vanger 0:b86d15c6ba29 5015 eSz += rawLen;
Vanger 0:b86d15c6ba29 5016 else {
Vanger 0:b86d15c6ba29 5017 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5018 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5019 XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5020 #endif
Vanger 0:b86d15c6ba29 5021 return MP_TO_E;
Vanger 0:b86d15c6ba29 5022 }
Vanger 0:b86d15c6ba29 5023 }
Vanger 0:b86d15c6ba29 5024 else {
Vanger 0:b86d15c6ba29 5025 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5026 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5027 XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5028 #endif
Vanger 0:b86d15c6ba29 5029 return BUFFER_E;
Vanger 0:b86d15c6ba29 5030 }
Vanger 0:b86d15c6ba29 5031
Vanger 0:b86d15c6ba29 5032 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5033 algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5034 if (algo == NULL) {
Vanger 0:b86d15c6ba29 5035 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5036 XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5037 return MEMORY_E;
Vanger 0:b86d15c6ba29 5038 }
Vanger 0:b86d15c6ba29 5039 #endif
Vanger 0:b86d15c6ba29 5040
Vanger 0:b86d15c6ba29 5041 /* headers */
Vanger 0:b86d15c6ba29 5042 algoSz = SetAlgoID(RSAk, algo, keyType, 0);
Vanger 0:b86d15c6ba29 5043 seqSz = SetSequence(nSz + eSz, seq);
Vanger 0:b86d15c6ba29 5044 lenSz = SetLength(seqSz + nSz + eSz + 1, len);
Vanger 0:b86d15c6ba29 5045 len[lenSz++] = 0; /* trailing 0 */
Vanger 0:b86d15c6ba29 5046
Vanger 0:b86d15c6ba29 5047 /* write */
Vanger 0:b86d15c6ba29 5048 idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
Vanger 0:b86d15c6ba29 5049 /* 1 is for ASN_BIT_STRING */
Vanger 0:b86d15c6ba29 5050 /* algo */
Vanger 0:b86d15c6ba29 5051 XMEMCPY(output + idx, algo, algoSz);
Vanger 0:b86d15c6ba29 5052 idx += algoSz;
Vanger 0:b86d15c6ba29 5053 /* bit string */
Vanger 0:b86d15c6ba29 5054 output[idx++] = ASN_BIT_STRING;
Vanger 0:b86d15c6ba29 5055 /* length */
Vanger 0:b86d15c6ba29 5056 XMEMCPY(output + idx, len, lenSz);
Vanger 0:b86d15c6ba29 5057 idx += lenSz;
Vanger 0:b86d15c6ba29 5058 /* seq */
Vanger 0:b86d15c6ba29 5059 XMEMCPY(output + idx, seq, seqSz);
Vanger 0:b86d15c6ba29 5060 idx += seqSz;
Vanger 0:b86d15c6ba29 5061 /* n */
Vanger 0:b86d15c6ba29 5062 XMEMCPY(output + idx, n, nSz);
Vanger 0:b86d15c6ba29 5063 idx += nSz;
Vanger 0:b86d15c6ba29 5064 /* e */
Vanger 0:b86d15c6ba29 5065 XMEMCPY(output + idx, e, eSz);
Vanger 0:b86d15c6ba29 5066 idx += eSz;
Vanger 0:b86d15c6ba29 5067
Vanger 0:b86d15c6ba29 5068 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5069 XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5070 XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5071 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5072 #endif
Vanger 0:b86d15c6ba29 5073
Vanger 0:b86d15c6ba29 5074 return idx;
Vanger 0:b86d15c6ba29 5075 }
Vanger 0:b86d15c6ba29 5076
Vanger 0:b86d15c6ba29 5077
Vanger 0:b86d15c6ba29 5078 static INLINE byte itob(int number)
Vanger 0:b86d15c6ba29 5079 {
Vanger 0:b86d15c6ba29 5080 return (byte)number + 0x30;
Vanger 0:b86d15c6ba29 5081 }
Vanger 0:b86d15c6ba29 5082
Vanger 0:b86d15c6ba29 5083
Vanger 0:b86d15c6ba29 5084 /* write time to output, format */
Vanger 0:b86d15c6ba29 5085 static void SetTime(struct tm* date, byte* output)
Vanger 0:b86d15c6ba29 5086 {
Vanger 0:b86d15c6ba29 5087 int i = 0;
Vanger 0:b86d15c6ba29 5088
Vanger 0:b86d15c6ba29 5089 output[i++] = itob((date->tm_year % 10000) / 1000);
Vanger 0:b86d15c6ba29 5090 output[i++] = itob((date->tm_year % 1000) / 100);
Vanger 0:b86d15c6ba29 5091 output[i++] = itob((date->tm_year % 100) / 10);
Vanger 0:b86d15c6ba29 5092 output[i++] = itob( date->tm_year % 10);
Vanger 0:b86d15c6ba29 5093
Vanger 0:b86d15c6ba29 5094 output[i++] = itob(date->tm_mon / 10);
Vanger 0:b86d15c6ba29 5095 output[i++] = itob(date->tm_mon % 10);
Vanger 0:b86d15c6ba29 5096
Vanger 0:b86d15c6ba29 5097 output[i++] = itob(date->tm_mday / 10);
Vanger 0:b86d15c6ba29 5098 output[i++] = itob(date->tm_mday % 10);
Vanger 0:b86d15c6ba29 5099
Vanger 0:b86d15c6ba29 5100 output[i++] = itob(date->tm_hour / 10);
Vanger 0:b86d15c6ba29 5101 output[i++] = itob(date->tm_hour % 10);
Vanger 0:b86d15c6ba29 5102
Vanger 0:b86d15c6ba29 5103 output[i++] = itob(date->tm_min / 10);
Vanger 0:b86d15c6ba29 5104 output[i++] = itob(date->tm_min % 10);
Vanger 0:b86d15c6ba29 5105
Vanger 0:b86d15c6ba29 5106 output[i++] = itob(date->tm_sec / 10);
Vanger 0:b86d15c6ba29 5107 output[i++] = itob(date->tm_sec % 10);
Vanger 0:b86d15c6ba29 5108
Vanger 0:b86d15c6ba29 5109 output[i] = 'Z'; /* Zulu profile */
Vanger 0:b86d15c6ba29 5110 }
Vanger 0:b86d15c6ba29 5111
Vanger 0:b86d15c6ba29 5112
Vanger 0:b86d15c6ba29 5113 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 5114
Vanger 0:b86d15c6ba29 5115 /* Copy Dates from cert, return bytes written */
Vanger 0:b86d15c6ba29 5116 static int CopyValidity(byte* output, Cert* cert)
Vanger 0:b86d15c6ba29 5117 {
Vanger 0:b86d15c6ba29 5118 int seqSz;
Vanger 0:b86d15c6ba29 5119
Vanger 0:b86d15c6ba29 5120 CYASSL_ENTER("CopyValidity");
Vanger 0:b86d15c6ba29 5121
Vanger 0:b86d15c6ba29 5122 /* headers and output */
Vanger 0:b86d15c6ba29 5123 seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
Vanger 0:b86d15c6ba29 5124 XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
Vanger 0:b86d15c6ba29 5125 XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
Vanger 0:b86d15c6ba29 5126 cert->afterDateSz);
Vanger 0:b86d15c6ba29 5127 return seqSz + cert->beforeDateSz + cert->afterDateSz;
Vanger 0:b86d15c6ba29 5128 }
Vanger 0:b86d15c6ba29 5129
Vanger 0:b86d15c6ba29 5130 #endif
Vanger 0:b86d15c6ba29 5131
Vanger 0:b86d15c6ba29 5132
Vanger 0:b86d15c6ba29 5133 /* Set Date validity from now until now + daysValid */
Vanger 0:b86d15c6ba29 5134 static int SetValidity(byte* output, int daysValid)
Vanger 0:b86d15c6ba29 5135 {
Vanger 0:b86d15c6ba29 5136 byte before[MAX_DATE_SIZE];
Vanger 0:b86d15c6ba29 5137 byte after[MAX_DATE_SIZE];
Vanger 0:b86d15c6ba29 5138
Vanger 0:b86d15c6ba29 5139 int beforeSz;
Vanger 0:b86d15c6ba29 5140 int afterSz;
Vanger 0:b86d15c6ba29 5141 int seqSz;
Vanger 0:b86d15c6ba29 5142
Vanger 0:b86d15c6ba29 5143 time_t ticks;
Vanger 0:b86d15c6ba29 5144 struct tm* now;
Vanger 0:b86d15c6ba29 5145 struct tm local;
Vanger 0:b86d15c6ba29 5146
Vanger 0:b86d15c6ba29 5147 ticks = XTIME(0);
Vanger 0:b86d15c6ba29 5148 now = XGMTIME(&ticks);
Vanger 0:b86d15c6ba29 5149
Vanger 0:b86d15c6ba29 5150 /* before now */
Vanger 0:b86d15c6ba29 5151 local = *now;
Vanger 0:b86d15c6ba29 5152 before[0] = ASN_GENERALIZED_TIME;
Vanger 0:b86d15c6ba29 5153 beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */
Vanger 0:b86d15c6ba29 5154
Vanger 0:b86d15c6ba29 5155 /* subtract 1 day for more compliance */
Vanger 0:b86d15c6ba29 5156 local.tm_mday -= 1;
Vanger 0:b86d15c6ba29 5157 mktime(&local);
Vanger 0:b86d15c6ba29 5158
Vanger 0:b86d15c6ba29 5159 /* adjust */
Vanger 0:b86d15c6ba29 5160 local.tm_year += 1900;
Vanger 0:b86d15c6ba29 5161 local.tm_mon += 1;
Vanger 0:b86d15c6ba29 5162
Vanger 0:b86d15c6ba29 5163 SetTime(&local, before + beforeSz);
Vanger 0:b86d15c6ba29 5164 beforeSz += ASN_GEN_TIME_SZ;
Vanger 0:b86d15c6ba29 5165
Vanger 0:b86d15c6ba29 5166 /* after now + daysValid */
Vanger 0:b86d15c6ba29 5167 local = *now;
Vanger 0:b86d15c6ba29 5168 after[0] = ASN_GENERALIZED_TIME;
Vanger 0:b86d15c6ba29 5169 afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */
Vanger 0:b86d15c6ba29 5170
Vanger 0:b86d15c6ba29 5171 /* add daysValid */
Vanger 0:b86d15c6ba29 5172 local.tm_mday += daysValid;
Vanger 0:b86d15c6ba29 5173 mktime(&local);
Vanger 0:b86d15c6ba29 5174
Vanger 0:b86d15c6ba29 5175 /* adjust */
Vanger 0:b86d15c6ba29 5176 local.tm_year += 1900;
Vanger 0:b86d15c6ba29 5177 local.tm_mon += 1;
Vanger 0:b86d15c6ba29 5178
Vanger 0:b86d15c6ba29 5179 SetTime(&local, after + afterSz);
Vanger 0:b86d15c6ba29 5180 afterSz += ASN_GEN_TIME_SZ;
Vanger 0:b86d15c6ba29 5181
Vanger 0:b86d15c6ba29 5182 /* headers and output */
Vanger 0:b86d15c6ba29 5183 seqSz = SetSequence(beforeSz + afterSz, output);
Vanger 0:b86d15c6ba29 5184 XMEMCPY(output + seqSz, before, beforeSz);
Vanger 0:b86d15c6ba29 5185 XMEMCPY(output + seqSz + beforeSz, after, afterSz);
Vanger 0:b86d15c6ba29 5186
Vanger 0:b86d15c6ba29 5187 return seqSz + beforeSz + afterSz;
Vanger 0:b86d15c6ba29 5188 }
Vanger 0:b86d15c6ba29 5189
Vanger 0:b86d15c6ba29 5190
Vanger 0:b86d15c6ba29 5191 /* ASN Encoded Name field */
Vanger 0:b86d15c6ba29 5192 typedef struct EncodedName {
Vanger 0:b86d15c6ba29 5193 int nameLen; /* actual string value length */
Vanger 0:b86d15c6ba29 5194 int totalLen; /* total encoded length */
Vanger 0:b86d15c6ba29 5195 int type; /* type of name */
Vanger 0:b86d15c6ba29 5196 int used; /* are we actually using this one */
Vanger 0:b86d15c6ba29 5197 byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
Vanger 0:b86d15c6ba29 5198 } EncodedName;
Vanger 0:b86d15c6ba29 5199
Vanger 0:b86d15c6ba29 5200
Vanger 0:b86d15c6ba29 5201 /* Get Which Name from index */
Vanger 0:b86d15c6ba29 5202 static const char* GetOneName(CertName* name, int idx)
Vanger 0:b86d15c6ba29 5203 {
Vanger 0:b86d15c6ba29 5204 switch (idx) {
Vanger 0:b86d15c6ba29 5205 case 0:
Vanger 0:b86d15c6ba29 5206 return name->country;
Vanger 0:b86d15c6ba29 5207
Vanger 0:b86d15c6ba29 5208 case 1:
Vanger 0:b86d15c6ba29 5209 return name->state;
Vanger 0:b86d15c6ba29 5210
Vanger 0:b86d15c6ba29 5211 case 2:
Vanger 0:b86d15c6ba29 5212 return name->locality;
Vanger 0:b86d15c6ba29 5213
Vanger 0:b86d15c6ba29 5214 case 3:
Vanger 0:b86d15c6ba29 5215 return name->sur;
Vanger 0:b86d15c6ba29 5216
Vanger 0:b86d15c6ba29 5217 case 4:
Vanger 0:b86d15c6ba29 5218 return name->org;
Vanger 0:b86d15c6ba29 5219
Vanger 0:b86d15c6ba29 5220 case 5:
Vanger 0:b86d15c6ba29 5221 return name->unit;
Vanger 0:b86d15c6ba29 5222
Vanger 0:b86d15c6ba29 5223 case 6:
Vanger 0:b86d15c6ba29 5224 return name->commonName;
Vanger 0:b86d15c6ba29 5225
Vanger 0:b86d15c6ba29 5226 case 7:
Vanger 0:b86d15c6ba29 5227 return name->email;
Vanger 0:b86d15c6ba29 5228
Vanger 0:b86d15c6ba29 5229 default:
Vanger 0:b86d15c6ba29 5230 return 0;
Vanger 0:b86d15c6ba29 5231 }
Vanger 0:b86d15c6ba29 5232 }
Vanger 0:b86d15c6ba29 5233
Vanger 0:b86d15c6ba29 5234
Vanger 0:b86d15c6ba29 5235 /* Get Which Name Encoding from index */
Vanger 0:b86d15c6ba29 5236 static char GetNameType(CertName* name, int idx)
Vanger 0:b86d15c6ba29 5237 {
Vanger 0:b86d15c6ba29 5238 switch (idx) {
Vanger 0:b86d15c6ba29 5239 case 0:
Vanger 0:b86d15c6ba29 5240 return name->countryEnc;
Vanger 0:b86d15c6ba29 5241
Vanger 0:b86d15c6ba29 5242 case 1:
Vanger 0:b86d15c6ba29 5243 return name->stateEnc;
Vanger 0:b86d15c6ba29 5244
Vanger 0:b86d15c6ba29 5245 case 2:
Vanger 0:b86d15c6ba29 5246 return name->localityEnc;
Vanger 0:b86d15c6ba29 5247
Vanger 0:b86d15c6ba29 5248 case 3:
Vanger 0:b86d15c6ba29 5249 return name->surEnc;
Vanger 0:b86d15c6ba29 5250
Vanger 0:b86d15c6ba29 5251 case 4:
Vanger 0:b86d15c6ba29 5252 return name->orgEnc;
Vanger 0:b86d15c6ba29 5253
Vanger 0:b86d15c6ba29 5254 case 5:
Vanger 0:b86d15c6ba29 5255 return name->unitEnc;
Vanger 0:b86d15c6ba29 5256
Vanger 0:b86d15c6ba29 5257 case 6:
Vanger 0:b86d15c6ba29 5258 return name->commonNameEnc;
Vanger 0:b86d15c6ba29 5259
Vanger 0:b86d15c6ba29 5260 default:
Vanger 0:b86d15c6ba29 5261 return 0;
Vanger 0:b86d15c6ba29 5262 }
Vanger 0:b86d15c6ba29 5263 }
Vanger 0:b86d15c6ba29 5264
Vanger 0:b86d15c6ba29 5265
Vanger 0:b86d15c6ba29 5266 /* Get ASN Name from index */
Vanger 0:b86d15c6ba29 5267 static byte GetNameId(int idx)
Vanger 0:b86d15c6ba29 5268 {
Vanger 0:b86d15c6ba29 5269 switch (idx) {
Vanger 0:b86d15c6ba29 5270 case 0:
Vanger 0:b86d15c6ba29 5271 return ASN_COUNTRY_NAME;
Vanger 0:b86d15c6ba29 5272
Vanger 0:b86d15c6ba29 5273 case 1:
Vanger 0:b86d15c6ba29 5274 return ASN_STATE_NAME;
Vanger 0:b86d15c6ba29 5275
Vanger 0:b86d15c6ba29 5276 case 2:
Vanger 0:b86d15c6ba29 5277 return ASN_LOCALITY_NAME;
Vanger 0:b86d15c6ba29 5278
Vanger 0:b86d15c6ba29 5279 case 3:
Vanger 0:b86d15c6ba29 5280 return ASN_SUR_NAME;
Vanger 0:b86d15c6ba29 5281
Vanger 0:b86d15c6ba29 5282 case 4:
Vanger 0:b86d15c6ba29 5283 return ASN_ORG_NAME;
Vanger 0:b86d15c6ba29 5284
Vanger 0:b86d15c6ba29 5285 case 5:
Vanger 0:b86d15c6ba29 5286 return ASN_ORGUNIT_NAME;
Vanger 0:b86d15c6ba29 5287
Vanger 0:b86d15c6ba29 5288 case 6:
Vanger 0:b86d15c6ba29 5289 return ASN_COMMON_NAME;
Vanger 0:b86d15c6ba29 5290
Vanger 0:b86d15c6ba29 5291 case 7:
Vanger 0:b86d15c6ba29 5292 /* email uses different id type */
Vanger 0:b86d15c6ba29 5293 return 0;
Vanger 0:b86d15c6ba29 5294
Vanger 0:b86d15c6ba29 5295 default:
Vanger 0:b86d15c6ba29 5296 return 0;
Vanger 0:b86d15c6ba29 5297 }
Vanger 0:b86d15c6ba29 5298 }
Vanger 0:b86d15c6ba29 5299
Vanger 0:b86d15c6ba29 5300
Vanger 0:b86d15c6ba29 5301 /* encode all extensions, return total bytes written */
Vanger 0:b86d15c6ba29 5302 static int SetExtensions(byte* output, const byte* ext, int extSz, int header)
Vanger 0:b86d15c6ba29 5303 {
Vanger 0:b86d15c6ba29 5304 byte sequence[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5305 byte len[MAX_LENGTH_SZ];
Vanger 0:b86d15c6ba29 5306
Vanger 0:b86d15c6ba29 5307 int sz = 0;
Vanger 0:b86d15c6ba29 5308 int seqSz = SetSequence(extSz, sequence);
Vanger 0:b86d15c6ba29 5309
Vanger 0:b86d15c6ba29 5310 if (header) {
Vanger 0:b86d15c6ba29 5311 int lenSz = SetLength(seqSz + extSz, len);
Vanger 0:b86d15c6ba29 5312 output[0] = ASN_EXTENSIONS; /* extensions id */
Vanger 0:b86d15c6ba29 5313 sz++;
Vanger 0:b86d15c6ba29 5314 XMEMCPY(&output[sz], len, lenSz); /* length */
Vanger 0:b86d15c6ba29 5315 sz += lenSz;
Vanger 0:b86d15c6ba29 5316 }
Vanger 0:b86d15c6ba29 5317 XMEMCPY(&output[sz], sequence, seqSz); /* sequence */
Vanger 0:b86d15c6ba29 5318 sz += seqSz;
Vanger 0:b86d15c6ba29 5319 XMEMCPY(&output[sz], ext, extSz); /* extensions */
Vanger 0:b86d15c6ba29 5320 sz += extSz;
Vanger 0:b86d15c6ba29 5321
Vanger 0:b86d15c6ba29 5322 return sz;
Vanger 0:b86d15c6ba29 5323 }
Vanger 0:b86d15c6ba29 5324
Vanger 0:b86d15c6ba29 5325
Vanger 0:b86d15c6ba29 5326 /* encode CA basic constraint true, return total bytes written */
Vanger 0:b86d15c6ba29 5327 static int SetCa(byte* output)
Vanger 0:b86d15c6ba29 5328 {
Vanger 0:b86d15c6ba29 5329 static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
Vanger 0:b86d15c6ba29 5330 0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
Vanger 0:b86d15c6ba29 5331
Vanger 0:b86d15c6ba29 5332 XMEMCPY(output, ca, sizeof(ca));
Vanger 0:b86d15c6ba29 5333
Vanger 0:b86d15c6ba29 5334 return (int)sizeof(ca);
Vanger 0:b86d15c6ba29 5335 }
Vanger 0:b86d15c6ba29 5336
Vanger 0:b86d15c6ba29 5337
Vanger 0:b86d15c6ba29 5338 /* encode CertName into output, return total bytes written */
Vanger 0:b86d15c6ba29 5339 static int SetName(byte* output, CertName* name)
Vanger 0:b86d15c6ba29 5340 {
Vanger 0:b86d15c6ba29 5341 int totalBytes = 0, i, idx;
Vanger 0:b86d15c6ba29 5342 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5343 EncodedName* names = NULL;
Vanger 0:b86d15c6ba29 5344 #else
Vanger 0:b86d15c6ba29 5345 EncodedName names[NAME_ENTRIES];
Vanger 0:b86d15c6ba29 5346 #endif
Vanger 0:b86d15c6ba29 5347
Vanger 0:b86d15c6ba29 5348 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5349 names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
Vanger 0:b86d15c6ba29 5350 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5351 if (names == NULL)
Vanger 0:b86d15c6ba29 5352 return MEMORY_E;
Vanger 0:b86d15c6ba29 5353 #endif
Vanger 0:b86d15c6ba29 5354
Vanger 0:b86d15c6ba29 5355 for (i = 0; i < NAME_ENTRIES; i++) {
Vanger 0:b86d15c6ba29 5356 const char* nameStr = GetOneName(name, i);
Vanger 0:b86d15c6ba29 5357 if (nameStr) {
Vanger 0:b86d15c6ba29 5358 /* bottom up */
Vanger 0:b86d15c6ba29 5359 byte firstLen[MAX_LENGTH_SZ];
Vanger 0:b86d15c6ba29 5360 byte secondLen[MAX_LENGTH_SZ];
Vanger 0:b86d15c6ba29 5361 byte sequence[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5362 byte set[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 5363
Vanger 0:b86d15c6ba29 5364 int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
Vanger 0:b86d15c6ba29 5365 int strLen = (int)XSTRLEN(nameStr);
Vanger 0:b86d15c6ba29 5366 int thisLen = strLen;
Vanger 0:b86d15c6ba29 5367 int firstSz, secondSz, seqSz, setSz;
Vanger 0:b86d15c6ba29 5368
Vanger 0:b86d15c6ba29 5369 if (strLen == 0) { /* no user data for this item */
Vanger 0:b86d15c6ba29 5370 names[i].used = 0;
Vanger 0:b86d15c6ba29 5371 continue;
Vanger 0:b86d15c6ba29 5372 }
Vanger 0:b86d15c6ba29 5373
Vanger 0:b86d15c6ba29 5374 secondSz = SetLength(strLen, secondLen);
Vanger 0:b86d15c6ba29 5375 thisLen += secondSz;
Vanger 0:b86d15c6ba29 5376 if (email) {
Vanger 0:b86d15c6ba29 5377 thisLen += EMAIL_JOINT_LEN;
Vanger 0:b86d15c6ba29 5378 thisLen ++; /* id type */
Vanger 0:b86d15c6ba29 5379 firstSz = SetLength(EMAIL_JOINT_LEN, firstLen);
Vanger 0:b86d15c6ba29 5380 }
Vanger 0:b86d15c6ba29 5381 else {
Vanger 0:b86d15c6ba29 5382 thisLen++; /* str type */
Vanger 0:b86d15c6ba29 5383 thisLen++; /* id type */
Vanger 0:b86d15c6ba29 5384 thisLen += JOINT_LEN;
Vanger 0:b86d15c6ba29 5385 firstSz = SetLength(JOINT_LEN + 1, firstLen);
Vanger 0:b86d15c6ba29 5386 }
Vanger 0:b86d15c6ba29 5387 thisLen += firstSz;
Vanger 0:b86d15c6ba29 5388 thisLen++; /* object id */
Vanger 0:b86d15c6ba29 5389
Vanger 0:b86d15c6ba29 5390 seqSz = SetSequence(thisLen, sequence);
Vanger 0:b86d15c6ba29 5391 thisLen += seqSz;
Vanger 0:b86d15c6ba29 5392 setSz = SetSet(thisLen, set);
Vanger 0:b86d15c6ba29 5393 thisLen += setSz;
Vanger 0:b86d15c6ba29 5394
Vanger 0:b86d15c6ba29 5395 if (thisLen > (int)sizeof(names[i].encoded)) {
Vanger 0:b86d15c6ba29 5396 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5397 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5398 #endif
Vanger 0:b86d15c6ba29 5399 return BUFFER_E;
Vanger 0:b86d15c6ba29 5400 }
Vanger 0:b86d15c6ba29 5401
Vanger 0:b86d15c6ba29 5402 /* store it */
Vanger 0:b86d15c6ba29 5403 idx = 0;
Vanger 0:b86d15c6ba29 5404 /* set */
Vanger 0:b86d15c6ba29 5405 XMEMCPY(names[i].encoded, set, setSz);
Vanger 0:b86d15c6ba29 5406 idx += setSz;
Vanger 0:b86d15c6ba29 5407 /* seq */
Vanger 0:b86d15c6ba29 5408 XMEMCPY(names[i].encoded + idx, sequence, seqSz);
Vanger 0:b86d15c6ba29 5409 idx += seqSz;
Vanger 0:b86d15c6ba29 5410 /* asn object id */
Vanger 0:b86d15c6ba29 5411 names[i].encoded[idx++] = ASN_OBJECT_ID;
Vanger 0:b86d15c6ba29 5412 /* first length */
Vanger 0:b86d15c6ba29 5413 XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
Vanger 0:b86d15c6ba29 5414 idx += firstSz;
Vanger 0:b86d15c6ba29 5415 if (email) {
Vanger 0:b86d15c6ba29 5416 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
Vanger 0:b86d15c6ba29 5417 0x01, 0x09, 0x01, 0x16 };
Vanger 0:b86d15c6ba29 5418 /* email joint id */
Vanger 0:b86d15c6ba29 5419 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
Vanger 0:b86d15c6ba29 5420 idx += (int)sizeof(EMAIL_OID);
Vanger 0:b86d15c6ba29 5421 }
Vanger 0:b86d15c6ba29 5422 else {
Vanger 0:b86d15c6ba29 5423 /* joint id */
Vanger 0:b86d15c6ba29 5424 byte bType = GetNameId(i);
Vanger 0:b86d15c6ba29 5425 names[i].encoded[idx++] = 0x55;
Vanger 0:b86d15c6ba29 5426 names[i].encoded[idx++] = 0x04;
Vanger 0:b86d15c6ba29 5427 /* id type */
Vanger 0:b86d15c6ba29 5428 names[i].encoded[idx++] = bType;
Vanger 0:b86d15c6ba29 5429 /* str type */
Vanger 0:b86d15c6ba29 5430 names[i].encoded[idx++] = GetNameType(name, i);
Vanger 0:b86d15c6ba29 5431 }
Vanger 0:b86d15c6ba29 5432 /* second length */
Vanger 0:b86d15c6ba29 5433 XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
Vanger 0:b86d15c6ba29 5434 idx += secondSz;
Vanger 0:b86d15c6ba29 5435 /* str value */
Vanger 0:b86d15c6ba29 5436 XMEMCPY(names[i].encoded + idx, nameStr, strLen);
Vanger 0:b86d15c6ba29 5437 idx += strLen;
Vanger 0:b86d15c6ba29 5438
Vanger 0:b86d15c6ba29 5439 totalBytes += idx;
Vanger 0:b86d15c6ba29 5440 names[i].totalLen = idx;
Vanger 0:b86d15c6ba29 5441 names[i].used = 1;
Vanger 0:b86d15c6ba29 5442 }
Vanger 0:b86d15c6ba29 5443 else
Vanger 0:b86d15c6ba29 5444 names[i].used = 0;
Vanger 0:b86d15c6ba29 5445 }
Vanger 0:b86d15c6ba29 5446
Vanger 0:b86d15c6ba29 5447 /* header */
Vanger 0:b86d15c6ba29 5448 idx = SetSequence(totalBytes, output);
Vanger 0:b86d15c6ba29 5449 totalBytes += idx;
Vanger 0:b86d15c6ba29 5450 if (totalBytes > ASN_NAME_MAX) {
Vanger 0:b86d15c6ba29 5451 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5452 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5453 #endif
Vanger 0:b86d15c6ba29 5454 return BUFFER_E;
Vanger 0:b86d15c6ba29 5455 }
Vanger 0:b86d15c6ba29 5456
Vanger 0:b86d15c6ba29 5457 for (i = 0; i < NAME_ENTRIES; i++) {
Vanger 0:b86d15c6ba29 5458 if (names[i].used) {
Vanger 0:b86d15c6ba29 5459 XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
Vanger 0:b86d15c6ba29 5460 idx += names[i].totalLen;
Vanger 0:b86d15c6ba29 5461 }
Vanger 0:b86d15c6ba29 5462 }
Vanger 0:b86d15c6ba29 5463
Vanger 0:b86d15c6ba29 5464 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5465 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5466 #endif
Vanger 0:b86d15c6ba29 5467
Vanger 0:b86d15c6ba29 5468 return totalBytes;
Vanger 0:b86d15c6ba29 5469 }
Vanger 0:b86d15c6ba29 5470
Vanger 0:b86d15c6ba29 5471 /* encode info from cert into DER encoded format */
Vanger 0:b86d15c6ba29 5472 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
Vanger 0:b86d15c6ba29 5473 RNG* rng, const byte* ntruKey, word16 ntruSz)
Vanger 0:b86d15c6ba29 5474 {
Vanger 0:b86d15c6ba29 5475 int ret;
Vanger 0:b86d15c6ba29 5476
Vanger 0:b86d15c6ba29 5477 (void)eccKey;
Vanger 0:b86d15c6ba29 5478 (void)ntruKey;
Vanger 0:b86d15c6ba29 5479 (void)ntruSz;
Vanger 0:b86d15c6ba29 5480
Vanger 0:b86d15c6ba29 5481 /* init */
Vanger 0:b86d15c6ba29 5482 XMEMSET(der, 0, sizeof(DerCert));
Vanger 0:b86d15c6ba29 5483
Vanger 0:b86d15c6ba29 5484 /* version */
Vanger 0:b86d15c6ba29 5485 der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
Vanger 0:b86d15c6ba29 5486
Vanger 0:b86d15c6ba29 5487 /* serial number */
Vanger 0:b86d15c6ba29 5488 ret = RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
Vanger 0:b86d15c6ba29 5489 if (ret != 0)
Vanger 0:b86d15c6ba29 5490 return ret;
Vanger 0:b86d15c6ba29 5491
Vanger 0:b86d15c6ba29 5492 cert->serial[0] = 0x01; /* ensure positive */
Vanger 0:b86d15c6ba29 5493 der->serialSz = SetSerial(cert->serial, der->serial);
Vanger 0:b86d15c6ba29 5494
Vanger 0:b86d15c6ba29 5495 /* signature algo */
Vanger 0:b86d15c6ba29 5496 der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0);
Vanger 0:b86d15c6ba29 5497 if (der->sigAlgoSz == 0)
Vanger 0:b86d15c6ba29 5498 return ALGO_ID_E;
Vanger 0:b86d15c6ba29 5499
Vanger 0:b86d15c6ba29 5500 /* public key */
Vanger 0:b86d15c6ba29 5501 if (cert->keyType == RSA_KEY) {
Vanger 0:b86d15c6ba29 5502 if (rsaKey == NULL)
Vanger 0:b86d15c6ba29 5503 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5504 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
Vanger 0:b86d15c6ba29 5505 if (der->publicKeySz <= 0)
Vanger 0:b86d15c6ba29 5506 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5507 }
Vanger 0:b86d15c6ba29 5508
Vanger 0:b86d15c6ba29 5509 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 5510 if (cert->keyType == ECC_KEY) {
Vanger 0:b86d15c6ba29 5511 if (eccKey == NULL)
Vanger 0:b86d15c6ba29 5512 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5513 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
Vanger 0:b86d15c6ba29 5514 if (der->publicKeySz <= 0)
Vanger 0:b86d15c6ba29 5515 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5516 }
Vanger 0:b86d15c6ba29 5517 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 5518
Vanger 0:b86d15c6ba29 5519 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 5520 if (cert->keyType == NTRU_KEY) {
Vanger 0:b86d15c6ba29 5521 word32 rc;
Vanger 0:b86d15c6ba29 5522 word16 encodedSz;
Vanger 0:b86d15c6ba29 5523
Vanger 0:b86d15c6ba29 5524 rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
Vanger 0:b86d15c6ba29 5525 ntruKey, &encodedSz, NULL);
Vanger 0:b86d15c6ba29 5526 if (rc != NTRU_OK)
Vanger 0:b86d15c6ba29 5527 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5528 if (encodedSz > MAX_PUBLIC_KEY_SZ)
Vanger 0:b86d15c6ba29 5529 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5530
Vanger 0:b86d15c6ba29 5531 rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
Vanger 0:b86d15c6ba29 5532 ntruKey, &encodedSz, der->publicKey);
Vanger 0:b86d15c6ba29 5533 if (rc != NTRU_OK)
Vanger 0:b86d15c6ba29 5534 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5535
Vanger 0:b86d15c6ba29 5536 der->publicKeySz = encodedSz;
Vanger 0:b86d15c6ba29 5537 }
Vanger 0:b86d15c6ba29 5538 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 5539
Vanger 0:b86d15c6ba29 5540 der->validitySz = 0;
Vanger 0:b86d15c6ba29 5541 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 5542 /* date validity copy ? */
Vanger 0:b86d15c6ba29 5543 if (cert->beforeDateSz && cert->afterDateSz) {
Vanger 0:b86d15c6ba29 5544 der->validitySz = CopyValidity(der->validity, cert);
Vanger 0:b86d15c6ba29 5545 if (der->validitySz == 0)
Vanger 0:b86d15c6ba29 5546 return DATE_E;
Vanger 0:b86d15c6ba29 5547 }
Vanger 0:b86d15c6ba29 5548 #endif
Vanger 0:b86d15c6ba29 5549
Vanger 0:b86d15c6ba29 5550 /* date validity */
Vanger 0:b86d15c6ba29 5551 if (der->validitySz == 0) {
Vanger 0:b86d15c6ba29 5552 der->validitySz = SetValidity(der->validity, cert->daysValid);
Vanger 0:b86d15c6ba29 5553 if (der->validitySz == 0)
Vanger 0:b86d15c6ba29 5554 return DATE_E;
Vanger 0:b86d15c6ba29 5555 }
Vanger 0:b86d15c6ba29 5556
Vanger 0:b86d15c6ba29 5557 /* subject name */
Vanger 0:b86d15c6ba29 5558 der->subjectSz = SetName(der->subject, &cert->subject);
Vanger 0:b86d15c6ba29 5559 if (der->subjectSz == 0)
Vanger 0:b86d15c6ba29 5560 return SUBJECT_E;
Vanger 0:b86d15c6ba29 5561
Vanger 0:b86d15c6ba29 5562 /* issuer name */
Vanger 0:b86d15c6ba29 5563 der->issuerSz = SetName(der->issuer, cert->selfSigned ?
Vanger 0:b86d15c6ba29 5564 &cert->subject : &cert->issuer);
Vanger 0:b86d15c6ba29 5565 if (der->issuerSz == 0)
Vanger 0:b86d15c6ba29 5566 return ISSUER_E;
Vanger 0:b86d15c6ba29 5567
Vanger 0:b86d15c6ba29 5568 /* CA */
Vanger 0:b86d15c6ba29 5569 if (cert->isCA) {
Vanger 0:b86d15c6ba29 5570 der->caSz = SetCa(der->ca);
Vanger 0:b86d15c6ba29 5571 if (der->caSz == 0)
Vanger 0:b86d15c6ba29 5572 return CA_TRUE_E;
Vanger 0:b86d15c6ba29 5573 }
Vanger 0:b86d15c6ba29 5574 else
Vanger 0:b86d15c6ba29 5575 der->caSz = 0;
Vanger 0:b86d15c6ba29 5576
Vanger 0:b86d15c6ba29 5577 /* extensions, just CA now */
Vanger 0:b86d15c6ba29 5578 if (cert->isCA) {
Vanger 0:b86d15c6ba29 5579 der->extensionsSz = SetExtensions(der->extensions,
Vanger 0:b86d15c6ba29 5580 der->ca, der->caSz, TRUE);
Vanger 0:b86d15c6ba29 5581 if (der->extensionsSz == 0)
Vanger 0:b86d15c6ba29 5582 return EXTENSIONS_E;
Vanger 0:b86d15c6ba29 5583 }
Vanger 0:b86d15c6ba29 5584 else
Vanger 0:b86d15c6ba29 5585 der->extensionsSz = 0;
Vanger 0:b86d15c6ba29 5586
Vanger 0:b86d15c6ba29 5587 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 5588 if (der->extensionsSz == 0 && cert->altNamesSz) {
Vanger 0:b86d15c6ba29 5589 der->extensionsSz = SetExtensions(der->extensions, cert->altNames,
Vanger 0:b86d15c6ba29 5590 cert->altNamesSz, TRUE);
Vanger 0:b86d15c6ba29 5591 if (der->extensionsSz == 0)
Vanger 0:b86d15c6ba29 5592 return EXTENSIONS_E;
Vanger 0:b86d15c6ba29 5593 }
Vanger 0:b86d15c6ba29 5594 #endif
Vanger 0:b86d15c6ba29 5595
Vanger 0:b86d15c6ba29 5596 der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
Vanger 0:b86d15c6ba29 5597 der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
Vanger 0:b86d15c6ba29 5598 der->extensionsSz;
Vanger 0:b86d15c6ba29 5599
Vanger 0:b86d15c6ba29 5600 return 0;
Vanger 0:b86d15c6ba29 5601 }
Vanger 0:b86d15c6ba29 5602
Vanger 0:b86d15c6ba29 5603
Vanger 0:b86d15c6ba29 5604 /* write DER encoded cert to buffer, size already checked */
Vanger 0:b86d15c6ba29 5605 static int WriteCertBody(DerCert* der, byte* buffer)
Vanger 0:b86d15c6ba29 5606 {
Vanger 0:b86d15c6ba29 5607 int idx;
Vanger 0:b86d15c6ba29 5608
Vanger 0:b86d15c6ba29 5609 /* signed part header */
Vanger 0:b86d15c6ba29 5610 idx = SetSequence(der->total, buffer);
Vanger 0:b86d15c6ba29 5611 /* version */
Vanger 0:b86d15c6ba29 5612 XMEMCPY(buffer + idx, der->version, der->versionSz);
Vanger 0:b86d15c6ba29 5613 idx += der->versionSz;
Vanger 0:b86d15c6ba29 5614 /* serial */
Vanger 0:b86d15c6ba29 5615 XMEMCPY(buffer + idx, der->serial, der->serialSz);
Vanger 0:b86d15c6ba29 5616 idx += der->serialSz;
Vanger 0:b86d15c6ba29 5617 /* sig algo */
Vanger 0:b86d15c6ba29 5618 XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
Vanger 0:b86d15c6ba29 5619 idx += der->sigAlgoSz;
Vanger 0:b86d15c6ba29 5620 /* issuer */
Vanger 0:b86d15c6ba29 5621 XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
Vanger 0:b86d15c6ba29 5622 idx += der->issuerSz;
Vanger 0:b86d15c6ba29 5623 /* validity */
Vanger 0:b86d15c6ba29 5624 XMEMCPY(buffer + idx, der->validity, der->validitySz);
Vanger 0:b86d15c6ba29 5625 idx += der->validitySz;
Vanger 0:b86d15c6ba29 5626 /* subject */
Vanger 0:b86d15c6ba29 5627 XMEMCPY(buffer + idx, der->subject, der->subjectSz);
Vanger 0:b86d15c6ba29 5628 idx += der->subjectSz;
Vanger 0:b86d15c6ba29 5629 /* public key */
Vanger 0:b86d15c6ba29 5630 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
Vanger 0:b86d15c6ba29 5631 idx += der->publicKeySz;
Vanger 0:b86d15c6ba29 5632 if (der->extensionsSz) {
Vanger 0:b86d15c6ba29 5633 /* extensions */
Vanger 0:b86d15c6ba29 5634 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
Vanger 0:b86d15c6ba29 5635 sizeof(der->extensions)));
Vanger 0:b86d15c6ba29 5636 idx += der->extensionsSz;
Vanger 0:b86d15c6ba29 5637 }
Vanger 0:b86d15c6ba29 5638
Vanger 0:b86d15c6ba29 5639 return idx;
Vanger 0:b86d15c6ba29 5640 }
Vanger 0:b86d15c6ba29 5641
Vanger 0:b86d15c6ba29 5642
Vanger 0:b86d15c6ba29 5643 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
Vanger 0:b86d15c6ba29 5644 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
Vanger 0:b86d15c6ba29 5645 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
Vanger 0:b86d15c6ba29 5646 int sigAlgoType)
Vanger 0:b86d15c6ba29 5647 {
Vanger 0:b86d15c6ba29 5648 int encSigSz, digestSz, typeH = 0, ret = 0;
Vanger 0:b86d15c6ba29 5649 byte digest[SHA256_DIGEST_SIZE]; /* max size */
Vanger 0:b86d15c6ba29 5650 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5651 byte* encSig;
Vanger 0:b86d15c6ba29 5652 #else
Vanger 0:b86d15c6ba29 5653 byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5654 #endif
Vanger 0:b86d15c6ba29 5655
Vanger 0:b86d15c6ba29 5656 (void)digest;
Vanger 0:b86d15c6ba29 5657 (void)digestSz;
Vanger 0:b86d15c6ba29 5658 (void)encSig;
Vanger 0:b86d15c6ba29 5659 (void)encSigSz;
Vanger 0:b86d15c6ba29 5660 (void)typeH;
Vanger 0:b86d15c6ba29 5661
Vanger 0:b86d15c6ba29 5662 (void)buffer;
Vanger 0:b86d15c6ba29 5663 (void)sz;
Vanger 0:b86d15c6ba29 5664 (void)sig;
Vanger 0:b86d15c6ba29 5665 (void)sigSz;
Vanger 0:b86d15c6ba29 5666 (void)rsaKey;
Vanger 0:b86d15c6ba29 5667 (void)eccKey;
Vanger 0:b86d15c6ba29 5668 (void)rng;
Vanger 0:b86d15c6ba29 5669
Vanger 0:b86d15c6ba29 5670 switch (sigAlgoType) {
Vanger 0:b86d15c6ba29 5671 #ifndef NO_MD5
Vanger 0:b86d15c6ba29 5672 case CTC_MD5wRSA:
Vanger 0:b86d15c6ba29 5673 if ((ret = Md5Hash(buffer, sz, digest)) == 0) {
Vanger 0:b86d15c6ba29 5674 typeH = MD5h;
Vanger 0:b86d15c6ba29 5675 digestSz = MD5_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 5676 }
Vanger 0:b86d15c6ba29 5677 break;
Vanger 0:b86d15c6ba29 5678 #endif
Vanger 0:b86d15c6ba29 5679 #ifndef NO_SHA
Vanger 0:b86d15c6ba29 5680 case CTC_SHAwRSA:
Vanger 0:b86d15c6ba29 5681 case CTC_SHAwECDSA:
Vanger 0:b86d15c6ba29 5682 if ((ret = ShaHash(buffer, sz, digest)) == 0) {
Vanger 0:b86d15c6ba29 5683 typeH = SHAh;
Vanger 0:b86d15c6ba29 5684 digestSz = SHA_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 5685 }
Vanger 0:b86d15c6ba29 5686 break;
Vanger 0:b86d15c6ba29 5687 #endif
Vanger 0:b86d15c6ba29 5688 #ifndef NO_SHA256
Vanger 0:b86d15c6ba29 5689 case CTC_SHA256wRSA:
Vanger 0:b86d15c6ba29 5690 case CTC_SHA256wECDSA:
Vanger 0:b86d15c6ba29 5691 if ((ret = Sha256Hash(buffer, sz, digest)) == 0) {
Vanger 0:b86d15c6ba29 5692 typeH = SHA256h;
Vanger 0:b86d15c6ba29 5693 digestSz = SHA256_DIGEST_SIZE;
Vanger 0:b86d15c6ba29 5694 }
Vanger 0:b86d15c6ba29 5695 break;
Vanger 0:b86d15c6ba29 5696 #endif
Vanger 0:b86d15c6ba29 5697 default:
Vanger 0:b86d15c6ba29 5698 CYASSL_MSG("MakeSignautre called with unsupported type");
Vanger 0:b86d15c6ba29 5699 ret = ALGO_ID_E;
Vanger 0:b86d15c6ba29 5700 }
Vanger 0:b86d15c6ba29 5701
Vanger 0:b86d15c6ba29 5702 if (ret != 0)
Vanger 0:b86d15c6ba29 5703 return ret;
Vanger 0:b86d15c6ba29 5704
Vanger 0:b86d15c6ba29 5705 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5706 encSig = (byte*)XMALLOC(MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
Vanger 0:b86d15c6ba29 5707 NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5708 if (encSig == NULL)
Vanger 0:b86d15c6ba29 5709 return MEMORY_E;
Vanger 0:b86d15c6ba29 5710 #endif
Vanger 0:b86d15c6ba29 5711
Vanger 0:b86d15c6ba29 5712 ret = ALGO_ID_E;
Vanger 0:b86d15c6ba29 5713
Vanger 0:b86d15c6ba29 5714 #ifndef NO_RSA
Vanger 0:b86d15c6ba29 5715 if (rsaKey) {
Vanger 0:b86d15c6ba29 5716 /* signature */
Vanger 0:b86d15c6ba29 5717 encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
Vanger 0:b86d15c6ba29 5718 ret = RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng);
Vanger 0:b86d15c6ba29 5719 }
Vanger 0:b86d15c6ba29 5720 #endif
Vanger 0:b86d15c6ba29 5721
Vanger 0:b86d15c6ba29 5722 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 5723 if (!rsaKey && eccKey) {
Vanger 0:b86d15c6ba29 5724 word32 outSz = sigSz;
Vanger 0:b86d15c6ba29 5725 ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey);
Vanger 0:b86d15c6ba29 5726
Vanger 0:b86d15c6ba29 5727 if (ret == 0)
Vanger 0:b86d15c6ba29 5728 ret = outSz;
Vanger 0:b86d15c6ba29 5729 }
Vanger 0:b86d15c6ba29 5730 #endif
Vanger 0:b86d15c6ba29 5731
Vanger 0:b86d15c6ba29 5732 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5733 XFREE(encSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5734 #endif
Vanger 0:b86d15c6ba29 5735
Vanger 0:b86d15c6ba29 5736 return ret;
Vanger 0:b86d15c6ba29 5737 }
Vanger 0:b86d15c6ba29 5738
Vanger 0:b86d15c6ba29 5739
Vanger 0:b86d15c6ba29 5740 /* add signature to end of buffer, size of buffer assumed checked, return
Vanger 0:b86d15c6ba29 5741 new length */
Vanger 0:b86d15c6ba29 5742 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
Vanger 0:b86d15c6ba29 5743 int sigAlgoType)
Vanger 0:b86d15c6ba29 5744 {
Vanger 0:b86d15c6ba29 5745 byte seq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5746 int idx = bodySz, seqSz;
Vanger 0:b86d15c6ba29 5747
Vanger 0:b86d15c6ba29 5748 /* algo */
Vanger 0:b86d15c6ba29 5749 idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0);
Vanger 0:b86d15c6ba29 5750 /* bit string */
Vanger 0:b86d15c6ba29 5751 buffer[idx++] = ASN_BIT_STRING;
Vanger 0:b86d15c6ba29 5752 /* length */
Vanger 0:b86d15c6ba29 5753 idx += SetLength(sigSz + 1, buffer + idx);
Vanger 0:b86d15c6ba29 5754 buffer[idx++] = 0; /* trailing 0 */
Vanger 0:b86d15c6ba29 5755 /* signature */
Vanger 0:b86d15c6ba29 5756 XMEMCPY(buffer + idx, sig, sigSz);
Vanger 0:b86d15c6ba29 5757 idx += sigSz;
Vanger 0:b86d15c6ba29 5758
Vanger 0:b86d15c6ba29 5759 /* make room for overall header */
Vanger 0:b86d15c6ba29 5760 seqSz = SetSequence(idx, seq);
Vanger 0:b86d15c6ba29 5761 XMEMMOVE(buffer + seqSz, buffer, idx);
Vanger 0:b86d15c6ba29 5762 XMEMCPY(buffer, seq, seqSz);
Vanger 0:b86d15c6ba29 5763
Vanger 0:b86d15c6ba29 5764 return idx + seqSz;
Vanger 0:b86d15c6ba29 5765 }
Vanger 0:b86d15c6ba29 5766
Vanger 0:b86d15c6ba29 5767
Vanger 0:b86d15c6ba29 5768 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
Vanger 0:b86d15c6ba29 5769 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
Vanger 0:b86d15c6ba29 5770 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
Vanger 0:b86d15c6ba29 5771 const byte* ntruKey, word16 ntruSz)
Vanger 0:b86d15c6ba29 5772 {
Vanger 0:b86d15c6ba29 5773 int ret;
Vanger 0:b86d15c6ba29 5774 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5775 DerCert* der;
Vanger 0:b86d15c6ba29 5776 #else
Vanger 0:b86d15c6ba29 5777 DerCert der[1];
Vanger 0:b86d15c6ba29 5778 #endif
Vanger 0:b86d15c6ba29 5779
Vanger 0:b86d15c6ba29 5780 cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY);
Vanger 0:b86d15c6ba29 5781
Vanger 0:b86d15c6ba29 5782 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5783 der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5784 if (der == NULL)
Vanger 0:b86d15c6ba29 5785 return MEMORY_E;
Vanger 0:b86d15c6ba29 5786 #endif
Vanger 0:b86d15c6ba29 5787
Vanger 0:b86d15c6ba29 5788 ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz);
Vanger 0:b86d15c6ba29 5789
Vanger 0:b86d15c6ba29 5790 if (ret == 0) {
Vanger 0:b86d15c6ba29 5791 if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
Vanger 0:b86d15c6ba29 5792 ret = BUFFER_E;
Vanger 0:b86d15c6ba29 5793 else
Vanger 0:b86d15c6ba29 5794 ret = cert->bodySz = WriteCertBody(der, derBuffer);
Vanger 0:b86d15c6ba29 5795 }
Vanger 0:b86d15c6ba29 5796
Vanger 0:b86d15c6ba29 5797 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5798 XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 5799 #endif
Vanger 0:b86d15c6ba29 5800
Vanger 0:b86d15c6ba29 5801 return ret;
Vanger 0:b86d15c6ba29 5802 }
Vanger 0:b86d15c6ba29 5803
Vanger 0:b86d15c6ba29 5804
Vanger 0:b86d15c6ba29 5805 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
Vanger 0:b86d15c6ba29 5806 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
Vanger 0:b86d15c6ba29 5807 ecc_key* eccKey, RNG* rng)
Vanger 0:b86d15c6ba29 5808 {
Vanger 0:b86d15c6ba29 5809 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0);
Vanger 0:b86d15c6ba29 5810 }
Vanger 0:b86d15c6ba29 5811
Vanger 0:b86d15c6ba29 5812
Vanger 0:b86d15c6ba29 5813 #ifdef HAVE_NTRU
Vanger 0:b86d15c6ba29 5814
Vanger 0:b86d15c6ba29 5815 int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
Vanger 0:b86d15c6ba29 5816 const byte* ntruKey, word16 keySz, RNG* rng)
Vanger 0:b86d15c6ba29 5817 {
Vanger 0:b86d15c6ba29 5818 return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
Vanger 0:b86d15c6ba29 5819 }
Vanger 0:b86d15c6ba29 5820
Vanger 0:b86d15c6ba29 5821 #endif /* HAVE_NTRU */
Vanger 0:b86d15c6ba29 5822
Vanger 0:b86d15c6ba29 5823
Vanger 0:b86d15c6ba29 5824 #ifdef CYASSL_CERT_REQ
Vanger 0:b86d15c6ba29 5825
Vanger 0:b86d15c6ba29 5826 static int SetReqAttrib(byte* output, char* pw, int extSz)
Vanger 0:b86d15c6ba29 5827 {
Vanger 0:b86d15c6ba29 5828 static const byte cpOid[] =
Vanger 0:b86d15c6ba29 5829 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
Vanger 0:b86d15c6ba29 5830 0x09, 0x07 };
Vanger 0:b86d15c6ba29 5831 static const byte erOid[] =
Vanger 0:b86d15c6ba29 5832 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
Vanger 0:b86d15c6ba29 5833 0x09, 0x0e };
Vanger 0:b86d15c6ba29 5834
Vanger 0:b86d15c6ba29 5835 int sz = 0; /* overall size */
Vanger 0:b86d15c6ba29 5836 int cpSz = 0; /* Challenge Password section size */
Vanger 0:b86d15c6ba29 5837 int cpSeqSz = 0;
Vanger 0:b86d15c6ba29 5838 int cpSetSz = 0;
Vanger 0:b86d15c6ba29 5839 int cpStrSz = 0;
Vanger 0:b86d15c6ba29 5840 int pwSz = 0;
Vanger 0:b86d15c6ba29 5841 int erSz = 0; /* Extension Request section size */
Vanger 0:b86d15c6ba29 5842 int erSeqSz = 0;
Vanger 0:b86d15c6ba29 5843 int erSetSz = 0;
Vanger 0:b86d15c6ba29 5844 byte cpSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5845 byte cpSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 5846 byte cpStr[MAX_PRSTR_SZ];
Vanger 0:b86d15c6ba29 5847 byte erSeq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 5848 byte erSet[MAX_SET_SZ];
Vanger 0:b86d15c6ba29 5849
Vanger 0:b86d15c6ba29 5850 output[0] = 0xa0;
Vanger 0:b86d15c6ba29 5851 sz++;
Vanger 0:b86d15c6ba29 5852
Vanger 0:b86d15c6ba29 5853 if (pw && pw[0]) {
Vanger 0:b86d15c6ba29 5854 pwSz = (int)XSTRLEN(pw);
Vanger 0:b86d15c6ba29 5855 cpStrSz = SetUTF8String(pwSz, cpStr);
Vanger 0:b86d15c6ba29 5856 cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
Vanger 0:b86d15c6ba29 5857 cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
Vanger 0:b86d15c6ba29 5858 cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
Vanger 0:b86d15c6ba29 5859 }
Vanger 0:b86d15c6ba29 5860
Vanger 0:b86d15c6ba29 5861 if (extSz) {
Vanger 0:b86d15c6ba29 5862 erSetSz = SetSet(extSz, erSet);
Vanger 0:b86d15c6ba29 5863 erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
Vanger 0:b86d15c6ba29 5864 erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
Vanger 0:b86d15c6ba29 5865 }
Vanger 0:b86d15c6ba29 5866
Vanger 0:b86d15c6ba29 5867 /* Put the pieces together. */
Vanger 0:b86d15c6ba29 5868 sz += SetLength(cpSz + erSz, &output[sz]);
Vanger 0:b86d15c6ba29 5869
Vanger 0:b86d15c6ba29 5870 if (cpSz) {
Vanger 0:b86d15c6ba29 5871 XMEMCPY(&output[sz], cpSeq, cpSeqSz);
Vanger 0:b86d15c6ba29 5872 sz += cpSeqSz;
Vanger 0:b86d15c6ba29 5873 XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
Vanger 0:b86d15c6ba29 5874 sz += sizeof(cpOid);
Vanger 0:b86d15c6ba29 5875 XMEMCPY(&output[sz], cpSet, cpSetSz);
Vanger 0:b86d15c6ba29 5876 sz += cpSetSz;
Vanger 0:b86d15c6ba29 5877 XMEMCPY(&output[sz], cpStr, cpStrSz);
Vanger 0:b86d15c6ba29 5878 sz += cpStrSz;
Vanger 0:b86d15c6ba29 5879 XMEMCPY(&output[sz], pw, pwSz);
Vanger 0:b86d15c6ba29 5880 sz += pwSz;
Vanger 0:b86d15c6ba29 5881 }
Vanger 0:b86d15c6ba29 5882
Vanger 0:b86d15c6ba29 5883 if (erSz) {
Vanger 0:b86d15c6ba29 5884 XMEMCPY(&output[sz], erSeq, erSeqSz);
Vanger 0:b86d15c6ba29 5885 sz += erSeqSz;
Vanger 0:b86d15c6ba29 5886 XMEMCPY(&output[sz], erOid, sizeof(erOid));
Vanger 0:b86d15c6ba29 5887 sz += sizeof(erOid);
Vanger 0:b86d15c6ba29 5888 XMEMCPY(&output[sz], erSet, erSetSz);
Vanger 0:b86d15c6ba29 5889 sz += erSetSz;
Vanger 0:b86d15c6ba29 5890 /* The actual extension data will be tacked onto the output later. */
Vanger 0:b86d15c6ba29 5891 }
Vanger 0:b86d15c6ba29 5892
Vanger 0:b86d15c6ba29 5893 return sz;
Vanger 0:b86d15c6ba29 5894 }
Vanger 0:b86d15c6ba29 5895
Vanger 0:b86d15c6ba29 5896
Vanger 0:b86d15c6ba29 5897 /* encode info from cert into DER encoded format */
Vanger 0:b86d15c6ba29 5898 static int EncodeCertReq(Cert* cert, DerCert* der,
Vanger 0:b86d15c6ba29 5899 RsaKey* rsaKey, ecc_key* eccKey)
Vanger 0:b86d15c6ba29 5900 {
Vanger 0:b86d15c6ba29 5901 (void)eccKey;
Vanger 0:b86d15c6ba29 5902
Vanger 0:b86d15c6ba29 5903 /* init */
Vanger 0:b86d15c6ba29 5904 XMEMSET(der, 0, sizeof(DerCert));
Vanger 0:b86d15c6ba29 5905
Vanger 0:b86d15c6ba29 5906 /* version */
Vanger 0:b86d15c6ba29 5907 der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
Vanger 0:b86d15c6ba29 5908
Vanger 0:b86d15c6ba29 5909 /* subject name */
Vanger 0:b86d15c6ba29 5910 der->subjectSz = SetName(der->subject, &cert->subject);
Vanger 0:b86d15c6ba29 5911 if (der->subjectSz == 0)
Vanger 0:b86d15c6ba29 5912 return SUBJECT_E;
Vanger 0:b86d15c6ba29 5913
Vanger 0:b86d15c6ba29 5914 /* public key */
Vanger 0:b86d15c6ba29 5915 if (cert->keyType == RSA_KEY) {
Vanger 0:b86d15c6ba29 5916 if (rsaKey == NULL)
Vanger 0:b86d15c6ba29 5917 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5918 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
Vanger 0:b86d15c6ba29 5919 if (der->publicKeySz <= 0)
Vanger 0:b86d15c6ba29 5920 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5921 }
Vanger 0:b86d15c6ba29 5922
Vanger 0:b86d15c6ba29 5923 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 5924 if (cert->keyType == ECC_KEY) {
Vanger 0:b86d15c6ba29 5925 if (eccKey == NULL)
Vanger 0:b86d15c6ba29 5926 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5927 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey);
Vanger 0:b86d15c6ba29 5928 if (der->publicKeySz <= 0)
Vanger 0:b86d15c6ba29 5929 return PUBLIC_KEY_E;
Vanger 0:b86d15c6ba29 5930 }
Vanger 0:b86d15c6ba29 5931 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 5932
Vanger 0:b86d15c6ba29 5933 /* CA */
Vanger 0:b86d15c6ba29 5934 if (cert->isCA) {
Vanger 0:b86d15c6ba29 5935 der->caSz = SetCa(der->ca);
Vanger 0:b86d15c6ba29 5936 if (der->caSz == 0)
Vanger 0:b86d15c6ba29 5937 return CA_TRUE_E;
Vanger 0:b86d15c6ba29 5938 }
Vanger 0:b86d15c6ba29 5939 else
Vanger 0:b86d15c6ba29 5940 der->caSz = 0;
Vanger 0:b86d15c6ba29 5941
Vanger 0:b86d15c6ba29 5942 /* extensions, just CA now */
Vanger 0:b86d15c6ba29 5943 if (cert->isCA) {
Vanger 0:b86d15c6ba29 5944 der->extensionsSz = SetExtensions(der->extensions,
Vanger 0:b86d15c6ba29 5945 der->ca, der->caSz, FALSE);
Vanger 0:b86d15c6ba29 5946 if (der->extensionsSz == 0)
Vanger 0:b86d15c6ba29 5947 return EXTENSIONS_E;
Vanger 0:b86d15c6ba29 5948 }
Vanger 0:b86d15c6ba29 5949 else
Vanger 0:b86d15c6ba29 5950 der->extensionsSz = 0;
Vanger 0:b86d15c6ba29 5951
Vanger 0:b86d15c6ba29 5952 der->attribSz = SetReqAttrib(der->attrib,
Vanger 0:b86d15c6ba29 5953 cert->challengePw, der->extensionsSz);
Vanger 0:b86d15c6ba29 5954 if (der->attribSz == 0)
Vanger 0:b86d15c6ba29 5955 return REQ_ATTRIBUTE_E;
Vanger 0:b86d15c6ba29 5956
Vanger 0:b86d15c6ba29 5957 der->total = der->versionSz + der->subjectSz + der->publicKeySz +
Vanger 0:b86d15c6ba29 5958 der->extensionsSz + der->attribSz;
Vanger 0:b86d15c6ba29 5959
Vanger 0:b86d15c6ba29 5960 return 0;
Vanger 0:b86d15c6ba29 5961 }
Vanger 0:b86d15c6ba29 5962
Vanger 0:b86d15c6ba29 5963
Vanger 0:b86d15c6ba29 5964 /* write DER encoded cert req to buffer, size already checked */
Vanger 0:b86d15c6ba29 5965 static int WriteCertReqBody(DerCert* der, byte* buffer)
Vanger 0:b86d15c6ba29 5966 {
Vanger 0:b86d15c6ba29 5967 int idx;
Vanger 0:b86d15c6ba29 5968
Vanger 0:b86d15c6ba29 5969 /* signed part header */
Vanger 0:b86d15c6ba29 5970 idx = SetSequence(der->total, buffer);
Vanger 0:b86d15c6ba29 5971 /* version */
Vanger 0:b86d15c6ba29 5972 XMEMCPY(buffer + idx, der->version, der->versionSz);
Vanger 0:b86d15c6ba29 5973 idx += der->versionSz;
Vanger 0:b86d15c6ba29 5974 /* subject */
Vanger 0:b86d15c6ba29 5975 XMEMCPY(buffer + idx, der->subject, der->subjectSz);
Vanger 0:b86d15c6ba29 5976 idx += der->subjectSz;
Vanger 0:b86d15c6ba29 5977 /* public key */
Vanger 0:b86d15c6ba29 5978 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
Vanger 0:b86d15c6ba29 5979 idx += der->publicKeySz;
Vanger 0:b86d15c6ba29 5980 /* attributes */
Vanger 0:b86d15c6ba29 5981 XMEMCPY(buffer + idx, der->attrib, der->attribSz);
Vanger 0:b86d15c6ba29 5982 idx += der->attribSz;
Vanger 0:b86d15c6ba29 5983 /* extensions */
Vanger 0:b86d15c6ba29 5984 if (der->extensionsSz) {
Vanger 0:b86d15c6ba29 5985 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
Vanger 0:b86d15c6ba29 5986 sizeof(der->extensions)));
Vanger 0:b86d15c6ba29 5987 idx += der->extensionsSz;
Vanger 0:b86d15c6ba29 5988 }
Vanger 0:b86d15c6ba29 5989
Vanger 0:b86d15c6ba29 5990 return idx;
Vanger 0:b86d15c6ba29 5991 }
Vanger 0:b86d15c6ba29 5992
Vanger 0:b86d15c6ba29 5993
Vanger 0:b86d15c6ba29 5994 int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
Vanger 0:b86d15c6ba29 5995 RsaKey* rsaKey, ecc_key* eccKey)
Vanger 0:b86d15c6ba29 5996 {
Vanger 0:b86d15c6ba29 5997 int ret;
Vanger 0:b86d15c6ba29 5998 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 5999 DerCert* der;
Vanger 0:b86d15c6ba29 6000 #else
Vanger 0:b86d15c6ba29 6001 DerCert der[1];
Vanger 0:b86d15c6ba29 6002 #endif
Vanger 0:b86d15c6ba29 6003
Vanger 0:b86d15c6ba29 6004 cert->keyType = eccKey ? ECC_KEY : RSA_KEY;
Vanger 0:b86d15c6ba29 6005
Vanger 0:b86d15c6ba29 6006 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6007 der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6008 if (der == NULL)
Vanger 0:b86d15c6ba29 6009 return MEMORY_E;
Vanger 0:b86d15c6ba29 6010 #endif
Vanger 0:b86d15c6ba29 6011
Vanger 0:b86d15c6ba29 6012 ret = EncodeCertReq(cert, der, rsaKey, eccKey);
Vanger 0:b86d15c6ba29 6013
Vanger 0:b86d15c6ba29 6014 if (ret == 0) {
Vanger 0:b86d15c6ba29 6015 if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
Vanger 0:b86d15c6ba29 6016 ret = BUFFER_E;
Vanger 0:b86d15c6ba29 6017 else
Vanger 0:b86d15c6ba29 6018 ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
Vanger 0:b86d15c6ba29 6019 }
Vanger 0:b86d15c6ba29 6020
Vanger 0:b86d15c6ba29 6021 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6022 XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6023 #endif
Vanger 0:b86d15c6ba29 6024
Vanger 0:b86d15c6ba29 6025 return ret;
Vanger 0:b86d15c6ba29 6026 }
Vanger 0:b86d15c6ba29 6027
Vanger 0:b86d15c6ba29 6028 #endif /* CYASSL_CERT_REQ */
Vanger 0:b86d15c6ba29 6029
Vanger 0:b86d15c6ba29 6030
Vanger 0:b86d15c6ba29 6031 int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
Vanger 0:b86d15c6ba29 6032 RsaKey* rsaKey, ecc_key* eccKey, RNG* rng)
Vanger 0:b86d15c6ba29 6033 {
Vanger 0:b86d15c6ba29 6034 int sigSz;
Vanger 0:b86d15c6ba29 6035 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6036 byte* sig;
Vanger 0:b86d15c6ba29 6037 #else
Vanger 0:b86d15c6ba29 6038 byte sig[MAX_ENCODED_SIG_SZ];
Vanger 0:b86d15c6ba29 6039 #endif
Vanger 0:b86d15c6ba29 6040
Vanger 0:b86d15c6ba29 6041 if (requestSz < 0)
Vanger 0:b86d15c6ba29 6042 return requestSz;
Vanger 0:b86d15c6ba29 6043
Vanger 0:b86d15c6ba29 6044 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6045 sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6046 if (sig == NULL)
Vanger 0:b86d15c6ba29 6047 return MEMORY_E;
Vanger 0:b86d15c6ba29 6048 #endif
Vanger 0:b86d15c6ba29 6049
Vanger 0:b86d15c6ba29 6050 sigSz = MakeSignature(buffer, requestSz, sig, MAX_ENCODED_SIG_SZ, rsaKey,
Vanger 0:b86d15c6ba29 6051 eccKey, rng, sType);
Vanger 0:b86d15c6ba29 6052
Vanger 0:b86d15c6ba29 6053 if (sigSz >= 0) {
Vanger 0:b86d15c6ba29 6054 if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
Vanger 0:b86d15c6ba29 6055 sigSz = BUFFER_E;
Vanger 0:b86d15c6ba29 6056 else
Vanger 0:b86d15c6ba29 6057 sigSz = AddSignature(buffer, requestSz, sig, sigSz, sType);
Vanger 0:b86d15c6ba29 6058 }
Vanger 0:b86d15c6ba29 6059
Vanger 0:b86d15c6ba29 6060 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6061 XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6062 #endif
Vanger 0:b86d15c6ba29 6063
Vanger 0:b86d15c6ba29 6064 return sigSz;
Vanger 0:b86d15c6ba29 6065 }
Vanger 0:b86d15c6ba29 6066
Vanger 0:b86d15c6ba29 6067
Vanger 0:b86d15c6ba29 6068 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
Vanger 0:b86d15c6ba29 6069 {
Vanger 0:b86d15c6ba29 6070 int ret = MakeCert(cert, buffer, buffSz, key, NULL, rng);
Vanger 0:b86d15c6ba29 6071
Vanger 0:b86d15c6ba29 6072 if (ret < 0)
Vanger 0:b86d15c6ba29 6073 return ret;
Vanger 0:b86d15c6ba29 6074
Vanger 0:b86d15c6ba29 6075 return SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng);
Vanger 0:b86d15c6ba29 6076 }
Vanger 0:b86d15c6ba29 6077
Vanger 0:b86d15c6ba29 6078
Vanger 0:b86d15c6ba29 6079 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 6080
Vanger 0:b86d15c6ba29 6081 /* Set Alt Names from der cert, return 0 on success */
Vanger 0:b86d15c6ba29 6082 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6083 {
Vanger 0:b86d15c6ba29 6084 int ret;
Vanger 0:b86d15c6ba29 6085 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6086 DecodedCert* decoded;
Vanger 0:b86d15c6ba29 6087 #else
Vanger 0:b86d15c6ba29 6088 DecodedCert decoded[1];
Vanger 0:b86d15c6ba29 6089 #endif
Vanger 0:b86d15c6ba29 6090
Vanger 0:b86d15c6ba29 6091 if (derSz < 0)
Vanger 0:b86d15c6ba29 6092 return derSz;
Vanger 0:b86d15c6ba29 6093
Vanger 0:b86d15c6ba29 6094 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6095 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 6096 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6097 if (decoded == NULL)
Vanger 0:b86d15c6ba29 6098 return MEMORY_E;
Vanger 0:b86d15c6ba29 6099 #endif
Vanger 0:b86d15c6ba29 6100
Vanger 0:b86d15c6ba29 6101 InitDecodedCert(decoded, (byte*)der, derSz, 0);
Vanger 0:b86d15c6ba29 6102 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 6103
Vanger 0:b86d15c6ba29 6104 if (ret < 0) {
Vanger 0:b86d15c6ba29 6105 CYASSL_MSG("ParseCertRelative error");
Vanger 0:b86d15c6ba29 6106 }
Vanger 0:b86d15c6ba29 6107 else if (decoded->extensions) {
Vanger 0:b86d15c6ba29 6108 byte b;
Vanger 0:b86d15c6ba29 6109 int length;
Vanger 0:b86d15c6ba29 6110 word32 maxExtensionsIdx;
Vanger 0:b86d15c6ba29 6111
Vanger 0:b86d15c6ba29 6112 decoded->srcIdx = decoded->extensionsIdx;
Vanger 0:b86d15c6ba29 6113 b = decoded->source[decoded->srcIdx++];
Vanger 0:b86d15c6ba29 6114
Vanger 0:b86d15c6ba29 6115 if (b != ASN_EXTENSIONS) {
Vanger 0:b86d15c6ba29 6116 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6117 }
Vanger 0:b86d15c6ba29 6118 else if (GetLength(decoded->source, &decoded->srcIdx, &length,
Vanger 0:b86d15c6ba29 6119 decoded->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 6120 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6121 }
Vanger 0:b86d15c6ba29 6122 else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
Vanger 0:b86d15c6ba29 6123 decoded->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 6124 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6125 }
Vanger 0:b86d15c6ba29 6126 else {
Vanger 0:b86d15c6ba29 6127 maxExtensionsIdx = decoded->srcIdx + length;
Vanger 0:b86d15c6ba29 6128
Vanger 0:b86d15c6ba29 6129 while (decoded->srcIdx < maxExtensionsIdx) {
Vanger 0:b86d15c6ba29 6130 word32 oid;
Vanger 0:b86d15c6ba29 6131 word32 startIdx = decoded->srcIdx;
Vanger 0:b86d15c6ba29 6132 word32 tmpIdx;
Vanger 0:b86d15c6ba29 6133
Vanger 0:b86d15c6ba29 6134 if (GetSequence(decoded->source, &decoded->srcIdx, &length,
Vanger 0:b86d15c6ba29 6135 decoded->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 6136 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6137 break;
Vanger 0:b86d15c6ba29 6138 }
Vanger 0:b86d15c6ba29 6139
Vanger 0:b86d15c6ba29 6140 tmpIdx = decoded->srcIdx;
Vanger 0:b86d15c6ba29 6141 decoded->srcIdx = startIdx;
Vanger 0:b86d15c6ba29 6142
Vanger 0:b86d15c6ba29 6143 if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
Vanger 0:b86d15c6ba29 6144 decoded->maxIdx) < 0) {
Vanger 0:b86d15c6ba29 6145 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6146 break;
Vanger 0:b86d15c6ba29 6147 }
Vanger 0:b86d15c6ba29 6148
Vanger 0:b86d15c6ba29 6149 if (oid == ALT_NAMES_OID) {
Vanger 0:b86d15c6ba29 6150 cert->altNamesSz = length + (tmpIdx - startIdx);
Vanger 0:b86d15c6ba29 6151
Vanger 0:b86d15c6ba29 6152 if (cert->altNamesSz < (int)sizeof(cert->altNames))
Vanger 0:b86d15c6ba29 6153 XMEMCPY(cert->altNames, &decoded->source[startIdx],
Vanger 0:b86d15c6ba29 6154 cert->altNamesSz);
Vanger 0:b86d15c6ba29 6155 else {
Vanger 0:b86d15c6ba29 6156 cert->altNamesSz = 0;
Vanger 0:b86d15c6ba29 6157 CYASSL_MSG("AltNames extensions too big");
Vanger 0:b86d15c6ba29 6158 ret = ALT_NAME_E;
Vanger 0:b86d15c6ba29 6159 break;
Vanger 0:b86d15c6ba29 6160 }
Vanger 0:b86d15c6ba29 6161 }
Vanger 0:b86d15c6ba29 6162 decoded->srcIdx = tmpIdx + length;
Vanger 0:b86d15c6ba29 6163 }
Vanger 0:b86d15c6ba29 6164 }
Vanger 0:b86d15c6ba29 6165 }
Vanger 0:b86d15c6ba29 6166
Vanger 0:b86d15c6ba29 6167 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 6168 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6169 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6170 #endif
Vanger 0:b86d15c6ba29 6171
Vanger 0:b86d15c6ba29 6172 return ret < 0 ? ret : 0;
Vanger 0:b86d15c6ba29 6173 }
Vanger 0:b86d15c6ba29 6174
Vanger 0:b86d15c6ba29 6175
Vanger 0:b86d15c6ba29 6176 /* Set Dates from der cert, return 0 on success */
Vanger 0:b86d15c6ba29 6177 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6178 {
Vanger 0:b86d15c6ba29 6179 int ret;
Vanger 0:b86d15c6ba29 6180 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6181 DecodedCert* decoded;
Vanger 0:b86d15c6ba29 6182 #else
Vanger 0:b86d15c6ba29 6183 DecodedCert decoded[1];
Vanger 0:b86d15c6ba29 6184 #endif
Vanger 0:b86d15c6ba29 6185
Vanger 0:b86d15c6ba29 6186 CYASSL_ENTER("SetDatesFromCert");
Vanger 0:b86d15c6ba29 6187 if (derSz < 0)
Vanger 0:b86d15c6ba29 6188 return derSz;
Vanger 0:b86d15c6ba29 6189
Vanger 0:b86d15c6ba29 6190 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6191 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 6192 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6193 if (decoded == NULL)
Vanger 0:b86d15c6ba29 6194 return MEMORY_E;
Vanger 0:b86d15c6ba29 6195 #endif
Vanger 0:b86d15c6ba29 6196
Vanger 0:b86d15c6ba29 6197 InitDecodedCert(decoded, (byte*)der, derSz, 0);
Vanger 0:b86d15c6ba29 6198 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 6199
Vanger 0:b86d15c6ba29 6200 if (ret < 0) {
Vanger 0:b86d15c6ba29 6201 CYASSL_MSG("ParseCertRelative error");
Vanger 0:b86d15c6ba29 6202 }
Vanger 0:b86d15c6ba29 6203 else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
Vanger 0:b86d15c6ba29 6204 CYASSL_MSG("Couldn't extract dates");
Vanger 0:b86d15c6ba29 6205 ret = -1;
Vanger 0:b86d15c6ba29 6206 }
Vanger 0:b86d15c6ba29 6207 else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
Vanger 0:b86d15c6ba29 6208 decoded->afterDateLen > MAX_DATE_SIZE) {
Vanger 0:b86d15c6ba29 6209 CYASSL_MSG("Bad date size");
Vanger 0:b86d15c6ba29 6210 ret = -1;
Vanger 0:b86d15c6ba29 6211 }
Vanger 0:b86d15c6ba29 6212 else {
Vanger 0:b86d15c6ba29 6213 XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
Vanger 0:b86d15c6ba29 6214 XMEMCPY(cert->afterDate, decoded->afterDate, decoded->afterDateLen);
Vanger 0:b86d15c6ba29 6215
Vanger 0:b86d15c6ba29 6216 cert->beforeDateSz = decoded->beforeDateLen;
Vanger 0:b86d15c6ba29 6217 cert->afterDateSz = decoded->afterDateLen;
Vanger 0:b86d15c6ba29 6218 }
Vanger 0:b86d15c6ba29 6219
Vanger 0:b86d15c6ba29 6220 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 6221
Vanger 0:b86d15c6ba29 6222 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6223 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6224 #endif
Vanger 0:b86d15c6ba29 6225
Vanger 0:b86d15c6ba29 6226 return ret < 0 ? ret : 0;
Vanger 0:b86d15c6ba29 6227 }
Vanger 0:b86d15c6ba29 6228
Vanger 0:b86d15c6ba29 6229
Vanger 0:b86d15c6ba29 6230 #endif /* CYASSL_ALT_NAMES && !NO_RSA */
Vanger 0:b86d15c6ba29 6231
Vanger 0:b86d15c6ba29 6232
Vanger 0:b86d15c6ba29 6233 /* Set cn name from der buffer, return 0 on success */
Vanger 0:b86d15c6ba29 6234 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6235 {
Vanger 0:b86d15c6ba29 6236 int ret, sz;
Vanger 0:b86d15c6ba29 6237 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6238 DecodedCert* decoded;
Vanger 0:b86d15c6ba29 6239 #else
Vanger 0:b86d15c6ba29 6240 DecodedCert decoded[1];
Vanger 0:b86d15c6ba29 6241 #endif
Vanger 0:b86d15c6ba29 6242
Vanger 0:b86d15c6ba29 6243 if (derSz < 0)
Vanger 0:b86d15c6ba29 6244 return derSz;
Vanger 0:b86d15c6ba29 6245
Vanger 0:b86d15c6ba29 6246 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6247 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
Vanger 0:b86d15c6ba29 6248 DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6249 if (decoded == NULL)
Vanger 0:b86d15c6ba29 6250 return MEMORY_E;
Vanger 0:b86d15c6ba29 6251 #endif
Vanger 0:b86d15c6ba29 6252
Vanger 0:b86d15c6ba29 6253 InitDecodedCert(decoded, (byte*)der, derSz, 0);
Vanger 0:b86d15c6ba29 6254 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 6255
Vanger 0:b86d15c6ba29 6256 if (ret < 0) {
Vanger 0:b86d15c6ba29 6257 CYASSL_MSG("ParseCertRelative error");
Vanger 0:b86d15c6ba29 6258 }
Vanger 0:b86d15c6ba29 6259 else {
Vanger 0:b86d15c6ba29 6260 if (decoded->subjectCN) {
Vanger 0:b86d15c6ba29 6261 sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
Vanger 0:b86d15c6ba29 6262 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6263 strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6264 cn->commonName[sz] = 0;
Vanger 0:b86d15c6ba29 6265 cn->commonNameEnc = decoded->subjectCNEnc;
Vanger 0:b86d15c6ba29 6266 }
Vanger 0:b86d15c6ba29 6267 if (decoded->subjectC) {
Vanger 0:b86d15c6ba29 6268 sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
Vanger 0:b86d15c6ba29 6269 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6270 strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6271 cn->country[sz] = 0;
Vanger 0:b86d15c6ba29 6272 cn->countryEnc = decoded->subjectCEnc;
Vanger 0:b86d15c6ba29 6273 }
Vanger 0:b86d15c6ba29 6274 if (decoded->subjectST) {
Vanger 0:b86d15c6ba29 6275 sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
Vanger 0:b86d15c6ba29 6276 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6277 strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6278 cn->state[sz] = 0;
Vanger 0:b86d15c6ba29 6279 cn->stateEnc = decoded->subjectSTEnc;
Vanger 0:b86d15c6ba29 6280 }
Vanger 0:b86d15c6ba29 6281 if (decoded->subjectL) {
Vanger 0:b86d15c6ba29 6282 sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
Vanger 0:b86d15c6ba29 6283 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6284 strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6285 cn->locality[sz] = 0;
Vanger 0:b86d15c6ba29 6286 cn->localityEnc = decoded->subjectLEnc;
Vanger 0:b86d15c6ba29 6287 }
Vanger 0:b86d15c6ba29 6288 if (decoded->subjectO) {
Vanger 0:b86d15c6ba29 6289 sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
Vanger 0:b86d15c6ba29 6290 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6291 strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6292 cn->org[sz] = 0;
Vanger 0:b86d15c6ba29 6293 cn->orgEnc = decoded->subjectOEnc;
Vanger 0:b86d15c6ba29 6294 }
Vanger 0:b86d15c6ba29 6295 if (decoded->subjectOU) {
Vanger 0:b86d15c6ba29 6296 sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
Vanger 0:b86d15c6ba29 6297 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6298 strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6299 cn->unit[sz] = 0;
Vanger 0:b86d15c6ba29 6300 cn->unitEnc = decoded->subjectOUEnc;
Vanger 0:b86d15c6ba29 6301 }
Vanger 0:b86d15c6ba29 6302 if (decoded->subjectSN) {
Vanger 0:b86d15c6ba29 6303 sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
Vanger 0:b86d15c6ba29 6304 : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6305 strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6306 cn->sur[sz] = 0;
Vanger 0:b86d15c6ba29 6307 cn->surEnc = decoded->subjectSNEnc;
Vanger 0:b86d15c6ba29 6308 }
Vanger 0:b86d15c6ba29 6309 if (decoded->subjectEmail) {
Vanger 0:b86d15c6ba29 6310 sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
Vanger 0:b86d15c6ba29 6311 ? decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
Vanger 0:b86d15c6ba29 6312 strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
Vanger 0:b86d15c6ba29 6313 cn->email[sz] = 0;
Vanger 0:b86d15c6ba29 6314 }
Vanger 0:b86d15c6ba29 6315 }
Vanger 0:b86d15c6ba29 6316
Vanger 0:b86d15c6ba29 6317 FreeDecodedCert(decoded);
Vanger 0:b86d15c6ba29 6318
Vanger 0:b86d15c6ba29 6319 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6320 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6321 #endif
Vanger 0:b86d15c6ba29 6322
Vanger 0:b86d15c6ba29 6323 return ret < 0 ? ret : 0;
Vanger 0:b86d15c6ba29 6324 }
Vanger 0:b86d15c6ba29 6325
Vanger 0:b86d15c6ba29 6326
Vanger 0:b86d15c6ba29 6327 #ifndef NO_FILESYSTEM
Vanger 0:b86d15c6ba29 6328
Vanger 0:b86d15c6ba29 6329 /* Set cert issuer from issuerFile in PEM */
Vanger 0:b86d15c6ba29 6330 int SetIssuer(Cert* cert, const char* issuerFile)
Vanger 0:b86d15c6ba29 6331 {
Vanger 0:b86d15c6ba29 6332 int ret;
Vanger 0:b86d15c6ba29 6333 int derSz;
Vanger 0:b86d15c6ba29 6334 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6335
Vanger 0:b86d15c6ba29 6336 if (der == NULL) {
Vanger 0:b86d15c6ba29 6337 CYASSL_MSG("SetIssuer OOF Problem");
Vanger 0:b86d15c6ba29 6338 return MEMORY_E;
Vanger 0:b86d15c6ba29 6339 }
Vanger 0:b86d15c6ba29 6340 derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
Vanger 0:b86d15c6ba29 6341 cert->selfSigned = 0;
Vanger 0:b86d15c6ba29 6342 ret = SetNameFromCert(&cert->issuer, der, derSz);
Vanger 0:b86d15c6ba29 6343 XFREE(der, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6344
Vanger 0:b86d15c6ba29 6345 return ret;
Vanger 0:b86d15c6ba29 6346 }
Vanger 0:b86d15c6ba29 6347
Vanger 0:b86d15c6ba29 6348
Vanger 0:b86d15c6ba29 6349 /* Set cert subject from subjectFile in PEM */
Vanger 0:b86d15c6ba29 6350 int SetSubject(Cert* cert, const char* subjectFile)
Vanger 0:b86d15c6ba29 6351 {
Vanger 0:b86d15c6ba29 6352 int ret;
Vanger 0:b86d15c6ba29 6353 int derSz;
Vanger 0:b86d15c6ba29 6354 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6355
Vanger 0:b86d15c6ba29 6356 if (der == NULL) {
Vanger 0:b86d15c6ba29 6357 CYASSL_MSG("SetSubject OOF Problem");
Vanger 0:b86d15c6ba29 6358 return MEMORY_E;
Vanger 0:b86d15c6ba29 6359 }
Vanger 0:b86d15c6ba29 6360 derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
Vanger 0:b86d15c6ba29 6361 ret = SetNameFromCert(&cert->subject, der, derSz);
Vanger 0:b86d15c6ba29 6362 XFREE(der, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6363
Vanger 0:b86d15c6ba29 6364 return ret;
Vanger 0:b86d15c6ba29 6365 }
Vanger 0:b86d15c6ba29 6366
Vanger 0:b86d15c6ba29 6367
Vanger 0:b86d15c6ba29 6368 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 6369
Vanger 0:b86d15c6ba29 6370 /* Set atl names from file in PEM */
Vanger 0:b86d15c6ba29 6371 int SetAltNames(Cert* cert, const char* file)
Vanger 0:b86d15c6ba29 6372 {
Vanger 0:b86d15c6ba29 6373 int ret;
Vanger 0:b86d15c6ba29 6374 int derSz;
Vanger 0:b86d15c6ba29 6375 byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6376
Vanger 0:b86d15c6ba29 6377 if (der == NULL) {
Vanger 0:b86d15c6ba29 6378 CYASSL_MSG("SetAltNames OOF Problem");
Vanger 0:b86d15c6ba29 6379 return MEMORY_E;
Vanger 0:b86d15c6ba29 6380 }
Vanger 0:b86d15c6ba29 6381 derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF);
Vanger 0:b86d15c6ba29 6382 ret = SetAltNamesFromCert(cert, der, derSz);
Vanger 0:b86d15c6ba29 6383 XFREE(der, NULL, DYNAMIC_TYPE_CERT);
Vanger 0:b86d15c6ba29 6384
Vanger 0:b86d15c6ba29 6385 return ret;
Vanger 0:b86d15c6ba29 6386 }
Vanger 0:b86d15c6ba29 6387
Vanger 0:b86d15c6ba29 6388 #endif /* CYASSL_ALT_NAMES */
Vanger 0:b86d15c6ba29 6389
Vanger 0:b86d15c6ba29 6390 #endif /* NO_FILESYSTEM */
Vanger 0:b86d15c6ba29 6391
Vanger 0:b86d15c6ba29 6392 /* Set cert issuer from DER buffer */
Vanger 0:b86d15c6ba29 6393 int SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6394 {
Vanger 0:b86d15c6ba29 6395 cert->selfSigned = 0;
Vanger 0:b86d15c6ba29 6396 return SetNameFromCert(&cert->issuer, der, derSz);
Vanger 0:b86d15c6ba29 6397 }
Vanger 0:b86d15c6ba29 6398
Vanger 0:b86d15c6ba29 6399
Vanger 0:b86d15c6ba29 6400 /* Set cert subject from DER buffer */
Vanger 0:b86d15c6ba29 6401 int SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6402 {
Vanger 0:b86d15c6ba29 6403 return SetNameFromCert(&cert->subject, der, derSz);
Vanger 0:b86d15c6ba29 6404 }
Vanger 0:b86d15c6ba29 6405
Vanger 0:b86d15c6ba29 6406
Vanger 0:b86d15c6ba29 6407 #ifdef CYASSL_ALT_NAMES
Vanger 0:b86d15c6ba29 6408
Vanger 0:b86d15c6ba29 6409 /* Set cert alt names from DER buffer */
Vanger 0:b86d15c6ba29 6410 int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6411 {
Vanger 0:b86d15c6ba29 6412 return SetAltNamesFromCert(cert, der, derSz);
Vanger 0:b86d15c6ba29 6413 }
Vanger 0:b86d15c6ba29 6414
Vanger 0:b86d15c6ba29 6415 /* Set cert dates from DER buffer */
Vanger 0:b86d15c6ba29 6416 int SetDatesBuffer(Cert* cert, const byte* der, int derSz)
Vanger 0:b86d15c6ba29 6417 {
Vanger 0:b86d15c6ba29 6418 return SetDatesFromCert(cert, der, derSz);
Vanger 0:b86d15c6ba29 6419 }
Vanger 0:b86d15c6ba29 6420
Vanger 0:b86d15c6ba29 6421 #endif /* CYASSL_ALT_NAMES */
Vanger 0:b86d15c6ba29 6422
Vanger 0:b86d15c6ba29 6423 #endif /* CYASSL_CERT_GEN */
Vanger 0:b86d15c6ba29 6424
Vanger 0:b86d15c6ba29 6425
Vanger 0:b86d15c6ba29 6426 #ifdef HAVE_ECC
Vanger 0:b86d15c6ba29 6427
Vanger 0:b86d15c6ba29 6428 /* Der Encode r & s ints into out, outLen is (in/out) size */
Vanger 0:b86d15c6ba29 6429 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
Vanger 0:b86d15c6ba29 6430 {
Vanger 0:b86d15c6ba29 6431 word32 idx = 0;
Vanger 0:b86d15c6ba29 6432 word32 rSz; /* encoding size */
Vanger 0:b86d15c6ba29 6433 word32 sSz;
Vanger 0:b86d15c6ba29 6434 word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */
Vanger 0:b86d15c6ba29 6435
Vanger 0:b86d15c6ba29 6436 /* If the leading bit on the INTEGER is a 1, add a leading zero */
Vanger 0:b86d15c6ba29 6437 int rLeadingZero = mp_leading_bit(r);
Vanger 0:b86d15c6ba29 6438 int sLeadingZero = mp_leading_bit(s);
Vanger 0:b86d15c6ba29 6439 int rLen = mp_unsigned_bin_size(r); /* big int size */
Vanger 0:b86d15c6ba29 6440 int sLen = mp_unsigned_bin_size(s);
Vanger 0:b86d15c6ba29 6441 int err;
Vanger 0:b86d15c6ba29 6442
Vanger 0:b86d15c6ba29 6443 if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
Vanger 0:b86d15c6ba29 6444 headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */
Vanger 0:b86d15c6ba29 6445 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 6446
Vanger 0:b86d15c6ba29 6447 idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
Vanger 0:b86d15c6ba29 6448
Vanger 0:b86d15c6ba29 6449 /* store r */
Vanger 0:b86d15c6ba29 6450 out[idx++] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 6451 rSz = SetLength(rLen + rLeadingZero, &out[idx]);
Vanger 0:b86d15c6ba29 6452 idx += rSz;
Vanger 0:b86d15c6ba29 6453 if (rLeadingZero)
Vanger 0:b86d15c6ba29 6454 out[idx++] = 0;
Vanger 0:b86d15c6ba29 6455 err = mp_to_unsigned_bin(r, &out[idx]);
Vanger 0:b86d15c6ba29 6456 if (err != MP_OKAY) return err;
Vanger 0:b86d15c6ba29 6457 idx += rLen;
Vanger 0:b86d15c6ba29 6458
Vanger 0:b86d15c6ba29 6459 /* store s */
Vanger 0:b86d15c6ba29 6460 out[idx++] = ASN_INTEGER;
Vanger 0:b86d15c6ba29 6461 sSz = SetLength(sLen + sLeadingZero, &out[idx]);
Vanger 0:b86d15c6ba29 6462 idx += sSz;
Vanger 0:b86d15c6ba29 6463 if (sLeadingZero)
Vanger 0:b86d15c6ba29 6464 out[idx++] = 0;
Vanger 0:b86d15c6ba29 6465 err = mp_to_unsigned_bin(s, &out[idx]);
Vanger 0:b86d15c6ba29 6466 if (err != MP_OKAY) return err;
Vanger 0:b86d15c6ba29 6467 idx += sLen;
Vanger 0:b86d15c6ba29 6468
Vanger 0:b86d15c6ba29 6469 *outLen = idx;
Vanger 0:b86d15c6ba29 6470
Vanger 0:b86d15c6ba29 6471 return 0;
Vanger 0:b86d15c6ba29 6472 }
Vanger 0:b86d15c6ba29 6473
Vanger 0:b86d15c6ba29 6474
Vanger 0:b86d15c6ba29 6475 /* Der Decode ECC-DSA Signautre, r & s stored as big ints */
Vanger 0:b86d15c6ba29 6476 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
Vanger 0:b86d15c6ba29 6477 {
Vanger 0:b86d15c6ba29 6478 word32 idx = 0;
Vanger 0:b86d15c6ba29 6479 int len = 0;
Vanger 0:b86d15c6ba29 6480
Vanger 0:b86d15c6ba29 6481 if (GetSequence(sig, &idx, &len, sigLen) < 0)
Vanger 0:b86d15c6ba29 6482 return ASN_ECC_KEY_E;
Vanger 0:b86d15c6ba29 6483
Vanger 0:b86d15c6ba29 6484 if ((word32)len > (sigLen - idx))
Vanger 0:b86d15c6ba29 6485 return ASN_ECC_KEY_E;
Vanger 0:b86d15c6ba29 6486
Vanger 0:b86d15c6ba29 6487 if (GetInt(r, sig, &idx, sigLen) < 0)
Vanger 0:b86d15c6ba29 6488 return ASN_ECC_KEY_E;
Vanger 0:b86d15c6ba29 6489
Vanger 0:b86d15c6ba29 6490 if (GetInt(s, sig, &idx, sigLen) < 0)
Vanger 0:b86d15c6ba29 6491 return ASN_ECC_KEY_E;
Vanger 0:b86d15c6ba29 6492
Vanger 0:b86d15c6ba29 6493 return 0;
Vanger 0:b86d15c6ba29 6494 }
Vanger 0:b86d15c6ba29 6495
Vanger 0:b86d15c6ba29 6496
Vanger 0:b86d15c6ba29 6497 int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
Vanger 0:b86d15c6ba29 6498 word32 inSz)
Vanger 0:b86d15c6ba29 6499 {
Vanger 0:b86d15c6ba29 6500 word32 oid = 0;
Vanger 0:b86d15c6ba29 6501 int version, length;
Vanger 0:b86d15c6ba29 6502 int privSz, pubSz;
Vanger 0:b86d15c6ba29 6503 byte b;
Vanger 0:b86d15c6ba29 6504 int ret = 0;
Vanger 0:b86d15c6ba29 6505 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6506 byte* priv;
Vanger 0:b86d15c6ba29 6507 byte* pub;
Vanger 0:b86d15c6ba29 6508 #else
Vanger 0:b86d15c6ba29 6509 byte priv[ECC_MAXSIZE];
Vanger 0:b86d15c6ba29 6510 byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */
Vanger 0:b86d15c6ba29 6511 #endif
Vanger 0:b86d15c6ba29 6512
Vanger 0:b86d15c6ba29 6513 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
Vanger 0:b86d15c6ba29 6514 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 6515
Vanger 0:b86d15c6ba29 6516 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 6517 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6518
Vanger 0:b86d15c6ba29 6519 if (GetMyVersion(input, inOutIdx, &version) < 0)
Vanger 0:b86d15c6ba29 6520 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6521
Vanger 0:b86d15c6ba29 6522 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6523 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6524
Vanger 0:b86d15c6ba29 6525 /* priv type */
Vanger 0:b86d15c6ba29 6526 if (b != 4 && b != 6 && b != 7)
Vanger 0:b86d15c6ba29 6527 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6528
Vanger 0:b86d15c6ba29 6529 if (GetLength(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 6530 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6531
Vanger 0:b86d15c6ba29 6532 if (length > ECC_MAXSIZE)
Vanger 0:b86d15c6ba29 6533 return BUFFER_E;
Vanger 0:b86d15c6ba29 6534
Vanger 0:b86d15c6ba29 6535 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6536 priv = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6537 if (priv == NULL)
Vanger 0:b86d15c6ba29 6538 return MEMORY_E;
Vanger 0:b86d15c6ba29 6539
Vanger 0:b86d15c6ba29 6540 pub = (byte*)XMALLOC(ECC_MAXSIZE * 2 + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6541 if (pub == NULL) {
Vanger 0:b86d15c6ba29 6542 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6543 return MEMORY_E;
Vanger 0:b86d15c6ba29 6544 }
Vanger 0:b86d15c6ba29 6545 #endif
Vanger 0:b86d15c6ba29 6546
Vanger 0:b86d15c6ba29 6547 /* priv key */
Vanger 0:b86d15c6ba29 6548 privSz = length;
Vanger 0:b86d15c6ba29 6549 XMEMCPY(priv, &input[*inOutIdx], privSz);
Vanger 0:b86d15c6ba29 6550 *inOutIdx += length;
Vanger 0:b86d15c6ba29 6551
Vanger 0:b86d15c6ba29 6552 /* prefix 0, may have */
Vanger 0:b86d15c6ba29 6553 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6554 if (b == ECC_PREFIX_0) {
Vanger 0:b86d15c6ba29 6555 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6556
Vanger 0:b86d15c6ba29 6557 if (GetLength(input, inOutIdx, &length, inSz) < 0)
Vanger 0:b86d15c6ba29 6558 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6559 else {
Vanger 0:b86d15c6ba29 6560 /* object id */
Vanger 0:b86d15c6ba29 6561 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6562 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6563
Vanger 0:b86d15c6ba29 6564 if (b != ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 6565 ret = ASN_OBJECT_ID_E;
Vanger 0:b86d15c6ba29 6566 }
Vanger 0:b86d15c6ba29 6567 else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
Vanger 0:b86d15c6ba29 6568 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6569 }
Vanger 0:b86d15c6ba29 6570 else {
Vanger 0:b86d15c6ba29 6571 while(length--) {
Vanger 0:b86d15c6ba29 6572 oid += input[*inOutIdx];
Vanger 0:b86d15c6ba29 6573 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6574 }
Vanger 0:b86d15c6ba29 6575 if (CheckCurve(oid) < 0)
Vanger 0:b86d15c6ba29 6576 ret = ECC_CURVE_OID_E;
Vanger 0:b86d15c6ba29 6577 }
Vanger 0:b86d15c6ba29 6578 }
Vanger 0:b86d15c6ba29 6579 }
Vanger 0:b86d15c6ba29 6580
Vanger 0:b86d15c6ba29 6581 if (ret == 0) {
Vanger 0:b86d15c6ba29 6582 /* prefix 1 */
Vanger 0:b86d15c6ba29 6583 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6584 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6585
Vanger 0:b86d15c6ba29 6586 if (b != ECC_PREFIX_1) {
Vanger 0:b86d15c6ba29 6587 ret = ASN_ECC_KEY_E;
Vanger 0:b86d15c6ba29 6588 }
Vanger 0:b86d15c6ba29 6589 else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
Vanger 0:b86d15c6ba29 6590 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6591 }
Vanger 0:b86d15c6ba29 6592 else {
Vanger 0:b86d15c6ba29 6593 /* key header */
Vanger 0:b86d15c6ba29 6594 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6595 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6596
Vanger 0:b86d15c6ba29 6597 if (b != ASN_BIT_STRING) {
Vanger 0:b86d15c6ba29 6598 ret = ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 6599 }
Vanger 0:b86d15c6ba29 6600 else if (GetLength(input, inOutIdx, &length, inSz) < 0) {
Vanger 0:b86d15c6ba29 6601 ret = ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6602 }
Vanger 0:b86d15c6ba29 6603 else {
Vanger 0:b86d15c6ba29 6604 b = input[*inOutIdx];
Vanger 0:b86d15c6ba29 6605 *inOutIdx += 1;
Vanger 0:b86d15c6ba29 6606
Vanger 0:b86d15c6ba29 6607 if (b != 0x00) {
Vanger 0:b86d15c6ba29 6608 ret = ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 6609 }
Vanger 0:b86d15c6ba29 6610 else {
Vanger 0:b86d15c6ba29 6611 /* pub key */
Vanger 0:b86d15c6ba29 6612 pubSz = length - 1; /* null prefix */
Vanger 0:b86d15c6ba29 6613 if (pubSz < (ECC_MAXSIZE*2 + 1)) {
Vanger 0:b86d15c6ba29 6614 XMEMCPY(pub, &input[*inOutIdx], pubSz);
Vanger 0:b86d15c6ba29 6615 *inOutIdx += length;
Vanger 0:b86d15c6ba29 6616 ret = ecc_import_private_key(priv, privSz, pub, pubSz,
Vanger 0:b86d15c6ba29 6617 key);
Vanger 0:b86d15c6ba29 6618 } else
Vanger 0:b86d15c6ba29 6619 ret = BUFFER_E;
Vanger 0:b86d15c6ba29 6620 }
Vanger 0:b86d15c6ba29 6621 }
Vanger 0:b86d15c6ba29 6622 }
Vanger 0:b86d15c6ba29 6623 }
Vanger 0:b86d15c6ba29 6624
Vanger 0:b86d15c6ba29 6625 #ifdef CYASSL_SMALL_STACK
Vanger 0:b86d15c6ba29 6626 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6627 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Vanger 0:b86d15c6ba29 6628 #endif
Vanger 0:b86d15c6ba29 6629
Vanger 0:b86d15c6ba29 6630 return ret;
Vanger 0:b86d15c6ba29 6631 }
Vanger 0:b86d15c6ba29 6632
Vanger 0:b86d15c6ba29 6633
Vanger 0:b86d15c6ba29 6634 #ifdef CYASSL_KEY_GEN
Vanger 0:b86d15c6ba29 6635
Vanger 0:b86d15c6ba29 6636 /* Write a Private ecc key to DER format, length on success else < 0 */
Vanger 0:b86d15c6ba29 6637 int EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
Vanger 0:b86d15c6ba29 6638 {
Vanger 0:b86d15c6ba29 6639 byte curve[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 6640 byte ver[MAX_VERSION_SZ];
Vanger 0:b86d15c6ba29 6641 byte seq[MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 6642 int ret;
Vanger 0:b86d15c6ba29 6643 int curveSz;
Vanger 0:b86d15c6ba29 6644 int verSz;
Vanger 0:b86d15c6ba29 6645 int privHdrSz = ASN_ECC_HEADER_SZ;
Vanger 0:b86d15c6ba29 6646 int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
Vanger 0:b86d15c6ba29 6647 int curveHdrSz = ASN_ECC_CONTEXT_SZ;
Vanger 0:b86d15c6ba29 6648 word32 seqSz;
Vanger 0:b86d15c6ba29 6649 word32 idx = 0;
Vanger 0:b86d15c6ba29 6650 word32 pubSz = ECC_BUFSIZE;
Vanger 0:b86d15c6ba29 6651 word32 privSz;
Vanger 0:b86d15c6ba29 6652 word32 totalSz;
Vanger 0:b86d15c6ba29 6653
Vanger 0:b86d15c6ba29 6654 if (key == NULL || output == NULL || inLen == 0)
Vanger 0:b86d15c6ba29 6655 return BAD_FUNC_ARG;
Vanger 0:b86d15c6ba29 6656
Vanger 0:b86d15c6ba29 6657 ret = ecc_export_x963(key, NULL, &pubSz);
Vanger 0:b86d15c6ba29 6658 if (ret != LENGTH_ONLY_E) {
Vanger 0:b86d15c6ba29 6659 return ret;
Vanger 0:b86d15c6ba29 6660 }
Vanger 0:b86d15c6ba29 6661 curveSz = SetCurve(key, curve);
Vanger 0:b86d15c6ba29 6662 if (curveSz < 0) {
Vanger 0:b86d15c6ba29 6663 return curveSz;
Vanger 0:b86d15c6ba29 6664 }
Vanger 0:b86d15c6ba29 6665
Vanger 0:b86d15c6ba29 6666 privSz = key->dp->size;
Vanger 0:b86d15c6ba29 6667
Vanger 0:b86d15c6ba29 6668 verSz = SetMyVersion(1, ver, FALSE);
Vanger 0:b86d15c6ba29 6669 if (verSz < 0) {
Vanger 0:b86d15c6ba29 6670 return verSz;
Vanger 0:b86d15c6ba29 6671 }
Vanger 0:b86d15c6ba29 6672
Vanger 0:b86d15c6ba29 6673 totalSz = verSz + privSz + privHdrSz + curveSz + curveHdrSz +
Vanger 0:b86d15c6ba29 6674 pubSz + pubHdrSz + 1; /* plus null byte b4 public */
Vanger 0:b86d15c6ba29 6675 seqSz = SetSequence(totalSz, seq);
Vanger 0:b86d15c6ba29 6676 totalSz += seqSz;
Vanger 0:b86d15c6ba29 6677
Vanger 0:b86d15c6ba29 6678 if (totalSz > inLen) {
Vanger 0:b86d15c6ba29 6679 return BUFFER_E;
Vanger 0:b86d15c6ba29 6680 }
Vanger 0:b86d15c6ba29 6681
Vanger 0:b86d15c6ba29 6682 /* write it out */
Vanger 0:b86d15c6ba29 6683 /* seq */
Vanger 0:b86d15c6ba29 6684 XMEMCPY(output + idx, seq, seqSz);
Vanger 0:b86d15c6ba29 6685 idx += seqSz;
Vanger 0:b86d15c6ba29 6686
Vanger 0:b86d15c6ba29 6687 /* ver */
Vanger 0:b86d15c6ba29 6688 XMEMCPY(output + idx, ver, verSz);
Vanger 0:b86d15c6ba29 6689 idx += verSz;
Vanger 0:b86d15c6ba29 6690
Vanger 0:b86d15c6ba29 6691 /* private */
Vanger 0:b86d15c6ba29 6692 output[idx++] = ASN_OCTET_STRING;
Vanger 0:b86d15c6ba29 6693 output[idx++] = (byte)privSz;
Vanger 0:b86d15c6ba29 6694 ret = ecc_export_private_only(key, output + idx, &privSz);
Vanger 0:b86d15c6ba29 6695 if (ret < 0) {
Vanger 0:b86d15c6ba29 6696 return ret;
Vanger 0:b86d15c6ba29 6697 }
Vanger 0:b86d15c6ba29 6698 idx += privSz;
Vanger 0:b86d15c6ba29 6699
Vanger 0:b86d15c6ba29 6700 /* curve */
Vanger 0:b86d15c6ba29 6701 output[idx++] = ECC_PREFIX_0;
Vanger 0:b86d15c6ba29 6702 output[idx++] = (byte)curveSz;
Vanger 0:b86d15c6ba29 6703 XMEMCPY(output + idx, curve, curveSz);
Vanger 0:b86d15c6ba29 6704 idx += curveSz;
Vanger 0:b86d15c6ba29 6705
Vanger 0:b86d15c6ba29 6706 /* public */
Vanger 0:b86d15c6ba29 6707 output[idx++] = ECC_PREFIX_1;
Vanger 0:b86d15c6ba29 6708 output[idx++] = (byte)pubSz + ASN_ECC_CONTEXT_SZ + 1; /* plus null byte */
Vanger 0:b86d15c6ba29 6709 output[idx++] = ASN_BIT_STRING;
Vanger 0:b86d15c6ba29 6710 output[idx++] = (byte)pubSz + 1; /* plus null byte */
Vanger 0:b86d15c6ba29 6711 output[idx++] = (byte)0; /* null byte */
Vanger 0:b86d15c6ba29 6712 ret = ecc_export_x963(key, output + idx, &pubSz);
Vanger 0:b86d15c6ba29 6713 if (ret != 0) {
Vanger 0:b86d15c6ba29 6714 return ret;
Vanger 0:b86d15c6ba29 6715 }
Vanger 0:b86d15c6ba29 6716 /* idx += pubSz if do more later */
Vanger 0:b86d15c6ba29 6717
Vanger 0:b86d15c6ba29 6718 return totalSz;
Vanger 0:b86d15c6ba29 6719 }
Vanger 0:b86d15c6ba29 6720
Vanger 0:b86d15c6ba29 6721 #endif /* CYASSL_KEY_GEN */
Vanger 0:b86d15c6ba29 6722
Vanger 0:b86d15c6ba29 6723 #endif /* HAVE_ECC */
Vanger 0:b86d15c6ba29 6724
Vanger 0:b86d15c6ba29 6725
Vanger 0:b86d15c6ba29 6726 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
Vanger 0:b86d15c6ba29 6727
Vanger 0:b86d15c6ba29 6728 /* Get raw Date only, no processing, 0 on success */
Vanger 0:b86d15c6ba29 6729 static int GetBasicDate(const byte* source, word32* idx, byte* date,
Vanger 0:b86d15c6ba29 6730 byte* format, int maxIdx)
Vanger 0:b86d15c6ba29 6731 {
Vanger 0:b86d15c6ba29 6732 int length;
Vanger 0:b86d15c6ba29 6733
Vanger 0:b86d15c6ba29 6734 CYASSL_ENTER("GetBasicDate");
Vanger 0:b86d15c6ba29 6735
Vanger 0:b86d15c6ba29 6736 *format = source[*idx];
Vanger 0:b86d15c6ba29 6737 *idx += 1;
Vanger 0:b86d15c6ba29 6738 if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
Vanger 0:b86d15c6ba29 6739 return ASN_TIME_E;
Vanger 0:b86d15c6ba29 6740
Vanger 0:b86d15c6ba29 6741 if (GetLength(source, idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 6742 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6743
Vanger 0:b86d15c6ba29 6744 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
Vanger 0:b86d15c6ba29 6745 return ASN_DATE_SZ_E;
Vanger 0:b86d15c6ba29 6746
Vanger 0:b86d15c6ba29 6747 XMEMCPY(date, &source[*idx], length);
Vanger 0:b86d15c6ba29 6748 *idx += length;
Vanger 0:b86d15c6ba29 6749
Vanger 0:b86d15c6ba29 6750 return 0;
Vanger 0:b86d15c6ba29 6751 }
Vanger 0:b86d15c6ba29 6752
Vanger 0:b86d15c6ba29 6753 #endif
Vanger 0:b86d15c6ba29 6754
Vanger 0:b86d15c6ba29 6755
Vanger 0:b86d15c6ba29 6756 #ifdef HAVE_OCSP
Vanger 0:b86d15c6ba29 6757
Vanger 0:b86d15c6ba29 6758 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
Vanger 0:b86d15c6ba29 6759 {
Vanger 0:b86d15c6ba29 6760 word32 idx = *inOutIdx;
Vanger 0:b86d15c6ba29 6761 word32 len;
Vanger 0:b86d15c6ba29 6762
Vanger 0:b86d15c6ba29 6763 CYASSL_ENTER("GetEnumerated");
Vanger 0:b86d15c6ba29 6764
Vanger 0:b86d15c6ba29 6765 *value = 0;
Vanger 0:b86d15c6ba29 6766
Vanger 0:b86d15c6ba29 6767 if (input[idx++] != ASN_ENUMERATED)
Vanger 0:b86d15c6ba29 6768 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6769
Vanger 0:b86d15c6ba29 6770 len = input[idx++];
Vanger 0:b86d15c6ba29 6771 if (len > 4)
Vanger 0:b86d15c6ba29 6772 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6773
Vanger 0:b86d15c6ba29 6774 while (len--) {
Vanger 0:b86d15c6ba29 6775 *value = *value << 8 | input[idx++];
Vanger 0:b86d15c6ba29 6776 }
Vanger 0:b86d15c6ba29 6777
Vanger 0:b86d15c6ba29 6778 *inOutIdx = idx;
Vanger 0:b86d15c6ba29 6779
Vanger 0:b86d15c6ba29 6780 return *value;
Vanger 0:b86d15c6ba29 6781 }
Vanger 0:b86d15c6ba29 6782
Vanger 0:b86d15c6ba29 6783
Vanger 0:b86d15c6ba29 6784 static int DecodeSingleResponse(byte* source,
Vanger 0:b86d15c6ba29 6785 word32* ioIndex, OcspResponse* resp, word32 size)
Vanger 0:b86d15c6ba29 6786 {
Vanger 0:b86d15c6ba29 6787 word32 idx = *ioIndex, prevIndex, oid;
Vanger 0:b86d15c6ba29 6788 int length, wrapperSz;
Vanger 0:b86d15c6ba29 6789 CertStatus* cs = resp->status;
Vanger 0:b86d15c6ba29 6790
Vanger 0:b86d15c6ba29 6791 CYASSL_ENTER("DecodeSingleResponse");
Vanger 0:b86d15c6ba29 6792
Vanger 0:b86d15c6ba29 6793 /* Outer wrapper of the SEQUENCE OF Single Responses. */
Vanger 0:b86d15c6ba29 6794 if (GetSequence(source, &idx, &wrapperSz, size) < 0)
Vanger 0:b86d15c6ba29 6795 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6796
Vanger 0:b86d15c6ba29 6797 prevIndex = idx;
Vanger 0:b86d15c6ba29 6798
Vanger 0:b86d15c6ba29 6799 /* When making a request, we only request one status on one certificate
Vanger 0:b86d15c6ba29 6800 * at a time. There should only be one SingleResponse */
Vanger 0:b86d15c6ba29 6801
Vanger 0:b86d15c6ba29 6802 /* Wrapper around the Single Response */
Vanger 0:b86d15c6ba29 6803 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6804 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6805
Vanger 0:b86d15c6ba29 6806 /* Wrapper around the CertID */
Vanger 0:b86d15c6ba29 6807 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6808 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6809 /* Skip the hash algorithm */
Vanger 0:b86d15c6ba29 6810 if (GetAlgoId(source, &idx, &oid, size) < 0)
Vanger 0:b86d15c6ba29 6811 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6812 /* Save reference to the hash of CN */
Vanger 0:b86d15c6ba29 6813 if (source[idx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 6814 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6815 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6816 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6817 resp->issuerHash = source + idx;
Vanger 0:b86d15c6ba29 6818 idx += length;
Vanger 0:b86d15c6ba29 6819 /* Save reference to the hash of the issuer public key */
Vanger 0:b86d15c6ba29 6820 if (source[idx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 6821 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6822 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6823 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6824 resp->issuerKeyHash = source + idx;
Vanger 0:b86d15c6ba29 6825 idx += length;
Vanger 0:b86d15c6ba29 6826
Vanger 0:b86d15c6ba29 6827 /* Read the serial number, it is handled as a string, not as a
Vanger 0:b86d15c6ba29 6828 * proper number. Just XMEMCPY the data over, rather than load it
Vanger 0:b86d15c6ba29 6829 * as an mp_int. */
Vanger 0:b86d15c6ba29 6830 if (source[idx++] != ASN_INTEGER)
Vanger 0:b86d15c6ba29 6831 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6832 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6833 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6834 if (length <= EXTERNAL_SERIAL_SIZE)
Vanger 0:b86d15c6ba29 6835 {
Vanger 0:b86d15c6ba29 6836 if (source[idx] == 0)
Vanger 0:b86d15c6ba29 6837 {
Vanger 0:b86d15c6ba29 6838 idx++;
Vanger 0:b86d15c6ba29 6839 length--;
Vanger 0:b86d15c6ba29 6840 }
Vanger 0:b86d15c6ba29 6841 XMEMCPY(cs->serial, source + idx, length);
Vanger 0:b86d15c6ba29 6842 cs->serialSz = length;
Vanger 0:b86d15c6ba29 6843 }
Vanger 0:b86d15c6ba29 6844 else
Vanger 0:b86d15c6ba29 6845 {
Vanger 0:b86d15c6ba29 6846 return ASN_GETINT_E;
Vanger 0:b86d15c6ba29 6847 }
Vanger 0:b86d15c6ba29 6848 idx += length;
Vanger 0:b86d15c6ba29 6849
Vanger 0:b86d15c6ba29 6850 /* CertStatus */
Vanger 0:b86d15c6ba29 6851 switch (source[idx++])
Vanger 0:b86d15c6ba29 6852 {
Vanger 0:b86d15c6ba29 6853 case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
Vanger 0:b86d15c6ba29 6854 cs->status = CERT_GOOD;
Vanger 0:b86d15c6ba29 6855 idx++;
Vanger 0:b86d15c6ba29 6856 break;
Vanger 0:b86d15c6ba29 6857 case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
Vanger 0:b86d15c6ba29 6858 cs->status = CERT_REVOKED;
Vanger 0:b86d15c6ba29 6859 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6860 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6861 idx += length;
Vanger 0:b86d15c6ba29 6862 break;
Vanger 0:b86d15c6ba29 6863 case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
Vanger 0:b86d15c6ba29 6864 cs->status = CERT_UNKNOWN;
Vanger 0:b86d15c6ba29 6865 idx++;
Vanger 0:b86d15c6ba29 6866 break;
Vanger 0:b86d15c6ba29 6867 default:
Vanger 0:b86d15c6ba29 6868 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6869 }
Vanger 0:b86d15c6ba29 6870
Vanger 0:b86d15c6ba29 6871 if (GetBasicDate(source, &idx, cs->thisDate,
Vanger 0:b86d15c6ba29 6872 &cs->thisDateFormat, size) < 0)
Vanger 0:b86d15c6ba29 6873 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6874 if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
Vanger 0:b86d15c6ba29 6875 return ASN_BEFORE_DATE_E;
Vanger 0:b86d15c6ba29 6876
Vanger 0:b86d15c6ba29 6877 /* The following items are optional. Only check for them if there is more
Vanger 0:b86d15c6ba29 6878 * unprocessed data in the singleResponse wrapper. */
Vanger 0:b86d15c6ba29 6879
Vanger 0:b86d15c6ba29 6880 if (((int)(idx - prevIndex) < wrapperSz) &&
Vanger 0:b86d15c6ba29 6881 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
Vanger 0:b86d15c6ba29 6882 {
Vanger 0:b86d15c6ba29 6883 idx++;
Vanger 0:b86d15c6ba29 6884 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6885 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6886 if (GetBasicDate(source, &idx, cs->nextDate,
Vanger 0:b86d15c6ba29 6887 &cs->nextDateFormat, size) < 0)
Vanger 0:b86d15c6ba29 6888 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6889 }
Vanger 0:b86d15c6ba29 6890 if (((int)(idx - prevIndex) < wrapperSz) &&
Vanger 0:b86d15c6ba29 6891 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
Vanger 0:b86d15c6ba29 6892 {
Vanger 0:b86d15c6ba29 6893 idx++;
Vanger 0:b86d15c6ba29 6894 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6895 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6896 idx += length;
Vanger 0:b86d15c6ba29 6897 }
Vanger 0:b86d15c6ba29 6898
Vanger 0:b86d15c6ba29 6899 *ioIndex = idx;
Vanger 0:b86d15c6ba29 6900
Vanger 0:b86d15c6ba29 6901 return 0;
Vanger 0:b86d15c6ba29 6902 }
Vanger 0:b86d15c6ba29 6903
Vanger 0:b86d15c6ba29 6904 static int DecodeOcspRespExtensions(byte* source,
Vanger 0:b86d15c6ba29 6905 word32* ioIndex, OcspResponse* resp, word32 sz)
Vanger 0:b86d15c6ba29 6906 {
Vanger 0:b86d15c6ba29 6907 word32 idx = *ioIndex;
Vanger 0:b86d15c6ba29 6908 int length;
Vanger 0:b86d15c6ba29 6909 int ext_bound; /* boundary index for the sequence of extensions */
Vanger 0:b86d15c6ba29 6910 word32 oid;
Vanger 0:b86d15c6ba29 6911
Vanger 0:b86d15c6ba29 6912 CYASSL_ENTER("DecodeOcspRespExtensions");
Vanger 0:b86d15c6ba29 6913
Vanger 0:b86d15c6ba29 6914 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
Vanger 0:b86d15c6ba29 6915 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6916
Vanger 0:b86d15c6ba29 6917 if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6918
Vanger 0:b86d15c6ba29 6919 if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6920
Vanger 0:b86d15c6ba29 6921 ext_bound = idx + length;
Vanger 0:b86d15c6ba29 6922
Vanger 0:b86d15c6ba29 6923 while (idx < (word32)ext_bound) {
Vanger 0:b86d15c6ba29 6924 if (GetSequence(source, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 6925 CYASSL_MSG("\tfail: should be a SEQUENCE");
Vanger 0:b86d15c6ba29 6926 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6927 }
Vanger 0:b86d15c6ba29 6928
Vanger 0:b86d15c6ba29 6929 oid = 0;
Vanger 0:b86d15c6ba29 6930 if (GetObjectId(source, &idx, &oid, sz) < 0) {
Vanger 0:b86d15c6ba29 6931 CYASSL_MSG("\tfail: OBJECT ID");
Vanger 0:b86d15c6ba29 6932 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6933 }
Vanger 0:b86d15c6ba29 6934
Vanger 0:b86d15c6ba29 6935 /* check for critical flag */
Vanger 0:b86d15c6ba29 6936 if (source[idx] == ASN_BOOLEAN) {
Vanger 0:b86d15c6ba29 6937 CYASSL_MSG("\tfound optional critical flag, moving past");
Vanger 0:b86d15c6ba29 6938 idx += (ASN_BOOL_SIZE + 1);
Vanger 0:b86d15c6ba29 6939 }
Vanger 0:b86d15c6ba29 6940
Vanger 0:b86d15c6ba29 6941 /* process the extension based on the OID */
Vanger 0:b86d15c6ba29 6942 if (source[idx++] != ASN_OCTET_STRING) {
Vanger 0:b86d15c6ba29 6943 CYASSL_MSG("\tfail: should be an OCTET STRING");
Vanger 0:b86d15c6ba29 6944 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6945 }
Vanger 0:b86d15c6ba29 6946
Vanger 0:b86d15c6ba29 6947 if (GetLength(source, &idx, &length, sz) < 0) {
Vanger 0:b86d15c6ba29 6948 CYASSL_MSG("\tfail: extension data length");
Vanger 0:b86d15c6ba29 6949 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6950 }
Vanger 0:b86d15c6ba29 6951
Vanger 0:b86d15c6ba29 6952 if (oid == OCSP_NONCE_OID) {
Vanger 0:b86d15c6ba29 6953 resp->nonce = source + idx;
Vanger 0:b86d15c6ba29 6954 resp->nonceSz = length;
Vanger 0:b86d15c6ba29 6955 }
Vanger 0:b86d15c6ba29 6956
Vanger 0:b86d15c6ba29 6957 idx += length;
Vanger 0:b86d15c6ba29 6958 }
Vanger 0:b86d15c6ba29 6959
Vanger 0:b86d15c6ba29 6960 *ioIndex = idx;
Vanger 0:b86d15c6ba29 6961 return 0;
Vanger 0:b86d15c6ba29 6962 }
Vanger 0:b86d15c6ba29 6963
Vanger 0:b86d15c6ba29 6964
Vanger 0:b86d15c6ba29 6965 static int DecodeResponseData(byte* source,
Vanger 0:b86d15c6ba29 6966 word32* ioIndex, OcspResponse* resp, word32 size)
Vanger 0:b86d15c6ba29 6967 {
Vanger 0:b86d15c6ba29 6968 word32 idx = *ioIndex, prev_idx;
Vanger 0:b86d15c6ba29 6969 int length;
Vanger 0:b86d15c6ba29 6970 int version;
Vanger 0:b86d15c6ba29 6971 word32 responderId = 0;
Vanger 0:b86d15c6ba29 6972
Vanger 0:b86d15c6ba29 6973 CYASSL_ENTER("DecodeResponseData");
Vanger 0:b86d15c6ba29 6974
Vanger 0:b86d15c6ba29 6975 resp->response = source + idx;
Vanger 0:b86d15c6ba29 6976 prev_idx = idx;
Vanger 0:b86d15c6ba29 6977 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6978 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6979 resp->responseSz = length + idx - prev_idx;
Vanger 0:b86d15c6ba29 6980
Vanger 0:b86d15c6ba29 6981 /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
Vanger 0:b86d15c6ba29 6982 * item isn't an EXPLICIT[0], then set version to zero and move
Vanger 0:b86d15c6ba29 6983 * onto the next item.
Vanger 0:b86d15c6ba29 6984 */
Vanger 0:b86d15c6ba29 6985 if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
Vanger 0:b86d15c6ba29 6986 {
Vanger 0:b86d15c6ba29 6987 idx += 2; /* Eat the value and length */
Vanger 0:b86d15c6ba29 6988 if (GetMyVersion(source, &idx, &version) < 0)
Vanger 0:b86d15c6ba29 6989 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6990 } else
Vanger 0:b86d15c6ba29 6991 version = 0;
Vanger 0:b86d15c6ba29 6992
Vanger 0:b86d15c6ba29 6993 responderId = source[idx++];
Vanger 0:b86d15c6ba29 6994 if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
Vanger 0:b86d15c6ba29 6995 (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
Vanger 0:b86d15c6ba29 6996 {
Vanger 0:b86d15c6ba29 6997 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 6998 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 6999 idx += length;
Vanger 0:b86d15c6ba29 7000 }
Vanger 0:b86d15c6ba29 7001 else
Vanger 0:b86d15c6ba29 7002 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7003
Vanger 0:b86d15c6ba29 7004 /* save pointer to the producedAt time */
Vanger 0:b86d15c6ba29 7005 if (GetBasicDate(source, &idx, resp->producedDate,
Vanger 0:b86d15c6ba29 7006 &resp->producedDateFormat, size) < 0)
Vanger 0:b86d15c6ba29 7007 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7008
Vanger 0:b86d15c6ba29 7009 if (DecodeSingleResponse(source, &idx, resp, size) < 0)
Vanger 0:b86d15c6ba29 7010 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7011
Vanger 0:b86d15c6ba29 7012 if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
Vanger 0:b86d15c6ba29 7013 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7014
Vanger 0:b86d15c6ba29 7015 *ioIndex = idx;
Vanger 0:b86d15c6ba29 7016 return 0;
Vanger 0:b86d15c6ba29 7017 }
Vanger 0:b86d15c6ba29 7018
Vanger 0:b86d15c6ba29 7019
Vanger 0:b86d15c6ba29 7020 static int DecodeCerts(byte* source,
Vanger 0:b86d15c6ba29 7021 word32* ioIndex, OcspResponse* resp, word32 size)
Vanger 0:b86d15c6ba29 7022 {
Vanger 0:b86d15c6ba29 7023 word32 idx = *ioIndex;
Vanger 0:b86d15c6ba29 7024
Vanger 0:b86d15c6ba29 7025 CYASSL_ENTER("DecodeCerts");
Vanger 0:b86d15c6ba29 7026
Vanger 0:b86d15c6ba29 7027 if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
Vanger 0:b86d15c6ba29 7028 {
Vanger 0:b86d15c6ba29 7029 int length;
Vanger 0:b86d15c6ba29 7030
Vanger 0:b86d15c6ba29 7031 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7032 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7033
Vanger 0:b86d15c6ba29 7034 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7035 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7036
Vanger 0:b86d15c6ba29 7037 resp->cert = source + idx;
Vanger 0:b86d15c6ba29 7038 resp->certSz = length;
Vanger 0:b86d15c6ba29 7039
Vanger 0:b86d15c6ba29 7040 idx += length;
Vanger 0:b86d15c6ba29 7041 }
Vanger 0:b86d15c6ba29 7042 *ioIndex = idx;
Vanger 0:b86d15c6ba29 7043 return 0;
Vanger 0:b86d15c6ba29 7044 }
Vanger 0:b86d15c6ba29 7045
Vanger 0:b86d15c6ba29 7046 static int DecodeBasicOcspResponse(byte* source,
Vanger 0:b86d15c6ba29 7047 word32* ioIndex, OcspResponse* resp, word32 size)
Vanger 0:b86d15c6ba29 7048 {
Vanger 0:b86d15c6ba29 7049 int length;
Vanger 0:b86d15c6ba29 7050 word32 idx = *ioIndex;
Vanger 0:b86d15c6ba29 7051 word32 end_index;
Vanger 0:b86d15c6ba29 7052
Vanger 0:b86d15c6ba29 7053 CYASSL_ENTER("DecodeBasicOcspResponse");
Vanger 0:b86d15c6ba29 7054
Vanger 0:b86d15c6ba29 7055 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7056 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7057
Vanger 0:b86d15c6ba29 7058 if (idx + length > size)
Vanger 0:b86d15c6ba29 7059 return ASN_INPUT_E;
Vanger 0:b86d15c6ba29 7060 end_index = idx + length;
Vanger 0:b86d15c6ba29 7061
Vanger 0:b86d15c6ba29 7062 if (DecodeResponseData(source, &idx, resp, size) < 0)
Vanger 0:b86d15c6ba29 7063 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7064
Vanger 0:b86d15c6ba29 7065 /* Get the signature algorithm */
Vanger 0:b86d15c6ba29 7066 if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
Vanger 0:b86d15c6ba29 7067 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7068
Vanger 0:b86d15c6ba29 7069 /* Obtain pointer to the start of the signature, and save the size */
Vanger 0:b86d15c6ba29 7070 if (source[idx++] == ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 7071 {
Vanger 0:b86d15c6ba29 7072 int sigLength = 0;
Vanger 0:b86d15c6ba29 7073 if (GetLength(source, &idx, &sigLength, size) < 0)
Vanger 0:b86d15c6ba29 7074 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7075 resp->sigSz = sigLength;
Vanger 0:b86d15c6ba29 7076 resp->sig = source + idx;
Vanger 0:b86d15c6ba29 7077 idx += sigLength;
Vanger 0:b86d15c6ba29 7078 }
Vanger 0:b86d15c6ba29 7079
Vanger 0:b86d15c6ba29 7080 /*
Vanger 0:b86d15c6ba29 7081 * Check the length of the BasicOcspResponse against the current index to
Vanger 0:b86d15c6ba29 7082 * see if there are certificates, they are optional.
Vanger 0:b86d15c6ba29 7083 */
Vanger 0:b86d15c6ba29 7084 if (idx < end_index)
Vanger 0:b86d15c6ba29 7085 {
Vanger 0:b86d15c6ba29 7086 DecodedCert cert;
Vanger 0:b86d15c6ba29 7087 int ret;
Vanger 0:b86d15c6ba29 7088
Vanger 0:b86d15c6ba29 7089 if (DecodeCerts(source, &idx, resp, size) < 0)
Vanger 0:b86d15c6ba29 7090 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7091
Vanger 0:b86d15c6ba29 7092 InitDecodedCert(&cert, resp->cert, resp->certSz, 0);
Vanger 0:b86d15c6ba29 7093 ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0);
Vanger 0:b86d15c6ba29 7094 if (ret < 0)
Vanger 0:b86d15c6ba29 7095 return ret;
Vanger 0:b86d15c6ba29 7096
Vanger 0:b86d15c6ba29 7097 ret = ConfirmSignature(resp->response, resp->responseSz,
Vanger 0:b86d15c6ba29 7098 cert.publicKey, cert.pubKeySize, cert.keyOID,
Vanger 0:b86d15c6ba29 7099 resp->sig, resp->sigSz, resp->sigOID, NULL);
Vanger 0:b86d15c6ba29 7100 FreeDecodedCert(&cert);
Vanger 0:b86d15c6ba29 7101
Vanger 0:b86d15c6ba29 7102 if (ret == 0)
Vanger 0:b86d15c6ba29 7103 {
Vanger 0:b86d15c6ba29 7104 CYASSL_MSG("\tOCSP Confirm signature failed");
Vanger 0:b86d15c6ba29 7105 return ASN_OCSP_CONFIRM_E;
Vanger 0:b86d15c6ba29 7106 }
Vanger 0:b86d15c6ba29 7107 }
Vanger 0:b86d15c6ba29 7108
Vanger 0:b86d15c6ba29 7109 *ioIndex = idx;
Vanger 0:b86d15c6ba29 7110 return 0;
Vanger 0:b86d15c6ba29 7111 }
Vanger 0:b86d15c6ba29 7112
Vanger 0:b86d15c6ba29 7113
Vanger 0:b86d15c6ba29 7114 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
Vanger 0:b86d15c6ba29 7115 byte* source, word32 inSz)
Vanger 0:b86d15c6ba29 7116 {
Vanger 0:b86d15c6ba29 7117 CYASSL_ENTER("InitOcspResponse");
Vanger 0:b86d15c6ba29 7118
Vanger 0:b86d15c6ba29 7119 resp->responseStatus = -1;
Vanger 0:b86d15c6ba29 7120 resp->response = NULL;
Vanger 0:b86d15c6ba29 7121 resp->responseSz = 0;
Vanger 0:b86d15c6ba29 7122 resp->producedDateFormat = 0;
Vanger 0:b86d15c6ba29 7123 resp->issuerHash = NULL;
Vanger 0:b86d15c6ba29 7124 resp->issuerKeyHash = NULL;
Vanger 0:b86d15c6ba29 7125 resp->sig = NULL;
Vanger 0:b86d15c6ba29 7126 resp->sigSz = 0;
Vanger 0:b86d15c6ba29 7127 resp->sigOID = 0;
Vanger 0:b86d15c6ba29 7128 resp->status = status;
Vanger 0:b86d15c6ba29 7129 resp->nonce = NULL;
Vanger 0:b86d15c6ba29 7130 resp->nonceSz = 0;
Vanger 0:b86d15c6ba29 7131 resp->source = source;
Vanger 0:b86d15c6ba29 7132 resp->maxIdx = inSz;
Vanger 0:b86d15c6ba29 7133 }
Vanger 0:b86d15c6ba29 7134
Vanger 0:b86d15c6ba29 7135
Vanger 0:b86d15c6ba29 7136 int OcspResponseDecode(OcspResponse* resp)
Vanger 0:b86d15c6ba29 7137 {
Vanger 0:b86d15c6ba29 7138 int length = 0;
Vanger 0:b86d15c6ba29 7139 word32 idx = 0;
Vanger 0:b86d15c6ba29 7140 byte* source = resp->source;
Vanger 0:b86d15c6ba29 7141 word32 size = resp->maxIdx;
Vanger 0:b86d15c6ba29 7142 word32 oid;
Vanger 0:b86d15c6ba29 7143
Vanger 0:b86d15c6ba29 7144 CYASSL_ENTER("OcspResponseDecode");
Vanger 0:b86d15c6ba29 7145
Vanger 0:b86d15c6ba29 7146 /* peel the outer SEQUENCE wrapper */
Vanger 0:b86d15c6ba29 7147 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7148 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7149
Vanger 0:b86d15c6ba29 7150 /* First get the responseStatus, an ENUMERATED */
Vanger 0:b86d15c6ba29 7151 if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
Vanger 0:b86d15c6ba29 7152 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7153
Vanger 0:b86d15c6ba29 7154 if (resp->responseStatus != OCSP_SUCCESSFUL)
Vanger 0:b86d15c6ba29 7155 return 0;
Vanger 0:b86d15c6ba29 7156
Vanger 0:b86d15c6ba29 7157 /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
Vanger 0:b86d15c6ba29 7158 if (idx >= size)
Vanger 0:b86d15c6ba29 7159 return ASN_INPUT_E;
Vanger 0:b86d15c6ba29 7160 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
Vanger 0:b86d15c6ba29 7161 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7162 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7163 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7164
Vanger 0:b86d15c6ba29 7165 /* Get the responseBytes SEQUENCE */
Vanger 0:b86d15c6ba29 7166 if (GetSequence(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7167 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7168
Vanger 0:b86d15c6ba29 7169 /* Check ObjectID for the resposeBytes */
Vanger 0:b86d15c6ba29 7170 if (GetObjectId(source, &idx, &oid, size) < 0)
Vanger 0:b86d15c6ba29 7171 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7172 if (oid != OCSP_BASIC_OID)
Vanger 0:b86d15c6ba29 7173 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7174 if (source[idx++] != ASN_OCTET_STRING)
Vanger 0:b86d15c6ba29 7175 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7176
Vanger 0:b86d15c6ba29 7177 if (GetLength(source, &idx, &length, size) < 0)
Vanger 0:b86d15c6ba29 7178 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7179
Vanger 0:b86d15c6ba29 7180 if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
Vanger 0:b86d15c6ba29 7181 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7182
Vanger 0:b86d15c6ba29 7183 return 0;
Vanger 0:b86d15c6ba29 7184 }
Vanger 0:b86d15c6ba29 7185
Vanger 0:b86d15c6ba29 7186
Vanger 0:b86d15c6ba29 7187 static word32 SetOcspReqExtensions(word32 extSz, byte* output,
Vanger 0:b86d15c6ba29 7188 const byte* nonce, word32 nonceSz)
Vanger 0:b86d15c6ba29 7189 {
Vanger 0:b86d15c6ba29 7190 static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
Vanger 0:b86d15c6ba29 7191 0x30, 0x01, 0x02 };
Vanger 0:b86d15c6ba29 7192 byte seqArray[5][MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 7193 word32 seqSz[5], totalSz;
Vanger 0:b86d15c6ba29 7194
Vanger 0:b86d15c6ba29 7195 CYASSL_ENTER("SetOcspReqExtensions");
Vanger 0:b86d15c6ba29 7196
Vanger 0:b86d15c6ba29 7197 if (nonce == NULL || nonceSz == 0) return 0;
Vanger 0:b86d15c6ba29 7198
Vanger 0:b86d15c6ba29 7199 seqArray[0][0] = ASN_OCTET_STRING;
Vanger 0:b86d15c6ba29 7200 seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
Vanger 0:b86d15c6ba29 7201
Vanger 0:b86d15c6ba29 7202 seqArray[1][0] = ASN_OBJECT_ID;
Vanger 0:b86d15c6ba29 7203 seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
Vanger 0:b86d15c6ba29 7204
Vanger 0:b86d15c6ba29 7205 totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
Vanger 0:b86d15c6ba29 7206
Vanger 0:b86d15c6ba29 7207 seqSz[2] = SetSequence(totalSz, seqArray[2]);
Vanger 0:b86d15c6ba29 7208 totalSz += seqSz[2];
Vanger 0:b86d15c6ba29 7209
Vanger 0:b86d15c6ba29 7210 seqSz[3] = SetSequence(totalSz, seqArray[3]);
Vanger 0:b86d15c6ba29 7211 totalSz += seqSz[3];
Vanger 0:b86d15c6ba29 7212
Vanger 0:b86d15c6ba29 7213 seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
Vanger 0:b86d15c6ba29 7214 seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
Vanger 0:b86d15c6ba29 7215 totalSz += seqSz[4];
Vanger 0:b86d15c6ba29 7216
Vanger 0:b86d15c6ba29 7217 if (totalSz < extSz)
Vanger 0:b86d15c6ba29 7218 {
Vanger 0:b86d15c6ba29 7219 totalSz = 0;
Vanger 0:b86d15c6ba29 7220 XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
Vanger 0:b86d15c6ba29 7221 totalSz += seqSz[4];
Vanger 0:b86d15c6ba29 7222 XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
Vanger 0:b86d15c6ba29 7223 totalSz += seqSz[3];
Vanger 0:b86d15c6ba29 7224 XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
Vanger 0:b86d15c6ba29 7225 totalSz += seqSz[2];
Vanger 0:b86d15c6ba29 7226 XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
Vanger 0:b86d15c6ba29 7227 totalSz += seqSz[1];
Vanger 0:b86d15c6ba29 7228 XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
Vanger 0:b86d15c6ba29 7229 totalSz += (word32)sizeof(NonceObjId);
Vanger 0:b86d15c6ba29 7230 XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
Vanger 0:b86d15c6ba29 7231 totalSz += seqSz[0];
Vanger 0:b86d15c6ba29 7232 XMEMCPY(output + totalSz, nonce, nonceSz);
Vanger 0:b86d15c6ba29 7233 totalSz += nonceSz;
Vanger 0:b86d15c6ba29 7234 }
Vanger 0:b86d15c6ba29 7235
Vanger 0:b86d15c6ba29 7236 return totalSz;
Vanger 0:b86d15c6ba29 7237 }
Vanger 0:b86d15c6ba29 7238
Vanger 0:b86d15c6ba29 7239
Vanger 0:b86d15c6ba29 7240 int EncodeOcspRequest(OcspRequest* req)
Vanger 0:b86d15c6ba29 7241 {
Vanger 0:b86d15c6ba29 7242 byte seqArray[5][MAX_SEQ_SZ];
Vanger 0:b86d15c6ba29 7243 /* The ASN.1 of the OCSP Request is an onion of sequences */
Vanger 0:b86d15c6ba29 7244 byte algoArray[MAX_ALGO_SZ];
Vanger 0:b86d15c6ba29 7245 byte issuerArray[MAX_ENCODED_DIG_SZ];
Vanger 0:b86d15c6ba29 7246 byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
Vanger 0:b86d15c6ba29 7247 byte snArray[MAX_SN_SZ];
Vanger 0:b86d15c6ba29 7248 byte extArray[MAX_OCSP_EXT_SZ];
Vanger 0:b86d15c6ba29 7249 byte* output = req->dest;
Vanger 0:b86d15c6ba29 7250 word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
Vanger 0:b86d15c6ba29 7251 int i;
Vanger 0:b86d15c6ba29 7252
Vanger 0:b86d15c6ba29 7253 CYASSL_ENTER("EncodeOcspRequest");
Vanger 0:b86d15c6ba29 7254
Vanger 0:b86d15c6ba29 7255 algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
Vanger 0:b86d15c6ba29 7256
Vanger 0:b86d15c6ba29 7257 req->issuerHash = req->cert->issuerHash;
Vanger 0:b86d15c6ba29 7258 issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray);
Vanger 0:b86d15c6ba29 7259
Vanger 0:b86d15c6ba29 7260 req->issuerKeyHash = req->cert->issuerKeyHash;
Vanger 0:b86d15c6ba29 7261 issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray);
Vanger 0:b86d15c6ba29 7262
Vanger 0:b86d15c6ba29 7263 req->serial = req->cert->serial;
Vanger 0:b86d15c6ba29 7264 req->serialSz = req->cert->serialSz;
Vanger 0:b86d15c6ba29 7265 snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
Vanger 0:b86d15c6ba29 7266
Vanger 0:b86d15c6ba29 7267 extSz = 0;
Vanger 0:b86d15c6ba29 7268 if (req->useNonce) {
Vanger 0:b86d15c6ba29 7269 RNG rng;
Vanger 0:b86d15c6ba29 7270 if (InitRng(&rng) != 0) {
Vanger 0:b86d15c6ba29 7271 CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
Vanger 0:b86d15c6ba29 7272 } else {
Vanger 0:b86d15c6ba29 7273 if (RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
Vanger 0:b86d15c6ba29 7274 CYASSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
Vanger 0:b86d15c6ba29 7275 else {
Vanger 0:b86d15c6ba29 7276 req->nonceSz = MAX_OCSP_NONCE_SZ;
Vanger 0:b86d15c6ba29 7277 extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
Vanger 0:b86d15c6ba29 7278 req->nonce, req->nonceSz);
Vanger 0:b86d15c6ba29 7279 }
Vanger 0:b86d15c6ba29 7280 }
Vanger 0:b86d15c6ba29 7281 }
Vanger 0:b86d15c6ba29 7282
Vanger 0:b86d15c6ba29 7283 totalSz = algoSz + issuerSz + issuerKeySz + snSz;
Vanger 0:b86d15c6ba29 7284
Vanger 0:b86d15c6ba29 7285 for (i = 4; i >= 0; i--) {
Vanger 0:b86d15c6ba29 7286 seqSz[i] = SetSequence(totalSz, seqArray[i]);
Vanger 0:b86d15c6ba29 7287 totalSz += seqSz[i];
Vanger 0:b86d15c6ba29 7288 if (i == 2) totalSz += extSz;
Vanger 0:b86d15c6ba29 7289 }
Vanger 0:b86d15c6ba29 7290 totalSz = 0;
Vanger 0:b86d15c6ba29 7291 for (i = 0; i < 5; i++) {
Vanger 0:b86d15c6ba29 7292 XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
Vanger 0:b86d15c6ba29 7293 totalSz += seqSz[i];
Vanger 0:b86d15c6ba29 7294 }
Vanger 0:b86d15c6ba29 7295 XMEMCPY(output + totalSz, algoArray, algoSz);
Vanger 0:b86d15c6ba29 7296 totalSz += algoSz;
Vanger 0:b86d15c6ba29 7297 XMEMCPY(output + totalSz, issuerArray, issuerSz);
Vanger 0:b86d15c6ba29 7298 totalSz += issuerSz;
Vanger 0:b86d15c6ba29 7299 XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
Vanger 0:b86d15c6ba29 7300 totalSz += issuerKeySz;
Vanger 0:b86d15c6ba29 7301 XMEMCPY(output + totalSz, snArray, snSz);
Vanger 0:b86d15c6ba29 7302 totalSz += snSz;
Vanger 0:b86d15c6ba29 7303 if (extSz != 0) {
Vanger 0:b86d15c6ba29 7304 XMEMCPY(output + totalSz, extArray, extSz);
Vanger 0:b86d15c6ba29 7305 totalSz += extSz;
Vanger 0:b86d15c6ba29 7306 }
Vanger 0:b86d15c6ba29 7307
Vanger 0:b86d15c6ba29 7308 return totalSz;
Vanger 0:b86d15c6ba29 7309 }
Vanger 0:b86d15c6ba29 7310
Vanger 0:b86d15c6ba29 7311
Vanger 0:b86d15c6ba29 7312 void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
Vanger 0:b86d15c6ba29 7313 byte* dest, word32 destSz)
Vanger 0:b86d15c6ba29 7314 {
Vanger 0:b86d15c6ba29 7315 CYASSL_ENTER("InitOcspRequest");
Vanger 0:b86d15c6ba29 7316
Vanger 0:b86d15c6ba29 7317 req->cert = cert;
Vanger 0:b86d15c6ba29 7318 req->useNonce = useNonce;
Vanger 0:b86d15c6ba29 7319 req->nonceSz = 0;
Vanger 0:b86d15c6ba29 7320 req->issuerHash = NULL;
Vanger 0:b86d15c6ba29 7321 req->issuerKeyHash = NULL;
Vanger 0:b86d15c6ba29 7322 req->serial = NULL;
Vanger 0:b86d15c6ba29 7323 req->dest = dest;
Vanger 0:b86d15c6ba29 7324 req->destSz = destSz;
Vanger 0:b86d15c6ba29 7325 }
Vanger 0:b86d15c6ba29 7326
Vanger 0:b86d15c6ba29 7327
Vanger 0:b86d15c6ba29 7328 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
Vanger 0:b86d15c6ba29 7329 {
Vanger 0:b86d15c6ba29 7330 int cmp;
Vanger 0:b86d15c6ba29 7331
Vanger 0:b86d15c6ba29 7332 CYASSL_ENTER("CompareOcspReqResp");
Vanger 0:b86d15c6ba29 7333
Vanger 0:b86d15c6ba29 7334 if (req == NULL)
Vanger 0:b86d15c6ba29 7335 {
Vanger 0:b86d15c6ba29 7336 CYASSL_MSG("\tReq missing");
Vanger 0:b86d15c6ba29 7337 return -1;
Vanger 0:b86d15c6ba29 7338 }
Vanger 0:b86d15c6ba29 7339
Vanger 0:b86d15c6ba29 7340 if (resp == NULL)
Vanger 0:b86d15c6ba29 7341 {
Vanger 0:b86d15c6ba29 7342 CYASSL_MSG("\tResp missing");
Vanger 0:b86d15c6ba29 7343 return 1;
Vanger 0:b86d15c6ba29 7344 }
Vanger 0:b86d15c6ba29 7345
Vanger 0:b86d15c6ba29 7346 /* Nonces are not critical. The responder may not necessarily add
Vanger 0:b86d15c6ba29 7347 * the nonce to the response. */
Vanger 0:b86d15c6ba29 7348 if (req->useNonce && resp->nonceSz != 0) {
Vanger 0:b86d15c6ba29 7349 cmp = req->nonceSz - resp->nonceSz;
Vanger 0:b86d15c6ba29 7350 if (cmp != 0)
Vanger 0:b86d15c6ba29 7351 {
Vanger 0:b86d15c6ba29 7352 CYASSL_MSG("\tnonceSz mismatch");
Vanger 0:b86d15c6ba29 7353 return cmp;
Vanger 0:b86d15c6ba29 7354 }
Vanger 0:b86d15c6ba29 7355
Vanger 0:b86d15c6ba29 7356 cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
Vanger 0:b86d15c6ba29 7357 if (cmp != 0)
Vanger 0:b86d15c6ba29 7358 {
Vanger 0:b86d15c6ba29 7359 CYASSL_MSG("\tnonce mismatch");
Vanger 0:b86d15c6ba29 7360 return cmp;
Vanger 0:b86d15c6ba29 7361 }
Vanger 0:b86d15c6ba29 7362 }
Vanger 0:b86d15c6ba29 7363
Vanger 0:b86d15c6ba29 7364 cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 7365 if (cmp != 0)
Vanger 0:b86d15c6ba29 7366 {
Vanger 0:b86d15c6ba29 7367 CYASSL_MSG("\tissuerHash mismatch");
Vanger 0:b86d15c6ba29 7368 return cmp;
Vanger 0:b86d15c6ba29 7369 }
Vanger 0:b86d15c6ba29 7370
Vanger 0:b86d15c6ba29 7371 cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE);
Vanger 0:b86d15c6ba29 7372 if (cmp != 0)
Vanger 0:b86d15c6ba29 7373 {
Vanger 0:b86d15c6ba29 7374 CYASSL_MSG("\tissuerKeyHash mismatch");
Vanger 0:b86d15c6ba29 7375 return cmp;
Vanger 0:b86d15c6ba29 7376 }
Vanger 0:b86d15c6ba29 7377
Vanger 0:b86d15c6ba29 7378 cmp = req->serialSz - resp->status->serialSz;
Vanger 0:b86d15c6ba29 7379 if (cmp != 0)
Vanger 0:b86d15c6ba29 7380 {
Vanger 0:b86d15c6ba29 7381 CYASSL_MSG("\tserialSz mismatch");
Vanger 0:b86d15c6ba29 7382 return cmp;
Vanger 0:b86d15c6ba29 7383 }
Vanger 0:b86d15c6ba29 7384
Vanger 0:b86d15c6ba29 7385 cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
Vanger 0:b86d15c6ba29 7386 if (cmp != 0)
Vanger 0:b86d15c6ba29 7387 {
Vanger 0:b86d15c6ba29 7388 CYASSL_MSG("\tserial mismatch");
Vanger 0:b86d15c6ba29 7389 return cmp;
Vanger 0:b86d15c6ba29 7390 }
Vanger 0:b86d15c6ba29 7391
Vanger 0:b86d15c6ba29 7392 return 0;
Vanger 0:b86d15c6ba29 7393 }
Vanger 0:b86d15c6ba29 7394
Vanger 0:b86d15c6ba29 7395 #endif
Vanger 0:b86d15c6ba29 7396
Vanger 0:b86d15c6ba29 7397
Vanger 0:b86d15c6ba29 7398 /* store SHA1 hash of NAME */
Vanger 0:b86d15c6ba29 7399 CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
Vanger 0:b86d15c6ba29 7400 int maxIdx)
Vanger 0:b86d15c6ba29 7401 {
Vanger 0:b86d15c6ba29 7402 Sha sha;
Vanger 0:b86d15c6ba29 7403 int length; /* length of all distinguished names */
Vanger 0:b86d15c6ba29 7404 int ret = 0;
Vanger 0:b86d15c6ba29 7405 word32 dummy;
Vanger 0:b86d15c6ba29 7406
Vanger 0:b86d15c6ba29 7407 CYASSL_ENTER("GetNameHash");
Vanger 0:b86d15c6ba29 7408
Vanger 0:b86d15c6ba29 7409 if (source[*idx] == ASN_OBJECT_ID) {
Vanger 0:b86d15c6ba29 7410 CYASSL_MSG("Trying optional prefix...");
Vanger 0:b86d15c6ba29 7411
Vanger 0:b86d15c6ba29 7412 if (GetLength(source, idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7413 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7414
Vanger 0:b86d15c6ba29 7415 *idx += length;
Vanger 0:b86d15c6ba29 7416 CYASSL_MSG("Got optional prefix");
Vanger 0:b86d15c6ba29 7417 }
Vanger 0:b86d15c6ba29 7418
Vanger 0:b86d15c6ba29 7419 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
Vanger 0:b86d15c6ba29 7420 * calculated over the entire DER encoding of the Name field, including
Vanger 0:b86d15c6ba29 7421 * the tag and length. */
Vanger 0:b86d15c6ba29 7422 dummy = *idx;
Vanger 0:b86d15c6ba29 7423 if (GetSequence(source, idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7424 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7425
Vanger 0:b86d15c6ba29 7426 ret = InitSha(&sha);
Vanger 0:b86d15c6ba29 7427 if (ret != 0)
Vanger 0:b86d15c6ba29 7428 return ret;
Vanger 0:b86d15c6ba29 7429 ShaUpdate(&sha, source + dummy, length + *idx - dummy);
Vanger 0:b86d15c6ba29 7430 ShaFinal(&sha, hash);
Vanger 0:b86d15c6ba29 7431
Vanger 0:b86d15c6ba29 7432 *idx += length;
Vanger 0:b86d15c6ba29 7433
Vanger 0:b86d15c6ba29 7434 return 0;
Vanger 0:b86d15c6ba29 7435 }
Vanger 0:b86d15c6ba29 7436
Vanger 0:b86d15c6ba29 7437
Vanger 0:b86d15c6ba29 7438 #ifdef HAVE_CRL
Vanger 0:b86d15c6ba29 7439
Vanger 0:b86d15c6ba29 7440 /* initialize decoded CRL */
Vanger 0:b86d15c6ba29 7441 void InitDecodedCRL(DecodedCRL* dcrl)
Vanger 0:b86d15c6ba29 7442 {
Vanger 0:b86d15c6ba29 7443 CYASSL_MSG("InitDecodedCRL");
Vanger 0:b86d15c6ba29 7444
Vanger 0:b86d15c6ba29 7445 dcrl->certBegin = 0;
Vanger 0:b86d15c6ba29 7446 dcrl->sigIndex = 0;
Vanger 0:b86d15c6ba29 7447 dcrl->sigLength = 0;
Vanger 0:b86d15c6ba29 7448 dcrl->signatureOID = 0;
Vanger 0:b86d15c6ba29 7449 dcrl->certs = NULL;
Vanger 0:b86d15c6ba29 7450 dcrl->totalCerts = 0;
Vanger 0:b86d15c6ba29 7451 }
Vanger 0:b86d15c6ba29 7452
Vanger 0:b86d15c6ba29 7453
Vanger 0:b86d15c6ba29 7454 /* free decoded CRL resources */
Vanger 0:b86d15c6ba29 7455 void FreeDecodedCRL(DecodedCRL* dcrl)
Vanger 0:b86d15c6ba29 7456 {
Vanger 0:b86d15c6ba29 7457 RevokedCert* tmp = dcrl->certs;
Vanger 0:b86d15c6ba29 7458
Vanger 0:b86d15c6ba29 7459 CYASSL_MSG("FreeDecodedCRL");
Vanger 0:b86d15c6ba29 7460
Vanger 0:b86d15c6ba29 7461 while(tmp) {
Vanger 0:b86d15c6ba29 7462 RevokedCert* next = tmp->next;
Vanger 0:b86d15c6ba29 7463 XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
Vanger 0:b86d15c6ba29 7464 tmp = next;
Vanger 0:b86d15c6ba29 7465 }
Vanger 0:b86d15c6ba29 7466 }
Vanger 0:b86d15c6ba29 7467
Vanger 0:b86d15c6ba29 7468
Vanger 0:b86d15c6ba29 7469 /* Get Revoked Cert list, 0 on success */
Vanger 0:b86d15c6ba29 7470 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
Vanger 0:b86d15c6ba29 7471 int maxIdx)
Vanger 0:b86d15c6ba29 7472 {
Vanger 0:b86d15c6ba29 7473 int len;
Vanger 0:b86d15c6ba29 7474 word32 end;
Vanger 0:b86d15c6ba29 7475 byte b;
Vanger 0:b86d15c6ba29 7476 RevokedCert* rc;
Vanger 0:b86d15c6ba29 7477
Vanger 0:b86d15c6ba29 7478 CYASSL_ENTER("GetRevoked");
Vanger 0:b86d15c6ba29 7479
Vanger 0:b86d15c6ba29 7480 if (GetSequence(buff, idx, &len, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7481 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7482
Vanger 0:b86d15c6ba29 7483 end = *idx + len;
Vanger 0:b86d15c6ba29 7484
Vanger 0:b86d15c6ba29 7485 /* get serial number */
Vanger 0:b86d15c6ba29 7486 b = buff[*idx];
Vanger 0:b86d15c6ba29 7487 *idx += 1;
Vanger 0:b86d15c6ba29 7488
Vanger 0:b86d15c6ba29 7489 if (b != ASN_INTEGER) {
Vanger 0:b86d15c6ba29 7490 CYASSL_MSG("Expecting Integer");
Vanger 0:b86d15c6ba29 7491 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7492 }
Vanger 0:b86d15c6ba29 7493
Vanger 0:b86d15c6ba29 7494 if (GetLength(buff, idx, &len, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7495 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7496
Vanger 0:b86d15c6ba29 7497 if (len > EXTERNAL_SERIAL_SIZE) {
Vanger 0:b86d15c6ba29 7498 CYASSL_MSG("Serial Size too big");
Vanger 0:b86d15c6ba29 7499 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7500 }
Vanger 0:b86d15c6ba29 7501
Vanger 0:b86d15c6ba29 7502 rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
Vanger 0:b86d15c6ba29 7503 if (rc == NULL) {
Vanger 0:b86d15c6ba29 7504 CYASSL_MSG("Alloc Revoked Cert failed");
Vanger 0:b86d15c6ba29 7505 return MEMORY_E;
Vanger 0:b86d15c6ba29 7506 }
Vanger 0:b86d15c6ba29 7507
Vanger 0:b86d15c6ba29 7508 XMEMCPY(rc->serialNumber, &buff[*idx], len);
Vanger 0:b86d15c6ba29 7509 rc->serialSz = len;
Vanger 0:b86d15c6ba29 7510
Vanger 0:b86d15c6ba29 7511 /* add to list */
Vanger 0:b86d15c6ba29 7512 rc->next = dcrl->certs;
Vanger 0:b86d15c6ba29 7513 dcrl->certs = rc;
Vanger 0:b86d15c6ba29 7514 dcrl->totalCerts++;
Vanger 0:b86d15c6ba29 7515
Vanger 0:b86d15c6ba29 7516 *idx += len;
Vanger 0:b86d15c6ba29 7517
Vanger 0:b86d15c6ba29 7518 /* get date */
Vanger 0:b86d15c6ba29 7519 b = buff[*idx];
Vanger 0:b86d15c6ba29 7520 *idx += 1;
Vanger 0:b86d15c6ba29 7521
Vanger 0:b86d15c6ba29 7522 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
Vanger 0:b86d15c6ba29 7523 CYASSL_MSG("Expecting Date");
Vanger 0:b86d15c6ba29 7524 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7525 }
Vanger 0:b86d15c6ba29 7526
Vanger 0:b86d15c6ba29 7527 if (GetLength(buff, idx, &len, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7528 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7529
Vanger 0:b86d15c6ba29 7530 /* skip for now */
Vanger 0:b86d15c6ba29 7531 *idx += len;
Vanger 0:b86d15c6ba29 7532
Vanger 0:b86d15c6ba29 7533 if (*idx != end) /* skip extensions */
Vanger 0:b86d15c6ba29 7534 *idx = end;
Vanger 0:b86d15c6ba29 7535
Vanger 0:b86d15c6ba29 7536 return 0;
Vanger 0:b86d15c6ba29 7537 }
Vanger 0:b86d15c6ba29 7538
Vanger 0:b86d15c6ba29 7539
Vanger 0:b86d15c6ba29 7540 /* Get CRL Signature, 0 on success */
Vanger 0:b86d15c6ba29 7541 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
Vanger 0:b86d15c6ba29 7542 int maxIdx)
Vanger 0:b86d15c6ba29 7543 {
Vanger 0:b86d15c6ba29 7544 int length;
Vanger 0:b86d15c6ba29 7545 byte b;
Vanger 0:b86d15c6ba29 7546
Vanger 0:b86d15c6ba29 7547 CYASSL_ENTER("GetCRL_Signature");
Vanger 0:b86d15c6ba29 7548
Vanger 0:b86d15c6ba29 7549 b = source[*idx];
Vanger 0:b86d15c6ba29 7550 *idx += 1;
Vanger 0:b86d15c6ba29 7551 if (b != ASN_BIT_STRING)
Vanger 0:b86d15c6ba29 7552 return ASN_BITSTR_E;
Vanger 0:b86d15c6ba29 7553
Vanger 0:b86d15c6ba29 7554 if (GetLength(source, idx, &length, maxIdx) < 0)
Vanger 0:b86d15c6ba29 7555 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7556
Vanger 0:b86d15c6ba29 7557 dcrl->sigLength = length;
Vanger 0:b86d15c6ba29 7558
Vanger 0:b86d15c6ba29 7559 b = source[*idx];
Vanger 0:b86d15c6ba29 7560 *idx += 1;
Vanger 0:b86d15c6ba29 7561 if (b != 0x00)
Vanger 0:b86d15c6ba29 7562 return ASN_EXPECT_0_E;
Vanger 0:b86d15c6ba29 7563
Vanger 0:b86d15c6ba29 7564 dcrl->sigLength--;
Vanger 0:b86d15c6ba29 7565 dcrl->signature = (byte*)&source[*idx];
Vanger 0:b86d15c6ba29 7566
Vanger 0:b86d15c6ba29 7567 *idx += dcrl->sigLength;
Vanger 0:b86d15c6ba29 7568
Vanger 0:b86d15c6ba29 7569 return 0;
Vanger 0:b86d15c6ba29 7570 }
Vanger 0:b86d15c6ba29 7571
Vanger 0:b86d15c6ba29 7572
Vanger 0:b86d15c6ba29 7573 /* prase crl buffer into decoded state, 0 on success */
Vanger 0:b86d15c6ba29 7574 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
Vanger 0:b86d15c6ba29 7575 {
Vanger 0:b86d15c6ba29 7576 int version, len;
Vanger 0:b86d15c6ba29 7577 word32 oid, idx = 0;
Vanger 0:b86d15c6ba29 7578 Signer* ca = NULL;
Vanger 0:b86d15c6ba29 7579
Vanger 0:b86d15c6ba29 7580 CYASSL_MSG("ParseCRL");
Vanger 0:b86d15c6ba29 7581
Vanger 0:b86d15c6ba29 7582 /* raw crl hash */
Vanger 0:b86d15c6ba29 7583 /* hash here if needed for optimized comparisons
Vanger 0:b86d15c6ba29 7584 * Sha sha;
Vanger 0:b86d15c6ba29 7585 * InitSha(&sha);
Vanger 0:b86d15c6ba29 7586 * ShaUpdate(&sha, buff, sz);
Vanger 0:b86d15c6ba29 7587 * ShaFinal(&sha, dcrl->crlHash); */
Vanger 0:b86d15c6ba29 7588
Vanger 0:b86d15c6ba29 7589 if (GetSequence(buff, &idx, &len, sz) < 0)
Vanger 0:b86d15c6ba29 7590 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7591
Vanger 0:b86d15c6ba29 7592 dcrl->certBegin = idx;
Vanger 0:b86d15c6ba29 7593
Vanger 0:b86d15c6ba29 7594 if (GetSequence(buff, &idx, &len, sz) < 0)
Vanger 0:b86d15c6ba29 7595 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7596 dcrl->sigIndex = len + idx;
Vanger 0:b86d15c6ba29 7597
Vanger 0:b86d15c6ba29 7598 /* may have version */
Vanger 0:b86d15c6ba29 7599 if (buff[idx] == ASN_INTEGER) {
Vanger 0:b86d15c6ba29 7600 if (GetMyVersion(buff, &idx, &version) < 0)
Vanger 0:b86d15c6ba29 7601 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7602 }
Vanger 0:b86d15c6ba29 7603
Vanger 0:b86d15c6ba29 7604 if (GetAlgoId(buff, &idx, &oid, sz) < 0)
Vanger 0:b86d15c6ba29 7605 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7606
Vanger 0:b86d15c6ba29 7607 if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
Vanger 0:b86d15c6ba29 7608 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7609
Vanger 0:b86d15c6ba29 7610 if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
Vanger 0:b86d15c6ba29 7611 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7612
Vanger 0:b86d15c6ba29 7613 if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
Vanger 0:b86d15c6ba29 7614 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7615
Vanger 0:b86d15c6ba29 7616 if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
Vanger 0:b86d15c6ba29 7617 CYASSL_MSG("CRL after date is no longer valid");
Vanger 0:b86d15c6ba29 7618 return ASN_AFTER_DATE_E;
Vanger 0:b86d15c6ba29 7619 }
Vanger 0:b86d15c6ba29 7620
Vanger 0:b86d15c6ba29 7621 if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
Vanger 0:b86d15c6ba29 7622 if (GetSequence(buff, &idx, &len, sz) < 0)
Vanger 0:b86d15c6ba29 7623 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7624
Vanger 0:b86d15c6ba29 7625 len += idx;
Vanger 0:b86d15c6ba29 7626
Vanger 0:b86d15c6ba29 7627 while (idx < (word32)len) {
Vanger 0:b86d15c6ba29 7628 if (GetRevoked(buff, &idx, dcrl, sz) < 0)
Vanger 0:b86d15c6ba29 7629 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7630 }
Vanger 0:b86d15c6ba29 7631 }
Vanger 0:b86d15c6ba29 7632
Vanger 0:b86d15c6ba29 7633 if (idx != dcrl->sigIndex)
Vanger 0:b86d15c6ba29 7634 idx = dcrl->sigIndex; /* skip extensions */
Vanger 0:b86d15c6ba29 7635
Vanger 0:b86d15c6ba29 7636 if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0)
Vanger 0:b86d15c6ba29 7637 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7638
Vanger 0:b86d15c6ba29 7639 if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
Vanger 0:b86d15c6ba29 7640 return ASN_PARSE_E;
Vanger 0:b86d15c6ba29 7641
Vanger 0:b86d15c6ba29 7642 /* openssl doesn't add skid by default for CRLs cause firefox chokes
Vanger 0:b86d15c6ba29 7643 we're not assuming it's available yet */
Vanger 0:b86d15c6ba29 7644 #if !defined(NO_SKID) && defined(CRL_SKID_READY)
Vanger 0:b86d15c6ba29 7645 if (dcrl->extAuthKeyIdSet)
Vanger 0:b86d15c6ba29 7646 ca = GetCA(cm, dcrl->extAuthKeyId);
Vanger 0:b86d15c6ba29 7647 if (ca == NULL)
Vanger 0:b86d15c6ba29 7648 ca = GetCAByName(cm, dcrl->issuerHash);
Vanger 0:b86d15c6ba29 7649 #else /* NO_SKID */
Vanger 0:b86d15c6ba29 7650 ca = GetCA(cm, dcrl->issuerHash);
Vanger 0:b86d15c6ba29 7651 #endif /* NO_SKID */
Vanger 0:b86d15c6ba29 7652 CYASSL_MSG("About to verify CRL signature");
Vanger 0:b86d15c6ba29 7653
Vanger 0:b86d15c6ba29 7654 if (ca) {
Vanger 0:b86d15c6ba29 7655 CYASSL_MSG("Found CRL issuer CA");
Vanger 0:b86d15c6ba29 7656 /* try to confirm/verify signature */
Vanger 0:b86d15c6ba29 7657 #ifndef IGNORE_KEY_EXTENSIONS
Vanger 0:b86d15c6ba29 7658 if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
Vanger 0:b86d15c6ba29 7659 CYASSL_MSG("CA cannot sign CRLs");
Vanger 0:b86d15c6ba29 7660 return ASN_CRL_NO_SIGNER_E;
Vanger 0:b86d15c6ba29 7661 }
Vanger 0:b86d15c6ba29 7662 #endif /* IGNORE_KEY_EXTENSIONS */
Vanger 0:b86d15c6ba29 7663 if (!ConfirmSignature(buff + dcrl->certBegin,
Vanger 0:b86d15c6ba29 7664 dcrl->sigIndex - dcrl->certBegin,
Vanger 0:b86d15c6ba29 7665 ca->publicKey, ca->pubKeySize, ca->keyOID,
Vanger 0:b86d15c6ba29 7666 dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
Vanger 0:b86d15c6ba29 7667 CYASSL_MSG("CRL Confirm signature failed");
Vanger 0:b86d15c6ba29 7668 return ASN_CRL_CONFIRM_E;
Vanger 0:b86d15c6ba29 7669 }
Vanger 0:b86d15c6ba29 7670 }
Vanger 0:b86d15c6ba29 7671 else {
Vanger 0:b86d15c6ba29 7672 CYASSL_MSG("Did NOT find CRL issuer CA");
Vanger 0:b86d15c6ba29 7673 return ASN_CRL_NO_SIGNER_E;
Vanger 0:b86d15c6ba29 7674 }
Vanger 0:b86d15c6ba29 7675
Vanger 0:b86d15c6ba29 7676 return 0;
Vanger 0:b86d15c6ba29 7677 }
Vanger 0:b86d15c6ba29 7678
Vanger 0:b86d15c6ba29 7679 #endif /* HAVE_CRL */
Vanger 0:b86d15c6ba29 7680 #endif
Vanger 0:b86d15c6ba29 7681
Vanger 0:b86d15c6ba29 7682 #ifdef CYASSL_SEP
Vanger 0:b86d15c6ba29 7683
Vanger 0:b86d15c6ba29 7684
Vanger 0:b86d15c6ba29 7685
Vanger 0:b86d15c6ba29 7686 #endif /* CYASSL_SEP */
Vanger 0:b86d15c6ba29 7687