source: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/asn.c@ 167

Last change on this file since 167 was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

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