From 36ef4922cce896ce3e9286a47d5e1b2bc7c9cc8e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 17 Aug 2022 23:05:56 +0200 Subject: [PATCH] Minor updates of BearSSL --- .../bearssl-esp8266/src/ec/ec_p256_m15.c | 22 +- .../bearssl-esp8266/src/ec/ec_prime_i15.c | 10 +- .../bearssl-esp8266/src/pgmspace_bearssl.h | 134 +- .../src/rsa/rsa_pss_sig_unpad.c | 2 +- .../bearssl-esp8266/src/ssl/ssl_engine.c | 15 + .../bearssl-esp8266/src/ssl/ssl_rec_cbc.c | 2 +- lib/lib_ssl/bearssl-esp8266/src/t_bearssl.h | 15 +- .../bearssl-esp8266/src/t_bearssl_ssl.h | 6 +- .../bearssl-esp8266/src/t_bearssl_x509.h | 5 +- lib/lib_ssl/bearssl-esp8266/src/t_inner.h | 26 +- .../bearssl-esp8266/src/x509/x509_minimal.c | 747 ++++---- .../bearssl-esp8266/src/x509/x509_minimal.t0 | 1570 ----------------- 12 files changed, 478 insertions(+), 2076 deletions(-) delete mode 100644 lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 diff --git a/lib/lib_ssl/bearssl-esp8266/src/ec/ec_p256_m15.c b/lib/lib_ssl/bearssl-esp8266/src/ec/ec_p256_m15.c index e5d76c6b4..7eb1c5b72 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/ec/ec_p256_m15.c +++ b/lib/lib_ssl/bearssl-esp8266/src/ec/ec_p256_m15.c @@ -2026,12 +2026,13 @@ api_mul(unsigned char *G, size_t Glen, p256_jacobian P; (void)curve; + if (Glen != 65) { + return 0; + } r = p256_decode(&P, G, Glen); p256_mul(&P, x, xlen); - if (Glen >= 65) { - p256_to_affine(&P); - p256_encode(G, &P); - } + p256_to_affine(&P); + p256_encode(G, &P); return r; } @@ -2046,16 +2047,6 @@ api_mulgen(unsigned char *R, p256_to_affine(&P); p256_encode(R, &P); return 65; - - /* - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; - */ } static uint32_t @@ -2068,6 +2059,9 @@ api_muladd(unsigned char *A, const unsigned char *B, size_t len, int i; (void)curve; + if (len != 65) { + return 0; + } r = p256_decode(&P, A, len); p256_mul(&P, x, xlen); if (B == NULL) { diff --git a/lib/lib_ssl/bearssl-esp8266/src/ec/ec_prime_i15.c b/lib/lib_ssl/bearssl-esp8266/src/ec/ec_prime_i15.c index 1bed22aa4..63d90fcf1 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/ec/ec_prime_i15.c +++ b/lib/lib_ssl/bearssl-esp8266/src/ec/ec_prime_i15.c @@ -735,11 +735,12 @@ api_mul(unsigned char *G, size_t Glen, jacobian P; cc = id_to_curve(curve); + if (Glen != cc->point_len) { + return 0; + } r = point_decode(&P, G, Glen, cc); point_mul(&P, x, xlen, cc); - if (Glen == cc->point_len) { - point_encode(G, &P, cc); - } + point_encode(G, &P, cc); return r; } @@ -772,6 +773,9 @@ api_muladd(unsigned char *A, const unsigned char *B, size_t len, */ cc = id_to_curve(curve); + if (len != cc->point_len) { + return 0; + } r = point_decode(&P, A, len, cc); if (B == NULL) { size_t Glen; diff --git a/lib/lib_ssl/bearssl-esp8266/src/pgmspace_bearssl.h b/lib/lib_ssl/bearssl-esp8266/src/pgmspace_bearssl.h index 30ed2a40f..852640d42 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/pgmspace_bearssl.h +++ b/lib/lib_ssl/bearssl-esp8266/src/pgmspace_bearssl.h @@ -1,113 +1,50 @@ -/* pgmspace_bearssl.h - Accessor utilities/types for accessing PROGMEM data */ +/* PGMSPACE.H - Accessor utilities/types for accessing PROGMEM data */ -//#pragma GCC optimize ("O2") // -Os is the default, forcing -O2 for BearSSL -//#define PGM_READ_UNALIGNED 0 // all calls are aligned, take the optimized version -//#include - - -#ifndef _PGMSPACE_H_ -#define _PGMSPACE_H_ +#ifndef _PGMSPACEWRAPPER_H_ +#define _PGMSPACEWRAPPER_H_ #include -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ESP32 -#ifndef ICACHE_RODATA_ATTR - #define ICACHE_RODATA_ATTR __attribute__((section(".irom.text"))) -#endif -#ifndef PROGMEM - // The following two macros cause a parameter to be enclosed in quotes - // by the preopressor (i.e. for concatenating ints to strings) - #define __STRINGIZE_NX(A) #A - #define __STRINGIZE(A) __STRINGIZE_NX(A) - // Since __section__ is supposed to be only use for global variables, - // there could be conflicts when a static/inlined function has them in the - // same file as a non-static PROGMEM object. - // Ref: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html - // Place each progmem object into its own named section, avoiding conflicts - #define PROGMEM __attribute__((section( "\".irom.text." __FILE__ "." __STRINGIZE(__LINE__) "." __STRINGIZE(__COUNTER__) "\""))) -#endif -#endif //ESP32 -#ifndef PGM_P - #define PGM_P const char * -#endif -#ifndef PGM_VOID_P - #define PGM_VOID_P const void * -#endif - -// PSTR() macro modified to start on a 32-bit boundary. This adds on average -// 1.5 bytes/string, but in return memcpy_P and strcpy_P will work 4~8x faster -#ifndef PSTR - #define PSTR(s) (__extension__({static const char __c[] __attribute__((__aligned__(4))) PROGMEM = (s); &__c[0];})) -#endif - #ifdef ESP8266 -// Flash memory must be read using 32 bit aligned addresses else a processor -// exception will be triggered. -// The order within the 32 bit values are: -// -------------- -// b3, b2, b1, b0 -// w1, w0 -#define pgm_read_with_offset(addr, res) \ - __asm__ ("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ - "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ - "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ - "slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \ - "ssr %0\n" /* Prepare to shift by offset (in bits) */ \ - "srl %0, %1\n" /* Shift right; now the requested byte is the first one */ \ - :"=r"(res), "=r"(addr) \ - :"1"(addr) \ - :); +#include -static inline uint8_t pgm_read_byte_inlined(const void* addr) { - register uint32_t res; - pgm_read_with_offset(addr, res); - return (uint8_t) res; /* This masks the lower byte from the returned word */ -} +#else //!ESP8266 -/* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */ -static inline uint16_t pgm_read_word_inlined(const void* addr) { - register uint32_t res; - pgm_read_with_offset(addr, res); - return (uint16_t) res; /* This masks the lower half-word from the returned word */ -} - -#define pgm_read_byte(addr) pgm_read_byte_inlined(addr) -#define pgm_read_word(addr) pgm_read_word_inlined(addr) -#ifdef __cplusplus - #define pgm_read_dword(addr) (*reinterpret_cast(addr)) - #define pgm_read_float(addr) (*reinterpret_cast(addr)) - #define pgm_read_ptr(addr) (*reinterpret_cast(addr)) -#else - #define pgm_read_dword(addr) (*(const uint32_t*)(addr)) - #define pgm_read_float(addr) (*(const float*)(addr)) - #define pgm_read_ptr(addr) (*(const void* const*)(addr)) +#ifndef ICACHE_RODATA_ATTR +#define ICACHE_RODATA_ATTR #endif -#else // ESP8266 +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef PGM_P +#define PGM_P const char * +#endif + +#ifndef PGM_VOID_P +#define PGM_VOID_P const void * +#endif + +#ifndef PSTR +#define PSTR +#endif #ifdef __cplusplus #define pgm_read_byte(addr) (*reinterpret_cast(addr)) #define pgm_read_word(addr) (*reinterpret_cast(addr)) #define pgm_read_dword(addr) (*reinterpret_cast(addr)) - #define pgm_read_float(addr) (*reinterpret_cast(addr)) - #define pgm_read_ptr(addr) (*reinterpret_cast(addr)) + #define pgm_read_float(addr) (*reinterpret_cast(addr)) + #define pgm_read_ptr(addr) (*reinterpret_cast(addr)) #else #define pgm_read_byte(addr) (*(const uint8_t*)(addr)) #define pgm_read_word(addr) (*(const uint16_t*)(addr)) #define pgm_read_dword(addr) (*(const uint32_t*)(addr)) - #define pgm_read_float(addr) (*(const float)(addr)) - #define pgm_read_ptr(addr) (*(const void* const *)(addr)) + #define pgm_read_float(addr) (*(const float*)(addr)) + #define pgm_read_ptr(addr) (*(const void const *)(addr)) #endif - -#endif // ESP8266 - #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr) @@ -119,24 +56,9 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) { #define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr) -#define _SFR_BYTE(n) (n) +#define memcpy_P memcpy +#define memcmp_P memcmp -#ifdef __PROG_TYPES_COMPAT__ - -typedef void prog_void; -typedef char prog_char; -typedef unsigned char prog_uchar; -typedef int8_t prog_int8_t; -typedef uint8_t prog_uint8_t; -typedef int16_t prog_int16_t; -typedef uint16_t prog_uint16_t; -typedef int32_t prog_int32_t; -typedef uint32_t prog_uint32_t; - -#endif // defined(__PROG_TYPES_COMPAT__) - -#ifdef __cplusplus -} -#endif +#endif // !ESP8266 #endif diff --git a/lib/lib_ssl/bearssl-esp8266/src/rsa/rsa_pss_sig_unpad.c b/lib/lib_ssl/bearssl-esp8266/src/rsa/rsa_pss_sig_unpad.c index 50f4db06a..ba81018a3 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/rsa/rsa_pss_sig_unpad.c +++ b/lib/lib_ssl/bearssl-esp8266/src/rsa/rsa_pss_sig_unpad.c @@ -114,7 +114,7 @@ br_rsa_pss_sig_unpad(const br_hash_class *hf_data, * in the string. */ for (u = 0; u < hash_len; u ++) { - r |= tmp[u] ^ x[(xlen - salt_len - 1) + u]; + r |= tmp[u] ^ x[(xlen - hash_len - 1) + u]; } return EQ0(r); diff --git a/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_engine.c b/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_engine.c index fdd4d5bb7..efd3eabfd 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_engine.c +++ b/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_engine.c @@ -1232,6 +1232,21 @@ void br_ssl_engine_close(br_ssl_engine_context *cc) { if (!br_ssl_engine_closed(cc)) { + /* + * If we are not already closed, then we need to + * initiate the closure. Once closing, any incoming + * application data is discarded; we should also discard + * application data which is already there but has not + * been acknowledged by the application yet (this mimics + * usual semantics on BSD sockets: you cannot read() + * once you called close(), even if there was some + * unread data already buffered). + */ + size_t len; + + if (br_ssl_engine_recvapp_buf(cc, &len) != NULL && len != 0) { + br_ssl_engine_recvapp_ack(cc, len); + } jump_handshake(cc, 1); } } diff --git a/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_rec_cbc.c b/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_rec_cbc.c index 5219795c8..e49f9fb98 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_rec_cbc.c +++ b/lib/lib_ssl/bearssl-esp8266/src/ssl/ssl_rec_cbc.c @@ -136,7 +136,7 @@ cbc_decrypt(br_sslrec_in_cbc_context *cc, /* * Use the last decrypted byte to compute the actual payload - * length. Take care not to underflow (we use unsigned types). + * length. Take care not to overflow (we use unsigned types). */ pad_len = buf[max_len]; good = LE(pad_len, (uint32_t)(max_len - min_len)); diff --git a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl.h b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl.h index 959fad72a..50752a682 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl.h +++ b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl.h @@ -137,9 +137,13 @@ #include "t_bearssl_x509.h" #include "t_bearssl_pem.h" +#ifdef __cplusplus +extern "C" { +#endif + /** \brief Type for a configuration option. * - * A "t_configuration option" is a value that is selected when the BearSSL + * A "configuration option" is a value that is selected when the BearSSL * library itself is compiled. Most options are boolean; their value is * then either 1 (option is enabled) or 0 (option is disabled). Some * values have other integer values. Option names correspond to macro @@ -167,4 +171,13 @@ typedef struct { */ const br_config_option *br_get_config(void); +/* ======================================================================= */ + +/** \brief Version feature: support for time callback. */ +#define BR_FEATURE_X509_TIME_CALLBACK 1 + +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_ssl.h b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_ssl.h index df0d44f08..1c4d691c3 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_ssl.h +++ b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_ssl.h @@ -1251,8 +1251,8 @@ static inline void br_ssl_engine_set_versions(br_ssl_engine_context *cc, unsigned version_min, unsigned version_max) { - cc->version_min = version_min; - cc->version_max = version_max; + cc->version_min = (uint16_t)version_min; + cc->version_max = (uint16_t)version_max; } /** @@ -1325,7 +1325,7 @@ br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, const char **names, size_t num) { ctx->protocol_names = names; - ctx->protocol_names_num = num; + ctx->protocol_names_num = (uint16_t)num; } /** diff --git a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_x509.h b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_x509.h index 47ed4e505..d5a6b6554 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_x509.h +++ b/lib/lib_ssl/bearssl-esp8266/src/t_bearssl_x509.h @@ -890,7 +890,10 @@ void br_x509_minimal_init_full(br_x509_minimal_context *ctx, * - Seconds are counted since midnight, from 0 to 86400 (a count of * 86400 is possible only if a leap second happened). * - * The validation date and time is understood in the UTC time zone. + * The validation date and time is understood in the UTC time zone. The + * "Unix Epoch" (January 1st, 1970, 00:00 UTC) corresponds to days=719528 + * and seconds=0; the "Windows Epoch" (January 1st, 1601, 00:00 UTC) is + * days=584754, seconds=0. * * If the validation date and time are not explicitly set, but BearSSL * was compiled with support for the system clock on the underlying diff --git a/lib/lib_ssl/bearssl-esp8266/src/t_inner.h b/lib/lib_ssl/bearssl-esp8266/src/t_inner.h index c596c9f18..924486db7 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/t_inner.h +++ b/lib/lib_ssl/bearssl-esp8266/src/t_inner.h @@ -325,9 +325,20 @@ * values are documented on: * https://sourceforge.net/p/predef/wiki/OperatingSystems/ * - * TODO: enrich the list of detected system. Also add detection for - * alternate system calls like getentropy(), which are usually - * preferable when available. + * Win32's CryptGenRandom() should be available on Windows systems. + * + * /dev/urandom should work on all Unix-like systems (including macOS X). + * + * getentropy() is present on Linux (Glibc 2.25+), FreeBSD (12.0+) and + * OpenBSD (5.6+). For OpenBSD, there does not seem to be easy to use + * macros to test the minimum version, so we just assume that it is + * recent enough (last version without getentropy() has gone out of + * support in May 2015). + * + * Ideally we should use getentropy() on macOS (10.12+) too, but I don't + * know how to test the exact OS version with preprocessor macros. + * + * TODO: enrich the list of detected system. */ #ifndef BR_USE_URANDOM @@ -344,6 +355,15 @@ #endif #endif +#ifndef BR_USE_GETENTROPY +#if (defined __linux__ \ + && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) \ + || (defined __FreeBSD__ && __FreeBSD__ >= 12) \ + || defined __OpenBSD__ +#define BR_USE_GETENTROPY 1 +#endif +#endif + #ifndef BR_USE_WIN32_RAND #if defined _WIN32 || defined _WIN64 #define BR_USE_WIN32_RAND 1 diff --git a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c index 12e4cd2d4..0d92e7b25 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c +++ b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c @@ -525,7 +525,7 @@ static const unsigned char t0_codeblock[] PROGMEM = { 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, - 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_DN), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_SERVER_NAME), 0x00, 0x00, 0x01, @@ -563,227 +563,224 @@ static const unsigned char t0_codeblock[] PROGMEM = { T0_INT2(offsetof(CONTEXT_NAME, next_dn_hash)), 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, num_certs)), 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, - T0_INT2(offsetof(CONTEXT_NAME, saved_dn_hash)), 0x00, 0x00, 0xC9, 0x71, - 0x00, 0x00, 0x01, 0x80, 0x73, 0x00, 0x00, 0x01, 0x80, 0x7C, 0x00, 0x00, - 0x01, 0x81, 0x02, 0x00, 0x00, 0x92, 0x05, 0x05, 0x34, 0x42, 0x01, 0x00, - 0x00, 0x34, 0x01, 0x0A, 0x0E, 0x09, 0x01, 0x9A, 0xFF, 0xB8, 0x00, 0x0A, - 0x00, 0x00, 0x01, 0x82, 0x19, 0x00, 0x00, 0x01, 0x82, 0x01, 0x00, 0x00, - 0x01, 0x81, 0x68, 0x00, 0x04, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, - 0x03, 0x02, 0x03, 0x02, 0x01, 0x11, 0x06, 0x07, 0x02, 0x02, 0x02, 0x00, - 0x0D, 0x04, 0x05, 0x02, 0x03, 0x02, 0x01, 0x0D, 0x00, 0x02, 0x03, 0x00, - 0x03, 0x01, 0x25, 0x02, 0x01, 0x13, 0x3B, 0x02, 0x00, 0x0F, 0x15, 0x00, - 0x00, 0x01, 0x81, 0x74, 0x00, 0x00, 0x05, 0x02, 0x52, 0x28, 0x00, 0x00, - 0x06, 0x02, 0x53, 0x28, 0x00, 0x00, 0x01, 0x10, 0x77, 0x00, 0x00, 0x11, - 0x05, 0x02, 0x56, 0x28, 0x74, 0x00, 0x00, 0x11, 0x05, 0x02, 0x56, 0x28, - 0x75, 0x00, 0x00, 0x06, 0x02, 0x4C, 0x28, 0x00, 0x00, 0x01, 0x82, 0x11, - 0x00, 0x00, 0x25, 0x20, 0x01, 0x08, 0x0E, 0x3B, 0x40, 0x20, 0x09, 0x00, - 0x09, 0x03, 0x00, 0x5B, 0x2B, 0xAF, 0x39, 0xAF, 0xB3, 0x25, 0x01, 0x20, - 0x11, 0x06, 0x11, 0x24, 0x74, 0xAD, 0xB3, 0x01, 0x02, 0x78, 0xB0, 0x01, - 0x02, 0x12, 0x06, 0x02, 0x57, 0x28, 0x79, 0xB3, 0x01, 0x02, 0x78, 0xAE, - 0xAF, 0xC2, 0x9C, 0x65, 0x61, 0x21, 0x16, 0xAF, 0xA7, 0x29, 0x69, 0x06, - 0x02, 0x4B, 0x28, 0xA7, 0x29, 0x71, 0x06, 0x02, 0x4B, 0x28, 0x79, 0x02, - 0x00, 0x06, 0x05, 0x9D, 0x03, 0x01, 0x04, 0x09, 0x9C, 0x61, 0x68, 0x21, - 0x27, 0x05, 0x02, 0x4A, 0x28, 0x68, 0x65, 0x21, 0x16, 0xAF, 0xAF, 0x9E, - 0x05, 0x02, 0x57, 0x28, 0xBC, 0x26, 0x06, 0x27, 0xC2, 0xA4, 0xAF, 0x63, - 0xAA, 0x03, 0x03, 0x63, 0x3B, 0x02, 0x03, 0x09, 0x3B, 0x02, 0x03, 0x0A, - 0xAA, 0x03, 0x04, 0x79, 0x64, 0x2A, 0x01, 0x81, 0x00, 0x09, 0x02, 0x03, - 0x12, 0x06, 0x02, 0x58, 0x28, 0x79, 0x5A, 0x03, 0x02, 0x04, 0x3A, 0x88, - 0x26, 0x06, 0x34, 0x9E, 0x05, 0x02, 0x57, 0x28, 0x6A, 0x26, 0x06, 0x04, - 0x01, 0x17, 0x04, 0x12, 0x6B, 0x26, 0x06, 0x04, 0x01, 0x18, 0x04, 0x0A, - 0x6C, 0x26, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, 0x57, 0x28, 0x03, 0x05, - 0x79, 0xA4, 0x25, 0x03, 0x06, 0x25, 0x63, 0x34, 0x0D, 0x06, 0x02, 0x50, - 0x28, 0xA5, 0x59, 0x03, 0x02, 0x04, 0x02, 0x57, 0x28, 0x79, 0x02, 0x00, - 0x06, 0x21, 0x02, 0x02, 0x5A, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x03, - 0x02, 0x04, 0x1D, 0x04, 0x10, 0x59, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, - 0x05, 0x02, 0x06, 0x1C, 0x04, 0x03, 0x57, 0x28, 0x24, 0x04, 0x24, 0x02, - 0x02, 0x5A, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x03, 0x02, 0x04, 0x23, - 0x04, 0x10, 0x59, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x05, 0x02, 0x06, - 0x22, 0x04, 0x03, 0x57, 0x28, 0x24, 0x25, 0x06, 0x01, 0x28, 0x24, 0x01, - 0x00, 0x03, 0x07, 0xB4, 0x01, 0x21, 0x8F, 0x01, 0x22, 0x8F, 0x25, 0x01, - 0x23, 0x11, 0x06, 0x81, 0x20, 0x24, 0x74, 0xAD, 0xAF, 0x25, 0x06, 0x81, - 0x14, 0x01, 0x00, 0x03, 0x08, 0xAF, 0x9E, 0x24, 0xB3, 0x25, 0x01, 0x01, - 0x11, 0x06, 0x04, 0xA6, 0x03, 0x08, 0xB3, 0x01, 0x04, 0x78, 0xAD, 0x70, - 0x26, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC3, 0x04, 0x05, 0x99, 0x01, - 0x7F, 0x03, 0x07, 0x04, 0x80, 0x66, 0x91, 0x26, 0x06, 0x06, 0x02, 0x00, - 0x9B, 0x04, 0x80, 0x5C, 0xC5, 0x26, 0x06, 0x11, 0x02, 0x00, 0x06, 0x09, - 0x01, 0x00, 0x03, 0x01, 0x98, 0x03, 0x01, 0x04, 0x01, 0xC3, 0x04, 0x80, - 0x47, 0x73, 0x26, 0x06, 0x0A, 0x02, 0x08, 0x06, 0x03, 0x9A, 0x04, 0x01, - 0xC3, 0x04, 0x39, 0x6F, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x32, 0xC8, 0x26, - 0x06, 0x03, 0xC3, 0x04, 0x2B, 0x90, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x24, - 0xC6, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x1D, 0x7A, 0x26, 0x06, 0x03, 0xC3, - 0x04, 0x16, 0x85, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x0F, 0x6E, 0x26, 0x06, - 0x03, 0xC3, 0x04, 0x08, 0xC7, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x01, 0xC3, - 0x79, 0x79, 0x04, 0xFE, 0x68, 0x79, 0x79, 0x04, 0x08, 0x01, 0x7F, 0x11, - 0x05, 0x02, 0x56, 0x28, 0x24, 0x79, 0x3A, 0x02, 0x00, 0x06, 0x08, 0x02, - 0x01, 0x3C, 0x2F, 0x05, 0x02, 0x45, 0x28, 0x02, 0x00, 0x06, 0x01, 0x17, - 0x02, 0x00, 0x02, 0x07, 0x2F, 0x05, 0x02, 0x51, 0x28, 0xB3, 0x76, 0xAD, - 0x9E, 0x06, 0x80, 0x77, 0xBD, 0x26, 0x06, 0x07, 0x01, 0x02, 0x5A, 0x8A, - 0x04, 0x80, 0x5E, 0xBE, 0x26, 0x06, 0x07, 0x01, 0x03, 0x5A, 0x8B, 0x04, - 0x80, 0x53, 0xBF, 0x26, 0x06, 0x07, 0x01, 0x04, 0x5A, 0x8C, 0x04, 0x80, - 0x48, 0xC0, 0x26, 0x06, 0x06, 0x01, 0x05, 0x5A, 0x8D, 0x04, 0x3E, 0xC1, - 0x26, 0x06, 0x06, 0x01, 0x06, 0x5A, 0x8E, 0x04, 0x34, 0x7F, 0x26, 0x06, - 0x06, 0x01, 0x02, 0x59, 0x8A, 0x04, 0x2A, 0x80, 0x26, 0x06, 0x06, 0x01, - 0x03, 0x59, 0x8B, 0x04, 0x20, 0x81, 0x26, 0x06, 0x06, 0x01, 0x04, 0x59, - 0x8C, 0x04, 0x16, 0x82, 0x26, 0x06, 0x06, 0x01, 0x05, 0x59, 0x8D, 0x04, - 0x0C, 0x83, 0x26, 0x06, 0x06, 0x01, 0x06, 0x59, 0x8E, 0x04, 0x02, 0x57, - 0x28, 0x5E, 0x35, 0x60, 0x37, 0x1B, 0x25, 0x05, 0x02, 0x57, 0x28, 0x5D, - 0x37, 0x04, 0x02, 0x57, 0x28, 0xC2, 0xA4, 0x25, 0x01, - T0_INT2(BR_X509_BUFSIZE_SIG), 0x12, 0x06, 0x02, 0x50, 0x28, 0x25, 0x5F, - 0x35, 0x5C, 0xA5, 0x79, 0x79, 0x01, 0x00, 0x5B, 0x36, 0x18, 0x00, 0x00, - 0x01, 0x30, 0x0A, 0x25, 0x01, 0x00, 0x01, 0x09, 0x72, 0x05, 0x02, 0x48, - 0x28, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x01, 0x81, 0x08, 0x00, 0x00, - 0x01, 0x81, 0x10, 0x00, 0x00, 0x01, 0x81, 0x19, 0x00, 0x00, 0x01, 0x81, - 0x22, 0x00, 0x00, 0x01, 0x81, 0x2B, 0x00, 0x01, 0x7E, 0x01, 0x01, 0x11, - 0x3B, 0x01, 0x83, 0xFD, 0x7F, 0x11, 0x15, 0x06, 0x03, 0x3B, 0x24, 0x00, - 0x3B, 0x25, 0x03, 0x00, 0x25, 0xCA, 0x05, 0x04, 0x42, 0x01, 0x00, 0x00, - 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x96, 0x04, 0x80, 0x49, 0x25, - 0x01, 0x90, 0x00, 0x0D, 0x06, 0x0F, 0x01, 0x06, 0x14, 0x01, 0x81, 0x40, - 0x2F, 0x96, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, 0x33, 0x25, 0x01, 0x83, - 0xFF, 0x7F, 0x0D, 0x06, 0x14, 0x01, 0x0C, 0x14, 0x01, 0x81, 0x60, 0x2F, - 0x96, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, - 0x17, 0x01, 0x12, 0x14, 0x01, 0x81, 0x70, 0x2F, 0x96, 0x02, 0x00, 0x01, - 0x0C, 0x97, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, 0x00, 0x97, - 0x00, 0x00, 0x01, 0x82, 0x15, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, - 0x01, 0x83, 0xB7, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x81, 0x34, 0x00, 0x00, - 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x81, 0x78, 0x00, 0x00, 0x01, 0x3D, - 0x00, 0x00, 0x01, 0x80, 0x43, 0x00, 0x00, 0x01, 0x80, 0x4D, 0x00, 0x00, - 0x01, 0x80, 0x57, 0x00, 0x00, 0x01, 0x80, 0x61, 0x00, 0x00, 0x30, 0x11, - 0x06, 0x04, 0x42, 0xAD, 0xC2, 0xB4, 0x00, 0x00, 0x01, 0x82, 0x09, 0x00, - 0x00, 0x01, 0x81, 0x6C, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB8, 0x00, 0x01, - 0x83, 0xBF, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x30, 0x62, 0x37, 0x01, 0x7F, - 0x7C, 0x19, 0x01, 0x00, 0x7C, 0x19, 0x04, 0x7A, 0x00, 0x01, 0x81, 0x38, - 0x00, 0x01, 0x7E, 0x0D, 0x06, 0x02, 0x4F, 0x28, 0x25, 0x03, 0x00, 0x0A, - 0x02, 0x00, 0x00, 0x00, 0x30, 0x25, 0x3F, 0x3B, 0x01, 0x82, 0x00, 0x13, - 0x2F, 0x06, 0x04, 0x42, 0x01, 0x00, 0x00, 0x30, 0x67, 0x09, 0x37, 0x40, - 0x00, 0x00, 0x14, 0x01, 0x3F, 0x15, 0x01, 0x81, 0x00, 0x2F, 0x96, 0x00, - 0x02, 0x01, 0x00, 0x03, 0x00, 0xAF, 0x25, 0x06, 0x80, 0x59, 0xB3, 0x01, - 0x20, 0x30, 0x11, 0x06, 0x17, 0x24, 0x74, 0xAD, 0x9E, 0x24, 0x01, 0x7F, - 0x2E, 0x03, 0x01, 0xB3, 0x01, 0x20, 0x77, 0xAD, 0xB2, 0x02, 0x01, 0x1F, - 0x79, 0x79, 0x04, 0x38, 0x01, 0x21, 0x30, 0x11, 0x06, 0x08, 0x24, 0x75, - 0xB6, 0x01, 0x01, 0x1E, 0x04, 0x2A, 0x01, 0x22, 0x30, 0x11, 0x06, 0x11, - 0x24, 0x75, 0xB6, 0x25, 0x06, 0x06, 0x2C, 0x02, 0x00, 0x2F, 0x03, 0x00, - 0x01, 0x02, 0x1E, 0x04, 0x13, 0x01, 0x26, 0x30, 0x11, 0x06, 0x08, 0x24, - 0x75, 0xB6, 0x01, 0x06, 0x1E, 0x04, 0x05, 0x42, 0xAE, 0x01, 0x00, 0x24, - 0x04, 0xFF, 0x23, 0x79, 0x02, 0x00, 0x00, 0x00, 0xAF, 0xB4, 0x25, 0x01, - 0x01, 0x11, 0x06, 0x08, 0xA6, 0x05, 0x02, 0x51, 0x28, 0xB4, 0x04, 0x02, - 0x51, 0x28, 0x25, 0x01, 0x02, 0x11, 0x06, 0x0C, 0x24, 0x75, 0xB0, 0x66, - 0x2B, 0x41, 0x0D, 0x06, 0x02, 0x51, 0x28, 0xB4, 0x01, 0x7F, 0x10, 0x06, - 0x02, 0x56, 0x28, 0x24, 0x79, 0x00, 0x00, 0xAF, 0x25, 0x06, 0x1A, 0xAF, - 0x9E, 0x24, 0x25, 0x06, 0x11, 0xAF, 0x25, 0x06, 0x0C, 0xAF, 0x9E, 0x24, - 0x89, 0x26, 0x05, 0x02, 0x49, 0x28, 0xC2, 0x04, 0x71, 0x79, 0x79, 0x04, - 0x63, 0x79, 0x00, 0x02, 0x03, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, - 0x03, 0x01, 0x02, 0x01, 0x01, 0x07, 0x12, 0x06, 0x02, 0x56, 0x28, 0x25, - 0x01, 0x00, 0x30, 0x11, 0x06, 0x05, 0x24, 0x4D, 0x28, 0x04, 0x15, 0x01, - 0x01, 0x30, 0x11, 0x06, 0x0A, 0x24, 0xBA, 0x02, 0x01, 0x14, 0x02, 0x01, - 0x0E, 0x04, 0x05, 0x24, 0xBA, 0x01, 0x00, 0x24, 0x02, 0x00, 0x06, 0x19, - 0x01, 0x00, 0x30, 0x01, 0x38, 0x15, 0x06, 0x03, 0x01, 0x10, 0x2F, 0x3B, - 0x01, 0x81, 0x40, 0x15, 0x06, 0x03, 0x01, 0x20, 0x2F, 0x62, 0x37, 0x04, - 0x07, 0x01, 0x04, 0x15, 0x05, 0x02, 0x4D, 0x28, 0xC2, 0x00, 0x00, 0x38, - 0xAF, 0xC2, 0x1A, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0x38, 0xAF, 0x25, - 0x06, 0x30, 0xB3, 0x01, 0x11, 0x77, 0xAD, 0x25, 0x05, 0x02, 0x44, 0x28, - 0x25, 0x06, 0x20, 0xAF, 0x9E, 0x24, 0x87, 0x26, 0x03, 0x01, 0x01, 0x00, - 0x2E, 0x03, 0x02, 0xB2, 0x25, 0x02, 0x01, 0x15, 0x06, 0x07, 0x2C, 0x06, - 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x02, 0x1F, 0x79, 0x04, 0x5D, 0x79, - 0x04, 0x4D, 0x79, 0x1A, 0x02, 0x00, 0x00, 0x00, 0xB3, 0x01, 0x06, 0x78, - 0xB1, 0x00, 0x00, 0xB8, 0x86, 0x06, 0x0E, 0x3B, 0x25, 0x05, 0x06, 0x42, - 0x01, 0x00, 0x01, 0x00, 0x00, 0xB8, 0x6D, 0x04, 0x08, 0x92, 0x06, 0x05, - 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB9, 0x86, 0x06, 0x0E, 0x3B, - 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0xB9, 0x6D, 0x04, - 0x08, 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xBA, - 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x00, 0x04, 0x80, 0x55, 0x25, - 0x01, 0x81, 0x40, 0x0D, 0x06, 0x07, 0x24, 0x01, 0x00, 0x00, 0x04, 0x80, - 0x47, 0x25, 0x01, 0x81, 0x60, 0x0D, 0x06, 0x0E, 0x01, 0x1F, 0x15, 0x01, - 0x01, 0xA3, 0x01, 0x81, 0x00, 0x01, 0x8F, 0x7F, 0x04, 0x32, 0x25, 0x01, - 0x81, 0x70, 0x0D, 0x06, 0x0F, 0x01, 0x0F, 0x15, 0x01, 0x02, 0xA3, 0x01, - 0x90, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x04, 0x1C, 0x25, 0x01, 0x81, 0x78, - 0x0D, 0x06, 0x11, 0x01, 0x07, 0x15, 0x01, 0x03, 0xA3, 0x01, 0x84, 0x80, - 0x00, 0x01, 0x80, 0xC3, 0xFF, 0x7F, 0x04, 0x04, 0x24, 0x01, 0x00, 0x00, - 0x72, 0x05, 0x03, 0x24, 0x01, 0x00, 0x00, 0x00, 0x3B, 0x25, 0x05, 0x06, - 0x42, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xBA, 0x34, 0x25, 0x3D, 0x06, 0x03, - 0x3B, 0x24, 0x00, 0x01, 0x06, 0x0E, 0x3B, 0x25, 0x01, 0x06, 0x14, 0x01, - 0x02, 0x10, 0x06, 0x04, 0x42, 0x01, 0x7F, 0x00, 0x01, 0x3F, 0x15, 0x09, - 0x00, 0x00, 0x25, 0x06, 0x06, 0x0B, 0xA2, 0x34, 0x41, 0x04, 0x77, 0x24, - 0x25, 0x00, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, 0x06, 0x02, 0x55, - 0x28, 0x00, 0x00, 0x3B, 0x25, 0x06, 0x07, 0x31, 0x25, 0x06, 0x01, 0x19, - 0x04, 0x76, 0x42, 0x00, 0x00, 0x01, 0x01, 0x78, 0xAC, 0x01, 0x01, 0x10, - 0x06, 0x02, 0x43, 0x28, 0xBA, 0x3E, 0x00, 0x04, 0xB3, 0x25, 0x01, 0x17, - 0x01, 0x18, 0x72, 0x05, 0x02, 0x48, 0x28, 0x01, 0x18, 0x11, 0x03, 0x00, - 0x75, 0xAD, 0xA8, 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, - 0x01, 0xA8, 0x02, 0x01, 0x09, 0x04, 0x0E, 0x25, 0x01, 0x32, 0x0D, 0x06, - 0x04, 0x01, 0x80, 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, - 0x01, 0x01, 0x82, 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, - 0x0C, 0x09, 0x02, 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, - 0x0A, 0x02, 0x01, 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, - 0x03, 0x03, 0x01, 0x01, 0x01, 0x0C, 0xA9, 0x41, 0x01, 0x01, 0x0E, 0x02, - 0x01, 0x01, 0x04, 0x07, 0x3F, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x3E, - 0x02, 0x01, 0x01, 0x83, 0x10, 0x07, 0x3F, 0x2F, 0x15, 0x06, 0x03, 0x01, - 0x18, 0x09, 0x94, 0x09, 0x7B, 0x25, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, - 0x03, 0x03, 0x01, 0x1F, 0x15, 0x01, 0x01, 0x3B, 0xA9, 0x02, 0x03, 0x09, - 0x41, 0x03, 0x03, 0x01, 0x00, 0x01, 0x17, 0xA9, 0x01, 0x9C, 0x10, 0x08, - 0x03, 0x02, 0x01, 0x00, 0x01, 0x3B, 0xA9, 0x01, 0x3C, 0x08, 0x02, 0x02, - 0x09, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3C, 0xA9, 0x02, 0x02, 0x09, 0x03, - 0x02, 0xBA, 0x25, 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x24, 0xBA, 0x25, 0x01, - 0x30, 0x01, 0x39, 0x72, 0x06, 0x03, 0x24, 0x04, 0x74, 0x01, 0x80, 0x5A, - 0x10, 0x06, 0x02, 0x48, 0x28, 0x79, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, - 0xBA, 0x7D, 0x01, 0x0A, 0x08, 0x03, 0x00, 0xBA, 0x7D, 0x02, 0x00, 0x09, - 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0xA8, 0x25, 0x02, 0x01, 0x02, 0x00, - 0x72, 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x34, 0xB3, 0x01, 0x02, 0x78, - 0x0B, 0xAB, 0x00, 0x03, 0x25, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0xAD, - 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, 0x28, 0x25, 0x01, - 0x00, 0x11, 0x06, 0x0B, 0x24, 0x25, 0x05, 0x04, 0x24, 0x01, 0x00, 0x00, - 0xBA, 0x04, 0x6F, 0x02, 0x01, 0x25, 0x05, 0x02, 0x50, 0x28, 0x41, 0x03, - 0x01, 0x02, 0x02, 0x37, 0x02, 0x02, 0x40, 0x03, 0x02, 0x25, 0x06, 0x03, - 0xBA, 0x04, 0x68, 0x24, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0xBA, - 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, - 0x25, 0x05, 0x02, 0x4E, 0x28, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x12, 0x06, 0x19, 0x02, 0x00, 0x41, 0x03, 0x00, 0x25, 0x01, 0x83, - 0xFF, 0xFF, 0x7F, 0x12, 0x06, 0x02, 0x4F, 0x28, 0x01, 0x08, 0x0E, 0x3B, - 0xBA, 0x34, 0x09, 0x04, 0x60, 0x00, 0x00, 0xAC, 0x95, 0x00, 0x00, 0xAD, - 0xC2, 0x00, 0x00, 0xB3, 0x76, 0xAD, 0x00, 0x01, 0xAD, 0x25, 0x05, 0x02, - 0x54, 0x28, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, 0x28, - 0x03, 0x00, 0x25, 0x06, 0x16, 0xBA, 0x02, 0x00, 0x25, 0x01, 0x87, 0xFF, - 0xFF, 0x7F, 0x13, 0x06, 0x02, 0x54, 0x28, 0x01, 0x08, 0x0E, 0x09, 0x03, - 0x00, 0x04, 0x67, 0x24, 0x02, 0x00, 0x00, 0x00, 0xAD, 0x25, 0x01, 0x81, - 0x7F, 0x12, 0x06, 0x08, 0xC2, 0x01, 0x00, 0x67, 0x37, 0x01, 0x00, 0x00, - 0x25, 0x67, 0x37, 0x67, 0x40, 0xA5, 0x01, 0x7F, 0x00, 0x00, 0xB3, 0x01, - 0x0C, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB6, 0x04, 0x3E, 0x01, 0x12, - 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x33, 0x01, 0x13, 0x30, - 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x28, 0x01, 0x14, 0x30, 0x11, - 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x1D, 0x01, 0x16, 0x30, 0x11, 0x06, - 0x05, 0x24, 0x75, 0xB7, 0x04, 0x12, 0x01, 0x1E, 0x30, 0x11, 0x06, 0x05, - 0x24, 0x75, 0xB5, 0x04, 0x07, 0x42, 0xAE, 0x01, 0x00, 0x01, 0x00, 0x24, - 0x00, 0x01, 0xBA, 0x03, 0x00, 0x02, 0x00, 0x01, 0x05, 0x14, 0x01, 0x01, - 0x15, 0x2D, 0x02, 0x00, 0x01, 0x06, 0x14, 0x25, 0x01, 0x01, 0x15, 0x06, - 0x02, 0x46, 0x28, 0x01, 0x04, 0x0E, 0x02, 0x00, 0x01, 0x1F, 0x15, 0x25, - 0x01, 0x1F, 0x11, 0x06, 0x02, 0x47, 0x28, 0x09, 0x00, 0x00, 0x25, 0x05, - 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xB3, 0x00, 0x01, 0xAD, 0x25, 0x05, - 0x05, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0x01, 0x03, 0x00, 0x9F, 0x25, - 0x01, 0x83, 0xFF, 0x7E, 0x11, 0x06, 0x16, 0x24, 0x25, 0x06, 0x10, 0xA0, - 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, - 0x00, 0x04, 0x6D, 0x04, 0x1B, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, - 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x25, 0x06, 0x0B, 0x9F, 0x25, 0x05, - 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x6D, 0x24, 0x02, 0x00, 0x25, - 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0xAD, 0x01, - 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xA1, 0x25, 0x05, 0x05, 0x24, 0xC2, - 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, 0x24, 0x02, - 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, - 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xBA, 0x25, 0x05, 0x05, - 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, - 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, - 0x00, 0x00, 0xBA, 0x01, 0x08, 0x0E, 0x3B, 0xBA, 0x34, 0x09, 0x00, 0x00, - 0xBA, 0x3B, 0xBA, 0x01, 0x08, 0x0E, 0x34, 0x09, 0x00, 0x00, 0x25, 0x05, - 0x02, 0x4F, 0x28, 0x41, 0xBB, 0x00, 0x00, 0x32, 0x25, 0x01, 0x00, 0x13, - 0x06, 0x01, 0x00, 0x24, 0x19, 0x04, 0x74, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, - 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0xC3, 0x24, 0x00, 0x00, - 0x25, 0x06, 0x07, 0xC4, 0x25, 0x06, 0x01, 0x19, 0x04, 0x76, 0x00, 0x00, - 0x01, 0x00, 0x30, 0x31, 0x0B, 0x42, 0x00, 0x00, 0x01, 0x81, 0x70, 0x00, - 0x00, 0x01, 0x82, 0x0D, 0x00, 0x00, 0x01, 0x82, 0x22, 0x00, 0x00, 0x01, - 0x82, 0x05, 0x00, 0x00, 0x01, 0x03, 0x33, 0x01, 0x03, 0x33, 0x00, 0x00, - 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F, 0x72, 0x06, 0x04, - 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xBF, - 0x7F, 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x01, 0x83, 0xFF, 0x7F, - 0x15, 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 + T0_INT2(offsetof(CONTEXT_NAME, saved_dn_hash)), 0x00, 0x00, 0x01, 0x80, + 0x73, 0x00, 0x00, 0x01, 0x80, 0x7C, 0x00, 0x00, 0x01, 0x81, 0x02, 0x00, + 0x00, 0x8F, 0x05, 0x05, 0x33, 0x41, 0x01, 0x00, 0x00, 0x33, 0x01, 0x0A, + 0x0E, 0x09, 0x01, 0x9A, 0xFF, 0xB8, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x82, + 0x19, 0x00, 0x00, 0x01, 0x82, 0x01, 0x00, 0x00, 0x01, 0x81, 0x68, 0x00, + 0x02, 0x03, 0x00, 0x03, 0x01, 0x26, 0x02, 0x01, 0x13, 0x3A, 0x02, 0x00, + 0x0F, 0x15, 0x00, 0x00, 0x01, 0x81, 0x74, 0x00, 0x00, 0x05, 0x02, 0x51, + 0x29, 0x00, 0x00, 0x06, 0x02, 0x52, 0x29, 0x00, 0x00, 0x01, 0x10, 0x74, + 0x00, 0x00, 0x11, 0x05, 0x02, 0x55, 0x29, 0x71, 0x00, 0x00, 0x11, 0x05, + 0x02, 0x55, 0x29, 0x72, 0x00, 0x00, 0x06, 0x02, 0x4B, 0x29, 0x00, 0x00, + 0x01, 0x82, 0x11, 0x00, 0x00, 0x26, 0x21, 0x01, 0x08, 0x0E, 0x3A, 0x3F, + 0x21, 0x09, 0x00, 0x0B, 0x03, 0x00, 0x5A, 0x2B, 0xAC, 0x38, 0xAC, 0xB0, + 0x26, 0x01, 0x20, 0x11, 0x06, 0x11, 0x25, 0x71, 0xAA, 0xB0, 0x01, 0x02, + 0x75, 0xAD, 0x01, 0x02, 0x12, 0x06, 0x02, 0x56, 0x29, 0x76, 0xB0, 0x01, + 0x02, 0x75, 0xAB, 0xAC, 0xBF, 0x99, 0x64, 0x60, 0x22, 0x16, 0xAC, 0xA4, + 0x03, 0x01, 0x03, 0x02, 0xA4, 0x02, 0x02, 0x02, 0x01, 0x19, 0x06, 0x02, + 0x4A, 0x29, 0x76, 0x02, 0x00, 0x06, 0x05, 0x9A, 0x03, 0x03, 0x04, 0x09, + 0x99, 0x60, 0x67, 0x22, 0x28, 0x05, 0x02, 0x49, 0x29, 0x67, 0x64, 0x22, + 0x16, 0xAC, 0xAC, 0x9B, 0x05, 0x02, 0x56, 0x29, 0xB9, 0x27, 0x06, 0x27, + 0xBF, 0xA1, 0xAC, 0x62, 0xA7, 0x03, 0x05, 0x62, 0x3A, 0x02, 0x05, 0x09, + 0x3A, 0x02, 0x05, 0x0A, 0xA7, 0x03, 0x06, 0x76, 0x63, 0x2A, 0x01, 0x81, + 0x00, 0x09, 0x02, 0x05, 0x12, 0x06, 0x02, 0x57, 0x29, 0x76, 0x59, 0x03, + 0x04, 0x04, 0x3A, 0x85, 0x27, 0x06, 0x34, 0x9B, 0x05, 0x02, 0x56, 0x29, + 0x68, 0x27, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x69, 0x27, 0x06, 0x04, + 0x01, 0x18, 0x04, 0x0A, 0x6A, 0x27, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, + 0x56, 0x29, 0x03, 0x07, 0x76, 0xA1, 0x26, 0x03, 0x08, 0x26, 0x62, 0x33, + 0x0D, 0x06, 0x02, 0x4F, 0x29, 0xA2, 0x58, 0x03, 0x04, 0x04, 0x02, 0x56, + 0x29, 0x76, 0x02, 0x00, 0x06, 0x21, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06, + 0x08, 0x25, 0x02, 0x05, 0x02, 0x06, 0x1E, 0x04, 0x10, 0x58, 0x30, 0x11, + 0x06, 0x08, 0x25, 0x02, 0x07, 0x02, 0x08, 0x1D, 0x04, 0x03, 0x56, 0x29, + 0x25, 0x04, 0x24, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06, 0x08, 0x25, 0x02, + 0x05, 0x02, 0x06, 0x24, 0x04, 0x10, 0x58, 0x30, 0x11, 0x06, 0x08, 0x25, + 0x02, 0x07, 0x02, 0x08, 0x23, 0x04, 0x03, 0x56, 0x29, 0x25, 0x26, 0x06, + 0x01, 0x29, 0x25, 0x01, 0x00, 0x03, 0x09, 0xB1, 0x01, 0x21, 0x8C, 0x01, + 0x22, 0x8C, 0x26, 0x01, 0x23, 0x11, 0x06, 0x81, 0x26, 0x25, 0x71, 0xAA, + 0xAC, 0x26, 0x06, 0x81, 0x1A, 0x01, 0x00, 0x03, 0x0A, 0xAC, 0x9B, 0x25, + 0xB0, 0x26, 0x01, 0x01, 0x11, 0x06, 0x04, 0xA3, 0x03, 0x0A, 0xB0, 0x01, + 0x04, 0x75, 0xAA, 0x6E, 0x27, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC0, + 0x04, 0x05, 0x96, 0x01, 0x7F, 0x03, 0x09, 0x04, 0x80, 0x6C, 0x8E, 0x27, + 0x06, 0x06, 0x02, 0x00, 0x98, 0x04, 0x80, 0x62, 0xC2, 0x27, 0x06, 0x11, + 0x02, 0x00, 0x06, 0x09, 0x01, 0x00, 0x03, 0x03, 0x95, 0x03, 0x03, 0x04, + 0x01, 0xC0, 0x04, 0x80, 0x4D, 0x70, 0x27, 0x06, 0x0A, 0x02, 0x0A, 0x06, + 0x03, 0x97, 0x04, 0x01, 0xC0, 0x04, 0x3F, 0x6D, 0x27, 0x06, 0x03, 0xC0, + 0x04, 0x38, 0xC5, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x31, 0x8D, 0x27, 0x06, + 0x03, 0xC0, 0x04, 0x2A, 0xC3, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x23, 0x77, + 0x27, 0x06, 0x03, 0xC0, 0x04, 0x1C, 0x82, 0x27, 0x06, 0x03, 0xC0, 0x04, + 0x15, 0x6C, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x0E, 0xC4, 0x27, 0x06, 0x03, + 0xC0, 0x04, 0x07, 0x02, 0x0A, 0x06, 0x02, 0x48, 0x29, 0xC0, 0x76, 0x76, + 0x04, 0xFE, 0x62, 0x76, 0x76, 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, + 0x55, 0x29, 0x25, 0x76, 0x39, 0x02, 0x00, 0x06, 0x08, 0x02, 0x03, 0x3B, + 0x2F, 0x05, 0x02, 0x44, 0x29, 0x02, 0x00, 0x06, 0x01, 0x17, 0x02, 0x00, + 0x02, 0x09, 0x2F, 0x05, 0x02, 0x50, 0x29, 0xB0, 0x73, 0xAA, 0x9B, 0x06, + 0x80, 0x77, 0xBA, 0x27, 0x06, 0x07, 0x01, 0x02, 0x59, 0x87, 0x04, 0x80, + 0x5E, 0xBB, 0x27, 0x06, 0x07, 0x01, 0x03, 0x59, 0x88, 0x04, 0x80, 0x53, + 0xBC, 0x27, 0x06, 0x07, 0x01, 0x04, 0x59, 0x89, 0x04, 0x80, 0x48, 0xBD, + 0x27, 0x06, 0x06, 0x01, 0x05, 0x59, 0x8A, 0x04, 0x3E, 0xBE, 0x27, 0x06, + 0x06, 0x01, 0x06, 0x59, 0x8B, 0x04, 0x34, 0x7C, 0x27, 0x06, 0x06, 0x01, + 0x02, 0x58, 0x87, 0x04, 0x2A, 0x7D, 0x27, 0x06, 0x06, 0x01, 0x03, 0x58, + 0x88, 0x04, 0x20, 0x7E, 0x27, 0x06, 0x06, 0x01, 0x04, 0x58, 0x89, 0x04, + 0x16, 0x7F, 0x27, 0x06, 0x06, 0x01, 0x05, 0x58, 0x8A, 0x04, 0x0C, 0x80, + 0x27, 0x06, 0x06, 0x01, 0x06, 0x58, 0x8B, 0x04, 0x02, 0x56, 0x29, 0x5D, + 0x34, 0x5F, 0x36, 0x1C, 0x26, 0x05, 0x02, 0x56, 0x29, 0x5C, 0x36, 0x04, + 0x02, 0x56, 0x29, 0xBF, 0xA1, 0x26, 0x01, T0_INT2(BR_X509_BUFSIZE_SIG), + 0x12, 0x06, 0x02, 0x4F, 0x29, 0x26, 0x5E, 0x34, 0x5B, 0xA2, 0x76, 0x76, + 0x01, 0x00, 0x5A, 0x35, 0x18, 0x00, 0x00, 0x01, 0x30, 0x0A, 0x26, 0x01, + 0x00, 0x01, 0x09, 0x6F, 0x05, 0x02, 0x47, 0x29, 0x00, 0x00, 0x30, 0x30, + 0x00, 0x00, 0x01, 0x81, 0x08, 0x00, 0x00, 0x01, 0x81, 0x10, 0x00, 0x00, + 0x01, 0x81, 0x19, 0x00, 0x00, 0x01, 0x81, 0x22, 0x00, 0x00, 0x01, 0x81, + 0x2B, 0x00, 0x01, 0x7B, 0x01, 0x01, 0x11, 0x3A, 0x01, 0x83, 0xFD, 0x7F, + 0x11, 0x15, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x3A, 0x26, 0x03, 0x00, 0x26, + 0xC6, 0x05, 0x04, 0x41, 0x01, 0x00, 0x00, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x04, 0x93, 0x04, 0x80, 0x49, 0x26, 0x01, 0x90, 0x00, 0x0D, 0x06, + 0x0F, 0x01, 0x06, 0x14, 0x01, 0x81, 0x40, 0x2F, 0x93, 0x02, 0x00, 0x01, + 0x00, 0x94, 0x04, 0x33, 0x26, 0x01, 0x83, 0xFF, 0x7F, 0x0D, 0x06, 0x14, + 0x01, 0x0C, 0x14, 0x01, 0x81, 0x60, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x06, + 0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x04, 0x17, 0x01, 0x12, 0x14, 0x01, + 0x81, 0x70, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x0C, 0x94, 0x02, 0x00, 0x01, + 0x06, 0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x00, 0x00, 0x01, 0x82, 0x15, + 0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xB7, 0x7F, 0x6F, + 0x00, 0x00, 0x01, 0x81, 0x34, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, + 0x01, 0x81, 0x78, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, 0x01, 0x80, 0x43, + 0x00, 0x00, 0x01, 0x80, 0x4D, 0x00, 0x00, 0x01, 0x80, 0x57, 0x00, 0x00, + 0x01, 0x80, 0x61, 0x00, 0x00, 0x30, 0x11, 0x06, 0x04, 0x41, 0xAA, 0xBF, + 0xB1, 0x00, 0x00, 0x01, 0x82, 0x09, 0x00, 0x00, 0x01, 0x81, 0x6C, 0x00, + 0x00, 0x26, 0x01, 0x83, 0xB8, 0x00, 0x01, 0x83, 0xBF, 0x7F, 0x6F, 0x00, + 0x00, 0x01, 0x30, 0x61, 0x36, 0x01, 0x7F, 0x79, 0x1A, 0x01, 0x00, 0x79, + 0x1A, 0x04, 0x7A, 0x00, 0x01, 0x81, 0x38, 0x00, 0x01, 0x7B, 0x0D, 0x06, + 0x02, 0x4E, 0x29, 0x26, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x30, + 0x26, 0x3E, 0x3A, 0x01, 0x82, 0x00, 0x13, 0x2F, 0x06, 0x04, 0x41, 0x01, + 0x00, 0x00, 0x30, 0x66, 0x09, 0x36, 0x3F, 0x00, 0x00, 0x14, 0x01, 0x3F, + 0x15, 0x01, 0x81, 0x00, 0x2F, 0x93, 0x00, 0x02, 0x01, 0x00, 0x03, 0x00, + 0xAC, 0x26, 0x06, 0x80, 0x59, 0xB0, 0x01, 0x20, 0x30, 0x11, 0x06, 0x17, + 0x25, 0x71, 0xAA, 0x9B, 0x25, 0x01, 0x7F, 0x2E, 0x03, 0x01, 0xB0, 0x01, + 0x20, 0x74, 0xAA, 0xAF, 0x02, 0x01, 0x20, 0x76, 0x76, 0x04, 0x38, 0x01, + 0x21, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x01, 0x1F, 0x04, + 0x2A, 0x01, 0x22, 0x30, 0x11, 0x06, 0x11, 0x25, 0x72, 0xB3, 0x26, 0x06, + 0x06, 0x2C, 0x02, 0x00, 0x2F, 0x03, 0x00, 0x01, 0x02, 0x1F, 0x04, 0x13, + 0x01, 0x26, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x06, 0x1F, + 0x04, 0x05, 0x41, 0xAB, 0x01, 0x00, 0x25, 0x04, 0xFF, 0x23, 0x76, 0x02, + 0x00, 0x00, 0x00, 0xAC, 0xB1, 0x26, 0x01, 0x01, 0x11, 0x06, 0x08, 0xA3, + 0x05, 0x02, 0x50, 0x29, 0xB1, 0x04, 0x02, 0x50, 0x29, 0x26, 0x01, 0x02, + 0x11, 0x06, 0x0C, 0x25, 0x72, 0xAD, 0x65, 0x2B, 0x40, 0x0D, 0x06, 0x02, + 0x50, 0x29, 0xB1, 0x01, 0x7F, 0x10, 0x06, 0x02, 0x55, 0x29, 0x25, 0x76, + 0x00, 0x00, 0xAC, 0x26, 0x06, 0x1A, 0xAC, 0x9B, 0x25, 0x26, 0x06, 0x11, + 0xAC, 0x26, 0x06, 0x0C, 0xAC, 0x9B, 0x25, 0x86, 0x27, 0x05, 0x02, 0x48, + 0x29, 0xBF, 0x04, 0x71, 0x76, 0x76, 0x04, 0x63, 0x76, 0x00, 0x02, 0x03, + 0x00, 0xB0, 0x01, 0x03, 0x75, 0xAA, 0xB7, 0x03, 0x01, 0x02, 0x01, 0x01, + 0x07, 0x12, 0x06, 0x02, 0x55, 0x29, 0x26, 0x01, 0x00, 0x30, 0x11, 0x06, + 0x05, 0x25, 0x4C, 0x29, 0x04, 0x15, 0x01, 0x01, 0x30, 0x11, 0x06, 0x0A, + 0x25, 0xB7, 0x02, 0x01, 0x14, 0x02, 0x01, 0x0E, 0x04, 0x05, 0x25, 0xB7, + 0x01, 0x00, 0x25, 0x02, 0x00, 0x06, 0x19, 0x01, 0x00, 0x30, 0x01, 0x38, + 0x15, 0x06, 0x03, 0x01, 0x10, 0x2F, 0x3A, 0x01, 0x81, 0x40, 0x15, 0x06, + 0x03, 0x01, 0x20, 0x2F, 0x61, 0x36, 0x04, 0x07, 0x01, 0x04, 0x15, 0x05, + 0x02, 0x4C, 0x29, 0xBF, 0x00, 0x00, 0x37, 0xAC, 0xBF, 0x1B, 0x00, 0x03, + 0x01, 0x00, 0x03, 0x00, 0x37, 0xAC, 0x26, 0x06, 0x30, 0xB0, 0x01, 0x11, + 0x74, 0xAA, 0x26, 0x05, 0x02, 0x43, 0x29, 0x26, 0x06, 0x20, 0xAC, 0x9B, + 0x25, 0x84, 0x27, 0x03, 0x01, 0x01, 0x00, 0x2E, 0x03, 0x02, 0xAF, 0x26, + 0x02, 0x01, 0x15, 0x06, 0x07, 0x2C, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, + 0x02, 0x02, 0x20, 0x76, 0x04, 0x5D, 0x76, 0x04, 0x4D, 0x76, 0x1B, 0x02, + 0x00, 0x00, 0x00, 0xB0, 0x01, 0x06, 0x75, 0xAE, 0x00, 0x00, 0xB5, 0x83, + 0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x00, 0x00, + 0xB5, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25, 0x01, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xB6, 0x83, 0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, + 0x00, 0x01, 0x00, 0x00, 0xB6, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25, + 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x04, 0x00, 0x04, 0x80, 0x55, 0x26, 0x01, 0x81, 0x40, 0x0D, 0x06, + 0x07, 0x25, 0x01, 0x00, 0x00, 0x04, 0x80, 0x47, 0x26, 0x01, 0x81, 0x60, + 0x0D, 0x06, 0x0E, 0x01, 0x1F, 0x15, 0x01, 0x01, 0xA0, 0x01, 0x81, 0x00, + 0x01, 0x8F, 0x7F, 0x04, 0x32, 0x26, 0x01, 0x81, 0x70, 0x0D, 0x06, 0x0F, + 0x01, 0x0F, 0x15, 0x01, 0x02, 0xA0, 0x01, 0x90, 0x00, 0x01, 0x83, 0xFF, + 0x7F, 0x04, 0x1C, 0x26, 0x01, 0x81, 0x78, 0x0D, 0x06, 0x11, 0x01, 0x07, + 0x15, 0x01, 0x03, 0xA0, 0x01, 0x84, 0x80, 0x00, 0x01, 0x80, 0xC3, 0xFF, + 0x7F, 0x04, 0x04, 0x25, 0x01, 0x00, 0x00, 0x6F, 0x05, 0x03, 0x25, 0x01, + 0x00, 0x00, 0x00, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x7F, + 0x00, 0xB7, 0x33, 0x26, 0x3C, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x01, 0x06, + 0x0E, 0x3A, 0x26, 0x01, 0x06, 0x14, 0x01, 0x02, 0x10, 0x06, 0x04, 0x41, + 0x01, 0x7F, 0x00, 0x01, 0x3F, 0x15, 0x09, 0x00, 0x00, 0x26, 0x06, 0x06, + 0x0B, 0x9F, 0x33, 0x40, 0x04, 0x77, 0x25, 0x26, 0x00, 0x00, 0xB0, 0x01, + 0x03, 0x75, 0xAA, 0xB7, 0x06, 0x02, 0x54, 0x29, 0x00, 0x00, 0x3A, 0x26, + 0x06, 0x07, 0x31, 0x26, 0x06, 0x01, 0x1A, 0x04, 0x76, 0x41, 0x00, 0x00, + 0x01, 0x01, 0x75, 0xA9, 0x01, 0x01, 0x10, 0x06, 0x02, 0x42, 0x29, 0xB7, + 0x3D, 0x00, 0x04, 0xB0, 0x26, 0x01, 0x17, 0x01, 0x18, 0x6F, 0x05, 0x02, + 0x47, 0x29, 0x01, 0x18, 0x11, 0x03, 0x00, 0x72, 0xAA, 0xA5, 0x02, 0x00, + 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0xA5, 0x02, 0x01, 0x09, + 0x04, 0x0E, 0x26, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, 0x64, 0x09, + 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, 0x6D, 0x08, + 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, 0x01, 0x01, + 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, 0x01, 0x83, + 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, 0x01, 0x01, + 0x0C, 0xA6, 0x40, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, 0x07, 0x3E, + 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x3D, 0x02, 0x01, 0x01, 0x83, 0x10, + 0x07, 0x3E, 0x2F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x91, 0x09, 0x78, + 0x26, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, 0x1F, 0x15, + 0x01, 0x01, 0x3A, 0xA6, 0x02, 0x03, 0x09, 0x40, 0x03, 0x03, 0x01, 0x00, + 0x01, 0x17, 0xA6, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, 0x00, 0x01, + 0x3B, 0xA6, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, 0x01, 0x00, + 0x01, 0x3C, 0xA6, 0x02, 0x02, 0x09, 0x03, 0x02, 0xB7, 0x26, 0x01, 0x2E, + 0x11, 0x06, 0x0D, 0x25, 0xB7, 0x26, 0x01, 0x30, 0x01, 0x39, 0x6F, 0x06, + 0x03, 0x25, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, 0x47, 0x29, + 0x76, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0xB7, 0x7A, 0x01, 0x0A, 0x08, + 0x03, 0x00, 0xB7, 0x7A, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, 0x00, 0x03, + 0x01, 0xA5, 0x26, 0x02, 0x01, 0x02, 0x00, 0x6F, 0x05, 0x02, 0x47, 0x29, + 0x00, 0x00, 0x33, 0xB0, 0x01, 0x02, 0x75, 0x0B, 0xA8, 0x00, 0x03, 0x26, + 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0xAA, 0xB7, 0x26, 0x01, 0x81, 0x00, + 0x13, 0x06, 0x02, 0x53, 0x29, 0x26, 0x01, 0x00, 0x11, 0x06, 0x0B, 0x25, + 0x26, 0x05, 0x04, 0x25, 0x01, 0x00, 0x00, 0xB7, 0x04, 0x6F, 0x02, 0x01, + 0x26, 0x05, 0x02, 0x4F, 0x29, 0x40, 0x03, 0x01, 0x02, 0x02, 0x36, 0x02, + 0x02, 0x3F, 0x03, 0x02, 0x26, 0x06, 0x03, 0xB7, 0x04, 0x68, 0x25, 0x02, + 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x26, 0x05, 0x02, 0x4D, 0x29, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, 0x19, 0x02, + 0x00, 0x40, 0x03, 0x00, 0x26, 0x01, 0x83, 0xFF, 0xFF, 0x7F, 0x12, 0x06, + 0x02, 0x4E, 0x29, 0x01, 0x08, 0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x04, 0x60, + 0x00, 0x00, 0xA9, 0x92, 0x00, 0x00, 0xAA, 0xBF, 0x00, 0x00, 0xB0, 0x73, + 0xAA, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x02, 0x53, 0x29, 0xB7, 0x26, 0x01, + 0x81, 0x00, 0x13, 0x06, 0x02, 0x53, 0x29, 0x03, 0x00, 0x26, 0x06, 0x16, + 0xB7, 0x02, 0x00, 0x26, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, 0x06, 0x02, + 0x53, 0x29, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, 0x25, 0x02, + 0x00, 0x00, 0x00, 0xAA, 0x26, 0x01, 0x81, 0x7F, 0x12, 0x06, 0x08, 0xBF, + 0x01, 0x00, 0x66, 0x36, 0x01, 0x00, 0x00, 0x26, 0x66, 0x36, 0x66, 0x3F, + 0xA2, 0x01, 0x7F, 0x00, 0x00, 0xB0, 0x01, 0x0C, 0x30, 0x11, 0x06, 0x05, + 0x25, 0x72, 0xB3, 0x04, 0x3E, 0x01, 0x12, 0x30, 0x11, 0x06, 0x05, 0x25, + 0x72, 0xB4, 0x04, 0x33, 0x01, 0x13, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, + 0xB4, 0x04, 0x28, 0x01, 0x14, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4, + 0x04, 0x1D, 0x01, 0x16, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4, 0x04, + 0x12, 0x01, 0x1E, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB2, 0x04, 0x07, + 0x41, 0xAB, 0x01, 0x00, 0x01, 0x00, 0x25, 0x00, 0x01, 0xB7, 0x03, 0x00, + 0x02, 0x00, 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x2D, 0x02, 0x00, 0x01, + 0x06, 0x14, 0x26, 0x01, 0x01, 0x15, 0x06, 0x02, 0x45, 0x29, 0x01, 0x04, + 0x0E, 0x02, 0x00, 0x01, 0x1F, 0x15, 0x26, 0x01, 0x1F, 0x11, 0x06, 0x02, + 0x46, 0x29, 0x09, 0x00, 0x00, 0x26, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, + 0x00, 0xB0, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x05, 0x66, 0x36, 0x01, 0x7F, + 0x00, 0x01, 0x01, 0x03, 0x00, 0x9C, 0x26, 0x01, 0x83, 0xFF, 0x7E, 0x11, + 0x06, 0x16, 0x25, 0x26, 0x06, 0x10, 0x9D, 0x26, 0x05, 0x05, 0x25, 0xBF, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x04, 0x1B, + 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03, + 0x00, 0x26, 0x06, 0x0B, 0x9C, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, + 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00, 0x40, 0x66, + 0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00, 0x26, 0x06, + 0x10, 0x9E, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00, + 0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00, + 0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00, + 0x26, 0x06, 0x10, 0xB7, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, + 0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, + 0x01, 0x00, 0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x00, 0xB7, 0x01, 0x08, + 0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x00, 0x00, 0xB7, 0x3A, 0xB7, 0x01, 0x08, + 0x0E, 0x33, 0x09, 0x00, 0x00, 0x26, 0x05, 0x02, 0x4E, 0x29, 0x40, 0xB8, + 0x00, 0x00, 0x32, 0x26, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x25, 0x1A, + 0x04, 0x74, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, + 0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, + 0x33, 0x00, 0x00, 0xC0, 0x25, 0x00, 0x00, 0x26, 0x06, 0x07, 0xC1, 0x26, + 0x06, 0x01, 0x1A, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B, + 0x41, 0x00, 0x00, 0x01, 0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00, + 0x00, 0x01, 0x82, 0x22, 0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x26, + 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F, 0x6F, 0x06, 0x04, 0x25, + 0x01, 0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xBF, 0x7F, + 0x6F, 0x06, 0x04, 0x25, 0x01, 0x00, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x15, + 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 }; static const uint16_t t0_caddr[] PROGMEM = { @@ -833,106 +830,103 @@ static const uint16_t t0_caddr[] PROGMEM = { 188, 193, 198, - 202, - 207, - 212, - 217, - 238, - 243, - 248, - 253, - 282, - 297, + 203, + 208, + 213, + 234, + 239, + 244, + 249, + 264, + 269, + 275, + 281, + 286, + 294, 302, 308, - 314, - 319, - 327, - 335, - 341, - 346, - 357, - 986, - 1001, - 1005, - 1010, - 1015, - 1020, - 1025, - 1030, - 1144, - 1149, - 1161, - 1166, - 1171, - 1176, - 1180, - 1185, - 1190, - 1195, - 1200, - 1210, - 1215, - 1220, - 1232, - 1247, - 1252, - 1266, - 1288, - 1299, - 1402, - 1449, - 1482, - 1573, - 1579, - 1642, - 1649, - 1677, - 1705, - 1810, - 1852, + 313, + 324, + 960, + 975, + 979, + 984, + 989, + 994, + 999, + 1004, + 1118, + 1123, + 1135, + 1140, + 1145, + 1150, + 1154, + 1159, + 1164, + 1169, + 1174, + 1184, + 1189, + 1194, + 1206, + 1221, + 1226, + 1240, + 1262, + 1273, + 1376, + 1423, + 1456, + 1547, + 1553, + 1616, + 1623, + 1651, + 1679, + 1784, + 1826, + 1839, + 1851, 1865, - 1877, - 1891, - 1906, - 2126, + 1880, + 2100, + 2114, + 2131, 2140, - 2157, - 2166, - 2233, - 2289, - 2293, - 2297, - 2302, + 2207, + 2263, + 2267, + 2271, + 2276, + 2324, 2350, - 2376, - 2452, - 2496, - 2507, - 2592, - 2630, - 2668, - 2678, + 2426, + 2470, + 2481, + 2566, + 2604, + 2642, + 2652, + 2662, + 2671, + 2684, 2688, - 2697, - 2710, - 2714, - 2718, - 2722, - 2726, - 2730, - 2734, - 2738, - 2750, - 2758, - 2763, - 2768, - 2773, - 2778, - 2786 + 2692, + 2696, + 2700, + 2704, + 2708, + 2712, + 2724, + 2732, + 2737, + 2742, + 2747, + 2752 }; -#define T0_INTERPRETED 61 +#define T0_INTERPRETED 60 #define T0_ENTER(ip, rp, slot) do { \ const unsigned char *t0_newip; \ @@ -953,7 +947,7 @@ name(void *ctx) \ T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ } -T0_DEFENTRY(br_x509_minimal_init_main, 147) +T0_DEFENTRY(br_x509_minimal_init_main, 144) #define T0_NEXT(t0ipp) (pgm_read_byte((*t0ipp)++)) @@ -1268,11 +1262,53 @@ br_x509_minimal_run(void *t0ctx) } break; case 25: { + /* check-validity-range */ + + uint32_t nbs = T0_POP(); + uint32_t nbd = T0_POP(); + uint32_t nas = T0_POP(); + uint32_t nad = T0_POP(); + int r; + uint32_t vd = CTX->days; + uint32_t vs = CTX->seconds; + if (vd == 0 && vs == 0) { +#if BR_USE_UNIX_TIME + time_t x = time(NULL); + + vd = (uint32_t)(x / 86400) + 719528; + vs = (uint32_t)(x % 86400); +#elif BR_USE_WIN32_TIME + FILETIME ft; + uint64_t x; + + GetSystemTimeAsFileTime(&ft); + x = ((uint64_t)ft.dwHighDateTime << 32) + + (uint64_t)ft.dwLowDateTime; + x = (x / 10000000); + vd = (uint32_t)(x / 86400) + 584754; + vs = (uint32_t)(x % 86400); +#else + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); +#endif + } + if (vd < nbd || (vd == nbd && vs < nbs)) { + r = -1; + } else if (vd > nad || (vd == nad && vs > nas)) { + r = 1; + } else { + r = 0; + } + T0_PUSHi(r); + + } + break; + case 26: { /* co */ T0_CO(); } break; - case 26: { + case 27: { /* compute-dn-hash */ CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); @@ -1280,7 +1316,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 27: { + case 28: { /* compute-tbs-hash */ int id = T0_POPi(); @@ -1290,7 +1326,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 28: { + case 29: { /* copy-ee-ec-pkey */ size_t qlen = T0_POP(); @@ -1303,7 +1339,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 29: { + case 30: { /* copy-ee-rsa-pkey */ size_t elen = T0_POP(); @@ -1317,7 +1353,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 30: { + case 31: { /* copy-name-SAN */ unsigned tag = T0_POP(); @@ -1343,7 +1379,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 31: { + case 32: { /* copy-name-element */ size_t len; @@ -1369,7 +1405,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 32: { + case 33: { /* data-get8 */ size_t addr = T0_POP(); @@ -1377,14 +1413,14 @@ br_x509_minimal_run(void *t0ctx) } break; - case 33: { + case 34: { /* dn-hash-length */ T0_PUSH(DNHASH_LEN); } break; - case 34: { + case 35: { /* do-ecdsa-vrfy */ size_t qlen = T0_POP(); @@ -1399,7 +1435,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 35: { + case 36: { /* do-rsa-vrfy */ size_t elen = T0_POP(); @@ -1415,17 +1451,17 @@ br_x509_minimal_run(void *t0ctx) } break; - case 36: { + case 37: { /* drop */ (void)T0_POP(); } break; - case 37: { + case 38: { /* dup */ T0_PUSH(T0_PEEK(0)); } break; - case 38: { + case 39: { /* eqOID */ const unsigned char *a2 = &t0_datablock[T0_POP()]; @@ -1441,7 +1477,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 39: { + case 40: { /* eqblob */ size_t len = T0_POP(); @@ -1451,42 +1487,12 @@ br_x509_minimal_run(void *t0ctx) } break; - case 40: { + case 41: { /* fail */ CTX->err = T0_POPi(); T0_CO(); - } - break; - case 41: { - /* get-system-date */ - - if (CTX->days == 0 && CTX->seconds == 0) { -#if BR_USE_UNIX_TIME - time_t x = time(NULL); - - T0_PUSH((uint32_t)(x / 86400) + 719528); - T0_PUSH((uint32_t)(x % 86400)); -#elif BR_USE_WIN32_TIME - FILETIME ft; - uint64_t x; - - GetSystemTimeAsFileTime(&ft); - x = ((uint64_t)ft.dwHighDateTime << 32) - + (uint64_t)ft.dwLowDateTime; - x = (x / 10000000); - T0_PUSH((uint32_t)(x / 86400) + 584754); - T0_PUSH((uint32_t)(x % 86400)); -#else - CTX->err = BR_ERR_X509_TIME_UNKNOWN; - T0_CO(); -#endif - } else { - T0_PUSH(CTX->days); - T0_PUSH(CTX->seconds); - } - } break; case 42: { @@ -1642,16 +1648,11 @@ br_x509_minimal_run(void *t0ctx) } break; case 51: { - /* roll */ - T0_ROLL(T0_POP()); - } - break; - case 52: { /* rot */ T0_ROT(); } break; - case 53: { + case 52: { /* set16 */ uint32_t addr = T0_POP(); @@ -1659,7 +1660,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 54: { + case 53: { /* set32 */ uint32_t addr = T0_POP(); @@ -1667,7 +1668,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 55: { + case 54: { /* set8 */ uint32_t addr = T0_POP(); @@ -1675,7 +1676,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 56: { + case 55: { /* start-dn-hash */ CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); @@ -1683,7 +1684,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 57: { + case 56: { /* start-tbs-hash */ br_multihash_init(&CTX->mhash); @@ -1691,19 +1692,19 @@ br_x509_minimal_run(void *t0ctx) } break; - case 58: { + case 57: { /* stop-tbs-hash */ CTX->do_mhash = 0; } break; - case 59: { + case 58: { /* swap */ T0_SWAP(); } break; - case 60: { + case 59: { /* zero-server-name */ T0_PUSHi(-(CTX->server_name == NULL)); diff --git a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 deleted file mode 100644 index 62a93e74c..000000000 --- a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 +++ /dev/null @@ -1,1570 +0,0 @@ -\ Copyright (c) 2016 Thomas Pornin -\ -\ Permission is hereby granted, free of charge, to any person obtaining -\ a copy of this software and associated documentation files (the -\ "Software"), to deal in the Software without restriction, including -\ without limitation the rights to use, copy, modify, merge, publish, -\ distribute, sublicense, and/or sell copies of the Software, and to -\ permit persons to whom the Software is furnished to do so, subject to -\ the following conditions: -\ -\ The above copyright notice and this permission notice shall be -\ included in all copies or substantial portions of the Software. -\ -\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -\ SOFTWARE. - -preamble { - -#include "inner.h" - -/* - * Implementation Notes - * -------------------- - * - * The C code pushes the data by chunks; all decoding is done in the - * T0 code. The cert_length value is set to the certificate length when - * a new certificate is started; the T0 code picks it up as outer limit, - * and decoding functions use it to ensure that no attempt is made at - * reading past it. The T0 code also checks that once the certificate is - * decoded, there are no trailing bytes. - * - * The T0 code sets cert_length to 0 when the certificate is fully - * decoded. - * - * The C code must still perform two checks: - * - * -- If the certificate length is 0, then the T0 code will not be - * invoked at all. This invalid condition must thus be reported by the - * C code. - * - * -- When reaching the end of certificate, the C code must verify that - * the certificate length has been set to 0, thereby signaling that - * the T0 code properly decoded a certificate. - * - * Processing of a chain works in the following way: - * - * -- The error flag is set to a non-zero value when validation is - * finished. The value is either BR_ERR_X509_OK (validation is - * successful) or another non-zero error code. When a non-zero error - * code is obtained, the remaining bytes in the current certificate and - * the subsequent certificates (if any) are completely ignored. - * - * -- Each certificate is decoded in due course, with the following - * "interesting points": - * - * -- Start of the TBS: the multihash engine is reset and activated. - * - * -- Start of the issuer DN: the secondary hash engine is started, - * to process the encoded issuer DN. - * - * -- End of the issuer DN: the secondary hash engine is stopped. The - * resulting hash value is computed and then copied into the - * next_dn_hash[] buffer. - * - * -- Start of the subject DN: the secondary hash engine is started, - * to process the encoded subject DN. - * - * -- For the EE certificate only: the Common Name, if any, is matched - * against the expected server name. - * - * -- End of the subject DN: the secondary hash engine is stopped. The - * resulting hash value is computed into the pad. It is then processed: - * - * -- If this is the EE certificate, then the hash is ignored - * (except for direct trust processing, see later; the hash is - * simply left in current_dn_hash[]). - * - * -- Otherwise, the hashed subject DN is compared with the saved - * hash value (in saved_dn_hash[]). They must match. - * - * Either way, the next_dn_hash[] value is then copied into the - * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] - * contains the hash of the issuer DN for the current certificate, - * and current_dn_hash[] contains the hash of the subject DN for the - * current certificate. - * - * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown - * key types are reported at that point. - * - * -- If this is the EE certificate, then the key type is compared - * with the expected key type (initialization parameter). The public - * key data is copied to ee_pkey_data[]. The key and hashed subject - * DN are also compared with the "direct trust" keys; if the key - * and DN are matched, then validation ends with a success. - * - * -- Otherwise, the saved signature (cert_sig[]) is verified - * against the saved TBS hash (tbs_hash[]) and that freshly - * decoded public key. Failure here ends validation with an error. - * - * -- Extensions: extension values are processed in due order. - * - * -- Basic Constraints: for all certificates except EE, must be - * present, indicate a CA, and have a path length compatible with - * the chain length so far. - * - * -- Key Usage: for the EE, if present, must allow signatures - * or encryption/key exchange, as required for the cipher suite. - * For non-EE, if present, must have the "certificate sign" bit. - * - * -- Subject Alt Name: for the EE, dNSName names are matched - * against the server name. Ignored for non-EE. - * - * -- Authority Key Identifier, Subject Key Identifier, Issuer - * Alt Name, Subject Directory Attributes, CRL Distribution Points - * Freshest CRL, Authority Info Access and Subject Info Access - * extensions are always ignored: they either contain only - * informative data, or they relate to revocation processing, which - * we explicitly do not support. - * - * -- All other extensions are ignored if non-critical. If a - * critical extension other than the ones above is encountered, - * then a failure is reported. - * - * -- End of the TBS: the multihash engine is stopped. - * - * -- Signature algorithm: the signature algorithm on the - * certificate is decoded. A failure is reported if that algorithm - * is unknown. The hashed TBS corresponding to the signature hash - * function is computed and stored in tbs_hash[] (if not supported, - * then a failure is reported). The hash OID and length are stored - * in cert_sig_hash_oid and cert_sig_hash_len. - * - * -- Signature value: the signature value is copied into the - * cert_sig[] array. - * - * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is - * looked up in the trust store (CA trust anchors only); for all - * that match, the signature (cert_sig[]) is verified against the - * anchor public key (hashed TBS is in tbs_hash[]). If one of these - * signatures is valid, then validation ends with a success. - * - * -- If the chain end is reached without obtaining a validation success, - * then validation is reported as failed. - */ - -#if BR_USE_UNIX_TIME -#include -#endif - -#if BR_USE_WIN32_TIME -#include -#endif - -/* - * The T0 compiler will produce these prototypes declarations in the - * header. - * -void br_x509_minimal_init_main(void *ctx); -void br_x509_minimal_run(void *ctx); - */ - -/* see bearssl_x509.h */ -void -br_x509_minimal_init(br_x509_minimal_context *ctx, - const br_hash_class *dn_hash_impl, - const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) -{ - memset(ctx, 0, sizeof *ctx); - ctx->vtable = &br_x509_minimal_vtable; - ctx->dn_hash_impl = dn_hash_impl; - ctx->trust_anchors = trust_anchors; - ctx->trust_anchors_num = trust_anchors_num; -} - -static void -xm_start_chain(const br_x509_class **ctx, const char *server_name) -{ - br_x509_minimal_context *cc; - size_t u; - - cc = (br_x509_minimal_context *)(void *)ctx; - for (u = 0; u < cc->num_name_elts; u ++) { - cc->name_elts[u].status = 0; - cc->name_elts[u].buf[0] = 0; - } - memset(&cc->pkey, 0, sizeof cc->pkey); - cc->num_certs = 0; - cc->err = 0; - cc->cpu.dp = cc->dp_stack; - cc->cpu.rp = cc->rp_stack; - br_x509_minimal_init_main(&cc->cpu); - if (server_name == NULL || *server_name == 0) { - cc->server_name = NULL; - } else { - cc->server_name = server_name; - } -} - -static void -xm_start_cert(const br_x509_class **ctx, uint32_t length) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err != 0) { - return; - } - if (length == 0) { - cc->err = BR_ERR_X509_TRUNCATED; - return; - } - cc->cert_length = length; -} - -static void -xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err != 0) { - return; - } - cc->hbuf = buf; - cc->hlen = len; - br_x509_minimal_run(&cc->cpu); -} - -static void -xm_end_cert(const br_x509_class **ctx) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == 0 && cc->cert_length != 0) { - cc->err = BR_ERR_X509_TRUNCATED; - } - cc->num_certs ++; -} - -static unsigned -xm_end_chain(const br_x509_class **ctx) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == 0) { - if (cc->num_certs == 0) { - cc->err = BR_ERR_X509_EMPTY_CHAIN; - } else { - cc->err = BR_ERR_X509_NOT_TRUSTED; - } - } else if (cc->err == BR_ERR_X509_OK) { - return 0; - } - return (unsigned)cc->err; -} - -static const br_x509_pkey * -xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) -{ - br_x509_minimal_context *cc; - - cc = (br_x509_minimal_context *)(void *)ctx; - if (cc->err == BR_ERR_X509_OK - || cc->err == BR_ERR_X509_NOT_TRUSTED) - { - if (usages != NULL) { - *usages = cc->key_usages; - } - return &((br_x509_minimal_context *)(void *)ctx)->pkey; - } else { - return NULL; - } -} - -/* see bearssl_x509.h */ -const br_x509_class br_x509_minimal_vtable PROGMEM = { - sizeof(br_x509_minimal_context), - xm_start_chain, - xm_start_cert, - xm_append, - xm_end_cert, - xm_end_chain, - xm_get_pkey -}; - -#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) -#define CONTEXT_NAME br_x509_minimal_context - -#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) -#define dnhash_len ((ctx->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) - -/* - * Hash a DN (from a trust anchor) into the provided buffer. This uses the - * DN hash implementation and context structure from the X.509 engine - * context. - */ -static void -hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, - unsigned char *out) -{ - ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); - ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); - ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); -} - -/* - * Compare two big integers for equality. The integers use unsigned big-endian - * encoding; extra leading bytes (of value 0) are allowed. - */ -static int -eqbigint(const unsigned char *b1, size_t len1, - const unsigned char *b2, size_t len2) -{ - while (len1 > 0 && *b1 == 0) { - b1 ++; - len1 --; - } - while (len2 > 0 && pgm_read_byte(b2) == 0) { - b2 ++; - len2 --; - } - if (len1 != len2) { - return 0; - } - return memcmp_P(b1, b2, len1) == 0; -} - -/* - * Compare two strings for equality, in a case-insensitive way. This - * function handles casing only for ASCII letters. - */ -static int -eqnocase(const void *s1, const void *s2, size_t len) -{ - const unsigned char *buf1, *buf2; - - buf1 = s1; - buf2 = s2; - while (len -- > 0) { - int x1, x2; - - x1 = *buf1 ++; - x2 = *buf2 ++; - if (x1 >= 'A' && x1 <= 'Z') { - x1 += 'a' - 'A'; - } - if (x2 >= 'A' && x2 <= 'Z') { - x2 += 'a' - 'A'; - } - if (x1 != x2) { - return 0; - } - } - return 1; -} - -static int verify_signature(br_x509_minimal_context *ctx, - const br_x509_pkey *pk); - -/* - * Check whether the current certificate (EE) is directly trusted against - * a single trust anchor - */ -static int check_single_direct_trust(br_x509_minimal_context *ctx, - unsigned char hashed_DN[64], - const br_x509_trust_anchor *ta) -{ - int kt; - - if (ta->flags & BR_X509_TA_CA) { - return 0; - } - if (memcmp(hashed_DN, ctx->current_dn_hash, dnhash_len)) { - return 0; - } - kt = ctx->pkey.key_type; - if ((pgm_read_byte(&ta->pkey.key_type) & 0x0F) != kt) { - return 0; - } - switch (kt) { - case BR_KEYTYPE_RSA: - if (!eqbigint(ctx->pkey.key.rsa.n, - ctx->pkey.key.rsa.nlen, - ta->pkey.key.rsa.n, - ta->pkey.key.rsa.nlen) - || !eqbigint(ctx->pkey.key.rsa.e, - ctx->pkey.key.rsa.elen, - ta->pkey.key.rsa.e, - ta->pkey.key.rsa.elen)) - { - return 0; - } - return 1; - case BR_KEYTYPE_EC: - if (ctx->pkey.key.ec.curve != ta->pkey.key.ec.curve - || ctx->pkey.key.ec.qlen != ta->pkey.key.ec.qlen - || memcmp_P(ctx->pkey.key.ec.q, - ta->pkey.key.ec.q, - ta->pkey.key.ec.qlen) != 0) - { - return 0; - } - return 1; - default: - return 0; - } - return 0; /* Should not get here */ -} - - -/* - * Check whether the current certificate (EE) is directly trusted against - * a single CA trust anchor. We use the issuer hash (in saved_dn_hash[]) - * as the CA identifier. - */ -static int check_single_trust_anchor_CA(br_x509_minimal_context *ctx, - unsigned char hashed_DN[64], - const br_x509_trust_anchor *ta) -{ - if (!(ta->flags & BR_X509_TA_CA)) { - return 0; - } - if (memcmp(hashed_DN, ctx->saved_dn_hash, dnhash_len)) { - return 0; - } - if (verify_signature(ctx, &ta->pkey) == 0) { - return 1; - } - return 0; -} - -} - - -postamble { - -/* - * Verify the signature on the certificate with the provided public key. - * This function checks the public key type with regards to the expected - * type. Returned value is either 0 on success, or a non-zero error code. - */ -static int -verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) -{ - unsigned char tmp[64]; - unsigned char tmp2[64]; - int kt; - - kt = ctx->cert_signer_key_type; - if ((pgm_read_byte(&pk->key_type) & 0x0F) != kt) { - return BR_ERR_X509_WRONG_KEY_TYPE; - } - switch (kt) { - - case BR_KEYTYPE_RSA: - if (ctx->irsa == 0) { - return BR_ERR_X509_UNSUPPORTED; - } - memcpy_P(tmp2, &t0_datablock[ctx->cert_sig_hash_oid], ctx->cert_sig_hash_len); - if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, - tmp2, //&t0_datablock[ctx->cert_sig_hash_oid], - ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) - { - return BR_ERR_X509_BAD_SIGNATURE; - } - if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { - return BR_ERR_X509_BAD_SIGNATURE; - } - return 0; - - case BR_KEYTYPE_EC: - if (ctx->iecdsa == 0) { - return BR_ERR_X509_UNSUPPORTED; - } - if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, - ctx->cert_sig_hash_len, &pk->key.ec, - ctx->cert_sig, ctx->cert_sig_len)) - { - return BR_ERR_X509_BAD_SIGNATURE; - } - return 0; - - default: - return BR_ERR_X509_UNSUPPORTED; - } -} - -} - -cc: read8-low ( -- x ) { - if (CTX->hlen == 0) { - T0_PUSHi(-1); - } else { - unsigned char x = *CTX->hbuf ++; - if (CTX->do_mhash) { - br_multihash_update(&CTX->mhash, &x, 1); - } - if (CTX->do_dn_hash) { - CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); - } - CTX->hlen --; - T0_PUSH(x); - } -} - -addr: cert_length -addr: num_certs - -cc: read-blob-inner ( addr len -- addr len ) { - uint32_t len = T0_POP(); - uint32_t addr = T0_POP(); - size_t clen = CTX->hlen; - if (clen > len) { - clen = (size_t)len; - } - if (addr != 0) { - memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); - } - if (CTX->do_mhash) { - br_multihash_update(&CTX->mhash, CTX->hbuf, clen); - } - if (CTX->do_dn_hash) { - CTX->dn_hash_impl->update( - &CTX->dn_hash.vtable, CTX->hbuf, clen); - } - CTX->hbuf += clen; - CTX->hlen -= clen; - T0_PUSH(addr + clen); - T0_PUSH(len - clen); -} - -\ Compute the TBS hash, using the provided hash ID. The hash value is -\ written in the tbs_hash[] array, and the hash length is returned. If -\ the requested hash function is not supported, then 0 is returned. -cc: compute-tbs-hash ( id -- hashlen ) { - int id = T0_POPi(); - size_t len; - len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); - T0_PUSH(len); -} - -\ Push true (-1) if no server name is expected in the EE certificate. -cc: zero-server-name ( -- bool ) { - T0_PUSHi(-(CTX->server_name == NULL)); -} - -addr: key_usages -addr: cert_sig -addr: cert_sig_len -addr: cert_signer_key_type -addr: cert_sig_hash_oid -addr: cert_sig_hash_len -addr: tbs_hash -addr: min_rsa_size - -\ Start TBS hash computation. The hash functions are reinitialised. -cc: start-tbs-hash ( -- ) { - br_multihash_init(&CTX->mhash); - CTX->do_mhash = 1; -} - -\ Stop TBS hash computation. -cc: stop-tbs-hash ( -- ) { - CTX->do_mhash = 0; -} - -\ Start DN hash computation. -cc: start-dn-hash ( -- ) { - CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); - CTX->do_dn_hash = 1; -} - -\ Terminate DN hash computation and write the DN hash into the -\ current_dn_hash buffer. -cc: compute-dn-hash ( -- ) { - CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); - CTX->do_dn_hash = 0; -} - -\ Get the length of hash values obtained with the DN hasher. -cc: dn-hash-length ( -- len ) { - T0_PUSH(DNHASH_LEN); -} - -\ Copy data between two areas in the context. -cc: blobcopy ( addr-dst addr-src len -- ) { - size_t len = T0_POP(); - unsigned char *src = (unsigned char *)CTX + T0_POP(); - unsigned char *dst = (unsigned char *)CTX + T0_POP(); - memcpy(dst, src, len); -} - -addr: current_dn_hash -addr: next_dn_hash -addr: saved_dn_hash - -\ Read a DN, hashing it into current_dn_hash. The DN contents are not -\ inspected (only the outer tag, for SEQUENCE, is checked). -: read-DN ( lim -- lim ) - start-dn-hash - read-sequence-open skip-close-elt - compute-dn-hash ; - -cc: offset-name-element ( san -- n ) { - unsigned san = T0_POP(); - size_t u; - - for (u = 0; u < CTX->num_name_elts; u ++) { - if (CTX->name_elts[u].status == 0) { - const unsigned char *oid; - size_t len, off; - - oid = CTX->name_elts[u].oid; - if (san) { - if (oid[0] != 0 || oid[1] != 0) { - continue; - } - off = 2; - } else { - off = 0; - } - len = oid[off]; - if (len != 0 && len == CTX->pad[0] - && memcmp(oid + off + 1, - CTX->pad + 1, len) == 0) - { - T0_PUSH(u); - T0_RET(); - } - } - } - T0_PUSHi(-1); -} - -cc: copy-name-element ( bool offbuf -- ) { - size_t len; - int32_t off = T0_POPi(); - int ok = T0_POPi(); - - if (off >= 0) { - br_name_element *ne = &CTX->name_elts[off]; - - if (ok) { - len = CTX->pad[0]; - if (len < ne->len) { - memcpy(ne->buf, CTX->pad + 1, len); - ne->buf[len] = 0; - ne->status = 1; - } else { - ne->status = -1; - } - } else { - ne->status = -1; - } - } -} - -cc: copy-name-SAN ( bool tag -- ) { - unsigned tag = T0_POP(); - unsigned ok = T0_POP(); - size_t u, len; - - len = CTX->pad[0]; - for (u = 0; u < CTX->num_name_elts; u ++) { - br_name_element *ne; - - ne = &CTX->name_elts[u]; - if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { - if (ok && ne->len > len) { - memcpy(ne->buf, CTX->pad + 1, len); - ne->buf[len] = 0; - ne->status = 1; - } else { - ne->status = -1; - } - break; - } - } -} - -\ Read a value, decoding string types. If the string type is recognised -\ and the value could be converted to UTF-8 into the pad, then true (-1) -\ is returned; in all other cases, false (0) is returned. Either way, the -\ object is consumed. -: read-string ( lim -- lim bool ) - read-tag case - \ UTF8String - 12 of check-primitive read-value-UTF8 endof - \ NumericString - 18 of check-primitive read-value-latin1 endof - \ PrintableString - 19 of check-primitive read-value-latin1 endof - \ TeletexString - 20 of check-primitive read-value-latin1 endof - \ IA5String - 22 of check-primitive read-value-latin1 endof - \ BMPString - 30 of check-primitive read-value-UTF16 endof - 2drop read-length-skip 0 0 - endcase ; - -\ Read a DN for the EE. The normalized DN hash is computed and stored in the -\ current_dn_hash. -\ Name elements are gathered. Also, the Common Name is matched against the -\ intended server name. -\ Returned value is true (-1) if the CN matches the intended server name, -\ false (0) otherwise. -: read-DN-EE ( lim -- lim bool ) - \ Flag will be set to true if there is a CN and it matches the - \ intended server name. - 0 { eename-matches } - - \ Activate DN hashing. - start-dn-hash - - \ Parse the DN structure: it is a SEQUENCE of SET of - \ AttributeTypeAndValue. Each AttributeTypeAndValue is a - \ SEQUENCE { OBJECT IDENTIFIER, ANY }. - read-sequence-open - begin - dup while - - read-tag 0x11 check-tag-constructed read-length-open-elt - dup ifnot ERR_X509_BAD_DN fail then - begin - dup while - - read-sequence-open - - \ Read the OID. If the OID could not be read (too - \ long) then the first pad byte will be 0. - read-OID drop - - \ If it is the Common Name then we'll need to - \ match it against the intended server name (if - \ applicable). - id-at-commonName eqOID { isCN } - - \ Get offset for reception buffer for that element - \ (or -1). - 0 offset-name-element { offbuf } - - \ Try to read the value as a string. - read-string - - \ If the value could be decoded as a string, - \ copy it and/or match it, as appropriate. - dup isCN and if - match-server-name if - -1 >eename-matches - then - then - offbuf copy-name-element - - \ Close the SEQUENCE - close-elt - - repeat - close-elt - repeat - close-elt - - \ Compute DN hash and deactivate DN hashing. - compute-dn-hash - - \ Return the CN match flag. - eename-matches ; - -\ Get the validation date and time from the context or system. -cc: get-system-date ( -- days seconds ) { - if (CTX->days == 0 && CTX->seconds == 0) { -#if BR_USE_UNIX_TIME - time_t x = time(NULL); - - T0_PUSH((uint32_t)(x / 86400) + 719528); - T0_PUSH((uint32_t)(x % 86400)); -#elif BR_USE_WIN32_TIME - FILETIME ft; - uint64_t x; - - GetSystemTimeAsFileTime(&ft); - x = ((uint64_t)ft.dwHighDateTime << 32) - + (uint64_t)ft.dwLowDateTime; - x = (x / 10000000); - T0_PUSH((uint32_t)(x / 86400) + 584754); - T0_PUSH((uint32_t)(x % 86400)); -#else - CTX->err = BR_ERR_X509_TIME_UNKNOWN; - T0_CO(); -#endif - } else { - T0_PUSH(CTX->days); - T0_PUSH(CTX->seconds); - } -} - -\ Compare two dates (days+seconds) together. -: before ( days1 seconds1 days2 seconds2 -- bool ) - { d1 s1 d2 s2 } - d1 d2 = if s1 s2 < else d1 d2 < then ; - -: after ( days1 seconds1 days2 seconds2 -- bool ) - swap2 before ; - -\ Swap the top two elements with the two elements immediately below. -: swap2 ( a b c d -- c d a b ) - 3 roll 3 roll ; - -\ Match the name in the pad with the expected server name. Returned value -\ is true (-1) on match, false (0) otherwise. If there is no expected -\ server name, then 0 is returned. -\ Match conditions: either an exact match (case insensitive), or a -\ wildcard match, if the found name starts with "*.". We only match a -\ starting wildcard, and only against a complete DN name component. -cc: match-server-name ( -- bool ) { - size_t n1, n2; - - if (CTX->server_name == NULL) { - T0_PUSH(0); - T0_RET(); - } - n1 = strlen(CTX->server_name); - n2 = CTX->pad[0]; - if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { - T0_PUSHi(-1); - T0_RET(); - } - if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { - size_t u; - - u = 0; - while (u < n1 && CTX->server_name[u] != '.') { - u ++; - } - u ++; - n1 -= u; - if ((n2 - 2) == n1 - && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) - { - T0_PUSHi(-1); - T0_RET(); - } - } - T0_PUSH(0); -} - -\ Get the address and length for the pkey_data buffer. -: addr-len-pkey_data ( -- addr len ) - CX 0 8191 { offsetof(br_x509_minimal_context, pkey_data) } - CX 0 8191 { BR_X509_BUFSIZE_KEY } ; - -\ Copy the EE public key to the permanent buffer (RSA). -cc: copy-ee-rsa-pkey ( nlen elen -- ) { - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); - CTX->pkey.key_type = BR_KEYTYPE_RSA; - CTX->pkey.key.rsa.n = CTX->ee_pkey_data; - CTX->pkey.key.rsa.nlen = nlen; - CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; - CTX->pkey.key.rsa.elen = elen; -} - -\ Copy the EE public key to the permanent buffer (EC). -cc: copy-ee-ec-pkey ( curve qlen -- ) { - size_t qlen = T0_POP(); - uint32_t curve = T0_POP(); - memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); - CTX->pkey.key_type = BR_KEYTYPE_EC; - CTX->pkey.key.ec.curve = curve; - CTX->pkey.key.ec.q = CTX->ee_pkey_data; - CTX->pkey.key.ec.qlen = qlen; -} - - -\ Check whether the current certificate (EE) is directly trusted. -cc: check-direct-trust ( -- ) { - size_t u; - const br_x509_trust_anchor *ta; - unsigned char hashed_DN[64]; - - for (u = 0; u < CTX->trust_anchors_num; u ++) { - ta = &CTX->trust_anchors[u]; - hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); - if (check_single_direct_trust(CTX, hashed_DN, ta)) { - /* - * Direct trust match! - */ - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - } - if (CTX->err != BR_ERR_X509_OK && CTX->trust_anchor_dynamic) { - ta = CTX->trust_anchor_dynamic(CTX->trust_anchor_dynamic_ctx, CTX->current_dn_hash, DNHASH_LEN); - if (ta) { - memcpy(hashed_DN, ta->dn.data, DNHASH_LEN); - int ret = check_single_direct_trust(CTX, hashed_DN, ta); - if (CTX->trust_anchor_dynamic_free) { - CTX->trust_anchor_dynamic_free(CTX->trust_anchor_dynamic_ctx, ta); - } - if (ret) { - /* - * Direct trust match! - */ - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - } - } -} - -\ Check the signature on the certificate with regards to all trusted CA. -\ We use the issuer hash (in saved_dn_hash[]) as CA identifier. -cc: check-trust-anchor-CA ( -- ) { - size_t u; - const br_x509_trust_anchor *ta; - unsigned char hashed_DN[64]; - - for (u = 0; u < CTX->trust_anchors_num; u ++) { - ta = &CTX->trust_anchors[u]; - hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); - if (check_single_trust_anchor_CA(CTX, hashed_DN, ta)) { - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - } - if (CTX->err != BR_ERR_X509_OK && CTX->trust_anchor_dynamic) { - ta = CTX->trust_anchor_dynamic(CTX->trust_anchor_dynamic_ctx, CTX->saved_dn_hash, DNHASH_LEN); - if (ta) { - memcpy(hashed_DN, ta->dn.data, DNHASH_LEN); - int ret; - ret = check_single_trust_anchor_CA(CTX, hashed_DN, ta); - if (CTX->trust_anchor_dynamic_free) { - CTX->trust_anchor_dynamic_free(CTX->trust_anchor_dynamic_ctx, ta); - } - if (ret) { - CTX->err = BR_ERR_X509_OK; - T0_CO(); - } - } - - } -} - -\ Verify RSA signature. This uses the public key that was just decoded -\ into CTX->pkey_data; the modulus and exponent length are provided as -\ parameters. The resulting hash value is compared with the one in -\ tbs_hash. Returned value is 0 on success, or a non-zero error code. -cc: do-rsa-vrfy ( nlen elen -- err ) { - size_t elen = T0_POP(); - size_t nlen = T0_POP(); - br_x509_pkey pk; - - pk.key_type = BR_KEYTYPE_RSA; - pk.key.rsa.n = CTX->pkey_data; - pk.key.rsa.nlen = nlen; - pk.key.rsa.e = CTX->pkey_data + nlen; - pk.key.rsa.elen = elen; - T0_PUSH(verify_signature(CTX, &pk)); -} - -\ Verify ECDSA signature. This uses the public key that was just decoded -\ into CTX->pkey_dayta; the curve ID and public point length are provided -\ as parameters. The hash value in tbs_hash is used. Returned value is 0 -\ on success, or non-zero error code. -cc: do-ecdsa-vrfy ( curve qlen -- err ) { - size_t qlen = T0_POP(); - int curve = T0_POP(); - br_x509_pkey pk; - - pk.key_type = BR_KEYTYPE_EC; - pk.key.ec.curve = curve; - pk.key.ec.q = CTX->pkey_data; - pk.key.ec.qlen = qlen; - T0_PUSH(verify_signature(CTX, &pk)); -} - -cc: print-bytes ( addr len -- ) { - extern int printf(const char *fmt, ...); - size_t len = T0_POP(); - unsigned char *buf = (unsigned char *)CTX + T0_POP(); - size_t u; - - for (u = 0; u < len; u ++) { - printf("%02X", buf[u]); - } -} - -cc: printOID ( -- ) { - extern int printf(const char *fmt, ...); - size_t u, len; - - len = CTX->pad[0]; - if (len == 0) { - printf("*"); - T0_RET(); - } - printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40); - u = 2; - while (u <= len) { - unsigned long ul; - - ul = 0; - for (;;) { - int x; - - if (u > len) { - printf("BAD"); - T0_RET(); - } - x = CTX->pad[u ++]; - ul = (ul << 7) + (x & 0x7F); - if (!(x & 0x80)) { - break; - } - } - printf(".%lu", ul); - } -} - -\ Extensions with specific processing. -OID: basicConstraints 2.5.29.19 -OID: keyUsage 2.5.29.15 -OID: subjectAltName 2.5.29.17 -OID: certificatePolicies 2.5.29.32 - -\ Policy qualifier "pointer to CPS" -OID: id-qt-cps 1.3.6.1.5.5.7.2.1 - -\ Extensions which are ignored when encountered, even if critical. -OID: authorityKeyIdentifier 2.5.29.35 -OID: subjectKeyIdentifier 2.5.29.14 -OID: issuerAltName 2.5.29.18 -OID: subjectDirectoryAttributes 2.5.29.9 -OID: crlDistributionPoints 2.5.29.31 -OID: freshestCRL 2.5.29.46 -OID: authorityInfoAccess 1.3.6.1.5.5.7.1.1 -OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 - -\ Process a Basic Constraints extension. This should be called only if -\ the certificate is not the EE. We check that the extension contains -\ the "CA" flag, and that the path length, if specified, is compatible -\ with the current chain length. -: process-basicConstraints ( lim -- lim ) - read-sequence-open - read-tag-or-end - dup 0x01 = if - read-boolean ifnot ERR_X509_NOT_CA fail then - read-tag-or-end - else - ERR_X509_NOT_CA fail - then - dup 0x02 = if - drop check-primitive read-small-int-value - addr-num_certs get32 1- < if ERR_X509_NOT_CA fail then - read-tag-or-end - then - -1 <> if ERR_X509_UNEXPECTED fail then - drop - close-elt - ; - -\ Process a Key Usage extension. -\ For the EE certificate: -\ -- if the key usage contains keyEncipherment (2), dataEncipherment (3) -\ or keyAgreement (4), then the "key exchange" usage is allowed; -\ -- if the key usage contains digitalSignature (0) or nonRepudiation (1), -\ then the "signature" usage is allowed. -\ For CA certificates, the extension must contain keyCertSign (5). -: process-keyUsage ( lim ee -- lim ) - { ee } - - \ Read tag for the BIT STRING and open it. - read-tag 0x03 check-tag-primitive - read-length-open-elt - \ First byte indicates number of ignored bits in the last byte. It - \ must be between 0 and 7. - read8 { ign } - ign 7 > if ERR_X509_UNEXPECTED fail then - \ Depending on length, we have either 0, 1 or more bytes to read. - dup case - 0 of ERR_X509_FORBIDDEN_KEY_USAGE fail endof - 1 of read8 ign >> ign << endof - drop read8 0 - endcase - - \ Check bits. - ee if - \ EE: get usages. - 0 - over 0x38 and if 0x10 or then - swap 0xC0 and if 0x20 or then - addr-key_usages set8 - else - \ Not EE: keyCertSign must be set. - 0x04 and ifnot ERR_X509_FORBIDDEN_KEY_USAGE fail then - then - - \ We don't care about subsequent bytes. - skip-close-elt ; - -\ Process a Certificate Policies extension. -\ -\ Since we don't actually support full policies processing, this function -\ only checks that the extension contents can be safely ignored. Indeed, -\ we don't validate against a specific set of policies (in RFC 5280 -\ terminology, user-initial-policy-set only contains the special value -\ any-policy). Moreover, we don't support policy constraints (if a -\ critical Policy Constraints extension is encountered, the validation -\ will fail). Therefore, we can safely ignore the contents of this -\ extension, except if it is critical AND one of the policy OID has a -\ qualifier which is distinct from id-qt-cps (because id-qt-cps is -\ specially designated by RFC 5280 has having no mandated action). -\ -\ This function is called only if the extension is critical. -: process-certPolicies ( lim -- lim ) - \ Extension value is a SEQUENCE OF PolicyInformation. - read-sequence-open - begin dup while - \ PolicyInformation ::= SEQUENCE { - \ policyIdentifier OBJECT IDENTIFIER, - \ policyQualifiers SEQUENCE OF PolicyQualifierInfo OPTIONAL - \ } - read-sequence-open - read-OID drop - dup if - read-sequence-open - begin dup while - \ PolicyQualifierInfo ::= SEQUENCE { - \ policyQualifierId OBJECT IDENTIFIER, - \ qualifier ANY - \ } - read-sequence-open - read-OID drop id-qt-cps eqOID ifnot - ERR_X509_CRITICAL_EXTENSION fail - then - skip-close-elt - repeat - close-elt - then - close-elt - repeat - close-elt ; - -\ Process a Subject Alt Name extension. Returned value is a boolean set -\ to true if the expected server name was matched against a dNSName in -\ the extension. -: process-SAN ( lim -- lim bool ) - 0 { m } - read-sequence-open - begin dup while - \ Read the tag. If the tag is context-0, then parse an - \ 'otherName'. If the tag is context-2, then parse a - \ dNSName. If the tag is context-1 or context-6, - \ parse - read-tag case - \ OtherName - 0x20 of - \ OtherName ::= SEQUENCE { - \ type-id OBJECT IDENTIFIER, - \ value [0] EXPLICIT ANY - \ } - check-constructed read-length-open-elt - read-OID drop - -1 offset-name-element { offbuf } - read-tag 0x20 check-tag-constructed - read-length-open-elt - read-string offbuf copy-name-element - close-elt - close-elt - endof - \ rfc822Name (IA5String) - 0x21 of - check-primitive - read-value-UTF8 1 copy-name-SAN - endof - \ dNSName (IA5String) - 0x22 of - check-primitive - read-value-UTF8 - dup if match-server-name m or >m then - 2 copy-name-SAN - endof - \ uniformResourceIdentifier (IA5String) - 0x26 of - check-primitive - read-value-UTF8 6 copy-name-SAN - endof - 2drop read-length-skip 0 - endcase - - \ We check only names of type dNSName; they use IA5String, - \ which is basically ASCII. - \ read-tag 0x22 = if - \ check-primitive - \ read-small-value drop - \ match-server-name m or >m - \ else - \ drop read-length-skip - \ then - repeat - close-elt - m ; - -\ Decode a certificate. The "ee" boolean must be true for the EE. -: decode-certificate ( ee -- ) - { ee } - - \ Obtain the total certificate length. - addr-cert_length get32 - - \ Open the outer SEQUENCE. - read-sequence-open - - \ TBS - \ Activate hashing. - start-tbs-hash - read-sequence-open - - \ First element may be an explicit version. We accept only - \ versions 0 to 2 (certificates v1 to v3). - read-tag dup 0x20 = if - drop check-constructed read-length-open-elt - read-tag - 0x02 check-tag-primitive - read-small-int-value - 2 > if ERR_X509_UNSUPPORTED fail then - close-elt - read-tag - then - - \ Serial number. We just check that the tag is correct. - 0x02 check-tag-primitive - read-length-skip - - \ Signature algorithm. This structure is redundant with the one - \ on the outside; we just skip it. - read-sequence-open skip-close-elt - - \ Issuer name: hashed, then copied into next_dn_hash[]. - read-DN - addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy - - \ Validity dates. - read-sequence-open - read-date get-system-date after if ERR_X509_EXPIRED fail then - read-date get-system-date before if ERR_X509_EXPIRED fail then - close-elt - - \ Subject name. - ee if - \ For the EE, we must check whether the Common Name, if - \ any, matches the expected server name. - read-DN-EE { eename } - else - \ For a non-EE certificate, the hashed subject DN must match - \ the saved hashed issuer DN from the previous certificate. - read-DN - addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob - ifnot ERR_X509_DN_MISMATCH fail then - then - \ Move the hashed issuer DN for this certificate into the - \ saved_dn_hash[] array. - addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy - - \ Public Key. - read-sequence-open - \ Algorithm Identifier. Right now we are only interested in the - \ OID, since we only support RSA keys. - read-sequence-open - read-OID ifnot ERR_X509_UNSUPPORTED fail then - { ; pkey-type } - choice - \ RSA public key. - rsaEncryption eqOID uf - skip-close-elt - \ Public key itself: the BIT STRING contains bytes - \ (no partial byte) and these bytes encode the - \ actual value. - read-bits-open - \ RSA public key is a SEQUENCE of two - \ INTEGER. We get both INTEGER values into - \ the pkey_data[] buffer, if they fit. - read-sequence-open - addr-len-pkey_data - read-integer { nlen } - addr-len-pkey_data swap nlen + swap nlen - - read-integer { elen } - close-elt - - \ Check that the public key fits our minimal - \ size requirements. Note that the integer - \ decoder already skipped the leading bytes - \ of value 0, so we are working on the true - \ modulus length here. - addr-min_rsa_size get16 128 + nlen > if - ERR_X509_WEAK_PUBLIC_KEY fail - then - close-elt - KEYTYPE_RSA >pkey-type - enduf - - \ EC public key. - id-ecPublicKey eqOID uf - \ We support only named curves, for which the - \ "parameters" field in the AlgorithmIdentifier - \ field should be an OID. - read-OID ifnot ERR_X509_UNSUPPORTED fail then - choice - ansix9p256r1 eqOID uf 23 enduf - ansix9p384r1 eqOID uf 24 enduf - ansix9p521r1 eqOID uf 25 enduf - ERR_X509_UNSUPPORTED fail - endchoice - { curve } - close-elt - read-bits-open - dup { qlen } - dup addr-len-pkey_data rot < if - ERR_X509_LIMIT_EXCEEDED fail - then - read-blob - KEYTYPE_EC >pkey-type - enduf - - \ Not a recognised public key type. - ERR_X509_UNSUPPORTED fail - endchoice - close-elt - - \ Process public key. - ee if - \ For the EE certificate, copy the key data to the - \ relevant buffer. - pkey-type case - KEYTYPE_RSA of nlen elen copy-ee-rsa-pkey endof - KEYTYPE_EC of curve qlen copy-ee-ec-pkey endof - ERR_X509_UNSUPPORTED fail - endcase - else - \ Verify signature on previous certificate. We invoke - \ the RSA implementation. - pkey-type case - KEYTYPE_RSA of nlen elen do-rsa-vrfy endof - KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof - ERR_X509_UNSUPPORTED fail - endcase - dup if fail then - drop - then - - \ This flag will be set to true if the Basic Constraints extension - \ is encountered. - 0 { seenBC } - - \ Skip issuerUniqueID and subjectUniqueID, and process extensions - \ if present. Extensions are an explicit context tag of value 3 - \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE - \ with an OID, an optional boolean, and a value; the value is - \ an OCTET STRING. - read-tag-or-end - 0x21 iftag-skip - 0x22 iftag-skip - dup 0x23 = if - drop - check-constructed read-length-open-elt - read-sequence-open - begin dup while - 0 { critical } - read-sequence-open - read-OID drop - read-tag dup 0x01 = if - read-boolean >critical - read-tag - then - 0x04 check-tag-primitive read-length-open-elt - choice - \ Extensions with specific processing. - basicConstraints eqOID uf - ee if - skip-remaining - else - process-basicConstraints - -1 >seenBC - then - enduf - keyUsage eqOID uf - ee process-keyUsage - enduf - subjectAltName eqOID uf - ee if - 0 >eename - process-SAN >eename - else - skip-remaining - then - enduf - - \ We don't implement full processing of - \ policies. The call below mostly checks - \ that the contents of the Certificate - \ Policies extension can be safely ignored. - certificatePolicies eqOID uf - critical if - process-certPolicies - else - skip-remaining - then - enduf - - \ Extensions which are always ignored, - \ even if critical. - authorityKeyIdentifier eqOID uf - skip-remaining - enduf - subjectKeyIdentifier eqOID uf - skip-remaining - enduf - issuerAltName eqOID uf - skip-remaining - enduf - subjectDirectoryAttributes eqOID uf - skip-remaining - enduf - crlDistributionPoints eqOID uf - skip-remaining - enduf - freshestCRL eqOID uf - skip-remaining - enduf - authorityInfoAccess eqOID uf - skip-remaining - enduf - subjectInfoAccess eqOID uf - skip-remaining - enduf - - \ Unrecognized extensions trigger a failure - \ if critical; otherwise, they are just - \ ignored. - \ critical if - \ ERR_X509_CRITICAL_EXTENSION fail - \ then - skip-remaining - endchoice - close-elt - close-elt - repeat - close-elt - close-elt - else - -1 = ifnot ERR_X509_UNEXPECTED fail then - drop - then - - close-elt - \ Terminate hashing. - stop-tbs-hash - - \ For the EE certificate, verify that the intended server name - \ was matched. - ee if - eename zero-server-name or ifnot - ERR_X509_BAD_SERVER_NAME fail - then - then - - \ If this is the EE certificate, then direct trust may apply. - \ Note: we do this at this point, not immediately after decoding - \ the public key, because even in case of direct trust we still - \ want to check the server name with regards to the SAN extension. - \ However, we want to check direct trust before trying to decode - \ the signature algorithm, because it should work even if that - \ algorithm is not supported. - ee if check-direct-trust then - - \ Non-EE certificates MUST have a Basic Constraints extension - \ (that marks them as being CA). - ee seenBC or ifnot ERR_X509_NOT_CA fail then - - \ signature algorithm - read-tag check-sequence read-length-open-elt - \ Read and understand the OID. Right now, we support only - \ RSA with PKCS#1 v1.5 padding, and hash functions SHA-1, - \ SHA-224, SHA-256, SHA-384 and SHA-512. We purposely do NOT - \ support MD5 here. - \ TODO: add support for RSA/PSS - read-OID if - \ Based on the signature OID, we get: - \ -- the signing key type - \ -- the hash function numeric identifier - \ -- the hash function OID - choice - sha1WithRSAEncryption eqOID - uf 2 KEYTYPE_RSA id-sha1 enduf - sha224WithRSAEncryption eqOID - uf 3 KEYTYPE_RSA id-sha224 enduf - sha256WithRSAEncryption eqOID - uf 4 KEYTYPE_RSA id-sha256 enduf - sha384WithRSAEncryption eqOID - uf 5 KEYTYPE_RSA id-sha384 enduf - sha512WithRSAEncryption eqOID - uf 6 KEYTYPE_RSA id-sha512 enduf - - ecdsa-with-SHA1 eqOID - uf 2 KEYTYPE_EC id-sha1 enduf - ecdsa-with-SHA224 eqOID - uf 3 KEYTYPE_EC id-sha224 enduf - ecdsa-with-SHA256 eqOID - uf 4 KEYTYPE_EC id-sha256 enduf - ecdsa-with-SHA384 eqOID - uf 5 KEYTYPE_EC id-sha384 enduf - ecdsa-with-SHA512 eqOID - uf 6 KEYTYPE_EC id-sha512 enduf - ERR_X509_UNSUPPORTED fail - endchoice - addr-cert_sig_hash_oid set16 - addr-cert_signer_key_type set8 - - \ Compute the TBS hash into tbs_hash. - compute-tbs-hash - dup ifnot ERR_X509_UNSUPPORTED fail then - addr-cert_sig_hash_len set8 - else - ERR_X509_UNSUPPORTED fail - then - \ We ignore the parameters, whether they are present or not, - \ because we got all the information from the OID. - skip-close-elt - - \ signature value - read-bits-open - dup CX 0 8191 { BR_X509_BUFSIZE_SIG } > if - ERR_X509_LIMIT_EXCEEDED fail - then - dup addr-cert_sig_len set16 - addr-cert_sig read-blob - - \ Close the outer SEQUENCE. - close-elt - - \ Close the advertised total certificate length. This checks that - \ there is no trailing garbage after the certificate. - close-elt - - \ Flag the certificate as fully processed. - 0 addr-cert_length set32 - - \ Check whether the issuer for the current certificate is known - \ as a trusted CA; in which case, verify the signature. - check-trust-anchor-CA ; - -: main - \ Unless restricted by a Key Usage extension, all usages are - \ deemed allowed. - 0x30 addr-key_usages set8 - -1 decode-certificate - co - begin - 0 decode-certificate co - again - ;