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

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

Committer:
Vanger
Date:
Mon Feb 09 22:41:21 2015 +0000
Revision:
2:dc991c4ab35e
Parent:
0:b86d15c6ba29
Child:
3:b777bfcb1381
Added define flags to remove date verification of certificates

Who changed what in which revision?

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