CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Committer:
toddouska
Date:
Sat Feb 05 01:09:17 2011 +0000
Revision:
0:5045d2638c29
Beta Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
toddouska 0:5045d2638c29 1 /* asn.c
toddouska 0:5045d2638c29 2 *
toddouska 0:5045d2638c29 3 * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
toddouska 0:5045d2638c29 4 *
toddouska 0:5045d2638c29 5 * This file is part of CyaSSL.
toddouska 0:5045d2638c29 6 *
toddouska 0:5045d2638c29 7 * CyaSSL is free software; you can redistribute it and/or modify
toddouska 0:5045d2638c29 8 * it under the terms of the GNU General Public License as published by
toddouska 0:5045d2638c29 9 * the Free Software Foundation; either version 2 of the License, or
toddouska 0:5045d2638c29 10 * (at your option) any later version.
toddouska 0:5045d2638c29 11 *
toddouska 0:5045d2638c29 12 * CyaSSL is distributed in the hope that it will be useful,
toddouska 0:5045d2638c29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
toddouska 0:5045d2638c29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
toddouska 0:5045d2638c29 15 * GNU General Public License for more details.
toddouska 0:5045d2638c29 16 *
toddouska 0:5045d2638c29 17 * You should have received a copy of the GNU General Public License
toddouska 0:5045d2638c29 18 * along with this program; if not, write to the Free Software
toddouska 0:5045d2638c29 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
toddouska 0:5045d2638c29 20 */
toddouska 0:5045d2638c29 21
toddouska 0:5045d2638c29 22
toddouska 0:5045d2638c29 23 #ifdef THREADX
toddouska 0:5045d2638c29 24 #include "os.h" /* dc_rtc_api needs */
toddouska 0:5045d2638c29 25 #include "dc_rtc_api.h" /* to get current time */
toddouska 0:5045d2638c29 26 #endif
toddouska 0:5045d2638c29 27 #include "asn.h"
toddouska 0:5045d2638c29 28 #include "coding.h"
toddouska 0:5045d2638c29 29 #include "ctc_sha.h"
toddouska 0:5045d2638c29 30 #include "ctc_md5.h"
toddouska 0:5045d2638c29 31 #include "error.h"
toddouska 0:5045d2638c29 32
toddouska 0:5045d2638c29 33 #ifdef HAVE_NTRU
toddouska 0:5045d2638c29 34 #include "crypto_ntru.h"
toddouska 0:5045d2638c29 35 #endif
toddouska 0:5045d2638c29 36
toddouska 0:5045d2638c29 37
toddouska 0:5045d2638c29 38 #ifdef _MSC_VER
toddouska 0:5045d2638c29 39 /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
toddouska 0:5045d2638c29 40 #pragma warning(disable: 4996)
toddouska 0:5045d2638c29 41 #endif
toddouska 0:5045d2638c29 42
toddouska 0:5045d2638c29 43
toddouska 0:5045d2638c29 44 #ifndef TRUE
toddouska 0:5045d2638c29 45 enum {
toddouska 0:5045d2638c29 46 FALSE = 0,
toddouska 0:5045d2638c29 47 TRUE = 1
toddouska 0:5045d2638c29 48 };
toddouska 0:5045d2638c29 49 #endif
toddouska 0:5045d2638c29 50
toddouska 0:5045d2638c29 51 enum {
toddouska 0:5045d2638c29 52 ISSUER = 0,
toddouska 0:5045d2638c29 53 SUBJECT = 1,
toddouska 0:5045d2638c29 54
toddouska 0:5045d2638c29 55 BEFORE = 0,
toddouska 0:5045d2638c29 56 AFTER = 1
toddouska 0:5045d2638c29 57 };
toddouska 0:5045d2638c29 58
toddouska 0:5045d2638c29 59
toddouska 0:5045d2638c29 60 #ifdef THREADX
toddouska 0:5045d2638c29 61 /* uses parital <time.h> structures */
toddouska 0:5045d2638c29 62 #define XTIME(tl) (0)
toddouska 0:5045d2638c29 63 #define XGMTIME(c) my_gmtime((c))
toddouska 0:5045d2638c29 64 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
toddouska 0:5045d2638c29 65 #elif defined(MICRIUM)
toddouska 0:5045d2638c29 66 #include <clk.h>
toddouska 0:5045d2638c29 67 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
toddouska 0:5045d2638c29 68 #define XVALIDATE_DATE(d, f, t) NetSecure_ValidDate((d), (f), (t))
toddouska 0:5045d2638c29 69 #else
toddouska 0:5045d2638c29 70 #define XVALIDATE_DATE(d, f, t) (0)
toddouska 0:5045d2638c29 71 #endif
toddouska 0:5045d2638c29 72 #define NO_TIME_H
toddouska 0:5045d2638c29 73 /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
toddouska 0:5045d2638c29 74 #elif defined(USER_TIME)
toddouska 0:5045d2638c29 75 /* no <time.h> strucutres used */
toddouska 0:5045d2638c29 76 #define NO_TIME_H
toddouska 0:5045d2638c29 77 /* user time, and gmtime compatible functions, there is a gmtime
toddouska 0:5045d2638c29 78 implementation here that WINCE uses, so really just need some ticks
toddouska 0:5045d2638c29 79 since the EPOCH
toddouska 0:5045d2638c29 80 */
toddouska 0:5045d2638c29 81 #else
toddouska 0:5045d2638c29 82 /* default */
toddouska 0:5045d2638c29 83 /* uses complete <time.h> facility */
toddouska 0:5045d2638c29 84 #include <time.h>
toddouska 0:5045d2638c29 85 #define XTIME(tl) time((tl))
toddouska 0:5045d2638c29 86 #define XGMTIME(c) gmtime((c))
toddouska 0:5045d2638c29 87 #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
toddouska 0:5045d2638c29 88 #endif
toddouska 0:5045d2638c29 89
toddouska 0:5045d2638c29 90
toddouska 0:5045d2638c29 91 #ifdef _WIN32_WCE
toddouska 0:5045d2638c29 92 /* no time() or gmtime() even though in time.h header?? */
toddouska 0:5045d2638c29 93
toddouska 0:5045d2638c29 94 #include <windows.h>
toddouska 0:5045d2638c29 95
toddouska 0:5045d2638c29 96
toddouska 0:5045d2638c29 97 time_t time(time_t* timer)
toddouska 0:5045d2638c29 98 {
toddouska 0:5045d2638c29 99 SYSTEMTIME sysTime;
toddouska 0:5045d2638c29 100 FILETIME fTime;
toddouska 0:5045d2638c29 101 ULARGE_INTEGER intTime;
toddouska 0:5045d2638c29 102 time_t localTime;
toddouska 0:5045d2638c29 103
toddouska 0:5045d2638c29 104 if (timer == NULL)
toddouska 0:5045d2638c29 105 timer = &localTime;
toddouska 0:5045d2638c29 106
toddouska 0:5045d2638c29 107 GetSystemTime(&sysTime);
toddouska 0:5045d2638c29 108 SystemTimeToFileTime(&sysTime, &fTime);
toddouska 0:5045d2638c29 109
toddouska 0:5045d2638c29 110 XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
toddouska 0:5045d2638c29 111 /* subtract EPOCH */
toddouska 0:5045d2638c29 112 intTime.QuadPart -= 0x19db1ded53e8000;
toddouska 0:5045d2638c29 113 /* to secs */
toddouska 0:5045d2638c29 114 intTime.QuadPart /= 10000000;
toddouska 0:5045d2638c29 115 *timer = (time_t)intTime.QuadPart;
toddouska 0:5045d2638c29 116
toddouska 0:5045d2638c29 117 return *timer;
toddouska 0:5045d2638c29 118 }
toddouska 0:5045d2638c29 119
toddouska 0:5045d2638c29 120
toddouska 0:5045d2638c29 121
toddouska 0:5045d2638c29 122 struct tm* gmtime(const time_t* timer)
toddouska 0:5045d2638c29 123 {
toddouska 0:5045d2638c29 124 #define YEAR0 1900
toddouska 0:5045d2638c29 125 #define EPOCH_YEAR 1970
toddouska 0:5045d2638c29 126 #define SECS_DAY (24L * 60L * 60L)
toddouska 0:5045d2638c29 127 #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
toddouska 0:5045d2638c29 128 #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
toddouska 0:5045d2638c29 129
toddouska 0:5045d2638c29 130 static const int _ytab[2][12] =
toddouska 0:5045d2638c29 131 {
toddouska 0:5045d2638c29 132 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
toddouska 0:5045d2638c29 133 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
toddouska 0:5045d2638c29 134 };
toddouska 0:5045d2638c29 135
toddouska 0:5045d2638c29 136 static struct tm st_time;
toddouska 0:5045d2638c29 137 struct tm* ret = &st_time;
toddouska 0:5045d2638c29 138 time_t time = *timer;
toddouska 0:5045d2638c29 139 unsigned long dayclock, dayno;
toddouska 0:5045d2638c29 140 int year = EPOCH_YEAR;
toddouska 0:5045d2638c29 141
toddouska 0:5045d2638c29 142 dayclock = (unsigned long)time % SECS_DAY;
toddouska 0:5045d2638c29 143 dayno = (unsigned long)time / SECS_DAY;
toddouska 0:5045d2638c29 144
toddouska 0:5045d2638c29 145 ret->tm_sec = dayclock % 60;
toddouska 0:5045d2638c29 146 ret->tm_min = (dayclock % 3600) / 60;
toddouska 0:5045d2638c29 147 ret->tm_hour = dayclock / 3600;
toddouska 0:5045d2638c29 148 ret->tm_wday = (dayno + 4) % 7; /* day 0 a Thursday */
toddouska 0:5045d2638c29 149
toddouska 0:5045d2638c29 150 while(dayno >= (unsigned long)YEARSIZE(year)) {
toddouska 0:5045d2638c29 151 dayno -= YEARSIZE(year);
toddouska 0:5045d2638c29 152 year++;
toddouska 0:5045d2638c29 153 }
toddouska 0:5045d2638c29 154
toddouska 0:5045d2638c29 155 ret->tm_year = year - YEAR0;
toddouska 0:5045d2638c29 156 ret->tm_yday = dayno;
toddouska 0:5045d2638c29 157 ret->tm_mon = 0;
toddouska 0:5045d2638c29 158
toddouska 0:5045d2638c29 159 while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
toddouska 0:5045d2638c29 160 dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
toddouska 0:5045d2638c29 161 ret->tm_mon++;
toddouska 0:5045d2638c29 162 }
toddouska 0:5045d2638c29 163
toddouska 0:5045d2638c29 164 ret->tm_mday = ++dayno;
toddouska 0:5045d2638c29 165 ret->tm_isdst = 0;
toddouska 0:5045d2638c29 166
toddouska 0:5045d2638c29 167 return ret;
toddouska 0:5045d2638c29 168 }
toddouska 0:5045d2638c29 169
toddouska 0:5045d2638c29 170 #endif /* _WIN32_WCE */
toddouska 0:5045d2638c29 171
toddouska 0:5045d2638c29 172
toddouska 0:5045d2638c29 173
toddouska 0:5045d2638c29 174 #ifdef THREADX
toddouska 0:5045d2638c29 175
toddouska 0:5045d2638c29 176 #define YEAR0 1900
toddouska 0:5045d2638c29 177
toddouska 0:5045d2638c29 178 struct tm* my_gmtime(const time_t* timer) /* has a gmtime() but hangs */
toddouska 0:5045d2638c29 179 {
toddouska 0:5045d2638c29 180 static struct tm st_time;
toddouska 0:5045d2638c29 181 struct tm* ret = &st_time;
toddouska 0:5045d2638c29 182
toddouska 0:5045d2638c29 183 DC_RTC_CALENDAR cal;
toddouska 0:5045d2638c29 184 dc_rtc_time_get(&cal, TRUE);
toddouska 0:5045d2638c29 185
toddouska 0:5045d2638c29 186 ret->tm_year = cal.year - YEAR0; /* gm starts at 1900 */
toddouska 0:5045d2638c29 187 ret->tm_mon = cal.month - 1; /* gm starts at 0 */
toddouska 0:5045d2638c29 188 ret->tm_mday = cal.day;
toddouska 0:5045d2638c29 189 ret->tm_hour = cal.hour;
toddouska 0:5045d2638c29 190 ret->tm_min = cal.minute;
toddouska 0:5045d2638c29 191 ret->tm_sec = cal.second;
toddouska 0:5045d2638c29 192
toddouska 0:5045d2638c29 193 return ret;
toddouska 0:5045d2638c29 194 }
toddouska 0:5045d2638c29 195
toddouska 0:5045d2638c29 196 #endif /* THREADX */
toddouska 0:5045d2638c29 197
toddouska 0:5045d2638c29 198
toddouska 0:5045d2638c29 199 static INLINE word32 btoi(byte b)
toddouska 0:5045d2638c29 200 {
toddouska 0:5045d2638c29 201 return b - 0x30;
toddouska 0:5045d2638c29 202 }
toddouska 0:5045d2638c29 203
toddouska 0:5045d2638c29 204
toddouska 0:5045d2638c29 205 /* two byte date/time, add to value */
toddouska 0:5045d2638c29 206 static INLINE void GetTime(int* value, const byte* date, int* idx)
toddouska 0:5045d2638c29 207 {
toddouska 0:5045d2638c29 208 int i = *idx;
toddouska 0:5045d2638c29 209
toddouska 0:5045d2638c29 210 *value += btoi(date[i++]) * 10;
toddouska 0:5045d2638c29 211 *value += btoi(date[i++]);
toddouska 0:5045d2638c29 212
toddouska 0:5045d2638c29 213 *idx = i;
toddouska 0:5045d2638c29 214 }
toddouska 0:5045d2638c29 215
toddouska 0:5045d2638c29 216
toddouska 0:5045d2638c29 217 #if defined(MICRIUM)
toddouska 0:5045d2638c29 218
toddouska 0:5045d2638c29 219 static int NetSecure_ValidDate(CPU_INT08U *date, CPU_INT08U format,
toddouska 0:5045d2638c29 220 CPU_INT08U dateType)
toddouska 0:5045d2638c29 221 {
toddouska 0:5045d2638c29 222 CLK_DATE_TIME cert_date_time;
toddouska 0:5045d2638c29 223 CLK_TS_SEC cert_ts_sec;
toddouska 0:5045d2638c29 224 CLK_TS_SEC local_ts_sec;
toddouska 0:5045d2638c29 225 CPU_INT32S i;
toddouska 0:5045d2638c29 226 CPU_INT32S val;
toddouska 0:5045d2638c29 227
toddouska 0:5045d2638c29 228 local_ts_sec = Clk_GetTS();
toddouska 0:5045d2638c29 229 XMEMSET(&cert_date_time, 0, sizeof(cert_date_time));
toddouska 0:5045d2638c29 230
toddouska 0:5045d2638c29 231 i = 0;
toddouska 0:5045d2638c29 232 if (format == ASN_UTC_TIME) {
toddouska 0:5045d2638c29 233 if (btoi(date[0]) >= 5)
toddouska 0:5045d2638c29 234 cert_date_time.Yr = 1900;
toddouska 0:5045d2638c29 235 else
toddouska 0:5045d2638c29 236 cert_date_time.Yr = 2000;
toddouska 0:5045d2638c29 237 }
toddouska 0:5045d2638c29 238 else { /* format == GENERALIZED_TIME */
toddouska 0:5045d2638c29 239 cert_date_time.Yr += btoi(date[i++]) * 1000;
toddouska 0:5045d2638c29 240 cert_date_time.Yr += btoi(date[i++]) * 100;
toddouska 0:5045d2638c29 241 }
toddouska 0:5045d2638c29 242
toddouska 0:5045d2638c29 243 val = cert_date_time.Yr;
toddouska 0:5045d2638c29 244 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 245 cert_date_time.Yr = (CLK_YR)val;
toddouska 0:5045d2638c29 246
toddouska 0:5045d2638c29 247 val = 0;
toddouska 0:5045d2638c29 248 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 249 cert_date_time.Month = (CLK_MONTH)val;
toddouska 0:5045d2638c29 250
toddouska 0:5045d2638c29 251 val = 0;
toddouska 0:5045d2638c29 252 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 253 cert_date_time.Day = (CLK_DAY)val;
toddouska 0:5045d2638c29 254
toddouska 0:5045d2638c29 255 val = 0;
toddouska 0:5045d2638c29 256 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 257 cert_date_time.Hr = (CLK_HR)val;
toddouska 0:5045d2638c29 258
toddouska 0:5045d2638c29 259 val = 0;
toddouska 0:5045d2638c29 260 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 261 cert_date_time.Min = (CLK_MIN)val;
toddouska 0:5045d2638c29 262
toddouska 0:5045d2638c29 263 val = 0;
toddouska 0:5045d2638c29 264 GetTime(&val, date, &i);
toddouska 0:5045d2638c29 265 cert_date_time.Sec = (CLK_SEC)val;
toddouska 0:5045d2638c29 266
toddouska 0:5045d2638c29 267 if (date[i] != 'Z') /* only Zulu supported for this profile */
toddouska 0:5045d2638c29 268 return 0;
toddouska 0:5045d2638c29 269
toddouska 0:5045d2638c29 270 cert_date_time.DayOfWk = 1;
toddouska 0:5045d2638c29 271 cert_date_time.DayOfYr = 1;
toddouska 0:5045d2638c29 272 Clk_DateTimeToTS(&cert_ts_sec, &cert_date_time);
toddouska 0:5045d2638c29 273
toddouska 0:5045d2638c29 274
toddouska 0:5045d2638c29 275 if (dateType == BEFORE) {
toddouska 0:5045d2638c29 276 if (local_ts_sec < cert_ts_sec) /* If cert creation date after
toddouska 0:5045d2638c29 277 current date... */
toddouska 0:5045d2638c29 278 return (DEF_FAIL); /* ... report an error. */
toddouska 0:5045d2638c29 279 } else {
toddouska 0:5045d2638c29 280 if (local_ts_sec > cert_ts_sec) /* If cert expiration date before
toddouska 0:5045d2638c29 281 current date... */
toddouska 0:5045d2638c29 282 return (DEF_FAIL); /* ... report an error. */
toddouska 0:5045d2638c29 283 }
toddouska 0:5045d2638c29 284
toddouska 0:5045d2638c29 285 return (DEF_OK);
toddouska 0:5045d2638c29 286 }
toddouska 0:5045d2638c29 287
toddouska 0:5045d2638c29 288 #endif /* MICRIUM */
toddouska 0:5045d2638c29 289
toddouska 0:5045d2638c29 290
toddouska 0:5045d2638c29 291 int GetLength(const byte* input, word32* inOutIdx, int* len)
toddouska 0:5045d2638c29 292 {
toddouska 0:5045d2638c29 293 int length = 0;
toddouska 0:5045d2638c29 294 word32 i = *inOutIdx;
toddouska 0:5045d2638c29 295
toddouska 0:5045d2638c29 296 byte b = input[i++];
toddouska 0:5045d2638c29 297 if (b >= ASN_LONG_LENGTH) {
toddouska 0:5045d2638c29 298 word32 bytes = b & 0x7F;
toddouska 0:5045d2638c29 299
toddouska 0:5045d2638c29 300 while (bytes--) {
toddouska 0:5045d2638c29 301 b = input[i++];
toddouska 0:5045d2638c29 302 length = (length << 8) | b;
toddouska 0:5045d2638c29 303 }
toddouska 0:5045d2638c29 304 }
toddouska 0:5045d2638c29 305 else
toddouska 0:5045d2638c29 306 length = b;
toddouska 0:5045d2638c29 307
toddouska 0:5045d2638c29 308 *inOutIdx = i;
toddouska 0:5045d2638c29 309 *len = length;
toddouska 0:5045d2638c29 310
toddouska 0:5045d2638c29 311 return length;
toddouska 0:5045d2638c29 312 }
toddouska 0:5045d2638c29 313
toddouska 0:5045d2638c29 314
toddouska 0:5045d2638c29 315 int GetSequence(const byte* input, word32* inOutIdx, int* len)
toddouska 0:5045d2638c29 316 {
toddouska 0:5045d2638c29 317 int length = -1;
toddouska 0:5045d2638c29 318 word32 idx = *inOutIdx;
toddouska 0:5045d2638c29 319
toddouska 0:5045d2638c29 320 if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
toddouska 0:5045d2638c29 321 GetLength(input, &idx, &length) < 0)
toddouska 0:5045d2638c29 322 return ASN_PARSE_E;
toddouska 0:5045d2638c29 323
toddouska 0:5045d2638c29 324 *len = length;
toddouska 0:5045d2638c29 325 *inOutIdx = idx;
toddouska 0:5045d2638c29 326
toddouska 0:5045d2638c29 327 return length;
toddouska 0:5045d2638c29 328 }
toddouska 0:5045d2638c29 329
toddouska 0:5045d2638c29 330
toddouska 0:5045d2638c29 331 int GetSet(const byte* input, word32* inOutIdx, int* len)
toddouska 0:5045d2638c29 332 {
toddouska 0:5045d2638c29 333 int length = -1;
toddouska 0:5045d2638c29 334 word32 idx = *inOutIdx;
toddouska 0:5045d2638c29 335
toddouska 0:5045d2638c29 336 if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
toddouska 0:5045d2638c29 337 GetLength(input, &idx, &length) < 0)
toddouska 0:5045d2638c29 338 return ASN_PARSE_E;
toddouska 0:5045d2638c29 339
toddouska 0:5045d2638c29 340 *len = length;
toddouska 0:5045d2638c29 341 *inOutIdx = idx;
toddouska 0:5045d2638c29 342
toddouska 0:5045d2638c29 343 return length;
toddouska 0:5045d2638c29 344 }
toddouska 0:5045d2638c29 345
toddouska 0:5045d2638c29 346
toddouska 0:5045d2638c29 347 /* winodws header clash for WinCE using GetVersion */
toddouska 0:5045d2638c29 348 int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
toddouska 0:5045d2638c29 349 {
toddouska 0:5045d2638c29 350 word32 idx = *inOutIdx;
toddouska 0:5045d2638c29 351
toddouska 0:5045d2638c29 352 if (input[idx++] != ASN_INTEGER)
toddouska 0:5045d2638c29 353 return ASN_PARSE_E;
toddouska 0:5045d2638c29 354
toddouska 0:5045d2638c29 355 if (input[idx++] != 0x01)
toddouska 0:5045d2638c29 356 return ASN_VERSION_E;
toddouska 0:5045d2638c29 357
toddouska 0:5045d2638c29 358 *version = input[idx++];
toddouska 0:5045d2638c29 359 *inOutIdx = idx;
toddouska 0:5045d2638c29 360
toddouska 0:5045d2638c29 361 return *version;
toddouska 0:5045d2638c29 362 }
toddouska 0:5045d2638c29 363
toddouska 0:5045d2638c29 364
toddouska 0:5045d2638c29 365 /* May not have one, not an error */
toddouska 0:5045d2638c29 366 int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
toddouska 0:5045d2638c29 367 {
toddouska 0:5045d2638c29 368 word32 idx = *inOutIdx;
toddouska 0:5045d2638c29 369
toddouska 0:5045d2638c29 370 if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
toddouska 0:5045d2638c29 371 *inOutIdx = ++idx; /* eat header */
toddouska 0:5045d2638c29 372 return GetMyVersion(input, inOutIdx, version);
toddouska 0:5045d2638c29 373 }
toddouska 0:5045d2638c29 374
toddouska 0:5045d2638c29 375 /* go back as is */
toddouska 0:5045d2638c29 376 *version = 0;
toddouska 0:5045d2638c29 377
toddouska 0:5045d2638c29 378 return 0;
toddouska 0:5045d2638c29 379 }
toddouska 0:5045d2638c29 380
toddouska 0:5045d2638c29 381
toddouska 0:5045d2638c29 382 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx )
toddouska 0:5045d2638c29 383 {
toddouska 0:5045d2638c29 384 word32 i = *inOutIdx;
toddouska 0:5045d2638c29 385 byte b = input[i++];
toddouska 0:5045d2638c29 386 int length;
toddouska 0:5045d2638c29 387
toddouska 0:5045d2638c29 388 if (b != ASN_INTEGER)
toddouska 0:5045d2638c29 389 return ASN_PARSE_E;
toddouska 0:5045d2638c29 390
toddouska 0:5045d2638c29 391 if (GetLength(input, &i, &length) < 0)
toddouska 0:5045d2638c29 392 return ASN_PARSE_E;
toddouska 0:5045d2638c29 393
toddouska 0:5045d2638c29 394 if ( (b = input[i++]) == 0x00)
toddouska 0:5045d2638c29 395 length--;
toddouska 0:5045d2638c29 396 else
toddouska 0:5045d2638c29 397 i--;
toddouska 0:5045d2638c29 398
toddouska 0:5045d2638c29 399 mp_init(mpi);
toddouska 0:5045d2638c29 400 if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) {
toddouska 0:5045d2638c29 401 mp_clear(mpi);
toddouska 0:5045d2638c29 402 return ASN_GETINT_E;
toddouska 0:5045d2638c29 403 }
toddouska 0:5045d2638c29 404
toddouska 0:5045d2638c29 405 *inOutIdx = i + length;
toddouska 0:5045d2638c29 406 return 0;
toddouska 0:5045d2638c29 407 }
toddouska 0:5045d2638c29 408
toddouska 0:5045d2638c29 409
toddouska 0:5045d2638c29 410 static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid)
toddouska 0:5045d2638c29 411 {
toddouska 0:5045d2638c29 412 int length;
toddouska 0:5045d2638c29 413 word32 i = *inOutIdx;
toddouska 0:5045d2638c29 414 byte b;
toddouska 0:5045d2638c29 415 *oid = 0;
toddouska 0:5045d2638c29 416
toddouska 0:5045d2638c29 417 if (GetSequence(input, &i, &length) < 0)
toddouska 0:5045d2638c29 418 return ASN_PARSE_E;
toddouska 0:5045d2638c29 419
toddouska 0:5045d2638c29 420 b = input[i++];
toddouska 0:5045d2638c29 421 if (b != ASN_OBJECT_ID)
toddouska 0:5045d2638c29 422 return ASN_OBJECT_ID_E;
toddouska 0:5045d2638c29 423
toddouska 0:5045d2638c29 424 if (GetLength(input, &i, &length) < 0)
toddouska 0:5045d2638c29 425 return ASN_PARSE_E;
toddouska 0:5045d2638c29 426
toddouska 0:5045d2638c29 427 while(length--)
toddouska 0:5045d2638c29 428 *oid += input[i++];
toddouska 0:5045d2638c29 429 /* just sum it up for now */
toddouska 0:5045d2638c29 430
toddouska 0:5045d2638c29 431 /* could have NULL tag and 0 terminator, but may not */
toddouska 0:5045d2638c29 432 b = input[i++];
toddouska 0:5045d2638c29 433
toddouska 0:5045d2638c29 434 if (b == ASN_TAG_NULL) {
toddouska 0:5045d2638c29 435 b = input[i++];
toddouska 0:5045d2638c29 436 if (b != 0)
toddouska 0:5045d2638c29 437 return ASN_EXPECT_0_E;
toddouska 0:5045d2638c29 438 }
toddouska 0:5045d2638c29 439 else
toddouska 0:5045d2638c29 440 /* go back, didn't have it */
toddouska 0:5045d2638c29 441 i--;
toddouska 0:5045d2638c29 442
toddouska 0:5045d2638c29 443 *inOutIdx = i;
toddouska 0:5045d2638c29 444
toddouska 0:5045d2638c29 445 return 0;
toddouska 0:5045d2638c29 446 }
toddouska 0:5045d2638c29 447
toddouska 0:5045d2638c29 448
toddouska 0:5045d2638c29 449 int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
toddouska 0:5045d2638c29 450 word32 inSz)
toddouska 0:5045d2638c29 451 {
toddouska 0:5045d2638c29 452 word32 begin = *inOutIdx;
toddouska 0:5045d2638c29 453 int version, length;
toddouska 0:5045d2638c29 454
toddouska 0:5045d2638c29 455 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 456 return ASN_PARSE_E;
toddouska 0:5045d2638c29 457
toddouska 0:5045d2638c29 458 if ((word32)length > (inSz - (*inOutIdx - begin)))
toddouska 0:5045d2638c29 459 return ASN_INPUT_E;
toddouska 0:5045d2638c29 460
toddouska 0:5045d2638c29 461 if (GetMyVersion(input, inOutIdx, &version) < 0)
toddouska 0:5045d2638c29 462 return ASN_PARSE_E;
toddouska 0:5045d2638c29 463
toddouska 0:5045d2638c29 464 key->type = RSA_PRIVATE;
toddouska 0:5045d2638c29 465
toddouska 0:5045d2638c29 466 if (GetInt(&key->n, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 467 GetInt(&key->e, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 468 GetInt(&key->d, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 469 GetInt(&key->p, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 470 GetInt(&key->q, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 471 GetInt(&key->dP, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 472 GetInt(&key->dQ, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 473 GetInt(&key->u, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E;
toddouska 0:5045d2638c29 474
toddouska 0:5045d2638c29 475 return 0;
toddouska 0:5045d2638c29 476 }
toddouska 0:5045d2638c29 477
toddouska 0:5045d2638c29 478
toddouska 0:5045d2638c29 479 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
toddouska 0:5045d2638c29 480 int ToTraditional(byte* input, word32 sz)
toddouska 0:5045d2638c29 481 {
toddouska 0:5045d2638c29 482 word32 inOutIdx = 0, oid;
toddouska 0:5045d2638c29 483 int version, length;
toddouska 0:5045d2638c29 484
toddouska 0:5045d2638c29 485 if (GetSequence(input, &inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 486 return ASN_PARSE_E;
toddouska 0:5045d2638c29 487
toddouska 0:5045d2638c29 488 if ((word32)length > (sz - inOutIdx))
toddouska 0:5045d2638c29 489 return ASN_INPUT_E;
toddouska 0:5045d2638c29 490
toddouska 0:5045d2638c29 491 if (GetMyVersion(input, &inOutIdx, &version) < 0)
toddouska 0:5045d2638c29 492 return ASN_PARSE_E;
toddouska 0:5045d2638c29 493
toddouska 0:5045d2638c29 494 if (GetAlgoId(input, &inOutIdx, &oid) < 0)
toddouska 0:5045d2638c29 495 return ASN_PARSE_E;
toddouska 0:5045d2638c29 496
toddouska 0:5045d2638c29 497 if (input[inOutIdx++] != ASN_OCTET_STRING)
toddouska 0:5045d2638c29 498 return ASN_PARSE_E;
toddouska 0:5045d2638c29 499
toddouska 0:5045d2638c29 500 if (GetLength(input, &inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 501 return ASN_PARSE_E;
toddouska 0:5045d2638c29 502
toddouska 0:5045d2638c29 503 if ((word32)length > (sz - inOutIdx))
toddouska 0:5045d2638c29 504 return ASN_INPUT_E;
toddouska 0:5045d2638c29 505
toddouska 0:5045d2638c29 506 XMEMMOVE(input, input + inOutIdx, length);
toddouska 0:5045d2638c29 507
toddouska 0:5045d2638c29 508 return 0;
toddouska 0:5045d2638c29 509 }
toddouska 0:5045d2638c29 510
toddouska 0:5045d2638c29 511
toddouska 0:5045d2638c29 512 int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
toddouska 0:5045d2638c29 513 word32 inSz)
toddouska 0:5045d2638c29 514 {
toddouska 0:5045d2638c29 515 word32 begin = *inOutIdx;
toddouska 0:5045d2638c29 516 int length;
toddouska 0:5045d2638c29 517 byte b;
toddouska 0:5045d2638c29 518
toddouska 0:5045d2638c29 519 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 520 return ASN_PARSE_E;
toddouska 0:5045d2638c29 521
toddouska 0:5045d2638c29 522 if ((word32)length > (inSz - (*inOutIdx - begin)))
toddouska 0:5045d2638c29 523 return ASN_INPUT_E;
toddouska 0:5045d2638c29 524
toddouska 0:5045d2638c29 525 key->type = RSA_PUBLIC;
toddouska 0:5045d2638c29 526 b = input[*inOutIdx];
toddouska 0:5045d2638c29 527
toddouska 0:5045d2638c29 528 #ifdef OPENSSL_EXTRA
toddouska 0:5045d2638c29 529 if (b != ASN_INTEGER) {
toddouska 0:5045d2638c29 530 /* not from decoded cert, will have algo id, skip past */
toddouska 0:5045d2638c29 531 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 532 return ASN_PARSE_E;
toddouska 0:5045d2638c29 533
toddouska 0:5045d2638c29 534 b = input[(*inOutIdx)++];
toddouska 0:5045d2638c29 535 if (b != ASN_OBJECT_ID)
toddouska 0:5045d2638c29 536 return ASN_OBJECT_ID_E;
toddouska 0:5045d2638c29 537
toddouska 0:5045d2638c29 538 if (GetLength(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 539 return ASN_PARSE_E;
toddouska 0:5045d2638c29 540
toddouska 0:5045d2638c29 541 *inOutIdx += length; /* skip past */
toddouska 0:5045d2638c29 542
toddouska 0:5045d2638c29 543 /* could have NULL tag and 0 terminator, but may not */
toddouska 0:5045d2638c29 544 b = input[(*inOutIdx)++];
toddouska 0:5045d2638c29 545
toddouska 0:5045d2638c29 546 if (b == ASN_TAG_NULL) {
toddouska 0:5045d2638c29 547 b = input[(*inOutIdx)++];
toddouska 0:5045d2638c29 548 if (b != 0)
toddouska 0:5045d2638c29 549 return ASN_EXPECT_0_E;
toddouska 0:5045d2638c29 550 }
toddouska 0:5045d2638c29 551 else
toddouska 0:5045d2638c29 552 /* go back, didn't have it */
toddouska 0:5045d2638c29 553 (*inOutIdx)--;
toddouska 0:5045d2638c29 554
toddouska 0:5045d2638c29 555 /* should have bit tag length and seq next */
toddouska 0:5045d2638c29 556 b = input[(*inOutIdx)++];
toddouska 0:5045d2638c29 557 if (b != ASN_BIT_STRING)
toddouska 0:5045d2638c29 558 return ASN_BITSTR_E;
toddouska 0:5045d2638c29 559
toddouska 0:5045d2638c29 560 if (GetLength(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 561 return ASN_PARSE_E;
toddouska 0:5045d2638c29 562
toddouska 0:5045d2638c29 563 /* could have 0 */
toddouska 0:5045d2638c29 564 b = input[(*inOutIdx)++];
toddouska 0:5045d2638c29 565 if (b != 0)
toddouska 0:5045d2638c29 566 (*inOutIdx)--;
toddouska 0:5045d2638c29 567
toddouska 0:5045d2638c29 568 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 569 return ASN_PARSE_E;
toddouska 0:5045d2638c29 570 }
toddouska 0:5045d2638c29 571 #endif /* OPENSSL_EXTRA */
toddouska 0:5045d2638c29 572
toddouska 0:5045d2638c29 573 if (GetInt(&key->n, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 574 GetInt(&key->e, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E;
toddouska 0:5045d2638c29 575
toddouska 0:5045d2638c29 576 return 0;
toddouska 0:5045d2638c29 577 }
toddouska 0:5045d2638c29 578
toddouska 0:5045d2638c29 579
toddouska 0:5045d2638c29 580 #ifndef NO_DH
toddouska 0:5045d2638c29 581
toddouska 0:5045d2638c29 582 int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
toddouska 0:5045d2638c29 583 {
toddouska 0:5045d2638c29 584 word32 begin = *inOutIdx;
toddouska 0:5045d2638c29 585 int length;
toddouska 0:5045d2638c29 586
toddouska 0:5045d2638c29 587 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 588 return ASN_PARSE_E;
toddouska 0:5045d2638c29 589
toddouska 0:5045d2638c29 590 if ((word32)length > (inSz - (*inOutIdx - begin)))
toddouska 0:5045d2638c29 591 return ASN_INPUT_E;
toddouska 0:5045d2638c29 592
toddouska 0:5045d2638c29 593 if (GetInt(&key->p, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 594 GetInt(&key->g, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
toddouska 0:5045d2638c29 595
toddouska 0:5045d2638c29 596 return 0;
toddouska 0:5045d2638c29 597 }
toddouska 0:5045d2638c29 598
toddouska 0:5045d2638c29 599 int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
toddouska 0:5045d2638c29 600 {
toddouska 0:5045d2638c29 601 /* may have leading 0 */
toddouska 0:5045d2638c29 602 if (p[0] == 0) {
toddouska 0:5045d2638c29 603 pSz--; p++;
toddouska 0:5045d2638c29 604 }
toddouska 0:5045d2638c29 605
toddouska 0:5045d2638c29 606 if (g[0] == 0) {
toddouska 0:5045d2638c29 607 gSz--; g++;
toddouska 0:5045d2638c29 608 }
toddouska 0:5045d2638c29 609
toddouska 0:5045d2638c29 610 mp_init(&key->p);
toddouska 0:5045d2638c29 611 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
toddouska 0:5045d2638c29 612 mp_clear(&key->p);
toddouska 0:5045d2638c29 613 return ASN_DH_KEY_E;
toddouska 0:5045d2638c29 614 }
toddouska 0:5045d2638c29 615
toddouska 0:5045d2638c29 616 mp_init(&key->g);
toddouska 0:5045d2638c29 617 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
toddouska 0:5045d2638c29 618 mp_clear(&key->p);
toddouska 0:5045d2638c29 619 return ASN_DH_KEY_E;
toddouska 0:5045d2638c29 620 }
toddouska 0:5045d2638c29 621
toddouska 0:5045d2638c29 622 return 0;
toddouska 0:5045d2638c29 623 }
toddouska 0:5045d2638c29 624
toddouska 0:5045d2638c29 625
toddouska 0:5045d2638c29 626 #endif /* NO_DH */
toddouska 0:5045d2638c29 627
toddouska 0:5045d2638c29 628
toddouska 0:5045d2638c29 629 #ifndef NO_DSA
toddouska 0:5045d2638c29 630
toddouska 0:5045d2638c29 631 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
toddouska 0:5045d2638c29 632 word32 inSz)
toddouska 0:5045d2638c29 633 {
toddouska 0:5045d2638c29 634 word32 begin = *inOutIdx;
toddouska 0:5045d2638c29 635 int length;
toddouska 0:5045d2638c29 636
toddouska 0:5045d2638c29 637 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 638 return ASN_PARSE_E;
toddouska 0:5045d2638c29 639
toddouska 0:5045d2638c29 640 if ((word32)length > (inSz - (*inOutIdx - begin)))
toddouska 0:5045d2638c29 641 return ASN_INPUT_E;
toddouska 0:5045d2638c29 642
toddouska 0:5045d2638c29 643 if (GetInt(&key->p, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 644 GetInt(&key->q, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 645 GetInt(&key->g, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 646 GetInt(&key->y, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
toddouska 0:5045d2638c29 647
toddouska 0:5045d2638c29 648 key->type = DSA_PUBLIC;
toddouska 0:5045d2638c29 649 return 0;
toddouska 0:5045d2638c29 650 }
toddouska 0:5045d2638c29 651
toddouska 0:5045d2638c29 652
toddouska 0:5045d2638c29 653 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
toddouska 0:5045d2638c29 654 word32 inSz)
toddouska 0:5045d2638c29 655 {
toddouska 0:5045d2638c29 656 word32 begin = *inOutIdx;
toddouska 0:5045d2638c29 657 int length, version;
toddouska 0:5045d2638c29 658
toddouska 0:5045d2638c29 659 if (GetSequence(input, inOutIdx, &length) < 0)
toddouska 0:5045d2638c29 660 return ASN_PARSE_E;
toddouska 0:5045d2638c29 661
toddouska 0:5045d2638c29 662 if ((word32)length > (inSz - (*inOutIdx - begin)))
toddouska 0:5045d2638c29 663 return ASN_INPUT_E;
toddouska 0:5045d2638c29 664
toddouska 0:5045d2638c29 665 if (GetMyVersion(input, inOutIdx, &version) < 0)
toddouska 0:5045d2638c29 666 return ASN_PARSE_E;
toddouska 0:5045d2638c29 667
toddouska 0:5045d2638c29 668 if (GetInt(&key->p, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 669 GetInt(&key->q, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 670 GetInt(&key->g, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 671 GetInt(&key->y, input, inOutIdx) < 0 ||
toddouska 0:5045d2638c29 672 GetInt(&key->x, input, inOutIdx) < 0 ) return ASN_DH_KEY_E;
toddouska 0:5045d2638c29 673
toddouska 0:5045d2638c29 674 key->type = DSA_PRIVATE;
toddouska 0:5045d2638c29 675 return 0;
toddouska 0:5045d2638c29 676 }
toddouska 0:5045d2638c29 677
toddouska 0:5045d2638c29 678 #endif /* NO_DSA */
toddouska 0:5045d2638c29 679
toddouska 0:5045d2638c29 680
toddouska 0:5045d2638c29 681 void InitDecodedCert(DecodedCert* cert, byte* source, void* heap)
toddouska 0:5045d2638c29 682 {
toddouska 0:5045d2638c29 683 cert->publicKey = 0;
toddouska 0:5045d2638c29 684 cert->pubKeyStored = 0;
toddouska 0:5045d2638c29 685 cert->signature = 0;
toddouska 0:5045d2638c29 686 cert->subjectCN = 0;
toddouska 0:5045d2638c29 687 cert->subjectCNLen = 0;
toddouska 0:5045d2638c29 688 cert->source = source; /* don't own */
toddouska 0:5045d2638c29 689 cert->srcIdx = 0;
toddouska 0:5045d2638c29 690 cert->heap = heap;
toddouska 0:5045d2638c29 691 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 692 cert->subjectSN = 0;
toddouska 0:5045d2638c29 693 cert->subjectSNLen = 0;
toddouska 0:5045d2638c29 694 cert->subjectC = 0;
toddouska 0:5045d2638c29 695 cert->subjectCLen = 0;
toddouska 0:5045d2638c29 696 cert->subjectL = 0;
toddouska 0:5045d2638c29 697 cert->subjectLLen = 0;
toddouska 0:5045d2638c29 698 cert->subjectST = 0;
toddouska 0:5045d2638c29 699 cert->subjectSTLen = 0;
toddouska 0:5045d2638c29 700 cert->subjectO = 0;
toddouska 0:5045d2638c29 701 cert->subjectOLen = 0;
toddouska 0:5045d2638c29 702 cert->subjectOU = 0;
toddouska 0:5045d2638c29 703 cert->subjectOULen = 0;
toddouska 0:5045d2638c29 704 cert->subjectEmail = 0;
toddouska 0:5045d2638c29 705 cert->subjectEmailLen = 0;
toddouska 0:5045d2638c29 706 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 707 }
toddouska 0:5045d2638c29 708
toddouska 0:5045d2638c29 709
toddouska 0:5045d2638c29 710 void FreeDecodedCert(DecodedCert* cert)
toddouska 0:5045d2638c29 711 {
toddouska 0:5045d2638c29 712 if (cert->subjectCNLen == 0) /* 0 means no longer pointer to raw, we own */
toddouska 0:5045d2638c29 713 XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
toddouska 0:5045d2638c29 714 if (cert->pubKeyStored == 1)
toddouska 0:5045d2638c29 715 XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
toddouska 0:5045d2638c29 716 }
toddouska 0:5045d2638c29 717
toddouska 0:5045d2638c29 718
toddouska 0:5045d2638c29 719 static int GetCertHeader(DecodedCert* cert, word32 inSz)
toddouska 0:5045d2638c29 720 {
toddouska 0:5045d2638c29 721 int ret = 0, version, len;
toddouska 0:5045d2638c29 722 word32 begin = cert->srcIdx;
toddouska 0:5045d2638c29 723 mp_int mpi;
toddouska 0:5045d2638c29 724
toddouska 0:5045d2638c29 725 if (GetSequence(cert->source, &cert->srcIdx, &len) < 0)
toddouska 0:5045d2638c29 726 return ASN_PARSE_E;
toddouska 0:5045d2638c29 727
toddouska 0:5045d2638c29 728 if ((word32)len > (inSz - (cert->srcIdx - begin))) return ASN_INPUT_E;
toddouska 0:5045d2638c29 729
toddouska 0:5045d2638c29 730 cert->certBegin = cert->srcIdx;
toddouska 0:5045d2638c29 731
toddouska 0:5045d2638c29 732 GetSequence(cert->source, &cert->srcIdx, &len);
toddouska 0:5045d2638c29 733 cert->sigIndex = len + cert->srcIdx;
toddouska 0:5045d2638c29 734
toddouska 0:5045d2638c29 735 if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
toddouska 0:5045d2638c29 736 return ASN_PARSE_E;
toddouska 0:5045d2638c29 737
toddouska 0:5045d2638c29 738 if (GetInt(&mpi, cert->source, &cert->srcIdx) < 0)
toddouska 0:5045d2638c29 739 ret = ASN_PARSE_E;
toddouska 0:5045d2638c29 740
toddouska 0:5045d2638c29 741 mp_clear(&mpi);
toddouska 0:5045d2638c29 742 return ret;
toddouska 0:5045d2638c29 743 }
toddouska 0:5045d2638c29 744
toddouska 0:5045d2638c29 745
toddouska 0:5045d2638c29 746 static int StoreKey(DecodedCert* cert)
toddouska 0:5045d2638c29 747 {
toddouska 0:5045d2638c29 748 int length;
toddouska 0:5045d2638c29 749 word32 read = cert->srcIdx;
toddouska 0:5045d2638c29 750
toddouska 0:5045d2638c29 751 if (cert->keyOID == NTRUk)
toddouska 0:5045d2638c29 752 return 0; /* already stored */
toddouska 0:5045d2638c29 753
toddouska 0:5045d2638c29 754 if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 755 return ASN_PARSE_E;
toddouska 0:5045d2638c29 756
toddouska 0:5045d2638c29 757 read = cert->srcIdx - read;
toddouska 0:5045d2638c29 758 length += read;
toddouska 0:5045d2638c29 759
toddouska 0:5045d2638c29 760 while (read--)
toddouska 0:5045d2638c29 761 cert->srcIdx--;
toddouska 0:5045d2638c29 762
toddouska 0:5045d2638c29 763 cert->pubKeySize = length;
toddouska 0:5045d2638c29 764 cert->publicKey = cert->source + cert->srcIdx;
toddouska 0:5045d2638c29 765 cert->srcIdx += length;
toddouska 0:5045d2638c29 766
toddouska 0:5045d2638c29 767 return 0;
toddouska 0:5045d2638c29 768 }
toddouska 0:5045d2638c29 769
toddouska 0:5045d2638c29 770
toddouska 0:5045d2638c29 771 static int GetKey(DecodedCert* cert)
toddouska 0:5045d2638c29 772 {
toddouska 0:5045d2638c29 773 int length;
toddouska 0:5045d2638c29 774 #ifdef HAVE_NTRU
toddouska 0:5045d2638c29 775 int tmpIdx = cert->srcIdx;
toddouska 0:5045d2638c29 776 #endif
toddouska 0:5045d2638c29 777
toddouska 0:5045d2638c29 778 if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 779 return ASN_PARSE_E;
toddouska 0:5045d2638c29 780
toddouska 0:5045d2638c29 781 if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID) < 0)
toddouska 0:5045d2638c29 782 return ASN_PARSE_E;
toddouska 0:5045d2638c29 783
toddouska 0:5045d2638c29 784 if (cert->keyOID == RSAk) {
toddouska 0:5045d2638c29 785 byte b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 786 if (b != ASN_BIT_STRING)
toddouska 0:5045d2638c29 787 return ASN_BITSTR_E;
toddouska 0:5045d2638c29 788
toddouska 0:5045d2638c29 789 if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 790 return ASN_PARSE_E;
toddouska 0:5045d2638c29 791 b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 792 if (b != 0x00)
toddouska 0:5045d2638c29 793 return ASN_EXPECT_0_E;
toddouska 0:5045d2638c29 794 }
toddouska 0:5045d2638c29 795 else if (cert->keyOID == DSAk )
toddouska 0:5045d2638c29 796 ; /* do nothing */
toddouska 0:5045d2638c29 797 #ifdef HAVE_NTRU
toddouska 0:5045d2638c29 798 else if (cert->keyOID == NTRUk ) {
toddouska 0:5045d2638c29 799 const byte* key = &cert->source[tmpIdx];
toddouska 0:5045d2638c29 800 byte* next = (byte*)key;
toddouska 0:5045d2638c29 801 word16 keyLen;
toddouska 0:5045d2638c29 802 byte keyBlob[MAX_NTRU_KEY_SZ];
toddouska 0:5045d2638c29 803
toddouska 0:5045d2638c29 804 word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
toddouska 0:5045d2638c29 805 &keyLen, NULL, &next);
toddouska 0:5045d2638c29 806
toddouska 0:5045d2638c29 807 if (rc != NTRU_OK)
toddouska 0:5045d2638c29 808 return ASN_NTRU_KEY_E;
toddouska 0:5045d2638c29 809 if (keyLen > sizeof(keyBlob))
toddouska 0:5045d2638c29 810 return ASN_NTRU_KEY_E;
toddouska 0:5045d2638c29 811
toddouska 0:5045d2638c29 812 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, &keyLen,
toddouska 0:5045d2638c29 813 keyBlob, &next);
toddouska 0:5045d2638c29 814 if (rc != NTRU_OK)
toddouska 0:5045d2638c29 815 return ASN_NTRU_KEY_E;
toddouska 0:5045d2638c29 816
toddouska 0:5045d2638c29 817 if ( (next - key) < 0)
toddouska 0:5045d2638c29 818 return ASN_NTRU_KEY_E;
toddouska 0:5045d2638c29 819
toddouska 0:5045d2638c29 820 cert->srcIdx = tmpIdx + (next - key);
toddouska 0:5045d2638c29 821
toddouska 0:5045d2638c29 822 cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
toddouska 0:5045d2638c29 823 DYNAMIC_TYPE_PUBLIC_KEY);
toddouska 0:5045d2638c29 824 if (cert->publicKey == NULL)
toddouska 0:5045d2638c29 825 return MEMORY_E;
toddouska 0:5045d2638c29 826 memcpy(cert->publicKey, keyBlob, keyLen);
toddouska 0:5045d2638c29 827 cert->pubKeyStored = 1;
toddouska 0:5045d2638c29 828 cert->pubKeySize = keyLen;
toddouska 0:5045d2638c29 829 }
toddouska 0:5045d2638c29 830 #endif
toddouska 0:5045d2638c29 831 else
toddouska 0:5045d2638c29 832 return ASN_UNKNOWN_OID_E;
toddouska 0:5045d2638c29 833
toddouska 0:5045d2638c29 834 return StoreKey(cert);
toddouska 0:5045d2638c29 835 }
toddouska 0:5045d2638c29 836
toddouska 0:5045d2638c29 837
toddouska 0:5045d2638c29 838 /* process NAME, either issuer or subject */
toddouska 0:5045d2638c29 839 static int GetName(DecodedCert* cert, int nameType)
toddouska 0:5045d2638c29 840 {
toddouska 0:5045d2638c29 841 Sha sha;
toddouska 0:5045d2638c29 842 int length; /* length of all distinguished names */
toddouska 0:5045d2638c29 843 int dummy;
toddouska 0:5045d2638c29 844 char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
toddouska 0:5045d2638c29 845 word32 idx = 0;
toddouska 0:5045d2638c29 846
toddouska 0:5045d2638c29 847 InitSha(&sha);
toddouska 0:5045d2638c29 848
toddouska 0:5045d2638c29 849 if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 850 return ASN_PARSE_E;
toddouska 0:5045d2638c29 851
toddouska 0:5045d2638c29 852 length += cert->srcIdx;
toddouska 0:5045d2638c29 853
toddouska 0:5045d2638c29 854 while (cert->srcIdx < (word32)length) {
toddouska 0:5045d2638c29 855 byte b;
toddouska 0:5045d2638c29 856 byte joint[2];
toddouska 0:5045d2638c29 857 int oidSz;
toddouska 0:5045d2638c29 858
toddouska 0:5045d2638c29 859 if (GetSet(cert->source, &cert->srcIdx, &dummy) < 0)
toddouska 0:5045d2638c29 860 return ASN_PARSE_E;
toddouska 0:5045d2638c29 861
toddouska 0:5045d2638c29 862 if (GetSequence(cert->source, &cert->srcIdx, &dummy) < 0)
toddouska 0:5045d2638c29 863 return ASN_PARSE_E;
toddouska 0:5045d2638c29 864
toddouska 0:5045d2638c29 865 b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 866 if (b != ASN_OBJECT_ID)
toddouska 0:5045d2638c29 867 return ASN_OBJECT_ID_E;
toddouska 0:5045d2638c29 868
toddouska 0:5045d2638c29 869 if (GetLength(cert->source, &cert->srcIdx, &oidSz) < 0)
toddouska 0:5045d2638c29 870 return ASN_PARSE_E;
toddouska 0:5045d2638c29 871
toddouska 0:5045d2638c29 872 XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
toddouska 0:5045d2638c29 873
toddouska 0:5045d2638c29 874 /* v1 name types */
toddouska 0:5045d2638c29 875 if (joint[0] == 0x55 && joint[1] == 0x04) {
toddouska 0:5045d2638c29 876 byte id;
toddouska 0:5045d2638c29 877 byte copy = FALSE;
toddouska 0:5045d2638c29 878 int strLen;
toddouska 0:5045d2638c29 879
toddouska 0:5045d2638c29 880 cert->srcIdx += 2;
toddouska 0:5045d2638c29 881 id = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 882 b = cert->source[cert->srcIdx++]; /* strType */
toddouska 0:5045d2638c29 883
toddouska 0:5045d2638c29 884 if (GetLength(cert->source, &cert->srcIdx, &strLen) < 0)
toddouska 0:5045d2638c29 885 return ASN_PARSE_E;
toddouska 0:5045d2638c29 886
toddouska 0:5045d2638c29 887 if (strLen > (int)(ASN_NAME_MAX - idx))
toddouska 0:5045d2638c29 888 return ASN_PARSE_E;
toddouska 0:5045d2638c29 889
toddouska 0:5045d2638c29 890 if (4 > (ASN_NAME_MAX - idx)) /* make sure room for biggest */
toddouska 0:5045d2638c29 891 return ASN_PARSE_E; /* pre fix header too "/CN=" */
toddouska 0:5045d2638c29 892
toddouska 0:5045d2638c29 893 if (id == ASN_COMMON_NAME) {
toddouska 0:5045d2638c29 894 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 895 cert->subjectCN = (char *)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 896 cert->subjectCNLen = strLen;
toddouska 0:5045d2638c29 897 }
toddouska 0:5045d2638c29 898
toddouska 0:5045d2638c29 899 XMEMCPY(&full[idx], "/CN=", 4);
toddouska 0:5045d2638c29 900 idx += 4;
toddouska 0:5045d2638c29 901 copy = TRUE;
toddouska 0:5045d2638c29 902 }
toddouska 0:5045d2638c29 903 else if (id == ASN_SUR_NAME) {
toddouska 0:5045d2638c29 904 XMEMCPY(&full[idx], "/SN=", 4);
toddouska 0:5045d2638c29 905 idx += 4;
toddouska 0:5045d2638c29 906 copy = TRUE;
toddouska 0:5045d2638c29 907 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 908 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 909 cert->subjectSN = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 910 cert->subjectSNLen = strLen;
toddouska 0:5045d2638c29 911 }
toddouska 0:5045d2638c29 912 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 913 }
toddouska 0:5045d2638c29 914 else if (id == ASN_COUNTRY_NAME) {
toddouska 0:5045d2638c29 915 XMEMCPY(&full[idx], "/C=", 3);
toddouska 0:5045d2638c29 916 idx += 3;
toddouska 0:5045d2638c29 917 copy = TRUE;
toddouska 0:5045d2638c29 918 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 919 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 920 cert->subjectC = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 921 cert->subjectCLen = strLen;
toddouska 0:5045d2638c29 922 }
toddouska 0:5045d2638c29 923 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 924 }
toddouska 0:5045d2638c29 925 else if (id == ASN_LOCALITY_NAME) {
toddouska 0:5045d2638c29 926 XMEMCPY(&full[idx], "/L=", 3);
toddouska 0:5045d2638c29 927 idx += 3;
toddouska 0:5045d2638c29 928 copy = TRUE;
toddouska 0:5045d2638c29 929 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 930 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 931 cert->subjectL = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 932 cert->subjectLLen = strLen;
toddouska 0:5045d2638c29 933 }
toddouska 0:5045d2638c29 934 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 935 }
toddouska 0:5045d2638c29 936 else if (id == ASN_STATE_NAME) {
toddouska 0:5045d2638c29 937 XMEMCPY(&full[idx], "/ST=", 4);
toddouska 0:5045d2638c29 938 idx += 4;
toddouska 0:5045d2638c29 939 copy = TRUE;
toddouska 0:5045d2638c29 940 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 941 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 942 cert->subjectST = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 943 cert->subjectSTLen = strLen;
toddouska 0:5045d2638c29 944 }
toddouska 0:5045d2638c29 945 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 946 }
toddouska 0:5045d2638c29 947 else if (id == ASN_ORG_NAME) {
toddouska 0:5045d2638c29 948 XMEMCPY(&full[idx], "/O=", 3);
toddouska 0:5045d2638c29 949 idx += 3;
toddouska 0:5045d2638c29 950 copy = TRUE;
toddouska 0:5045d2638c29 951 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 952 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 953 cert->subjectO = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 954 cert->subjectOLen = strLen;
toddouska 0:5045d2638c29 955 }
toddouska 0:5045d2638c29 956 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 957 }
toddouska 0:5045d2638c29 958 else if (id == ASN_ORGUNIT_NAME) {
toddouska 0:5045d2638c29 959 XMEMCPY(&full[idx], "/OU=", 4);
toddouska 0:5045d2638c29 960 idx += 4;
toddouska 0:5045d2638c29 961 copy = TRUE;
toddouska 0:5045d2638c29 962 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 963 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 964 cert->subjectOU = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 965 cert->subjectOULen = strLen;
toddouska 0:5045d2638c29 966 }
toddouska 0:5045d2638c29 967 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 968 }
toddouska 0:5045d2638c29 969
toddouska 0:5045d2638c29 970 if (copy) {
toddouska 0:5045d2638c29 971 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
toddouska 0:5045d2638c29 972 idx += strLen;
toddouska 0:5045d2638c29 973 }
toddouska 0:5045d2638c29 974
toddouska 0:5045d2638c29 975 ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen);
toddouska 0:5045d2638c29 976 cert->srcIdx += strLen;
toddouska 0:5045d2638c29 977 }
toddouska 0:5045d2638c29 978 else {
toddouska 0:5045d2638c29 979 /* skip */
toddouska 0:5045d2638c29 980 byte email = FALSE;
toddouska 0:5045d2638c29 981 int adv;
toddouska 0:5045d2638c29 982
toddouska 0:5045d2638c29 983 if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */
toddouska 0:5045d2638c29 984 email = TRUE;
toddouska 0:5045d2638c29 985
toddouska 0:5045d2638c29 986 cert->srcIdx += oidSz + 1;
toddouska 0:5045d2638c29 987
toddouska 0:5045d2638c29 988 if (GetLength(cert->source, &cert->srcIdx, &adv) < 0)
toddouska 0:5045d2638c29 989 return ASN_PARSE_E;
toddouska 0:5045d2638c29 990
toddouska 0:5045d2638c29 991 if (adv > (int)(ASN_NAME_MAX - idx))
toddouska 0:5045d2638c29 992 return ASN_PARSE_E;
toddouska 0:5045d2638c29 993
toddouska 0:5045d2638c29 994 if (email) {
toddouska 0:5045d2638c29 995 if (14 > (ASN_NAME_MAX - idx))
toddouska 0:5045d2638c29 996 return ASN_PARSE_E;
toddouska 0:5045d2638c29 997 XMEMCPY(&full[idx], "/emailAddress=", 14);
toddouska 0:5045d2638c29 998 idx += 14;
toddouska 0:5045d2638c29 999
toddouska 0:5045d2638c29 1000 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 1001 if (nameType == SUBJECT) {
toddouska 0:5045d2638c29 1002 cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 1003 cert->subjectEmailLen = adv;
toddouska 0:5045d2638c29 1004 }
toddouska 0:5045d2638c29 1005 #endif /* CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 1006
toddouska 0:5045d2638c29 1007 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
toddouska 0:5045d2638c29 1008 idx += adv;
toddouska 0:5045d2638c29 1009 }
toddouska 0:5045d2638c29 1010
toddouska 0:5045d2638c29 1011 cert->srcIdx += adv;
toddouska 0:5045d2638c29 1012 }
toddouska 0:5045d2638c29 1013 }
toddouska 0:5045d2638c29 1014 full[idx++] = 0;
toddouska 0:5045d2638c29 1015
toddouska 0:5045d2638c29 1016 if (nameType == ISSUER)
toddouska 0:5045d2638c29 1017 ShaFinal(&sha, cert->issuerHash);
toddouska 0:5045d2638c29 1018 else
toddouska 0:5045d2638c29 1019 ShaFinal(&sha, cert->subjectHash);
toddouska 0:5045d2638c29 1020
toddouska 0:5045d2638c29 1021 return 0;
toddouska 0:5045d2638c29 1022 }
toddouska 0:5045d2638c29 1023
toddouska 0:5045d2638c29 1024
toddouska 0:5045d2638c29 1025 #ifndef NO_TIME_H
toddouska 0:5045d2638c29 1026
toddouska 0:5045d2638c29 1027 /* to the second */
toddouska 0:5045d2638c29 1028 static int DateGreaterThan(const struct tm* a, const struct tm* b)
toddouska 0:5045d2638c29 1029 {
toddouska 0:5045d2638c29 1030 if (a->tm_year > b->tm_year)
toddouska 0:5045d2638c29 1031 return 1;
toddouska 0:5045d2638c29 1032
toddouska 0:5045d2638c29 1033 if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
toddouska 0:5045d2638c29 1034 return 1;
toddouska 0:5045d2638c29 1035
toddouska 0:5045d2638c29 1036 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
toddouska 0:5045d2638c29 1037 a->tm_mday > b->tm_mday)
toddouska 0:5045d2638c29 1038 return 1;
toddouska 0:5045d2638c29 1039
toddouska 0:5045d2638c29 1040 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
toddouska 0:5045d2638c29 1041 a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
toddouska 0:5045d2638c29 1042 return 1;
toddouska 0:5045d2638c29 1043
toddouska 0:5045d2638c29 1044 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
toddouska 0:5045d2638c29 1045 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
toddouska 0:5045d2638c29 1046 a->tm_min > b->tm_min)
toddouska 0:5045d2638c29 1047 return 1;
toddouska 0:5045d2638c29 1048
toddouska 0:5045d2638c29 1049 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
toddouska 0:5045d2638c29 1050 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
toddouska 0:5045d2638c29 1051 a->tm_min == b->tm_min && a->tm_sec > b->tm_sec)
toddouska 0:5045d2638c29 1052 return 1;
toddouska 0:5045d2638c29 1053
toddouska 0:5045d2638c29 1054 return 0; /* false */
toddouska 0:5045d2638c29 1055 }
toddouska 0:5045d2638c29 1056
toddouska 0:5045d2638c29 1057
toddouska 0:5045d2638c29 1058 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
toddouska 0:5045d2638c29 1059 {
toddouska 0:5045d2638c29 1060 return !DateGreaterThan(a,b);
toddouska 0:5045d2638c29 1061 }
toddouska 0:5045d2638c29 1062
toddouska 0:5045d2638c29 1063
toddouska 0:5045d2638c29 1064 /* like atoi but only use first byte */
toddouska 0:5045d2638c29 1065 /* Make sure before and after dates are valid */
toddouska 0:5045d2638c29 1066 static int ValidateDate(const byte* date, byte format, int dateType)
toddouska 0:5045d2638c29 1067 {
toddouska 0:5045d2638c29 1068 time_t ltime;
toddouska 0:5045d2638c29 1069 struct tm certTime;
toddouska 0:5045d2638c29 1070 struct tm* localTime;
toddouska 0:5045d2638c29 1071 int i = 0;
toddouska 0:5045d2638c29 1072
toddouska 0:5045d2638c29 1073 ltime = XTIME(0);
toddouska 0:5045d2638c29 1074 XMEMSET(&certTime, 0, sizeof(certTime));
toddouska 0:5045d2638c29 1075
toddouska 0:5045d2638c29 1076 if (format == ASN_UTC_TIME) {
toddouska 0:5045d2638c29 1077 if (btoi(date[0]) >= 5)
toddouska 0:5045d2638c29 1078 certTime.tm_year = 1900;
toddouska 0:5045d2638c29 1079 else
toddouska 0:5045d2638c29 1080 certTime.tm_year = 2000;
toddouska 0:5045d2638c29 1081 }
toddouska 0:5045d2638c29 1082 else { /* format == GENERALIZED_TIME */
toddouska 0:5045d2638c29 1083 certTime.tm_year += btoi(date[i++]) * 1000;
toddouska 0:5045d2638c29 1084 certTime.tm_year += btoi(date[i++]) * 100;
toddouska 0:5045d2638c29 1085 }
toddouska 0:5045d2638c29 1086
toddouska 0:5045d2638c29 1087 GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */
toddouska 0:5045d2638c29 1088 GetTime(&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; /* adjust */
toddouska 0:5045d2638c29 1089 GetTime(&certTime.tm_mday, date, &i);
toddouska 0:5045d2638c29 1090 GetTime(&certTime.tm_hour, date, &i);
toddouska 0:5045d2638c29 1091 GetTime(&certTime.tm_min, date, &i);
toddouska 0:5045d2638c29 1092 GetTime(&certTime.tm_sec, date, &i);
toddouska 0:5045d2638c29 1093
toddouska 0:5045d2638c29 1094 if (date[i] != 'Z') /* only Zulu supported for this profile */
toddouska 0:5045d2638c29 1095 return 0;
toddouska 0:5045d2638c29 1096
toddouska 0:5045d2638c29 1097 localTime = XGMTIME(&ltime);
toddouska 0:5045d2638c29 1098
toddouska 0:5045d2638c29 1099 if (dateType == BEFORE) {
toddouska 0:5045d2638c29 1100 if (DateLessThan(localTime, &certTime))
toddouska 0:5045d2638c29 1101 return 0;
toddouska 0:5045d2638c29 1102 }
toddouska 0:5045d2638c29 1103 else
toddouska 0:5045d2638c29 1104 if (DateGreaterThan(localTime, &certTime))
toddouska 0:5045d2638c29 1105 return 0;
toddouska 0:5045d2638c29 1106
toddouska 0:5045d2638c29 1107 return 1;
toddouska 0:5045d2638c29 1108 }
toddouska 0:5045d2638c29 1109
toddouska 0:5045d2638c29 1110 #endif /* NO_TIME_H */
toddouska 0:5045d2638c29 1111
toddouska 0:5045d2638c29 1112
toddouska 0:5045d2638c29 1113 static int GetDate(DecodedCert* cert, int dateType)
toddouska 0:5045d2638c29 1114 {
toddouska 0:5045d2638c29 1115 int length;
toddouska 0:5045d2638c29 1116 byte date[MAX_DATE_SIZE];
toddouska 0:5045d2638c29 1117 byte b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 1118
toddouska 0:5045d2638c29 1119 if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
toddouska 0:5045d2638c29 1120 return ASN_TIME_E;
toddouska 0:5045d2638c29 1121
toddouska 0:5045d2638c29 1122 if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 1123 return ASN_PARSE_E;
toddouska 0:5045d2638c29 1124
toddouska 0:5045d2638c29 1125 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
toddouska 0:5045d2638c29 1126 return ASN_DATE_SZ_E;
toddouska 0:5045d2638c29 1127
toddouska 0:5045d2638c29 1128 XMEMCPY(date, &cert->source[cert->srcIdx], length);
toddouska 0:5045d2638c29 1129 cert->srcIdx += length;
toddouska 0:5045d2638c29 1130
toddouska 0:5045d2638c29 1131 if (!XVALIDATE_DATE(date, b, dateType)) {
toddouska 0:5045d2638c29 1132 if (dateType == BEFORE)
toddouska 0:5045d2638c29 1133 return ASN_BEFORE_DATE_E;
toddouska 0:5045d2638c29 1134 else
toddouska 0:5045d2638c29 1135 return ASN_AFTER_DATE_E;
toddouska 0:5045d2638c29 1136 }
toddouska 0:5045d2638c29 1137
toddouska 0:5045d2638c29 1138 return 0;
toddouska 0:5045d2638c29 1139 }
toddouska 0:5045d2638c29 1140
toddouska 0:5045d2638c29 1141
toddouska 0:5045d2638c29 1142 static int GetValidity(DecodedCert* cert, int verify)
toddouska 0:5045d2638c29 1143 {
toddouska 0:5045d2638c29 1144 int length;
toddouska 0:5045d2638c29 1145 int badDate = 0;
toddouska 0:5045d2638c29 1146
toddouska 0:5045d2638c29 1147 if (GetSequence(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 1148 return ASN_PARSE_E;
toddouska 0:5045d2638c29 1149
toddouska 0:5045d2638c29 1150 if (GetDate(cert, BEFORE) < 0 && verify)
toddouska 0:5045d2638c29 1151 badDate = ASN_BEFORE_DATE_E; /* continue parsing */
toddouska 0:5045d2638c29 1152
toddouska 0:5045d2638c29 1153 if (GetDate(cert, AFTER) < 0 && verify)
toddouska 0:5045d2638c29 1154 return ASN_AFTER_DATE_E;
toddouska 0:5045d2638c29 1155
toddouska 0:5045d2638c29 1156 if (badDate != 0)
toddouska 0:5045d2638c29 1157 return badDate;
toddouska 0:5045d2638c29 1158
toddouska 0:5045d2638c29 1159 return 0;
toddouska 0:5045d2638c29 1160 }
toddouska 0:5045d2638c29 1161
toddouska 0:5045d2638c29 1162
toddouska 0:5045d2638c29 1163 static int DecodeToKey(DecodedCert* cert, word32 inSz, int verify)
toddouska 0:5045d2638c29 1164 {
toddouska 0:5045d2638c29 1165 int badDate = 0;
toddouska 0:5045d2638c29 1166 int ret;
toddouska 0:5045d2638c29 1167
toddouska 0:5045d2638c29 1168 if ( (ret = GetCertHeader(cert, inSz)) < 0)
toddouska 0:5045d2638c29 1169 return ret;
toddouska 0:5045d2638c29 1170
toddouska 0:5045d2638c29 1171 if ( (ret = GetAlgoId(cert->source, &cert->srcIdx,&cert->signatureOID)) < 0)
toddouska 0:5045d2638c29 1172 return ret;
toddouska 0:5045d2638c29 1173
toddouska 0:5045d2638c29 1174 if ( (ret = GetName(cert, ISSUER)) < 0)
toddouska 0:5045d2638c29 1175 return ret;
toddouska 0:5045d2638c29 1176
toddouska 0:5045d2638c29 1177 if ( (ret = GetValidity(cert, verify)) < 0)
toddouska 0:5045d2638c29 1178 badDate = ret;
toddouska 0:5045d2638c29 1179
toddouska 0:5045d2638c29 1180 if ( (ret = GetName(cert, SUBJECT)) < 0)
toddouska 0:5045d2638c29 1181 return ret;
toddouska 0:5045d2638c29 1182
toddouska 0:5045d2638c29 1183 if ( (ret = GetKey(cert)) < 0)
toddouska 0:5045d2638c29 1184 return ret;
toddouska 0:5045d2638c29 1185
toddouska 0:5045d2638c29 1186 if (badDate != 0)
toddouska 0:5045d2638c29 1187 return badDate;
toddouska 0:5045d2638c29 1188
toddouska 0:5045d2638c29 1189 return ret;
toddouska 0:5045d2638c29 1190 }
toddouska 0:5045d2638c29 1191
toddouska 0:5045d2638c29 1192
toddouska 0:5045d2638c29 1193 static int GetSignature(DecodedCert* cert)
toddouska 0:5045d2638c29 1194 {
toddouska 0:5045d2638c29 1195 int length;
toddouska 0:5045d2638c29 1196 byte b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 1197
toddouska 0:5045d2638c29 1198 if (b != ASN_BIT_STRING)
toddouska 0:5045d2638c29 1199 return ASN_BITSTR_E;
toddouska 0:5045d2638c29 1200
toddouska 0:5045d2638c29 1201 if (GetLength(cert->source, &cert->srcIdx, &length) < 0)
toddouska 0:5045d2638c29 1202 return ASN_PARSE_E;
toddouska 0:5045d2638c29 1203
toddouska 0:5045d2638c29 1204 cert->sigLength = length;
toddouska 0:5045d2638c29 1205
toddouska 0:5045d2638c29 1206 b = cert->source[cert->srcIdx++];
toddouska 0:5045d2638c29 1207 if (b != 0x00)
toddouska 0:5045d2638c29 1208 return ASN_EXPECT_0_E;
toddouska 0:5045d2638c29 1209
toddouska 0:5045d2638c29 1210 cert->sigLength--;
toddouska 0:5045d2638c29 1211 cert->signature = &cert->source[cert->srcIdx];
toddouska 0:5045d2638c29 1212 cert->srcIdx += cert->sigLength;
toddouska 0:5045d2638c29 1213
toddouska 0:5045d2638c29 1214 return 0;
toddouska 0:5045d2638c29 1215 }
toddouska 0:5045d2638c29 1216
toddouska 0:5045d2638c29 1217
toddouska 0:5045d2638c29 1218 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
toddouska 0:5045d2638c29 1219 {
toddouska 0:5045d2638c29 1220 output[0] = ASN_OCTET_STRING;
toddouska 0:5045d2638c29 1221 output[1] = digSz;
toddouska 0:5045d2638c29 1222 XMEMCPY(&output[2], digest, digSz);
toddouska 0:5045d2638c29 1223
toddouska 0:5045d2638c29 1224 return digSz + 2;
toddouska 0:5045d2638c29 1225 }
toddouska 0:5045d2638c29 1226
toddouska 0:5045d2638c29 1227
toddouska 0:5045d2638c29 1228 static word32 BytePrecision(word32 value)
toddouska 0:5045d2638c29 1229 {
toddouska 0:5045d2638c29 1230 word32 i;
toddouska 0:5045d2638c29 1231 for (i = sizeof(value); i; --i)
toddouska 0:5045d2638c29 1232 if (value >> (i - 1) * 8)
toddouska 0:5045d2638c29 1233 break;
toddouska 0:5045d2638c29 1234
toddouska 0:5045d2638c29 1235 return i;
toddouska 0:5045d2638c29 1236 }
toddouska 0:5045d2638c29 1237
toddouska 0:5045d2638c29 1238
toddouska 0:5045d2638c29 1239 static word32 SetLength(word32 length, byte* output)
toddouska 0:5045d2638c29 1240 {
toddouska 0:5045d2638c29 1241 word32 i = 0, j;
toddouska 0:5045d2638c29 1242
toddouska 0:5045d2638c29 1243 if (length < ASN_LONG_LENGTH)
toddouska 0:5045d2638c29 1244 output[i++] = length;
toddouska 0:5045d2638c29 1245 else {
toddouska 0:5045d2638c29 1246 output[i++] = BytePrecision(length) | ASN_LONG_LENGTH;
toddouska 0:5045d2638c29 1247
toddouska 0:5045d2638c29 1248 for (j = BytePrecision(length); j; --j) {
toddouska 0:5045d2638c29 1249 output[i] = length >> (j - 1) * 8;
toddouska 0:5045d2638c29 1250 i++;
toddouska 0:5045d2638c29 1251 }
toddouska 0:5045d2638c29 1252 }
toddouska 0:5045d2638c29 1253
toddouska 0:5045d2638c29 1254 return i;
toddouska 0:5045d2638c29 1255 }
toddouska 0:5045d2638c29 1256
toddouska 0:5045d2638c29 1257
toddouska 0:5045d2638c29 1258 static word32 SetSequence(word32 len, byte* output)
toddouska 0:5045d2638c29 1259 {
toddouska 0:5045d2638c29 1260 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
toddouska 0:5045d2638c29 1261 return SetLength(len, output + 1) + 1;
toddouska 0:5045d2638c29 1262 }
toddouska 0:5045d2638c29 1263
toddouska 0:5045d2638c29 1264
toddouska 0:5045d2638c29 1265 static word32 SetAlgoID(int algoOID, byte* output, int type)
toddouska 0:5045d2638c29 1266 {
toddouska 0:5045d2638c29 1267 /* adding TAG_NULL and 0 to end */
toddouska 0:5045d2638c29 1268
toddouska 0:5045d2638c29 1269 /* hashTypes */
toddouska 0:5045d2638c29 1270 static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a,
toddouska 0:5045d2638c29 1271 0x05, 0x00 };
toddouska 0:5045d2638c29 1272 static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
toddouska 0:5045d2638c29 1273 0x02, 0x05, 0x05, 0x00 };
toddouska 0:5045d2638c29 1274 static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
toddouska 0:5045d2638c29 1275 0x02, 0x02, 0x05, 0x00};
toddouska 0:5045d2638c29 1276
toddouska 0:5045d2638c29 1277 /* sigTypes */
toddouska 0:5045d2638c29 1278 static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
toddouska 0:5045d2638c29 1279 0x01, 0x01, 0x04, 0x05, 0x00};
toddouska 0:5045d2638c29 1280
toddouska 0:5045d2638c29 1281 /* keyTypes */
toddouska 0:5045d2638c29 1282 static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
toddouska 0:5045d2638c29 1283 0x01, 0x01, 0x01, 0x05, 0x00};
toddouska 0:5045d2638c29 1284
toddouska 0:5045d2638c29 1285 int algoSz = 0;
toddouska 0:5045d2638c29 1286 word32 idSz, seqSz;
toddouska 0:5045d2638c29 1287 const byte* algoName = 0;
toddouska 0:5045d2638c29 1288 byte ID_Length[MAX_LENGTH_SZ];
toddouska 0:5045d2638c29 1289 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
toddouska 0:5045d2638c29 1290
toddouska 0:5045d2638c29 1291 if (type == hashType) {
toddouska 0:5045d2638c29 1292 switch (algoOID) {
toddouska 0:5045d2638c29 1293 case SHAh:
toddouska 0:5045d2638c29 1294 algoSz = sizeof(shaAlgoID);
toddouska 0:5045d2638c29 1295 algoName = shaAlgoID;
toddouska 0:5045d2638c29 1296 break;
toddouska 0:5045d2638c29 1297
toddouska 0:5045d2638c29 1298 case MD2h:
toddouska 0:5045d2638c29 1299 algoSz = sizeof(md2AlgoID);
toddouska 0:5045d2638c29 1300 algoName = md2AlgoID;
toddouska 0:5045d2638c29 1301 break;
toddouska 0:5045d2638c29 1302
toddouska 0:5045d2638c29 1303 case MD5h:
toddouska 0:5045d2638c29 1304 algoSz = sizeof(md5AlgoID);
toddouska 0:5045d2638c29 1305 algoName = md5AlgoID;
toddouska 0:5045d2638c29 1306 break;
toddouska 0:5045d2638c29 1307
toddouska 0:5045d2638c29 1308 default:
toddouska 0:5045d2638c29 1309 return 0; /* UNKOWN_HASH_E; */
toddouska 0:5045d2638c29 1310 }
toddouska 0:5045d2638c29 1311 }
toddouska 0:5045d2638c29 1312 else if (type == sigType) { /* sigType */
toddouska 0:5045d2638c29 1313 switch (algoOID) {
toddouska 0:5045d2638c29 1314 case MD5wRSA:
toddouska 0:5045d2638c29 1315 algoSz = sizeof(md5wRSA_AlgoID);
toddouska 0:5045d2638c29 1316 algoName = md5wRSA_AlgoID;
toddouska 0:5045d2638c29 1317 break;
toddouska 0:5045d2638c29 1318
toddouska 0:5045d2638c29 1319 default:
toddouska 0:5045d2638c29 1320 return 0; /* UNKOWN_HASH_E; */
toddouska 0:5045d2638c29 1321 }
toddouska 0:5045d2638c29 1322 }
toddouska 0:5045d2638c29 1323 else if (type == keyType) { /* keyType */
toddouska 0:5045d2638c29 1324 switch (algoOID) {
toddouska 0:5045d2638c29 1325 case RSAk:
toddouska 0:5045d2638c29 1326 algoSz = sizeof(RSA_AlgoID);
toddouska 0:5045d2638c29 1327 algoName = RSA_AlgoID;
toddouska 0:5045d2638c29 1328 break;
toddouska 0:5045d2638c29 1329
toddouska 0:5045d2638c29 1330 default:
toddouska 0:5045d2638c29 1331 return 0; /* UNKOWN_HASH_E; */
toddouska 0:5045d2638c29 1332 }
toddouska 0:5045d2638c29 1333 }
toddouska 0:5045d2638c29 1334 else
toddouska 0:5045d2638c29 1335 return 0; /* UNKNOWN_TYPE */
toddouska 0:5045d2638c29 1336
toddouska 0:5045d2638c29 1337
toddouska 0:5045d2638c29 1338 idSz = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */
toddouska 0:5045d2638c29 1339 seqSz = SetSequence(idSz + algoSz + 1, seqArray);
toddouska 0:5045d2638c29 1340 seqArray[seqSz++] = ASN_OBJECT_ID;
toddouska 0:5045d2638c29 1341
toddouska 0:5045d2638c29 1342 XMEMCPY(output, seqArray, seqSz);
toddouska 0:5045d2638c29 1343 XMEMCPY(output + seqSz, ID_Length, idSz);
toddouska 0:5045d2638c29 1344 XMEMCPY(output + seqSz + idSz, algoName, algoSz);
toddouska 0:5045d2638c29 1345
toddouska 0:5045d2638c29 1346 return seqSz + idSz + algoSz;
toddouska 0:5045d2638c29 1347
toddouska 0:5045d2638c29 1348 }
toddouska 0:5045d2638c29 1349
toddouska 0:5045d2638c29 1350
toddouska 0:5045d2638c29 1351 word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
toddouska 0:5045d2638c29 1352 {
toddouska 0:5045d2638c29 1353 byte digArray[MAX_ENCODED_DIG_SZ];
toddouska 0:5045d2638c29 1354 byte algoArray[MAX_ALGO_SZ];
toddouska 0:5045d2638c29 1355 byte seqArray[MAX_SEQ_SZ];
toddouska 0:5045d2638c29 1356 word32 encDigSz, algoSz, seqSz;
toddouska 0:5045d2638c29 1357
toddouska 0:5045d2638c29 1358 encDigSz = SetDigest(digest, digSz, digArray);
toddouska 0:5045d2638c29 1359 algoSz = SetAlgoID(hashOID, algoArray, hashType);
toddouska 0:5045d2638c29 1360 seqSz = SetSequence(encDigSz + algoSz, seqArray);
toddouska 0:5045d2638c29 1361
toddouska 0:5045d2638c29 1362 XMEMCPY(out, seqArray, seqSz);
toddouska 0:5045d2638c29 1363 XMEMCPY(out + seqSz, algoArray, algoSz);
toddouska 0:5045d2638c29 1364 XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
toddouska 0:5045d2638c29 1365
toddouska 0:5045d2638c29 1366 return encDigSz + algoSz + seqSz;
toddouska 0:5045d2638c29 1367 }
toddouska 0:5045d2638c29 1368
toddouska 0:5045d2638c29 1369
toddouska 0:5045d2638c29 1370 /* return true (1) for Confirmation */
toddouska 0:5045d2638c29 1371 static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
toddouska 0:5045d2638c29 1372 word32 keyOID)
toddouska 0:5045d2638c29 1373 {
toddouska 0:5045d2638c29 1374 byte digest[SHA_DIGEST_SIZE]; /* max size */
toddouska 0:5045d2638c29 1375 int hashType, digestSz, ret;
toddouska 0:5045d2638c29 1376
toddouska 0:5045d2638c29 1377 if (cert->signatureOID == MD5wRSA) {
toddouska 0:5045d2638c29 1378 Md5 md5;
toddouska 0:5045d2638c29 1379 InitMd5(&md5);
toddouska 0:5045d2638c29 1380 Md5Update(&md5, cert->source + cert->certBegin,
toddouska 0:5045d2638c29 1381 cert->sigIndex - cert->certBegin);
toddouska 0:5045d2638c29 1382 Md5Final(&md5, digest);
toddouska 0:5045d2638c29 1383 hashType = MD5h;
toddouska 0:5045d2638c29 1384 digestSz = MD5_DIGEST_SIZE;
toddouska 0:5045d2638c29 1385 }
toddouska 0:5045d2638c29 1386 else if (cert->signatureOID == SHAwRSA || cert->signatureOID == SHAwDSA) {
toddouska 0:5045d2638c29 1387 Sha sha;
toddouska 0:5045d2638c29 1388 InitSha(&sha);
toddouska 0:5045d2638c29 1389 ShaUpdate(&sha, cert->source + cert->certBegin,
toddouska 0:5045d2638c29 1390 cert->sigIndex - cert->certBegin);
toddouska 0:5045d2638c29 1391 ShaFinal(&sha, digest);
toddouska 0:5045d2638c29 1392 hashType = SHAh;
toddouska 0:5045d2638c29 1393 digestSz = SHA_DIGEST_SIZE;
toddouska 0:5045d2638c29 1394 }
toddouska 0:5045d2638c29 1395 else
toddouska 0:5045d2638c29 1396 return 0; /* ASN_SIG_HASH_E; */
toddouska 0:5045d2638c29 1397
toddouska 0:5045d2638c29 1398 if (keyOID == RSAk) {
toddouska 0:5045d2638c29 1399 RsaKey pubKey;
toddouska 0:5045d2638c29 1400 byte encodedSig[MAX_ENCODED_SIG_SZ];
toddouska 0:5045d2638c29 1401 byte plain[MAX_ENCODED_SIG_SZ];
toddouska 0:5045d2638c29 1402 word32 idx = 0;
toddouska 0:5045d2638c29 1403 int sigSz, verifySz;
toddouska 0:5045d2638c29 1404 byte* out;
toddouska 0:5045d2638c29 1405
toddouska 0:5045d2638c29 1406 if (cert->sigLength > MAX_ENCODED_SIG_SZ)
toddouska 0:5045d2638c29 1407 return 0; /* the key is too big */
toddouska 0:5045d2638c29 1408
toddouska 0:5045d2638c29 1409 InitRsaKey(&pubKey, cert->heap);
toddouska 0:5045d2638c29 1410 if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0)
toddouska 0:5045d2638c29 1411 ret = 0; /* ASN_KEY_DECODE_E; */
toddouska 0:5045d2638c29 1412
toddouska 0:5045d2638c29 1413 else {
toddouska 0:5045d2638c29 1414 XMEMCPY(plain, cert->signature, cert->sigLength);
toddouska 0:5045d2638c29 1415 if ( (verifySz = RsaSSL_VerifyInline(plain, cert->sigLength, &out,
toddouska 0:5045d2638c29 1416 &pubKey)) < 0)
toddouska 0:5045d2638c29 1417 ret = 0; /* ASN_VERIFY_E; */
toddouska 0:5045d2638c29 1418 else {
toddouska 0:5045d2638c29 1419 /* make sure we're right justified */
toddouska 0:5045d2638c29 1420 sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
toddouska 0:5045d2638c29 1421 if (sigSz != verifySz || XMEMCMP(out, encodedSig, sigSz) != 0)
toddouska 0:5045d2638c29 1422 ret = 0; /* ASN_VERIFY_MATCH_E; */
toddouska 0:5045d2638c29 1423 else
toddouska 0:5045d2638c29 1424 ret = 1; /* match */
toddouska 0:5045d2638c29 1425 }
toddouska 0:5045d2638c29 1426 }
toddouska 0:5045d2638c29 1427 FreeRsaKey(&pubKey);
toddouska 0:5045d2638c29 1428 return ret;
toddouska 0:5045d2638c29 1429 }
toddouska 0:5045d2638c29 1430 else
toddouska 0:5045d2638c29 1431 return 0; /* ASN_SIG_KEY_E; */
toddouska 0:5045d2638c29 1432 }
toddouska 0:5045d2638c29 1433
toddouska 0:5045d2638c29 1434
toddouska 0:5045d2638c29 1435 int ParseCert(DecodedCert* cert, word32 inSz, int type, int verify,
toddouska 0:5045d2638c29 1436 Signer* signers)
toddouska 0:5045d2638c29 1437 {
toddouska 0:5045d2638c29 1438 int ret;
toddouska 0:5045d2638c29 1439 char* ptr;
toddouska 0:5045d2638c29 1440
toddouska 0:5045d2638c29 1441 ret = ParseCertRelative(cert, inSz, type, verify, signers);
toddouska 0:5045d2638c29 1442 if (ret < 0)
toddouska 0:5045d2638c29 1443 return ret;
toddouska 0:5045d2638c29 1444
toddouska 0:5045d2638c29 1445 if (cert->subjectCNLen > 0) {
toddouska 0:5045d2638c29 1446 ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
toddouska 0:5045d2638c29 1447 DYNAMIC_TYPE_SUBJECT_CN);
toddouska 0:5045d2638c29 1448 if (ptr == NULL)
toddouska 0:5045d2638c29 1449 return MEMORY_E;
toddouska 0:5045d2638c29 1450 XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
toddouska 0:5045d2638c29 1451 ptr[cert->subjectCNLen] = '\0';
toddouska 0:5045d2638c29 1452 cert->subjectCN = ptr;
toddouska 0:5045d2638c29 1453 cert->subjectCNLen = 0;
toddouska 0:5045d2638c29 1454 }
toddouska 0:5045d2638c29 1455
toddouska 0:5045d2638c29 1456 if (cert->keyOID == RSAk && cert->pubKeySize > 0) {
toddouska 0:5045d2638c29 1457 ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
toddouska 0:5045d2638c29 1458 DYNAMIC_TYPE_PUBLIC_KEY);
toddouska 0:5045d2638c29 1459 if (ptr == NULL)
toddouska 0:5045d2638c29 1460 return MEMORY_E;
toddouska 0:5045d2638c29 1461 XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
toddouska 0:5045d2638c29 1462 cert->publicKey = (byte *)ptr;
toddouska 0:5045d2638c29 1463 cert->pubKeyStored = 1;
toddouska 0:5045d2638c29 1464 }
toddouska 0:5045d2638c29 1465
toddouska 0:5045d2638c29 1466 return ret;
toddouska 0:5045d2638c29 1467 }
toddouska 0:5045d2638c29 1468
toddouska 0:5045d2638c29 1469
toddouska 0:5045d2638c29 1470 int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify,
toddouska 0:5045d2638c29 1471 Signer* signers)
toddouska 0:5045d2638c29 1472 {
toddouska 0:5045d2638c29 1473 word32 confirmOID;
toddouska 0:5045d2638c29 1474 int ret;
toddouska 0:5045d2638c29 1475 int badDate = 0;
toddouska 0:5045d2638c29 1476 int confirm = 0;
toddouska 0:5045d2638c29 1477
toddouska 0:5045d2638c29 1478 if ((ret = DecodeToKey(cert, inSz, verify)) < 0) {
toddouska 0:5045d2638c29 1479 if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
toddouska 0:5045d2638c29 1480 badDate = ret;
toddouska 0:5045d2638c29 1481 else
toddouska 0:5045d2638c29 1482 return ret;
toddouska 0:5045d2638c29 1483 }
toddouska 0:5045d2638c29 1484
toddouska 0:5045d2638c29 1485 if (cert->srcIdx != cert->sigIndex)
toddouska 0:5045d2638c29 1486 cert->srcIdx = cert->sigIndex;
toddouska 0:5045d2638c29 1487
toddouska 0:5045d2638c29 1488 if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID)) < 0)
toddouska 0:5045d2638c29 1489 return ret;
toddouska 0:5045d2638c29 1490
toddouska 0:5045d2638c29 1491 if ((ret = GetSignature(cert)) < 0)
toddouska 0:5045d2638c29 1492 return ret;
toddouska 0:5045d2638c29 1493
toddouska 0:5045d2638c29 1494 if (confirmOID != cert->signatureOID)
toddouska 0:5045d2638c29 1495 return ASN_SIG_OID_E;
toddouska 0:5045d2638c29 1496
toddouska 0:5045d2638c29 1497 if (verify && type != CA_TYPE) {
toddouska 0:5045d2638c29 1498 while (signers) {
toddouska 0:5045d2638c29 1499 if (XMEMCMP(cert->issuerHash, signers->hash, SHA_DIGEST_SIZE)
toddouska 0:5045d2638c29 1500 == 0) {
toddouska 0:5045d2638c29 1501 /* other confirm */
toddouska 0:5045d2638c29 1502 if (!ConfirmSignature(cert, signers->publicKey,
toddouska 0:5045d2638c29 1503 signers->pubKeySize, signers->keyOID))
toddouska 0:5045d2638c29 1504 return ASN_SIG_CONFIRM_E;
toddouska 0:5045d2638c29 1505 else {
toddouska 0:5045d2638c29 1506 confirm = 1;
toddouska 0:5045d2638c29 1507 break;
toddouska 0:5045d2638c29 1508 }
toddouska 0:5045d2638c29 1509 }
toddouska 0:5045d2638c29 1510 signers = signers->next;
toddouska 0:5045d2638c29 1511 }
toddouska 0:5045d2638c29 1512 if (!confirm)
toddouska 0:5045d2638c29 1513 return ASN_SIG_CONFIRM_E;
toddouska 0:5045d2638c29 1514 }
toddouska 0:5045d2638c29 1515 if (badDate != 0)
toddouska 0:5045d2638c29 1516 return badDate;
toddouska 0:5045d2638c29 1517
toddouska 0:5045d2638c29 1518 return 0;
toddouska 0:5045d2638c29 1519 }
toddouska 0:5045d2638c29 1520
toddouska 0:5045d2638c29 1521
toddouska 0:5045d2638c29 1522 Signer* MakeSigner(void* heap)
toddouska 0:5045d2638c29 1523 {
toddouska 0:5045d2638c29 1524 Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
toddouska 0:5045d2638c29 1525 DYNAMIC_TYPE_SIGNER);
toddouska 0:5045d2638c29 1526 if (signer) {
toddouska 0:5045d2638c29 1527 signer->name = 0;
toddouska 0:5045d2638c29 1528 signer->publicKey = 0;
toddouska 0:5045d2638c29 1529 signer->next = 0;
toddouska 0:5045d2638c29 1530 }
toddouska 0:5045d2638c29 1531
toddouska 0:5045d2638c29 1532 return signer;
toddouska 0:5045d2638c29 1533 }
toddouska 0:5045d2638c29 1534
toddouska 0:5045d2638c29 1535
toddouska 0:5045d2638c29 1536 void FreeSigners(Signer* signer, void* heap)
toddouska 0:5045d2638c29 1537 {
toddouska 0:5045d2638c29 1538 Signer* next = signer;
toddouska 0:5045d2638c29 1539
toddouska 0:5045d2638c29 1540 while( (signer = next) ) {
toddouska 0:5045d2638c29 1541 next = signer->next;
toddouska 0:5045d2638c29 1542 XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
toddouska 0:5045d2638c29 1543 XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
toddouska 0:5045d2638c29 1544 XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
toddouska 0:5045d2638c29 1545 }
toddouska 0:5045d2638c29 1546 }
toddouska 0:5045d2638c29 1547
toddouska 0:5045d2638c29 1548
toddouska 0:5045d2638c29 1549 void CTaoCryptErrorString(int error, char* buffer)
toddouska 0:5045d2638c29 1550 {
toddouska 0:5045d2638c29 1551 const int max = MAX_ERROR_SZ; /* shorthand */
toddouska 0:5045d2638c29 1552
toddouska 0:5045d2638c29 1553 #ifdef NO_ERROR_STRINGS
toddouska 0:5045d2638c29 1554
toddouska 0:5045d2638c29 1555 XSTRNCPY(buffer, "no support for error strings built in", max);
toddouska 0:5045d2638c29 1556
toddouska 0:5045d2638c29 1557 #else
toddouska 0:5045d2638c29 1558
toddouska 0:5045d2638c29 1559 switch (error) {
toddouska 0:5045d2638c29 1560
toddouska 0:5045d2638c29 1561 case OPEN_RAN_E :
toddouska 0:5045d2638c29 1562 XSTRNCPY(buffer, "opening random device error", max);
toddouska 0:5045d2638c29 1563 break;
toddouska 0:5045d2638c29 1564
toddouska 0:5045d2638c29 1565 case READ_RAN_E :
toddouska 0:5045d2638c29 1566 XSTRNCPY(buffer, "reading random device error", max);
toddouska 0:5045d2638c29 1567 break;
toddouska 0:5045d2638c29 1568
toddouska 0:5045d2638c29 1569 case WINCRYPT_E :
toddouska 0:5045d2638c29 1570 XSTRNCPY(buffer, "windows crypt init error", max);
toddouska 0:5045d2638c29 1571 break;
toddouska 0:5045d2638c29 1572
toddouska 0:5045d2638c29 1573 case CRYPTGEN_E :
toddouska 0:5045d2638c29 1574 XSTRNCPY(buffer, "windows crypt generation error", max);
toddouska 0:5045d2638c29 1575 break;
toddouska 0:5045d2638c29 1576
toddouska 0:5045d2638c29 1577 case RAN_BLOCK_E :
toddouska 0:5045d2638c29 1578 XSTRNCPY(buffer, "random device read would block error", max);
toddouska 0:5045d2638c29 1579 break;
toddouska 0:5045d2638c29 1580
toddouska 0:5045d2638c29 1581 case MP_INIT_E :
toddouska 0:5045d2638c29 1582 XSTRNCPY(buffer, "mp_init error state", max);
toddouska 0:5045d2638c29 1583 break;
toddouska 0:5045d2638c29 1584
toddouska 0:5045d2638c29 1585 case MP_READ_E :
toddouska 0:5045d2638c29 1586 XSTRNCPY(buffer, "mp_read error state", max);
toddouska 0:5045d2638c29 1587 break;
toddouska 0:5045d2638c29 1588
toddouska 0:5045d2638c29 1589 case MP_EXPTMOD_E :
toddouska 0:5045d2638c29 1590 XSTRNCPY(buffer, "mp_exptmod error state", max);
toddouska 0:5045d2638c29 1591 break;
toddouska 0:5045d2638c29 1592
toddouska 0:5045d2638c29 1593 case MP_TO_E :
toddouska 0:5045d2638c29 1594 XSTRNCPY(buffer, "mp_to_xxx error state, can't convert", max);
toddouska 0:5045d2638c29 1595 break;
toddouska 0:5045d2638c29 1596
toddouska 0:5045d2638c29 1597 case MP_SUB_E :
toddouska 0:5045d2638c29 1598 XSTRNCPY(buffer, "mp_sub error state, can't subtract", max);
toddouska 0:5045d2638c29 1599 break;
toddouska 0:5045d2638c29 1600
toddouska 0:5045d2638c29 1601 case MP_ADD_E :
toddouska 0:5045d2638c29 1602 XSTRNCPY(buffer, "mp_add error state, can't add", max);
toddouska 0:5045d2638c29 1603 break;
toddouska 0:5045d2638c29 1604
toddouska 0:5045d2638c29 1605 case MP_MUL_E :
toddouska 0:5045d2638c29 1606 XSTRNCPY(buffer, "mp_mul error state, can't multiply", max);
toddouska 0:5045d2638c29 1607 break;
toddouska 0:5045d2638c29 1608
toddouska 0:5045d2638c29 1609 case MP_MULMOD_E :
toddouska 0:5045d2638c29 1610 XSTRNCPY(buffer, "mp_mulmod error state, can't multiply mod", max);
toddouska 0:5045d2638c29 1611 break;
toddouska 0:5045d2638c29 1612
toddouska 0:5045d2638c29 1613 case MP_MOD_E :
toddouska 0:5045d2638c29 1614 XSTRNCPY(buffer, "mp_mod error state, can't mod", max);
toddouska 0:5045d2638c29 1615 break;
toddouska 0:5045d2638c29 1616
toddouska 0:5045d2638c29 1617 case MP_INVMOD_E :
toddouska 0:5045d2638c29 1618 XSTRNCPY(buffer, "mp_invmod error state, can't inv mod", max);
toddouska 0:5045d2638c29 1619 break;
toddouska 0:5045d2638c29 1620
toddouska 0:5045d2638c29 1621 case MP_CMP_E :
toddouska 0:5045d2638c29 1622 XSTRNCPY(buffer, "mp_cmp error state", max);
toddouska 0:5045d2638c29 1623 break;
toddouska 0:5045d2638c29 1624
toddouska 0:5045d2638c29 1625 case MEMORY_E :
toddouska 0:5045d2638c29 1626 XSTRNCPY(buffer, "out of memory error", max);
toddouska 0:5045d2638c29 1627 break;
toddouska 0:5045d2638c29 1628
toddouska 0:5045d2638c29 1629 case RSA_WRONG_TYPE_E :
toddouska 0:5045d2638c29 1630 XSTRNCPY(buffer, "RSA wrong block type for RSA function", max);
toddouska 0:5045d2638c29 1631 break;
toddouska 0:5045d2638c29 1632
toddouska 0:5045d2638c29 1633 case RSA_BUFFER_E :
toddouska 0:5045d2638c29 1634 XSTRNCPY(buffer, "RSA buffer error, output too small or input too big",
toddouska 0:5045d2638c29 1635 max);
toddouska 0:5045d2638c29 1636 break;
toddouska 0:5045d2638c29 1637
toddouska 0:5045d2638c29 1638 case BUFFER_E :
toddouska 0:5045d2638c29 1639 XSTRNCPY(buffer, "Buffer error, output too small or input too big", max);
toddouska 0:5045d2638c29 1640 break;
toddouska 0:5045d2638c29 1641
toddouska 0:5045d2638c29 1642 case ALGO_ID_E :
toddouska 0:5045d2638c29 1643 XSTRNCPY(buffer, "Setting Cert AlogID error", max);
toddouska 0:5045d2638c29 1644 break;
toddouska 0:5045d2638c29 1645
toddouska 0:5045d2638c29 1646 case PUBLIC_KEY_E :
toddouska 0:5045d2638c29 1647 XSTRNCPY(buffer, "Setting Cert Public Key error", max);
toddouska 0:5045d2638c29 1648 break;
toddouska 0:5045d2638c29 1649
toddouska 0:5045d2638c29 1650 case DATE_E :
toddouska 0:5045d2638c29 1651 XSTRNCPY(buffer, "Setting Cert Date validity error", max);
toddouska 0:5045d2638c29 1652 break;
toddouska 0:5045d2638c29 1653
toddouska 0:5045d2638c29 1654 case SUBJECT_E :
toddouska 0:5045d2638c29 1655 XSTRNCPY(buffer, "Setting Cert Subject name error", max);
toddouska 0:5045d2638c29 1656 break;
toddouska 0:5045d2638c29 1657
toddouska 0:5045d2638c29 1658 case ISSUER_E :
toddouska 0:5045d2638c29 1659 XSTRNCPY(buffer, "Setting Cert Issuer name error", max);
toddouska 0:5045d2638c29 1660 break;
toddouska 0:5045d2638c29 1661
toddouska 0:5045d2638c29 1662 case ASN_PARSE_E :
toddouska 0:5045d2638c29 1663 XSTRNCPY(buffer, "ASN parsing error, invalid input", max);
toddouska 0:5045d2638c29 1664 break;
toddouska 0:5045d2638c29 1665
toddouska 0:5045d2638c29 1666 case ASN_VERSION_E :
toddouska 0:5045d2638c29 1667 XSTRNCPY(buffer, "ASN version error, invalid number", max);
toddouska 0:5045d2638c29 1668 break;
toddouska 0:5045d2638c29 1669
toddouska 0:5045d2638c29 1670 case ASN_GETINT_E :
toddouska 0:5045d2638c29 1671 XSTRNCPY(buffer, "ASN get big int error, invalid data", max);
toddouska 0:5045d2638c29 1672 break;
toddouska 0:5045d2638c29 1673
toddouska 0:5045d2638c29 1674 case ASN_RSA_KEY_E :
toddouska 0:5045d2638c29 1675 XSTRNCPY(buffer, "ASN key init error, invalid input", max);
toddouska 0:5045d2638c29 1676 break;
toddouska 0:5045d2638c29 1677
toddouska 0:5045d2638c29 1678 case ASN_OBJECT_ID_E :
toddouska 0:5045d2638c29 1679 XSTRNCPY(buffer, "ASN object id error, invalid id", max);
toddouska 0:5045d2638c29 1680 break;
toddouska 0:5045d2638c29 1681
toddouska 0:5045d2638c29 1682 case ASN_TAG_NULL_E :
toddouska 0:5045d2638c29 1683 XSTRNCPY(buffer, "ASN tag error, not null", max);
toddouska 0:5045d2638c29 1684 break;
toddouska 0:5045d2638c29 1685
toddouska 0:5045d2638c29 1686 case ASN_EXPECT_0_E :
toddouska 0:5045d2638c29 1687 XSTRNCPY(buffer, "ASN expect error, not zero", max);
toddouska 0:5045d2638c29 1688 break;
toddouska 0:5045d2638c29 1689
toddouska 0:5045d2638c29 1690 case ASN_BITSTR_E :
toddouska 0:5045d2638c29 1691 XSTRNCPY(buffer, "ASN bit string error, wrong id", max);
toddouska 0:5045d2638c29 1692 break;
toddouska 0:5045d2638c29 1693
toddouska 0:5045d2638c29 1694 case ASN_UNKNOWN_OID_E :
toddouska 0:5045d2638c29 1695 XSTRNCPY(buffer, "ASN oid error, unknown sum id", max);
toddouska 0:5045d2638c29 1696 break;
toddouska 0:5045d2638c29 1697
toddouska 0:5045d2638c29 1698 case ASN_DATE_SZ_E :
toddouska 0:5045d2638c29 1699 XSTRNCPY(buffer, "ASN date error, bad size", max);
toddouska 0:5045d2638c29 1700 break;
toddouska 0:5045d2638c29 1701
toddouska 0:5045d2638c29 1702 case ASN_BEFORE_DATE_E :
toddouska 0:5045d2638c29 1703 XSTRNCPY(buffer, "ASN date error, current date before", max);
toddouska 0:5045d2638c29 1704 break;
toddouska 0:5045d2638c29 1705
toddouska 0:5045d2638c29 1706 case ASN_AFTER_DATE_E :
toddouska 0:5045d2638c29 1707 XSTRNCPY(buffer, "ASN date error, current date after", max);
toddouska 0:5045d2638c29 1708 break;
toddouska 0:5045d2638c29 1709
toddouska 0:5045d2638c29 1710 case ASN_SIG_OID_E :
toddouska 0:5045d2638c29 1711 XSTRNCPY(buffer, "ASN signature error, mismatched oid", max);
toddouska 0:5045d2638c29 1712 break;
toddouska 0:5045d2638c29 1713
toddouska 0:5045d2638c29 1714 case ASN_TIME_E :
toddouska 0:5045d2638c29 1715 XSTRNCPY(buffer, "ASN time error, unkown time type", max);
toddouska 0:5045d2638c29 1716 break;
toddouska 0:5045d2638c29 1717
toddouska 0:5045d2638c29 1718 case ASN_INPUT_E :
toddouska 0:5045d2638c29 1719 XSTRNCPY(buffer, "ASN input error, not enough data", max);
toddouska 0:5045d2638c29 1720 break;
toddouska 0:5045d2638c29 1721
toddouska 0:5045d2638c29 1722 case ASN_SIG_CONFIRM_E :
toddouska 0:5045d2638c29 1723 XSTRNCPY(buffer, "ASN sig error, confirm failure", max);
toddouska 0:5045d2638c29 1724 break;
toddouska 0:5045d2638c29 1725
toddouska 0:5045d2638c29 1726 case ASN_SIG_HASH_E :
toddouska 0:5045d2638c29 1727 XSTRNCPY(buffer, "ASN sig error, unsupported hash type", max);
toddouska 0:5045d2638c29 1728 break;
toddouska 0:5045d2638c29 1729
toddouska 0:5045d2638c29 1730 case ASN_SIG_KEY_E :
toddouska 0:5045d2638c29 1731 XSTRNCPY(buffer, "ASN sig error, unsupported key type", max);
toddouska 0:5045d2638c29 1732 break;
toddouska 0:5045d2638c29 1733
toddouska 0:5045d2638c29 1734 case ASN_DH_KEY_E :
toddouska 0:5045d2638c29 1735 XSTRNCPY(buffer, "ASN key init error, invalid input", max);
toddouska 0:5045d2638c29 1736 break;
toddouska 0:5045d2638c29 1737
toddouska 0:5045d2638c29 1738 case ASN_NTRU_KEY_E :
toddouska 0:5045d2638c29 1739 XSTRNCPY(buffer, "ASN NTRU key decode error, invalid input", max);
toddouska 0:5045d2638c29 1740 break;
toddouska 0:5045d2638c29 1741
toddouska 0:5045d2638c29 1742 default:
toddouska 0:5045d2638c29 1743 XSTRNCPY(buffer, "unknown error number", max);
toddouska 0:5045d2638c29 1744
toddouska 0:5045d2638c29 1745 }
toddouska 0:5045d2638c29 1746
toddouska 0:5045d2638c29 1747 #endif /* NO_ERROR_STRINGS */
toddouska 0:5045d2638c29 1748
toddouska 0:5045d2638c29 1749 }
toddouska 0:5045d2638c29 1750
toddouska 0:5045d2638c29 1751
toddouska 0:5045d2638c29 1752 #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
toddouska 0:5045d2638c29 1753
toddouska 0:5045d2638c29 1754 static int SetMyVersion(word32 version, byte* output, int header)
toddouska 0:5045d2638c29 1755 {
toddouska 0:5045d2638c29 1756 int i = 0;
toddouska 0:5045d2638c29 1757
toddouska 0:5045d2638c29 1758 if (header) {
toddouska 0:5045d2638c29 1759 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
toddouska 0:5045d2638c29 1760 output[i++] = ASN_BIT_STRING;
toddouska 0:5045d2638c29 1761 }
toddouska 0:5045d2638c29 1762 output[i++] = ASN_INTEGER;
toddouska 0:5045d2638c29 1763 output[i++] = 0x01;
toddouska 0:5045d2638c29 1764 output[i++] = version;
toddouska 0:5045d2638c29 1765
toddouska 0:5045d2638c29 1766 return i;
toddouska 0:5045d2638c29 1767 }
toddouska 0:5045d2638c29 1768
toddouska 0:5045d2638c29 1769
toddouska 0:5045d2638c29 1770 int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz,
toddouska 0:5045d2638c29 1771 int type)
toddouska 0:5045d2638c29 1772 {
toddouska 0:5045d2638c29 1773 char header[80];
toddouska 0:5045d2638c29 1774 char footer[80];
toddouska 0:5045d2638c29 1775
toddouska 0:5045d2638c29 1776 int headerLen;
toddouska 0:5045d2638c29 1777 int footerLen;
toddouska 0:5045d2638c29 1778 int i;
toddouska 0:5045d2638c29 1779 int outLen; /* return length or error */
toddouska 0:5045d2638c29 1780
toddouska 0:5045d2638c29 1781 if (type == CERT_TYPE) {
toddouska 0:5045d2638c29 1782 XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header));
toddouska 0:5045d2638c29 1783 XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer));
toddouska 0:5045d2638c29 1784 } else {
toddouska 0:5045d2638c29 1785 XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header));
toddouska 0:5045d2638c29 1786 XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer));
toddouska 0:5045d2638c29 1787 }
toddouska 0:5045d2638c29 1788
toddouska 0:5045d2638c29 1789 headerLen = XSTRLEN(header);
toddouska 0:5045d2638c29 1790 footerLen = XSTRLEN(footer);
toddouska 0:5045d2638c29 1791
toddouska 0:5045d2638c29 1792 if (!der || !output)
toddouska 0:5045d2638c29 1793 return -1;
toddouska 0:5045d2638c29 1794
toddouska 0:5045d2638c29 1795 /* don't even try if outSz too short */
toddouska 0:5045d2638c29 1796 if (outSz < headerLen + footerLen + derSz)
toddouska 0:5045d2638c29 1797 return -1;
toddouska 0:5045d2638c29 1798
toddouska 0:5045d2638c29 1799 /* header */
toddouska 0:5045d2638c29 1800 XMEMCPY(output, header, headerLen);
toddouska 0:5045d2638c29 1801 i = headerLen;
toddouska 0:5045d2638c29 1802
toddouska 0:5045d2638c29 1803 /* body */
toddouska 0:5045d2638c29 1804 outLen = outSz; /* input to Base64Encode */
toddouska 0:5045d2638c29 1805 if (Base64Encode(der, derSz, output + i, (word32*)&outLen) < 0)
toddouska 0:5045d2638c29 1806 return -1;
toddouska 0:5045d2638c29 1807 i += outLen;
toddouska 0:5045d2638c29 1808
toddouska 0:5045d2638c29 1809 /* footer */
toddouska 0:5045d2638c29 1810 if ( (i + footerLen) > (int)outSz)
toddouska 0:5045d2638c29 1811 return -1;
toddouska 0:5045d2638c29 1812 XMEMCPY(output + i, footer, footerLen);
toddouska 0:5045d2638c29 1813
toddouska 0:5045d2638c29 1814 return outLen + headerLen + footerLen;
toddouska 0:5045d2638c29 1815 }
toddouska 0:5045d2638c29 1816
toddouska 0:5045d2638c29 1817
toddouska 0:5045d2638c29 1818 #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */
toddouska 0:5045d2638c29 1819
toddouska 0:5045d2638c29 1820
toddouska 0:5045d2638c29 1821 #ifdef CYASSL_KEY_GEN
toddouska 0:5045d2638c29 1822
toddouska 0:5045d2638c29 1823
toddouska 0:5045d2638c29 1824 static mp_int* GetRsaInt(RsaKey* key, int index)
toddouska 0:5045d2638c29 1825 {
toddouska 0:5045d2638c29 1826 if (index == 0)
toddouska 0:5045d2638c29 1827 return &key->n;
toddouska 0:5045d2638c29 1828 if (index == 1)
toddouska 0:5045d2638c29 1829 return &key->e;
toddouska 0:5045d2638c29 1830 if (index == 2)
toddouska 0:5045d2638c29 1831 return &key->d;
toddouska 0:5045d2638c29 1832 if (index == 3)
toddouska 0:5045d2638c29 1833 return &key->p;
toddouska 0:5045d2638c29 1834 if (index == 4)
toddouska 0:5045d2638c29 1835 return &key->q;
toddouska 0:5045d2638c29 1836 if (index == 5)
toddouska 0:5045d2638c29 1837 return &key->dP;
toddouska 0:5045d2638c29 1838 if (index == 6)
toddouska 0:5045d2638c29 1839 return &key->dQ;
toddouska 0:5045d2638c29 1840 if (index == 7)
toddouska 0:5045d2638c29 1841 return &key->u;
toddouska 0:5045d2638c29 1842
toddouska 0:5045d2638c29 1843 return NULL;
toddouska 0:5045d2638c29 1844 }
toddouska 0:5045d2638c29 1845
toddouska 0:5045d2638c29 1846
toddouska 0:5045d2638c29 1847 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
toddouska 0:5045d2638c29 1848 written */
toddouska 0:5045d2638c29 1849 int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
toddouska 0:5045d2638c29 1850 {
toddouska 0:5045d2638c29 1851 word32 seqSz, verSz, rawLen, intTotalLen = 0;
toddouska 0:5045d2638c29 1852 word32 sizes[RSA_INTS];
toddouska 0:5045d2638c29 1853 int i, j, outLen;
toddouska 0:5045d2638c29 1854
toddouska 0:5045d2638c29 1855 byte seq[MAX_SEQ_SZ];
toddouska 0:5045d2638c29 1856 byte ver[MAX_VERSION_SZ];
toddouska 0:5045d2638c29 1857 byte tmps[RSA_INTS][MAX_RSA_INT_SZ];
toddouska 0:5045d2638c29 1858
toddouska 0:5045d2638c29 1859 if (!key || !output)
toddouska 0:5045d2638c29 1860 return -1;
toddouska 0:5045d2638c29 1861
toddouska 0:5045d2638c29 1862 if (key->type != RSA_PRIVATE)
toddouska 0:5045d2638c29 1863 return -1;
toddouska 0:5045d2638c29 1864
toddouska 0:5045d2638c29 1865 /* write all big ints from key to DER tmps */
toddouska 0:5045d2638c29 1866 for (i = 0; i < RSA_INTS; i++) {
toddouska 0:5045d2638c29 1867 mp_int* keyInt = GetRsaInt(key, i);
toddouska 0:5045d2638c29 1868 rawLen = mp_unsigned_bin_size(keyInt);
toddouska 0:5045d2638c29 1869
toddouska 0:5045d2638c29 1870 tmps[i][0] = ASN_INTEGER;
toddouska 0:5045d2638c29 1871 sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */
toddouska 0:5045d2638c29 1872
toddouska 0:5045d2638c29 1873 if ( (sizes[i] + rawLen) < sizeof(tmps[i])) {
toddouska 0:5045d2638c29 1874 int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]);
toddouska 0:5045d2638c29 1875 if (err == MP_OKAY) {
toddouska 0:5045d2638c29 1876 sizes[i] += rawLen;
toddouska 0:5045d2638c29 1877 intTotalLen += sizes[i];
toddouska 0:5045d2638c29 1878 }
toddouska 0:5045d2638c29 1879 else
toddouska 0:5045d2638c29 1880 return err;
toddouska 0:5045d2638c29 1881 }
toddouska 0:5045d2638c29 1882 else
toddouska 0:5045d2638c29 1883 return -1;
toddouska 0:5045d2638c29 1884 }
toddouska 0:5045d2638c29 1885
toddouska 0:5045d2638c29 1886 /* make headers */
toddouska 0:5045d2638c29 1887 verSz = SetMyVersion(0, ver, FALSE);
toddouska 0:5045d2638c29 1888 seqSz = SetSequence(verSz + intTotalLen, seq);
toddouska 0:5045d2638c29 1889
toddouska 0:5045d2638c29 1890 outLen = seqSz + verSz + intTotalLen;
toddouska 0:5045d2638c29 1891 if (outLen > (int)inLen)
toddouska 0:5045d2638c29 1892 return -1;
toddouska 0:5045d2638c29 1893
toddouska 0:5045d2638c29 1894 /* write to output */
toddouska 0:5045d2638c29 1895 XMEMCPY(output, seq, seqSz);
toddouska 0:5045d2638c29 1896 j = seqSz;
toddouska 0:5045d2638c29 1897 XMEMCPY(output + j, ver, verSz);
toddouska 0:5045d2638c29 1898 j += verSz;
toddouska 0:5045d2638c29 1899
toddouska 0:5045d2638c29 1900 for (i = 0; i < RSA_INTS; i++) {
toddouska 0:5045d2638c29 1901 XMEMCPY(output + j, tmps[i], sizes[i]);
toddouska 0:5045d2638c29 1902 j += sizes[i];
toddouska 0:5045d2638c29 1903 }
toddouska 0:5045d2638c29 1904
toddouska 0:5045d2638c29 1905 return outLen;
toddouska 0:5045d2638c29 1906 }
toddouska 0:5045d2638c29 1907
toddouska 0:5045d2638c29 1908 #endif /* CYASSL_KEY_GEN */
toddouska 0:5045d2638c29 1909
toddouska 0:5045d2638c29 1910
toddouska 0:5045d2638c29 1911 #ifdef CYASSL_CERT_GEN
toddouska 0:5045d2638c29 1912
toddouska 0:5045d2638c29 1913 /* Initialize and Set Certficate defaults:
toddouska 0:5045d2638c29 1914 version = 3 (0x2)
toddouska 0:5045d2638c29 1915 serial = 0
toddouska 0:5045d2638c29 1916 sigType = MD5_WITH_RSA
toddouska 0:5045d2638c29 1917 issuer = blank
toddouska 0:5045d2638c29 1918 daysValid = 500
toddouska 0:5045d2638c29 1919 selfSigned = 1 (true) use subject as issuer
toddouska 0:5045d2638c29 1920 subject = blank
toddouska 0:5045d2638c29 1921 */
toddouska 0:5045d2638c29 1922 void InitCert(Cert* cert)
toddouska 0:5045d2638c29 1923 {
toddouska 0:5045d2638c29 1924 cert->version = 2; /* version 3 is hex 2 */
toddouska 0:5045d2638c29 1925 cert->sigType = MD5wRSA;
toddouska 0:5045d2638c29 1926 cert->daysValid = 500;
toddouska 0:5045d2638c29 1927 cert->selfSigned = 1;
toddouska 0:5045d2638c29 1928 cert->bodySz = 0;
toddouska 0:5045d2638c29 1929 cert->keyType = RSA_KEY;
toddouska 0:5045d2638c29 1930 XMEMSET(cert->serial, 0, SERIAL_SIZE);
toddouska 0:5045d2638c29 1931
toddouska 0:5045d2638c29 1932 cert->issuer.country[0] = '\0';
toddouska 0:5045d2638c29 1933 cert->issuer.state[0] = '\0';
toddouska 0:5045d2638c29 1934 cert->issuer.locality[0] = '\0';
toddouska 0:5045d2638c29 1935 cert->issuer.sur[0] = '\0';
toddouska 0:5045d2638c29 1936 cert->issuer.org[0] = '\0';
toddouska 0:5045d2638c29 1937 cert->issuer.unit[0] = '\0';
toddouska 0:5045d2638c29 1938 cert->issuer.commonName[0] = '\0';
toddouska 0:5045d2638c29 1939 cert->issuer.email[0] = '\0';
toddouska 0:5045d2638c29 1940
toddouska 0:5045d2638c29 1941 cert->subject.country[0] = '\0';
toddouska 0:5045d2638c29 1942 cert->subject.state[0] = '\0';
toddouska 0:5045d2638c29 1943 cert->subject.locality[0] = '\0';
toddouska 0:5045d2638c29 1944 cert->subject.sur[0] = '\0';
toddouska 0:5045d2638c29 1945 cert->subject.org[0] = '\0';
toddouska 0:5045d2638c29 1946 cert->subject.unit[0] = '\0';
toddouska 0:5045d2638c29 1947 cert->subject.commonName[0] = '\0';
toddouska 0:5045d2638c29 1948 cert->subject.email[0] = '\0';
toddouska 0:5045d2638c29 1949 }
toddouska 0:5045d2638c29 1950
toddouska 0:5045d2638c29 1951
toddouska 0:5045d2638c29 1952 /* DER encoded x509 Certificate */
toddouska 0:5045d2638c29 1953 typedef struct DerCert {
toddouska 0:5045d2638c29 1954 byte size[MAX_LENGTH_SZ]; /* length encoded */
toddouska 0:5045d2638c29 1955 byte version[MAX_VERSION_SZ]; /* version encoded */
toddouska 0:5045d2638c29 1956 byte serial[SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
toddouska 0:5045d2638c29 1957 byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */
toddouska 0:5045d2638c29 1958 byte issuer[ASN_NAME_MAX]; /* issuer encoded */
toddouska 0:5045d2638c29 1959 byte subject[ASN_NAME_MAX]; /* subject encoded */
toddouska 0:5045d2638c29 1960 byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */
toddouska 0:5045d2638c29 1961 byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
toddouska 0:5045d2638c29 1962 int sizeSz; /* encoded size length */
toddouska 0:5045d2638c29 1963 int versionSz; /* encoded version length */
toddouska 0:5045d2638c29 1964 int serialSz; /* encoded serial length */
toddouska 0:5045d2638c29 1965 int sigAlgoSz; /* enocded sig alog length */
toddouska 0:5045d2638c29 1966 int issuerSz; /* encoded issuer length */
toddouska 0:5045d2638c29 1967 int subjectSz; /* encoded subject length */
toddouska 0:5045d2638c29 1968 int validitySz; /* encoded validity length */
toddouska 0:5045d2638c29 1969 int publicKeySz; /* encoded public key length */
toddouska 0:5045d2638c29 1970 int total; /* total encoded lengths */
toddouska 0:5045d2638c29 1971 } DerCert;
toddouska 0:5045d2638c29 1972
toddouska 0:5045d2638c29 1973
toddouska 0:5045d2638c29 1974 /* Write a set header to output */
toddouska 0:5045d2638c29 1975 static word32 SetSet(word32 len, byte* output)
toddouska 0:5045d2638c29 1976 {
toddouska 0:5045d2638c29 1977 output[0] = ASN_SET | ASN_CONSTRUCTED;
toddouska 0:5045d2638c29 1978 return SetLength(len, output + 1) + 1;
toddouska 0:5045d2638c29 1979 }
toddouska 0:5045d2638c29 1980
toddouska 0:5045d2638c29 1981
toddouska 0:5045d2638c29 1982 /* Write a serial number to output */
toddouska 0:5045d2638c29 1983 static int SetSerial(const byte* serial, byte* output)
toddouska 0:5045d2638c29 1984 {
toddouska 0:5045d2638c29 1985 int length = 0;
toddouska 0:5045d2638c29 1986
toddouska 0:5045d2638c29 1987 output[length++] = ASN_INTEGER;
toddouska 0:5045d2638c29 1988 length += SetLength(SERIAL_SIZE, &output[length]);
toddouska 0:5045d2638c29 1989 XMEMCPY(&output[length], serial, SERIAL_SIZE);
toddouska 0:5045d2638c29 1990
toddouska 0:5045d2638c29 1991 return length + SERIAL_SIZE;
toddouska 0:5045d2638c29 1992 }
toddouska 0:5045d2638c29 1993
toddouska 0:5045d2638c29 1994
toddouska 0:5045d2638c29 1995 /* Write a public RSA key to output */
toddouska 0:5045d2638c29 1996 static int SetPublicKey(byte* output, RsaKey* key)
toddouska 0:5045d2638c29 1997 {
toddouska 0:5045d2638c29 1998 byte n[MAX_RSA_INT_SZ];
toddouska 0:5045d2638c29 1999 byte e[MAX_RSA_E_SZ];
toddouska 0:5045d2638c29 2000 byte algo[MAX_ALGO_SZ];
toddouska 0:5045d2638c29 2001 byte seq[MAX_SEQ_SZ];
toddouska 0:5045d2638c29 2002 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
toddouska 0:5045d2638c29 2003 int nSz;
toddouska 0:5045d2638c29 2004 int eSz;
toddouska 0:5045d2638c29 2005 int algoSz;
toddouska 0:5045d2638c29 2006 int seqSz;
toddouska 0:5045d2638c29 2007 int lenSz;
toddouska 0:5045d2638c29 2008 int idx;
toddouska 0:5045d2638c29 2009 int rawLen;
toddouska 0:5045d2638c29 2010
toddouska 0:5045d2638c29 2011 /* n */
toddouska 0:5045d2638c29 2012 rawLen = mp_unsigned_bin_size(&key->n);
toddouska 0:5045d2638c29 2013 n[0] = ASN_INTEGER;
toddouska 0:5045d2638c29 2014 nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
toddouska 0:5045d2638c29 2015
toddouska 0:5045d2638c29 2016 if ( (nSz + rawLen) < sizeof(n)) {
toddouska 0:5045d2638c29 2017 int err = mp_to_unsigned_bin(&key->n, n + nSz);
toddouska 0:5045d2638c29 2018 if (err == MP_OKAY)
toddouska 0:5045d2638c29 2019 nSz += rawLen;
toddouska 0:5045d2638c29 2020 else
toddouska 0:5045d2638c29 2021 return MP_TO_E;
toddouska 0:5045d2638c29 2022 }
toddouska 0:5045d2638c29 2023 else
toddouska 0:5045d2638c29 2024 return BUFFER_E;
toddouska 0:5045d2638c29 2025
toddouska 0:5045d2638c29 2026 /* e */
toddouska 0:5045d2638c29 2027 rawLen = mp_unsigned_bin_size(&key->e);
toddouska 0:5045d2638c29 2028 e[0] = ASN_INTEGER;
toddouska 0:5045d2638c29 2029 eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
toddouska 0:5045d2638c29 2030
toddouska 0:5045d2638c29 2031 if ( (eSz + rawLen) < sizeof(e)) {
toddouska 0:5045d2638c29 2032 int err = mp_to_unsigned_bin(&key->e, e + eSz);
toddouska 0:5045d2638c29 2033 if (err == MP_OKAY)
toddouska 0:5045d2638c29 2034 eSz += rawLen;
toddouska 0:5045d2638c29 2035 else
toddouska 0:5045d2638c29 2036 return MP_TO_E;
toddouska 0:5045d2638c29 2037 }
toddouska 0:5045d2638c29 2038 else
toddouska 0:5045d2638c29 2039 return BUFFER_E;
toddouska 0:5045d2638c29 2040
toddouska 0:5045d2638c29 2041 /* headers */
toddouska 0:5045d2638c29 2042 algoSz = SetAlgoID(RSAk, algo, keyType);
toddouska 0:5045d2638c29 2043 seqSz = SetSequence(nSz + eSz, seq);
toddouska 0:5045d2638c29 2044 lenSz = SetLength(seqSz + nSz + eSz + 1, len);
toddouska 0:5045d2638c29 2045 len[lenSz++] = 0; /* trailing 0 */
toddouska 0:5045d2638c29 2046
toddouska 0:5045d2638c29 2047 /* write */
toddouska 0:5045d2638c29 2048 idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
toddouska 0:5045d2638c29 2049 /* 1 is for ASN_BIT_STRING */
toddouska 0:5045d2638c29 2050 /* algo */
toddouska 0:5045d2638c29 2051 XMEMCPY(output + idx, algo, algoSz);
toddouska 0:5045d2638c29 2052 idx += algoSz;
toddouska 0:5045d2638c29 2053 /* bit string */
toddouska 0:5045d2638c29 2054 output[idx++] = ASN_BIT_STRING;
toddouska 0:5045d2638c29 2055 /* length */
toddouska 0:5045d2638c29 2056 XMEMCPY(output + idx, len, lenSz);
toddouska 0:5045d2638c29 2057 idx += lenSz;
toddouska 0:5045d2638c29 2058 /* seq */
toddouska 0:5045d2638c29 2059 XMEMCPY(output + idx, seq, seqSz);
toddouska 0:5045d2638c29 2060 idx += seqSz;
toddouska 0:5045d2638c29 2061 /* n */
toddouska 0:5045d2638c29 2062 XMEMCPY(output + idx, n, nSz);
toddouska 0:5045d2638c29 2063 idx += nSz;
toddouska 0:5045d2638c29 2064 /* e */
toddouska 0:5045d2638c29 2065 XMEMCPY(output + idx, e, eSz);
toddouska 0:5045d2638c29 2066 idx += eSz;
toddouska 0:5045d2638c29 2067
toddouska 0:5045d2638c29 2068 return idx;
toddouska 0:5045d2638c29 2069 }
toddouska 0:5045d2638c29 2070
toddouska 0:5045d2638c29 2071
toddouska 0:5045d2638c29 2072 static INLINE byte itob(int number)
toddouska 0:5045d2638c29 2073 {
toddouska 0:5045d2638c29 2074 return (byte)number + 0x30;
toddouska 0:5045d2638c29 2075 }
toddouska 0:5045d2638c29 2076
toddouska 0:5045d2638c29 2077
toddouska 0:5045d2638c29 2078 /* write time to output, format */
toddouska 0:5045d2638c29 2079 static void SetTime(struct tm* date, byte* output)
toddouska 0:5045d2638c29 2080 {
toddouska 0:5045d2638c29 2081 int i = 0;
toddouska 0:5045d2638c29 2082
toddouska 0:5045d2638c29 2083 output[i++] = itob((date->tm_year % 10000) / 1000);
toddouska 0:5045d2638c29 2084 output[i++] = itob((date->tm_year % 1000) / 100);
toddouska 0:5045d2638c29 2085 output[i++] = itob((date->tm_year % 100) / 10);
toddouska 0:5045d2638c29 2086 output[i++] = itob( date->tm_year % 10);
toddouska 0:5045d2638c29 2087
toddouska 0:5045d2638c29 2088 output[i++] = itob(date->tm_mon / 10);
toddouska 0:5045d2638c29 2089 output[i++] = itob(date->tm_mon % 10);
toddouska 0:5045d2638c29 2090
toddouska 0:5045d2638c29 2091 output[i++] = itob(date->tm_mday / 10);
toddouska 0:5045d2638c29 2092 output[i++] = itob(date->tm_mday % 10);
toddouska 0:5045d2638c29 2093
toddouska 0:5045d2638c29 2094 output[i++] = itob(date->tm_hour / 10);
toddouska 0:5045d2638c29 2095 output[i++] = itob(date->tm_hour % 10);
toddouska 0:5045d2638c29 2096
toddouska 0:5045d2638c29 2097 output[i++] = itob(date->tm_min / 10);
toddouska 0:5045d2638c29 2098 output[i++] = itob(date->tm_min % 10);
toddouska 0:5045d2638c29 2099
toddouska 0:5045d2638c29 2100 output[i++] = itob(date->tm_sec / 10);
toddouska 0:5045d2638c29 2101 output[i++] = itob(date->tm_sec % 10);
toddouska 0:5045d2638c29 2102
toddouska 0:5045d2638c29 2103 output[i] = 'Z'; /* Zulu profiel */
toddouska 0:5045d2638c29 2104 }
toddouska 0:5045d2638c29 2105
toddouska 0:5045d2638c29 2106
toddouska 0:5045d2638c29 2107 /* Set Date validity from now until now + daysValid */
toddouska 0:5045d2638c29 2108 static int SetValidity(byte* output, int daysValid)
toddouska 0:5045d2638c29 2109 {
toddouska 0:5045d2638c29 2110 byte before[MAX_DATE_SIZE];
toddouska 0:5045d2638c29 2111 byte after[MAX_DATE_SIZE];
toddouska 0:5045d2638c29 2112
toddouska 0:5045d2638c29 2113 int beforeSz;
toddouska 0:5045d2638c29 2114 int afterSz;
toddouska 0:5045d2638c29 2115 int seqSz;
toddouska 0:5045d2638c29 2116
toddouska 0:5045d2638c29 2117 time_t ticks;
toddouska 0:5045d2638c29 2118 struct tm* now;
toddouska 0:5045d2638c29 2119 struct tm local;
toddouska 0:5045d2638c29 2120
toddouska 0:5045d2638c29 2121 ticks = XTIME(0);
toddouska 0:5045d2638c29 2122 now = XGMTIME(&ticks);
toddouska 0:5045d2638c29 2123
toddouska 0:5045d2638c29 2124 /* before now */
toddouska 0:5045d2638c29 2125 local = *now;
toddouska 0:5045d2638c29 2126 before[0] = ASN_GENERALIZED_TIME;
toddouska 0:5045d2638c29 2127 beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */
toddouska 0:5045d2638c29 2128
toddouska 0:5045d2638c29 2129 /* adjust */
toddouska 0:5045d2638c29 2130 local.tm_year += 1900;
toddouska 0:5045d2638c29 2131 local.tm_mon += 1;
toddouska 0:5045d2638c29 2132
toddouska 0:5045d2638c29 2133 SetTime(&local, before + beforeSz);
toddouska 0:5045d2638c29 2134 beforeSz += ASN_GEN_TIME_SZ;
toddouska 0:5045d2638c29 2135
toddouska 0:5045d2638c29 2136 /* after now + daysValid */
toddouska 0:5045d2638c29 2137 local = *now;
toddouska 0:5045d2638c29 2138 after[0] = ASN_GENERALIZED_TIME;
toddouska 0:5045d2638c29 2139 afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */
toddouska 0:5045d2638c29 2140
toddouska 0:5045d2638c29 2141 /* add daysValid */
toddouska 0:5045d2638c29 2142 local.tm_mday += daysValid;
toddouska 0:5045d2638c29 2143 mktime(&local);
toddouska 0:5045d2638c29 2144
toddouska 0:5045d2638c29 2145 /* adjust */
toddouska 0:5045d2638c29 2146 local.tm_year += 1900;
toddouska 0:5045d2638c29 2147 local.tm_mon += 1;
toddouska 0:5045d2638c29 2148
toddouska 0:5045d2638c29 2149 SetTime(&local, after + afterSz);
toddouska 0:5045d2638c29 2150 afterSz += ASN_GEN_TIME_SZ;
toddouska 0:5045d2638c29 2151
toddouska 0:5045d2638c29 2152 /* headers and output */
toddouska 0:5045d2638c29 2153 seqSz = SetSequence(beforeSz + afterSz, output);
toddouska 0:5045d2638c29 2154 XMEMCPY(output + seqSz, before, beforeSz);
toddouska 0:5045d2638c29 2155 XMEMCPY(output + seqSz + beforeSz, after, afterSz);
toddouska 0:5045d2638c29 2156
toddouska 0:5045d2638c29 2157 return seqSz + beforeSz + afterSz;
toddouska 0:5045d2638c29 2158 }
toddouska 0:5045d2638c29 2159
toddouska 0:5045d2638c29 2160
toddouska 0:5045d2638c29 2161 /* ASN Encoded Name field */
toddouska 0:5045d2638c29 2162 typedef struct EncodedName {
toddouska 0:5045d2638c29 2163 int nameLen; /* actual string value length */
toddouska 0:5045d2638c29 2164 int totalLen; /* total encodeding length */
toddouska 0:5045d2638c29 2165 int type; /* type of name */
toddouska 0:5045d2638c29 2166 int used; /* are we actually using this one */
toddouska 0:5045d2638c29 2167 byte encoded[NAME_SIZE * 2]; /* encoding */
toddouska 0:5045d2638c29 2168 } EncodedName;
toddouska 0:5045d2638c29 2169
toddouska 0:5045d2638c29 2170
toddouska 0:5045d2638c29 2171 /* Get Which Name from index */
toddouska 0:5045d2638c29 2172 static const char* GetOneName(CertName* name, int index)
toddouska 0:5045d2638c29 2173 {
toddouska 0:5045d2638c29 2174 switch (index) {
toddouska 0:5045d2638c29 2175 case 0:
toddouska 0:5045d2638c29 2176 return name->country;
toddouska 0:5045d2638c29 2177 break;
toddouska 0:5045d2638c29 2178 case 1:
toddouska 0:5045d2638c29 2179 return name->state;
toddouska 0:5045d2638c29 2180 break;
toddouska 0:5045d2638c29 2181 case 2:
toddouska 0:5045d2638c29 2182 return name->locality;
toddouska 0:5045d2638c29 2183 break;
toddouska 0:5045d2638c29 2184 case 3:
toddouska 0:5045d2638c29 2185 return name->sur;
toddouska 0:5045d2638c29 2186 break;
toddouska 0:5045d2638c29 2187 case 4:
toddouska 0:5045d2638c29 2188 return name->org;
toddouska 0:5045d2638c29 2189 break;
toddouska 0:5045d2638c29 2190 case 5:
toddouska 0:5045d2638c29 2191 return name->unit;
toddouska 0:5045d2638c29 2192 break;
toddouska 0:5045d2638c29 2193 case 6:
toddouska 0:5045d2638c29 2194 return name->commonName;
toddouska 0:5045d2638c29 2195 break;
toddouska 0:5045d2638c29 2196 case 7:
toddouska 0:5045d2638c29 2197 return name->email;
toddouska 0:5045d2638c29 2198 break;
toddouska 0:5045d2638c29 2199 default:
toddouska 0:5045d2638c29 2200 return 0;
toddouska 0:5045d2638c29 2201 }
toddouska 0:5045d2638c29 2202
toddouska 0:5045d2638c29 2203 return 0;
toddouska 0:5045d2638c29 2204 }
toddouska 0:5045d2638c29 2205
toddouska 0:5045d2638c29 2206
toddouska 0:5045d2638c29 2207 /* Get ASN Name from index */
toddouska 0:5045d2638c29 2208 static byte GetNameId(int index)
toddouska 0:5045d2638c29 2209 {
toddouska 0:5045d2638c29 2210 switch (index) {
toddouska 0:5045d2638c29 2211 case 0:
toddouska 0:5045d2638c29 2212 return ASN_COUNTRY_NAME;
toddouska 0:5045d2638c29 2213 break;
toddouska 0:5045d2638c29 2214 case 1:
toddouska 0:5045d2638c29 2215 return ASN_STATE_NAME;
toddouska 0:5045d2638c29 2216 break;
toddouska 0:5045d2638c29 2217 case 2:
toddouska 0:5045d2638c29 2218 return ASN_LOCALITY_NAME;
toddouska 0:5045d2638c29 2219 break;
toddouska 0:5045d2638c29 2220 case 3:
toddouska 0:5045d2638c29 2221 return ASN_SUR_NAME;
toddouska 0:5045d2638c29 2222 break;
toddouska 0:5045d2638c29 2223 case 4:
toddouska 0:5045d2638c29 2224 return ASN_ORG_NAME;
toddouska 0:5045d2638c29 2225 break;
toddouska 0:5045d2638c29 2226 case 5:
toddouska 0:5045d2638c29 2227 return ASN_ORGUNIT_NAME;
toddouska 0:5045d2638c29 2228 break;
toddouska 0:5045d2638c29 2229 case 6:
toddouska 0:5045d2638c29 2230 return ASN_COMMON_NAME;
toddouska 0:5045d2638c29 2231 break;
toddouska 0:5045d2638c29 2232 case 7:
toddouska 0:5045d2638c29 2233 /* email uses different id type */
toddouska 0:5045d2638c29 2234 return 0;
toddouska 0:5045d2638c29 2235 break;
toddouska 0:5045d2638c29 2236 default:
toddouska 0:5045d2638c29 2237 return 0;
toddouska 0:5045d2638c29 2238 }
toddouska 0:5045d2638c29 2239
toddouska 0:5045d2638c29 2240 return 0;
toddouska 0:5045d2638c29 2241 }
toddouska 0:5045d2638c29 2242
toddouska 0:5045d2638c29 2243
toddouska 0:5045d2638c29 2244 /* encode CertName into output, return total bytes written */
toddouska 0:5045d2638c29 2245 static int SetName(byte* output, CertName* name)
toddouska 0:5045d2638c29 2246 {
toddouska 0:5045d2638c29 2247 int totalBytes = 0, i, idx;
toddouska 0:5045d2638c29 2248 EncodedName names[NAME_ENTRIES];
toddouska 0:5045d2638c29 2249
toddouska 0:5045d2638c29 2250 for (i = 0; i < NAME_ENTRIES; i++) {
toddouska 0:5045d2638c29 2251 const char* nameStr = GetOneName(name, i);
toddouska 0:5045d2638c29 2252 if (nameStr) {
toddouska 0:5045d2638c29 2253 /* bottom up */
toddouska 0:5045d2638c29 2254 byte firstLen[MAX_LENGTH_SZ];
toddouska 0:5045d2638c29 2255 byte secondLen[MAX_LENGTH_SZ];
toddouska 0:5045d2638c29 2256 byte sequence[MAX_SEQ_SZ];
toddouska 0:5045d2638c29 2257 byte set[MAX_SET_SZ];
toddouska 0:5045d2638c29 2258
toddouska 0:5045d2638c29 2259 int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
toddouska 0:5045d2638c29 2260 int strLen = XSTRLEN(nameStr);
toddouska 0:5045d2638c29 2261 int thisLen = strLen;
toddouska 0:5045d2638c29 2262 int firstSz, secondSz, seqSz, setSz;
toddouska 0:5045d2638c29 2263
toddouska 0:5045d2638c29 2264 if (strLen == 0) { /* no user data for this item */
toddouska 0:5045d2638c29 2265 names[i].used = 0;
toddouska 0:5045d2638c29 2266 continue;
toddouska 0:5045d2638c29 2267 }
toddouska 0:5045d2638c29 2268
toddouska 0:5045d2638c29 2269 secondSz = SetLength(strLen, secondLen);
toddouska 0:5045d2638c29 2270 thisLen += secondSz;
toddouska 0:5045d2638c29 2271 if (email) {
toddouska 0:5045d2638c29 2272 thisLen += EMAIL_JOINT_LEN;
toddouska 0:5045d2638c29 2273 thisLen ++; /* id type */
toddouska 0:5045d2638c29 2274 firstSz = SetLength(EMAIL_JOINT_LEN, firstLen);
toddouska 0:5045d2638c29 2275 }
toddouska 0:5045d2638c29 2276 else {
toddouska 0:5045d2638c29 2277 thisLen++; /* str type */
toddouska 0:5045d2638c29 2278 thisLen++; /* id type */
toddouska 0:5045d2638c29 2279 thisLen += JOINT_LEN;
toddouska 0:5045d2638c29 2280 firstSz = SetLength(JOINT_LEN + 1, firstLen);
toddouska 0:5045d2638c29 2281 }
toddouska 0:5045d2638c29 2282 thisLen += firstSz;
toddouska 0:5045d2638c29 2283 thisLen++; /* object id */
toddouska 0:5045d2638c29 2284
toddouska 0:5045d2638c29 2285 seqSz = SetSequence(thisLen, sequence);
toddouska 0:5045d2638c29 2286 thisLen += seqSz;
toddouska 0:5045d2638c29 2287 setSz = SetSet(thisLen, set);
toddouska 0:5045d2638c29 2288 thisLen += setSz;
toddouska 0:5045d2638c29 2289
toddouska 0:5045d2638c29 2290 if (thisLen > sizeof(names[i].encoded))
toddouska 0:5045d2638c29 2291 return BUFFER_E;
toddouska 0:5045d2638c29 2292
toddouska 0:5045d2638c29 2293 /* store it */
toddouska 0:5045d2638c29 2294 idx = 0;
toddouska 0:5045d2638c29 2295 /* set */
toddouska 0:5045d2638c29 2296 XMEMCPY(names[i].encoded, set, setSz);
toddouska 0:5045d2638c29 2297 idx += setSz;
toddouska 0:5045d2638c29 2298 /* seq */
toddouska 0:5045d2638c29 2299 XMEMCPY(names[i].encoded + idx, sequence, seqSz);
toddouska 0:5045d2638c29 2300 idx += seqSz;
toddouska 0:5045d2638c29 2301 /* asn object id */
toddouska 0:5045d2638c29 2302 names[i].encoded[idx++] = ASN_OBJECT_ID;
toddouska 0:5045d2638c29 2303 /* first length */
toddouska 0:5045d2638c29 2304 XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
toddouska 0:5045d2638c29 2305 idx += firstSz;
toddouska 0:5045d2638c29 2306 if (email) {
toddouska 0:5045d2638c29 2307 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
toddouska 0:5045d2638c29 2308 0x01, 0x09, 0x01, 0x16 };
toddouska 0:5045d2638c29 2309 /* email joint id */
toddouska 0:5045d2638c29 2310 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
toddouska 0:5045d2638c29 2311 idx += sizeof(EMAIL_OID);
toddouska 0:5045d2638c29 2312 }
toddouska 0:5045d2638c29 2313 else {
toddouska 0:5045d2638c29 2314 /* joint id */
toddouska 0:5045d2638c29 2315 names[i].encoded[idx++] = 0x55;
toddouska 0:5045d2638c29 2316 names[i].encoded[idx++] = 0x04;
toddouska 0:5045d2638c29 2317 /* id type */
toddouska 0:5045d2638c29 2318 names[i].encoded[idx++] = GetNameId(i);
toddouska 0:5045d2638c29 2319 /* str type */
toddouska 0:5045d2638c29 2320 names[i].encoded[idx++] = 0x13;
toddouska 0:5045d2638c29 2321 }
toddouska 0:5045d2638c29 2322 /* second length */
toddouska 0:5045d2638c29 2323 XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
toddouska 0:5045d2638c29 2324 idx += secondSz;
toddouska 0:5045d2638c29 2325 /* str value */
toddouska 0:5045d2638c29 2326 XMEMCPY(names[i].encoded + idx, nameStr, strLen);
toddouska 0:5045d2638c29 2327 idx += strLen;
toddouska 0:5045d2638c29 2328
toddouska 0:5045d2638c29 2329 totalBytes += idx;
toddouska 0:5045d2638c29 2330 names[i].totalLen = idx;
toddouska 0:5045d2638c29 2331 names[i].used = 1;
toddouska 0:5045d2638c29 2332 }
toddouska 0:5045d2638c29 2333 else
toddouska 0:5045d2638c29 2334 names[i].used = 0;
toddouska 0:5045d2638c29 2335 }
toddouska 0:5045d2638c29 2336
toddouska 0:5045d2638c29 2337 /* header */
toddouska 0:5045d2638c29 2338 idx = SetSequence(totalBytes, output);
toddouska 0:5045d2638c29 2339 totalBytes += idx;
toddouska 0:5045d2638c29 2340 if (totalBytes > ASN_NAME_MAX)
toddouska 0:5045d2638c29 2341 return BUFFER_E;
toddouska 0:5045d2638c29 2342
toddouska 0:5045d2638c29 2343 for (i = 0; i < NAME_ENTRIES; i++) {
toddouska 0:5045d2638c29 2344 if (names[i].used) {
toddouska 0:5045d2638c29 2345 XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
toddouska 0:5045d2638c29 2346 idx += names[i].totalLen;
toddouska 0:5045d2638c29 2347 }
toddouska 0:5045d2638c29 2348 }
toddouska 0:5045d2638c29 2349 return totalBytes;
toddouska 0:5045d2638c29 2350 }
toddouska 0:5045d2638c29 2351
toddouska 0:5045d2638c29 2352
toddouska 0:5045d2638c29 2353 /* encode info from cert into DER enocder format */
toddouska 0:5045d2638c29 2354 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng,
toddouska 0:5045d2638c29 2355 const byte* ntruKey, word16 ntruSz)
toddouska 0:5045d2638c29 2356 {
toddouska 0:5045d2638c29 2357 /* version */
toddouska 0:5045d2638c29 2358 der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
toddouska 0:5045d2638c29 2359
toddouska 0:5045d2638c29 2360 /* serial number */
toddouska 0:5045d2638c29 2361 RNG_GenerateBlock(rng, cert->serial, SERIAL_SIZE);
toddouska 0:5045d2638c29 2362 cert->serial[0] = 0x01; /* ensure positive */
toddouska 0:5045d2638c29 2363 der->serialSz = SetSerial(cert->serial, der->serial);
toddouska 0:5045d2638c29 2364
toddouska 0:5045d2638c29 2365 /* signature algo */
toddouska 0:5045d2638c29 2366 der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType);
toddouska 0:5045d2638c29 2367 if (der->sigAlgoSz == 0)
toddouska 0:5045d2638c29 2368 return ALGO_ID_E;
toddouska 0:5045d2638c29 2369
toddouska 0:5045d2638c29 2370 /* public key */
toddouska 0:5045d2638c29 2371 if (cert->keyType == RSA_KEY) {
toddouska 0:5045d2638c29 2372 der->publicKeySz = SetPublicKey(der->publicKey, rsaKey);
toddouska 0:5045d2638c29 2373 if (der->publicKeySz == 0)
toddouska 0:5045d2638c29 2374 return PUBLIC_KEY_E;
toddouska 0:5045d2638c29 2375 }
toddouska 0:5045d2638c29 2376 else {
toddouska 0:5045d2638c29 2377 #ifdef HAVE_NTRU
toddouska 0:5045d2638c29 2378 word32 rc;
toddouska 0:5045d2638c29 2379 word16 encodedSz;
toddouska 0:5045d2638c29 2380
toddouska 0:5045d2638c29 2381 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
toddouska 0:5045d2638c29 2382 ntruKey, &encodedSz, NULL);
toddouska 0:5045d2638c29 2383 if (rc != NTRU_OK)
toddouska 0:5045d2638c29 2384 return PUBLIC_KEY_E;
toddouska 0:5045d2638c29 2385 if (encodedSz > MAX_PUBLIC_KEY_SZ)
toddouska 0:5045d2638c29 2386 return PUBLIC_KEY_E;
toddouska 0:5045d2638c29 2387
toddouska 0:5045d2638c29 2388 rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz,
toddouska 0:5045d2638c29 2389 ntruKey, &encodedSz, der->publicKey);
toddouska 0:5045d2638c29 2390 if (rc != NTRU_OK)
toddouska 0:5045d2638c29 2391 return PUBLIC_KEY_E;
toddouska 0:5045d2638c29 2392
toddouska 0:5045d2638c29 2393 der->publicKeySz = encodedSz;
toddouska 0:5045d2638c29 2394 #endif
toddouska 0:5045d2638c29 2395 }
toddouska 0:5045d2638c29 2396
toddouska 0:5045d2638c29 2397 /* date validity */
toddouska 0:5045d2638c29 2398 der->validitySz = SetValidity(der->validity, cert->daysValid);
toddouska 0:5045d2638c29 2399 if (der->validitySz == 0)
toddouska 0:5045d2638c29 2400 return DATE_E;
toddouska 0:5045d2638c29 2401
toddouska 0:5045d2638c29 2402 /* subject name */
toddouska 0:5045d2638c29 2403 der->subjectSz = SetName(der->subject, &cert->subject);
toddouska 0:5045d2638c29 2404 if (der->subjectSz == 0)
toddouska 0:5045d2638c29 2405 return SUBJECT_E;
toddouska 0:5045d2638c29 2406
toddouska 0:5045d2638c29 2407 /* issuer name */
toddouska 0:5045d2638c29 2408 der->issuerSz = SetName(der->issuer, cert->selfSigned ?
toddouska 0:5045d2638c29 2409 &cert->subject : &cert->issuer);
toddouska 0:5045d2638c29 2410 if (der->issuerSz == 0)
toddouska 0:5045d2638c29 2411 return ISSUER_E;
toddouska 0:5045d2638c29 2412
toddouska 0:5045d2638c29 2413 der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
toddouska 0:5045d2638c29 2414 der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz;
toddouska 0:5045d2638c29 2415
toddouska 0:5045d2638c29 2416 return 0;
toddouska 0:5045d2638c29 2417 }
toddouska 0:5045d2638c29 2418
toddouska 0:5045d2638c29 2419
toddouska 0:5045d2638c29 2420 /* write DER encoded cert to buffer, size already checked */
toddouska 0:5045d2638c29 2421 static int WriteCertBody(DerCert* der, byte* buffer)
toddouska 0:5045d2638c29 2422 {
toddouska 0:5045d2638c29 2423 int idx;
toddouska 0:5045d2638c29 2424
toddouska 0:5045d2638c29 2425 /* signed part header */
toddouska 0:5045d2638c29 2426 idx = SetSequence(der->total, buffer);
toddouska 0:5045d2638c29 2427 /* version */
toddouska 0:5045d2638c29 2428 XMEMCPY(buffer + idx, der->version, der->versionSz);
toddouska 0:5045d2638c29 2429 idx += der->versionSz;
toddouska 0:5045d2638c29 2430 /* serial */
toddouska 0:5045d2638c29 2431 XMEMCPY(buffer + idx, der->serial, der->serialSz);
toddouska 0:5045d2638c29 2432 idx += der->serialSz;
toddouska 0:5045d2638c29 2433 /* sig algo */
toddouska 0:5045d2638c29 2434 XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
toddouska 0:5045d2638c29 2435 idx += der->sigAlgoSz;
toddouska 0:5045d2638c29 2436 /* issuer */
toddouska 0:5045d2638c29 2437 XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
toddouska 0:5045d2638c29 2438 idx += der->issuerSz;
toddouska 0:5045d2638c29 2439 /* validity */
toddouska 0:5045d2638c29 2440 XMEMCPY(buffer + idx, der->validity, der->validitySz);
toddouska 0:5045d2638c29 2441 idx += der->validitySz;
toddouska 0:5045d2638c29 2442 /* subject */
toddouska 0:5045d2638c29 2443 XMEMCPY(buffer + idx, der->subject, der->subjectSz);
toddouska 0:5045d2638c29 2444 idx += der->subjectSz;
toddouska 0:5045d2638c29 2445 /* public key */
toddouska 0:5045d2638c29 2446 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
toddouska 0:5045d2638c29 2447 idx += der->publicKeySz;
toddouska 0:5045d2638c29 2448
toddouska 0:5045d2638c29 2449 return idx;
toddouska 0:5045d2638c29 2450 }
toddouska 0:5045d2638c29 2451
toddouska 0:5045d2638c29 2452
toddouska 0:5045d2638c29 2453 /* Make MD5wRSA signature from buffer (sz), write to sig (sigSz) */
toddouska 0:5045d2638c29 2454 static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
toddouska 0:5045d2638c29 2455 RsaKey* key, RNG* rng)
toddouska 0:5045d2638c29 2456 {
toddouska 0:5045d2638c29 2457 byte digest[SHA_DIGEST_SIZE]; /* max size */
toddouska 0:5045d2638c29 2458 byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
toddouska 0:5045d2638c29 2459 int encSigSz, digestSz, hashType;
toddouska 0:5045d2638c29 2460 Md5 md5; /* md5 for now */
toddouska 0:5045d2638c29 2461
toddouska 0:5045d2638c29 2462 InitMd5(&md5);
toddouska 0:5045d2638c29 2463 Md5Update(&md5, buffer, sz);
toddouska 0:5045d2638c29 2464 Md5Final(&md5, digest);
toddouska 0:5045d2638c29 2465 digestSz = MD5_DIGEST_SIZE;
toddouska 0:5045d2638c29 2466 hashType = MD5h;
toddouska 0:5045d2638c29 2467
toddouska 0:5045d2638c29 2468 /* signature */
toddouska 0:5045d2638c29 2469 encSigSz = EncodeSignature(encSig, digest, digestSz, hashType);
toddouska 0:5045d2638c29 2470 return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng);
toddouska 0:5045d2638c29 2471 }
toddouska 0:5045d2638c29 2472
toddouska 0:5045d2638c29 2473
toddouska 0:5045d2638c29 2474 /* add signature to end of buffer, size of buffer assumed checked, return
toddouska 0:5045d2638c29 2475 new length */
toddouska 0:5045d2638c29 2476 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz)
toddouska 0:5045d2638c29 2477 {
toddouska 0:5045d2638c29 2478 byte seq[MAX_SEQ_SZ];
toddouska 0:5045d2638c29 2479 int idx = bodySz, seqSz;
toddouska 0:5045d2638c29 2480
toddouska 0:5045d2638c29 2481 /* algo */
toddouska 0:5045d2638c29 2482 idx += SetAlgoID(MD5wRSA, buffer + idx, sigType);
toddouska 0:5045d2638c29 2483 /* bit string */
toddouska 0:5045d2638c29 2484 buffer[idx++] = ASN_BIT_STRING;
toddouska 0:5045d2638c29 2485 /* length */
toddouska 0:5045d2638c29 2486 idx += SetLength(sigSz + 1, buffer + idx);
toddouska 0:5045d2638c29 2487 buffer[idx++] = 0; /* trailing 0 */
toddouska 0:5045d2638c29 2488 /* signature */
toddouska 0:5045d2638c29 2489 XMEMCPY(buffer + idx, sig, sigSz);
toddouska 0:5045d2638c29 2490 idx += sigSz;
toddouska 0:5045d2638c29 2491
toddouska 0:5045d2638c29 2492 /* make room for overall header */
toddouska 0:5045d2638c29 2493 seqSz = SetSequence(idx, seq);
toddouska 0:5045d2638c29 2494 XMEMMOVE(buffer + seqSz, buffer, idx);
toddouska 0:5045d2638c29 2495 XMEMCPY(buffer, seq, seqSz);
toddouska 0:5045d2638c29 2496
toddouska 0:5045d2638c29 2497 return idx + seqSz;
toddouska 0:5045d2638c29 2498 }
toddouska 0:5045d2638c29 2499
toddouska 0:5045d2638c29 2500
toddouska 0:5045d2638c29 2501 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
toddouska 0:5045d2638c29 2502 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
toddouska 0:5045d2638c29 2503 RsaKey* rsaKey, RNG* rng, const byte* ntruKey, word16 ntruSz)
toddouska 0:5045d2638c29 2504 {
toddouska 0:5045d2638c29 2505 DerCert der;
toddouska 0:5045d2638c29 2506 int ret;
toddouska 0:5045d2638c29 2507
toddouska 0:5045d2638c29 2508 cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY;
toddouska 0:5045d2638c29 2509 ret = EncodeCert(cert, &der, rsaKey, rng, ntruKey, ntruSz);
toddouska 0:5045d2638c29 2510 if (ret != 0)
toddouska 0:5045d2638c29 2511 return ret;
toddouska 0:5045d2638c29 2512
toddouska 0:5045d2638c29 2513 if (der.total + MAX_SEQ_SZ * 2 > (int)derSz)
toddouska 0:5045d2638c29 2514 return BUFFER_E;
toddouska 0:5045d2638c29 2515
toddouska 0:5045d2638c29 2516 return cert->bodySz = WriteCertBody(&der, derBuffer);
toddouska 0:5045d2638c29 2517 }
toddouska 0:5045d2638c29 2518
toddouska 0:5045d2638c29 2519
toddouska 0:5045d2638c29 2520 /* Make an x509 Certificate v3 RSA from cert input, write to buffer */
toddouska 0:5045d2638c29 2521 int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,RNG* rng)
toddouska 0:5045d2638c29 2522 {
toddouska 0:5045d2638c29 2523 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, rng, NULL, 0);
toddouska 0:5045d2638c29 2524 }
toddouska 0:5045d2638c29 2525
toddouska 0:5045d2638c29 2526
toddouska 0:5045d2638c29 2527 #ifdef HAVE_NTRU
toddouska 0:5045d2638c29 2528
toddouska 0:5045d2638c29 2529 int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
toddouska 0:5045d2638c29 2530 const byte* ntruKey, word16 keySz, RNG* rng)
toddouska 0:5045d2638c29 2531 {
toddouska 0:5045d2638c29 2532 return MakeAnyCert(cert, derBuffer, derSz, NULL, rng, ntruKey, keySz);
toddouska 0:5045d2638c29 2533 }
toddouska 0:5045d2638c29 2534
toddouska 0:5045d2638c29 2535 #endif /* HAVE_NTRU */
toddouska 0:5045d2638c29 2536
toddouska 0:5045d2638c29 2537
toddouska 0:5045d2638c29 2538 int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
toddouska 0:5045d2638c29 2539 {
toddouska 0:5045d2638c29 2540 byte sig[MAX_ENCODED_SIG_SZ];
toddouska 0:5045d2638c29 2541 int sigSz;
toddouska 0:5045d2638c29 2542 int bodySz = cert->bodySz;
toddouska 0:5045d2638c29 2543
toddouska 0:5045d2638c29 2544 if (bodySz < 0)
toddouska 0:5045d2638c29 2545 return bodySz;
toddouska 0:5045d2638c29 2546
toddouska 0:5045d2638c29 2547 sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng);
toddouska 0:5045d2638c29 2548 if (sigSz < 0)
toddouska 0:5045d2638c29 2549 return sigSz;
toddouska 0:5045d2638c29 2550
toddouska 0:5045d2638c29 2551 if (bodySz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
toddouska 0:5045d2638c29 2552 return BUFFER_E;
toddouska 0:5045d2638c29 2553
toddouska 0:5045d2638c29 2554 return AddSignature(buffer, bodySz, sig, sigSz);
toddouska 0:5045d2638c29 2555 }
toddouska 0:5045d2638c29 2556
toddouska 0:5045d2638c29 2557
toddouska 0:5045d2638c29 2558 int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
toddouska 0:5045d2638c29 2559 {
toddouska 0:5045d2638c29 2560 int ret = MakeCert(cert, buffer, buffSz, key, rng);
toddouska 0:5045d2638c29 2561
toddouska 0:5045d2638c29 2562 if (ret < 0)
toddouska 0:5045d2638c29 2563 return ret;
toddouska 0:5045d2638c29 2564
toddouska 0:5045d2638c29 2565 return SignCert(cert, buffer, buffSz, key, rng);
toddouska 0:5045d2638c29 2566 }
toddouska 0:5045d2638c29 2567
toddouska 0:5045d2638c29 2568
toddouska 0:5045d2638c29 2569 /* forward from CyaSSL */
toddouska 0:5045d2638c29 2570 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
toddouska 0:5045d2638c29 2571
toddouska 0:5045d2638c29 2572 #ifndef NO_FILESYSTEM
toddouska 0:5045d2638c29 2573
toddouska 0:5045d2638c29 2574 int SetIssuer(Cert* cert, const char* issuerCertFile)
toddouska 0:5045d2638c29 2575 {
toddouska 0:5045d2638c29 2576 DecodedCert decoded;
toddouska 0:5045d2638c29 2577 byte der[8192];
toddouska 0:5045d2638c29 2578 int derSz = CyaSSL_PemCertToDer(issuerCertFile, der, sizeof(der));
toddouska 0:5045d2638c29 2579 int ret;
toddouska 0:5045d2638c29 2580 int sz;
toddouska 0:5045d2638c29 2581
toddouska 0:5045d2638c29 2582 if (derSz < 0)
toddouska 0:5045d2638c29 2583 return derSz;
toddouska 0:5045d2638c29 2584
toddouska 0:5045d2638c29 2585 cert->selfSigned = 0;
toddouska 0:5045d2638c29 2586
toddouska 0:5045d2638c29 2587 InitDecodedCert(&decoded, der, 0);
toddouska 0:5045d2638c29 2588 ret = ParseCertRelative(&decoded, derSz, CA_TYPE, NO_VERIFY, 0);
toddouska 0:5045d2638c29 2589
toddouska 0:5045d2638c29 2590 if (ret < 0)
toddouska 0:5045d2638c29 2591 return ret;
toddouska 0:5045d2638c29 2592
toddouska 0:5045d2638c29 2593 if (decoded.subjectCN) {
toddouska 0:5045d2638c29 2594 sz = (decoded.subjectCNLen < NAME_SIZE) ? decoded.subjectCNLen :
toddouska 0:5045d2638c29 2595 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2596 strncpy(cert->issuer.commonName, decoded.subjectCN, NAME_SIZE);
toddouska 0:5045d2638c29 2597 cert->issuer.commonName[sz] = 0;
toddouska 0:5045d2638c29 2598 }
toddouska 0:5045d2638c29 2599 if (decoded.subjectC) {
toddouska 0:5045d2638c29 2600 sz = (decoded.subjectCLen < NAME_SIZE) ? decoded.subjectCLen :
toddouska 0:5045d2638c29 2601 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2602 strncpy(cert->issuer.country, decoded.subjectC, NAME_SIZE);
toddouska 0:5045d2638c29 2603 cert->issuer.country[sz] = 0;
toddouska 0:5045d2638c29 2604 }
toddouska 0:5045d2638c29 2605 if (decoded.subjectST) {
toddouska 0:5045d2638c29 2606 sz = (decoded.subjectSTLen < NAME_SIZE) ? decoded.subjectSTLen :
toddouska 0:5045d2638c29 2607 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2608 strncpy(cert->issuer.state, decoded.subjectST, NAME_SIZE);
toddouska 0:5045d2638c29 2609 cert->issuer.state[sz] = 0;
toddouska 0:5045d2638c29 2610 }
toddouska 0:5045d2638c29 2611 if (decoded.subjectL) {
toddouska 0:5045d2638c29 2612 sz = (decoded.subjectLLen < NAME_SIZE) ? decoded.subjectLLen :
toddouska 0:5045d2638c29 2613 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2614 strncpy(cert->issuer.locality, decoded.subjectL, NAME_SIZE);
toddouska 0:5045d2638c29 2615 cert->issuer.locality[sz] = 0;
toddouska 0:5045d2638c29 2616 }
toddouska 0:5045d2638c29 2617 if (decoded.subjectO) {
toddouska 0:5045d2638c29 2618 sz = (decoded.subjectOLen < NAME_SIZE) ? decoded.subjectOLen :
toddouska 0:5045d2638c29 2619 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2620 strncpy(cert->issuer.org, decoded.subjectO, NAME_SIZE);
toddouska 0:5045d2638c29 2621 cert->issuer.org[sz] = 0;
toddouska 0:5045d2638c29 2622 }
toddouska 0:5045d2638c29 2623 if (decoded.subjectOU) {
toddouska 0:5045d2638c29 2624 sz = (decoded.subjectOULen < NAME_SIZE) ? decoded.subjectOULen :
toddouska 0:5045d2638c29 2625 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2626 strncpy(cert->issuer.unit, decoded.subjectOU, NAME_SIZE);
toddouska 0:5045d2638c29 2627 cert->issuer.unit[sz] = 0;
toddouska 0:5045d2638c29 2628 }
toddouska 0:5045d2638c29 2629 if (decoded.subjectSN) {
toddouska 0:5045d2638c29 2630 sz = (decoded.subjectSNLen < NAME_SIZE) ? decoded.subjectSNLen :
toddouska 0:5045d2638c29 2631 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2632 strncpy(cert->issuer.sur, decoded.subjectSN, NAME_SIZE);
toddouska 0:5045d2638c29 2633 cert->issuer.sur[sz] = 0;
toddouska 0:5045d2638c29 2634 }
toddouska 0:5045d2638c29 2635 if (decoded.subjectEmail) {
toddouska 0:5045d2638c29 2636 sz = (decoded.subjectEmailLen < NAME_SIZE) ? decoded.subjectEmailLen :
toddouska 0:5045d2638c29 2637 NAME_SIZE - 1;
toddouska 0:5045d2638c29 2638 strncpy(cert->issuer.email, decoded.subjectEmail, NAME_SIZE);
toddouska 0:5045d2638c29 2639 cert->issuer.email[sz] = 0;
toddouska 0:5045d2638c29 2640 }
toddouska 0:5045d2638c29 2641
toddouska 0:5045d2638c29 2642 FreeDecodedCert(&decoded);
toddouska 0:5045d2638c29 2643
toddouska 0:5045d2638c29 2644 return 0;
toddouska 0:5045d2638c29 2645 }
toddouska 0:5045d2638c29 2646
toddouska 0:5045d2638c29 2647 #endif /* NO_FILESYSTEM */
toddouska 0:5045d2638c29 2648 #endif /* CYASSL_CERT_GEN */