From d40d23b60cf1a42188a441b59226db35da234fea Mon Sep 17 00:00:00 2001 From: Thomas Pornin <thomas.pornin@nccgroup.com> Date: Sun, 17 Apr 2022 15:02:36 -0400 Subject: [PATCH] Added generic API for date range validation (with callbacks). --- T0Comp.exe | Bin 72704 -> 73216 bytes inc/bearssl_x509.h | 83 ++++- src/x509/x509_minimal.c | 751 ++++++++++++++++++++------------------- src/x509/x509_minimal.t0 | 78 ++-- test/test_x509.c | 210 ++++++----- 5 files changed, 631 insertions(+), 491 deletions(-) diff --git a/T0Comp.exe b/T0Comp.exe index 67eba109800eaebba3b6d72a00e5390a7089078e..de2364d69e075555677f324e70665250ea3e07c8 100755 GIT binary patch delta 28000 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 D&Oj7a delta 27840 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 F{}*Y&;zR%d diff --git a/inc/bearssl_x509.h b/inc/bearssl_x509.h index 49d2fba..7668e1d 100644 --- a/inc/bearssl_x509.h +++ b/inc/bearssl_x509.h @@ -625,6 +625,52 @@ typedef struct { } br_name_element; +/** + * \brief Callback for validity date checks. + * + * The function receives as parameter an arbitrary user-provided context, + * and the notBefore and notAfter dates specified in an X.509 certificate, + * both expressed as a number of days and a number of seconds: + * + * - Days are counted in a proleptic Gregorian calendar since + * January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; + * it is also traditionally known as "1 BC". + * + * - Seconds are counted since midnight, from 0 to 86400 (a count of + * 86400 is possible only if a leap second happened). + * + * Each 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. + * + * This function must return -1 if the current date is strictly before + * the "notBefore" time, or +1 if the current date is strictly after the + * "notAfter" time. If neither condition holds, then the function returns + * 0, which means that the current date falls within the validity range of + * the certificate. If the function returns a value distinct from -1, 0 + * and +1, then this is interpreted as an unavailability of the current + * time, which normally ends the validation process with a + * `BR_ERR_X509_TIME_UNKNOWN` error. + * + * During path validation, this callback will be invoked for each + * considered X.509 certificate. Validation fails if any of the calls + * returns a non-zero value. + * + * The context value is an abritrary pointer set by the caller when + * configuring this callback. + * + * \param tctx context pointer. + * \param not_before_days notBefore date (days since Jan 1st, 0 AD). + * \param not_before_seconds notBefore time (seconds, at most 86400). + * \param not_after_days notAfter date (days since Jan 1st, 0 AD). + * \param not_after_seconds notAfter time (seconds, at most 86400). + * \return -1, 0 or +1. + */ +typedef int (*br_x509_time_check)(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds); + /** * \brief The "minimal" X.509 engine structure. * @@ -647,8 +693,8 @@ typedef struct { uint32_t *rp; const unsigned char *ip; } cpu; - uint32_t dp_stack[32]; - uint32_t rp_stack[32]; + uint32_t dp_stack[31]; + uint32_t rp_stack[31]; int err; /* Server name to match with the SAN / CN of the EE certificate. */ @@ -723,6 +769,12 @@ typedef struct { br_name_element *name_elts; size_t num_name_elts; + /* + * Callback function (and context) to get the current date. + */ + void *itime_ctx; + br_x509_time_check itime; + /* * Public key cryptography implementations (signature verification). */ @@ -853,7 +905,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 @@ -871,6 +926,28 @@ br_x509_minimal_set_time(br_x509_minimal_context *ctx, { ctx->days = days; ctx->seconds = seconds; + ctx->itime = 0; +} + +/** + * \brief Set the validity range callback function for the X.509 + * "minimal" engine. + * + * The provided function will be invoked to check whether the validation + * date is within the validity range for a given X.509 certificate; a + * call will be issued for each considered certificate. The provided + * context pointer (itime_ctx) will be passed as first parameter to the + * callback. + * + * \param tctx context for callback invocation. + * \param cb callback function. + */ +static inline void +br_x509_minimal_set_time_callback(br_x509_minimal_context *ctx, + void *itime_ctx, br_x509_time_check itime) +{ + ctx->itime_ctx = itime_ctx; + ctx->itime = itime; } /** diff --git a/src/x509/x509_minimal.c b/src/x509/x509_minimal.c index 6103c08..04f149b 100644 --- a/src/x509/x509_minimal.c +++ b/src/x509/x509_minimal.c @@ -157,7 +157,7 @@ void br_x509_minimal_run(void *t0ctx); * -- 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 legnth compatible with + * 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 @@ -448,7 +448,7 @@ static const unsigned char t0_datablock[] = { static const unsigned char t0_codeblock[] = { 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, @@ -486,227 +486,224 @@ static const unsigned char t0_codeblock[] = { 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, 0x26, 0x24, 0x74, 0xAD, 0xAF, 0x25, 0x06, 0x81, - 0x1A, 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, 0x6C, 0x91, 0x26, 0x06, 0x06, 0x02, 0x00, - 0x9B, 0x04, 0x80, 0x62, 0xC5, 0x26, 0x06, 0x11, 0x02, 0x00, 0x06, 0x09, - 0x01, 0x00, 0x03, 0x01, 0x98, 0x03, 0x01, 0x04, 0x01, 0xC3, 0x04, 0x80, - 0x4D, 0x73, 0x26, 0x06, 0x0A, 0x02, 0x08, 0x06, 0x03, 0x9A, 0x04, 0x01, - 0xC3, 0x04, 0x3F, 0x6F, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x38, 0xC8, 0x26, - 0x06, 0x03, 0xC3, 0x04, 0x31, 0x90, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x2A, - 0xC6, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x23, 0x7A, 0x26, 0x06, 0x03, 0xC3, - 0x04, 0x1C, 0x85, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x15, 0x6E, 0x26, 0x06, - 0x03, 0xC3, 0x04, 0x0E, 0xC7, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x07, 0x02, - 0x08, 0x06, 0x02, 0x49, 0x28, 0xC3, 0x79, 0x79, 0x04, 0xFE, 0x62, 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[] = { @@ -755,106 +752,103 @@ static const uint16_t t0_caddr[] = { 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, - 992, - 1007, - 1011, - 1016, - 1021, - 1026, - 1031, - 1036, + 313, + 324, + 960, + 975, + 979, + 984, + 989, + 994, + 999, + 1004, + 1118, + 1123, + 1135, + 1140, + 1145, 1150, - 1155, - 1167, - 1172, - 1177, - 1182, - 1186, - 1191, - 1196, - 1201, + 1154, + 1159, + 1164, + 1169, + 1174, + 1184, + 1189, + 1194, 1206, - 1216, 1221, 1226, - 1238, - 1253, - 1258, - 1272, - 1294, - 1305, - 1408, - 1455, - 1488, - 1579, - 1585, - 1648, - 1655, - 1683, - 1711, - 1816, - 1858, - 1871, - 1883, - 1897, - 1912, - 2132, - 2146, - 2163, - 2172, - 2239, - 2295, - 2299, - 2303, - 2308, - 2356, - 2382, - 2458, - 2502, - 2513, - 2598, - 2636, - 2674, + 1240, + 1262, + 1273, + 1376, + 1423, + 1456, + 1547, + 1553, + 1616, + 1623, + 1651, + 1679, + 1784, + 1826, + 1839, + 1851, + 1865, + 1880, + 2100, + 2114, + 2131, + 2140, + 2207, + 2263, + 2267, + 2271, + 2276, + 2324, + 2350, + 2426, + 2470, + 2481, + 2566, + 2604, + 2642, + 2652, + 2662, + 2671, 2684, - 2694, - 2703, - 2716, - 2720, + 2688, + 2692, + 2696, + 2700, + 2704, + 2708, + 2712, 2724, - 2728, 2732, - 2736, - 2740, - 2744, - 2756, - 2764, - 2769, - 2774, - 2779, - 2784, - 2792 + 2737, + 2742, + 2747, + 2752 }; -#define T0_INTERPRETED 61 +#define T0_INTERPRETED 60 #define T0_ENTER(ip, rp, slot) do { \ const unsigned char *t0_newip; \ @@ -875,7 +869,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) (*(*(t0ipp)) ++) @@ -1205,11 +1199,61 @@ 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; + if (CTX->itime != 0) { + r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas); + if (r < -1 || r > 1) { + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); + } + } else { + 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); @@ -1217,7 +1261,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 27: { + case 28: { /* compute-tbs-hash */ int id = T0_POPi(); @@ -1227,7 +1271,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 28: { + case 29: { /* copy-ee-ec-pkey */ size_t qlen = T0_POP(); @@ -1240,7 +1284,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 29: { + case 30: { /* copy-ee-rsa-pkey */ size_t elen = T0_POP(); @@ -1254,7 +1298,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 30: { + case 31: { /* copy-name-SAN */ unsigned tag = T0_POP(); @@ -1280,7 +1324,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 31: { + case 32: { /* copy-name-element */ size_t len; @@ -1306,7 +1350,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 32: { + case 33: { /* data-get8 */ size_t addr = T0_POP(); @@ -1314,14 +1358,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(); @@ -1336,7 +1380,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 35: { + case 36: { /* do-rsa-vrfy */ size_t elen = T0_POP(); @@ -1352,17 +1396,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()]; @@ -1378,7 +1422,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 39: { + case 40: { /* eqblob */ size_t len = T0_POP(); @@ -1388,42 +1432,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: { @@ -1579,16 +1593,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(); @@ -1596,7 +1605,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 54: { + case 53: { /* set32 */ uint32_t addr = T0_POP(); @@ -1604,7 +1613,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 55: { + case 54: { /* set8 */ uint32_t addr = T0_POP(); @@ -1612,7 +1621,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 56: { + case 55: { /* start-dn-hash */ CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); @@ -1620,7 +1629,7 @@ br_x509_minimal_run(void *t0ctx) } break; - case 57: { + case 56: { /* start-tbs-hash */ br_multihash_init(&CTX->mhash); @@ -1628,19 +1637,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/src/x509/x509_minimal.t0 b/src/x509/x509_minimal.t0 index 50995dc..80a3701 100644 --- a/src/x509/x509_minimal.t0 +++ b/src/x509/x509_minimal.t0 @@ -698,42 +698,60 @@ cc: copy-name-SAN ( bool tag -- ) { \ 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) { +\ Check the provided validity range against the current (or configured) +\ date and time ("na" = notAfter, "nb = notBefore). Returned value: +\ -1 current date/time is before the notBefore date +\ 0 current date/time is within the allowed range +\ +1 current date/time is after the notAfter range +\ If the current date/time is not available, then this function triggers a +\ failure and does not return. +cc: check-validity-range ( na-days na-seconds nb-days nb-seconds -- int ) { + uint32_t nbs = T0_POP(); + uint32_t nbd = T0_POP(); + uint32_t nas = T0_POP(); + uint32_t nad = T0_POP(); + int r; + if (CTX->itime != 0) { + r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas); + if (r < -1 || r > 1) { + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); + } + } else { + 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); + time_t x = time(NULL); - T0_PUSH((uint32_t)(x / 86400) + 719528); - T0_PUSH((uint32_t)(x % 86400)); + 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); - T0_PUSH((uint32_t)(x / 86400) + 584754); - T0_PUSH((uint32_t)(x % 86400)); + 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(); + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); #endif - } else { - T0_PUSH(CTX->days); - T0_PUSH(CTX->seconds); + } + 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); } -\ 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 ; @@ -1189,8 +1207,8 @@ OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 \ 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 + read-date { nbd nbs } read-date nbd nbs check-validity-range + if ERR_X509_EXPIRED fail then close-elt \ Subject name. diff --git a/test/test_x509.c b/test/test_x509.c index 2c61cf5..c007068 100644 --- a/test/test_x509.c +++ b/test/test_x509.c @@ -1438,6 +1438,21 @@ eqpkey(const br_x509_pkey *pk1, const br_x509_pkey *pk2) static size_t max_dp_usage; static size_t max_rp_usage; +static int +check_time(void *ctx, uint32_t nbd, uint32_t nbs, uint32_t nad, uint32_t nas) +{ + test_case *tc; + + tc = ctx; + if (tc->days < nbd || (tc->days == nbd && tc->seconds < nbs)) { + return -1; + } + if (tc->days > nad || (tc->days == nad && tc->seconds > nas)) { + return 1; + } + return 0; +} + static void run_test_case(test_case *tc) { @@ -1452,6 +1467,7 @@ run_test_case(test_case *tc) const br_x509_pkey *ee_pkey; unsigned usages; unsigned status; + int j; printf("%s: ", tc->name); fflush(stdout); @@ -1520,110 +1536,130 @@ run_test_case(test_case *tc) } /* - * Initialise the engine. + * We do the test twice, to exercise distinct API functions. */ - br_x509_minimal_init(&ctx, dnhash, anchors, num_anchors); - for (u = 0; hash_impls[u].id; u ++) { - int id; + for (j = 0; j < 2; j ++) { + /* + * Initialise the engine. + */ + br_x509_minimal_init(&ctx, dnhash, anchors, num_anchors); + for (u = 0; hash_impls[u].id; u ++) { + int id; + + id = hash_impls[u].id; + if ((tc->hashes & ((unsigned)1 << id)) != 0) { + br_x509_minimal_set_hash(&ctx, + id, hash_impls[u].impl); + } + } + br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default()); + br_x509_minimal_set_ecdsa(&ctx, + br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default()); - id = hash_impls[u].id; - if ((tc->hashes & ((unsigned)1 << id)) != 0) { - br_x509_minimal_set_hash(&ctx, id, hash_impls[u].impl); + /* + * Set the validation date. + */ + if (j == 0) { + br_x509_minimal_set_time(&ctx, tc->days, tc->seconds); + } else { + br_x509_minimal_set_time_callback(&ctx, + tc, &check_time); } - } - br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default()); - br_x509_minimal_set_ecdsa(&ctx, - br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default()); - /* - * Set the validation date. - */ - br_x509_minimal_set_time(&ctx, tc->days, tc->seconds); + /* + * Put "canaries" to detect actual stack usage. + */ + for (u = 0; u < (sizeof ctx.dp_stack) / sizeof(uint32_t); + u ++) + { + ctx.dp_stack[u] = 0xA7C083FE; + } + for (u = 0; u < (sizeof ctx.rp_stack) / sizeof(uint32_t); + u ++) + { + ctx.rp_stack[u] = 0xA7C083FE; + } - /* - * Put "canaries" to detect actual stack usage. - */ - for (u = 0; u < (sizeof ctx.dp_stack) / sizeof(uint32_t); u ++) { - ctx.dp_stack[u] = 0xA7C083FE; - } - for (u = 0; u < (sizeof ctx.rp_stack) / sizeof(uint32_t); u ++) { - ctx.rp_stack[u] = 0xA7C083FE; - } + /* + * Run the engine. We inject certificates by chunks of 100 + * bytes in order to exercise the coroutine API. + */ + ctx.vtable->start_chain(&ctx.vtable, tc->servername); + for (u = 0; u < num_certs; u ++) { + size_t v; - /* - * Run the engine. We inject certificates by chunks of 100 bytes - * in order to exercise the coroutine API. - */ - ctx.vtable->start_chain(&ctx.vtable, tc->servername); - for (u = 0; u < num_certs; u ++) { - size_t v; + ctx.vtable->start_cert(&ctx.vtable, certs[u].len); + v = 0; + while (v < certs[u].len) { + size_t w; - ctx.vtable->start_cert(&ctx.vtable, certs[u].len); - v = 0; - while (v < certs[u].len) { - size_t w; + w = certs[u].len - v; + if (w > 100) { + w = 100; + } + ctx.vtable->append(&ctx.vtable, + certs[u].data + v, w); + v += w; + } + ctx.vtable->end_cert(&ctx.vtable); + } + status = ctx.vtable->end_chain(&ctx.vtable); + ee_pkey = ctx.vtable->get_pkey(&ctx.vtable, &usages); - w = certs[u].len - v; - if (w > 100) { - w = 100; + /* + * Check key type and usage. + */ + if (ee_pkey != NULL) { + unsigned ktu; + + ktu = ee_pkey->key_type | usages; + if (tc->key_type_usage != (ktu & tc->key_type_usage)) { + fprintf(stderr, "wrong key type + usage" + " (expected 0x%02X, got 0x%02X)\n", + tc->key_type_usage, ktu); + exit(EXIT_FAILURE); } - ctx.vtable->append(&ctx.vtable, certs[u].data + v, w); - v += w; } - ctx.vtable->end_cert(&ctx.vtable); - } - status = ctx.vtable->end_chain(&ctx.vtable); - ee_pkey = ctx.vtable->get_pkey(&ctx.vtable, &usages); - /* - * Check key type and usage. - */ - if (ee_pkey != NULL) { - unsigned ktu; - - ktu = ee_pkey->key_type | usages; - if (tc->key_type_usage != (ktu & tc->key_type_usage)) { - fprintf(stderr, "wrong key type + usage" - " (expected 0x%02X, got 0x%02X)\n", - tc->key_type_usage, ktu); + /* + * Check results. Note that we may still get a public key if + * the path is "not trusted" (but otherwise fine). + */ + if (status != tc->status) { + fprintf(stderr, "wrong status (got %d, expected %d)\n", + status, tc->status); + exit(EXIT_FAILURE); + } + if (status == BR_ERR_X509_NOT_TRUSTED) { + ee_pkey = NULL; + } + if (!eqpkey(ee_pkey, ee_pkey_ref)) { + fprintf(stderr, "wrong EE public key\n"); exit(EXIT_FAILURE); } - } - - /* - * Check results. Note that we may still get a public key if - * the path is "not trusted" (but otherwise fine). - */ - if (status != tc->status) { - fprintf(stderr, "wrong status (got %d, expected %d)\n", - status, tc->status); - exit(EXIT_FAILURE); - } - if (status == BR_ERR_X509_NOT_TRUSTED) { - ee_pkey = NULL; - } - if (!eqpkey(ee_pkey, ee_pkey_ref)) { - fprintf(stderr, "wrong EE public key\n"); - exit(EXIT_FAILURE); - } - /* - * Check stack usage. - */ - for (u = (sizeof ctx.dp_stack) / sizeof(uint32_t); u > 0; u --) { - if (ctx.dp_stack[u - 1] != 0xA7C083FE) { - if (max_dp_usage < u) { - max_dp_usage = u; + /* + * Check stack usage. + */ + for (u = (sizeof ctx.dp_stack) / sizeof(uint32_t); + u > 0; u --) + { + if (ctx.dp_stack[u - 1] != 0xA7C083FE) { + if (max_dp_usage < u) { + max_dp_usage = u; + } + break; } - break; } - } - for (u = (sizeof ctx.rp_stack) / sizeof(uint32_t); u > 0; u --) { - if (ctx.rp_stack[u - 1] != 0xA7C083FE) { - if (max_rp_usage < u) { - max_rp_usage = u; + for (u = (sizeof ctx.rp_stack) / sizeof(uint32_t); + u > 0; u --) + { + if (ctx.rp_stack[u - 1] != 0xA7C083FE) { + if (max_rp_usage < u) { + max_rp_usage = u; + } + break; } - break; } } -- 2.17.1