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

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

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
3:b777bfcb1381
fix whitespace in sha512.c

Who changed what in which revision?

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