CyaSSL changed for NucleoF401RE board: implemented random and time functions for build. (Has trouble with wildcard domains like *.google.com, *.yahoo.com)

Fork of CyaSSL by wolf SSL

Committer:
Vanger
Date:
Wed Jan 14 22:07:14 2015 +0000
Revision:
4:e505054279ed
Parent:
0:1239e9b70ca2
Implemented some platform specific functions in the Cyassl library code: time functions, seed random functions, and also changed the settings.h file to define settings specific to the platform being used

Who changed what in which revision?

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