/* Automatically generated code; do not modify directly. */
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} t0_context;
static uint32_t
t0_parse7E_unsigned(const unsigned char **p)
{
uint32_t x;
x = 0;
for (;;) {
unsigned y;
y = *(*p) ++;
x = (x << 7) | (uint32_t)(y & 0x7F);
if (y < 0x80) {
return x;
}
}
}
static int32_t
t0_parse7E_signed(const unsigned char **p)
{
int neg;
uint32_t x;
neg = ((**p) >> 6) & 1;
x = (uint32_t)-neg;
for (;;) {
unsigned y;
y = *(*p) ++;
x = (x << 7) | (uint32_t)(y & 0x7F);
if (y < 0x80) {
if (neg) {
return -(int32_t)~x - 1;
} else {
return (int32_t)x;
}
}
}
}
#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80)
#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F)
#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8)
#define T0_INT1(x) T0_FBYTE(x, 0)
#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0)
#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
/* static const unsigned char t0_datablock[]; */
void br_x509_minimal_init_main(void *t0ctx);
void br_x509_minimal_run(void *t0ctx);
#include "inner.h"
#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 legnth 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 <time.h>
#endif
#if BR_USE_WIN32_TIME
#include <windows.h>
#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 = {
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)
/*
* 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 && *b2 == 0) {
b2 ++;
len2 --;
}
if (len1 != len2) {
return 0;
}
return memcmp(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);
static const unsigned char t0_datablock[] = {
0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01,
0x0D, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x04, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
0x02, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x07,
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE,
0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B,
0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01,
0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, 0x2A, 0x86,
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04,
0x03, 0x55, 0x04, 0x03, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E,
0x0F, 0x1F, 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F,
0x26, 0x1E, 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E,
0x0F, 0x3F, 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F,
0x26, 0x3E, 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13, 0x03, 0x55, 0x1D, 0x0F,
0x03, 0x55, 0x1D, 0x11, 0x03, 0x55, 0x1D, 0x20, 0x08, 0x2B, 0x06, 0x01,
0x05, 0x05, 0x07, 0x02, 0x01, 0x03, 0x55, 0x1D, 0x23, 0x03, 0x55, 0x1D,
0x0E, 0x03, 0x55, 0x1D, 0x12, 0x03, 0x55, 0x1D, 0x09, 0x03, 0x55, 0x1D,
0x1F, 0x03, 0x55, 0x1D, 0x2E, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
0x01, 0x01, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0B
};
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,
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,
T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_CRITICAL_EXTENSION), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_DN_MISMATCH), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_EXPIRED), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_FORBIDDEN_KEY_USAGE), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_NOT_CA), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01,
T0_INT1(BR_ERR_X509_WEAK_PUBLIC_KEY), 0x00, 0x00, 0x01,
T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA),
0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_length)), 0x00,
0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig)), 0x00, 0x00,
0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_len)), 0x00, 0x00,
0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_oid)), 0x00, 0x00,
0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_len)), 0x00, 0x00, 0x01,
T0_INT2(offsetof(CONTEXT_NAME, cert_signer_key_type)), 0x00, 0x00,
0x01, T0_INT2(offsetof(CONTEXT_NAME, current_dn_hash)), 0x00, 0x00,
0x01, T0_INT2(offsetof(CONTEXT_NAME, key_usages)), 0x00, 0x00, 0x01,
T0_INT2(offsetof(br_x509_minimal_context, pkey_data)), 0x01,
T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01,
T0_INT2(offsetof(CONTEXT_NAME, min_rsa_size)), 0x00, 0x00, 0x01,
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, 0xFD, 0x5F,
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
};
static const uint16_t t0_caddr[] = {
0,
5,
10,
15,
20,
25,
29,
33,
37,
41,
45,
49,
53,
57,
61,
65,
69,
73,
77,
81,
85,
89,
93,
97,
101,
105,
109,
113,
117,
121,
125,
130,
135,
140,
145,
150,
155,
160,
165,
173,
178,
183,
188,
193,
198,
202,
207,
212,
217,
238,
243,
248,
253,
282,
297,
302,
308,
314,
319,
327,
335,
341,
346,
357,
992,
1007,
1011,
1016,
1021,
1026,
1031,
1036,
1150,
1155,
1167,
1172,
1177,
1182,
1186,
1191,
1196,
1201,
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,
2684,
2694,
2703,
2716,
2720,
2724,
2728,
2732,
2736,
2740,
2744,
2756,
2764,
2769,
2774,
2779,
2784,
2792
};
#define T0_INTERPRETED 61
#define T0_ENTER(ip, rp, slot) do { \
const unsigned char *t0_newip; \
uint32_t t0_lnum; \
t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \
t0_lnum = t0_parse7E_unsigned(&t0_newip); \
(rp) += t0_lnum; \
*((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \
(ip) = t0_newip; \
} while (0)
#define T0_DEFENTRY(name, slot) \
void \
name(void *ctx) \
{ \
t0_context *t0ctx = ctx; \
t0ctx->ip = &t0_codeblock[0]; \
T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \
}
T0_DEFENTRY(br_x509_minimal_init_main, 147)
#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++)
void
br_x509_minimal_run(void *t0ctx)
{
uint32_t *dp, *rp;
const unsigned char *ip;
#define T0_LOCAL(x) (*(rp - 2 - (x)))
#define T0_POP() (*-- dp)
#define T0_POPi() (*(int32_t *)(-- dp))
#define T0_PEEK(x) (*(dp - 1 - (x)))
#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x)))
#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0)
#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0)
#define T0_RPOP() (*-- rp)
#define T0_RPOPi() (*(int32_t *)(-- rp))
#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0)
#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0)
#define T0_ROLL(x) do { \
size_t t0len = (size_t)(x); \
uint32_t t0tmp = *(dp - 1 - t0len); \
memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \
*(dp - 1) = t0tmp; \
} while (0)
#define T0_SWAP() do { \
uint32_t t0tmp = *(dp - 2); \
*(dp - 2) = *(dp - 1); \
*(dp - 1) = t0tmp; \
} while (0)
#define T0_ROT() do { \
uint32_t t0tmp = *(dp - 3); \
*(dp - 3) = *(dp - 2); \
*(dp - 2) = *(dp - 1); \
*(dp - 1) = t0tmp; \
} while (0)
#define T0_NROT() do { \
uint32_t t0tmp = *(dp - 1); \
*(dp - 1) = *(dp - 2); \
*(dp - 2) = *(dp - 3); \
*(dp - 3) = t0tmp; \
} while (0)
#define T0_PICK(x) do { \
uint32_t t0depth = (x); \
T0_PUSH(T0_PEEK(t0depth)); \
} while (0)
#define T0_CO() do { \
goto t0_exit; \
} while (0)
#define T0_RET() goto t0_next
dp = ((t0_context *)t0ctx)->dp;
rp = ((t0_context *)t0ctx)->rp;
ip = ((t0_context *)t0ctx)->ip;
goto t0_next;
for (;;) {
uint32_t t0x;
t0_next:
t0x = T0_NEXT(&ip);
if (t0x < T0_INTERPRETED) {
switch (t0x) {
int32_t t0off;
case 0: /* ret */
t0x = T0_RPOP();
rp -= (t0x >> 16);
t0x &= 0xFFFF;
if (t0x == 0) {
ip = NULL;
goto t0_exit;
}
ip = &t0_codeblock[t0x];
break;
case 1: /* literal constant */
T0_PUSHi(t0_parse7E_signed(&ip));
break;
case 2: /* read local */
T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip)));
break;
case 3: /* write local */
T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP();
break;
case 4: /* jump */
t0off = t0_parse7E_signed(&ip);
ip += t0off;
break;
case 5: /* jump if */
t0off = t0_parse7E_signed(&ip);
if (T0_POP()) {
ip += t0off;
}
break;
case 6: /* jump if not */
t0off = t0_parse7E_signed(&ip);
if (!T0_POP()) {
ip += t0off;
}
break;
case 7: {
/* %25 */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSHi(a % b);
}
break;
case 8: {
/* * */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(a * b);
}
break;
case 9: {
/* + */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(a + b);
}
break;
case 10: {
/* - */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(a - b);
}
break;
case 11: {
/* -rot */
T0_NROT();
}
break;
case 12: {
/* / */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSHi(a / b);
}
break;
case 13: {
/* < */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSH(-(uint32_t)(a < b));
}
break;
case 14: {
/* << */
int c = (int)T0_POPi();
uint32_t x = T0_POP();
T0_PUSH(x << c);
}
break;
case 15: {
/* <= */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSH(-(uint32_t)(a <= b));
}
break;
case 16: {
/* <> */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(-(uint32_t)(a != b));
}
break;
case 17: {
/* = */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(-(uint32_t)(a == b));
}
break;
case 18: {
/* > */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSH(-(uint32_t)(a > b));
}
break;
case 19: {
/* >= */
int32_t b = T0_POPi();
int32_t a = T0_POPi();
T0_PUSH(-(uint32_t)(a >= b));
}
break;
case 20: {
/* >> */
int c = (int)T0_POPi();
int32_t x = T0_POPi();
T0_PUSHi(x >> c);
}
break;
case 21: {
/* and */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(a & b);
}
break;
case 22: {
/* blobcopy */
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);
}
break;
case 23: {
/* check-direct-trust */
size_t u;
for (u = 0; u < CTX->trust_anchors_num; u ++) {
const br_x509_trust_anchor *ta;
unsigned char hashed_DN[64];
int kt;
ta = &CTX->trust_anchors[u];
if (ta->flags & BR_X509_TA_CA) {
continue;
}
hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) {
continue;
}
kt = CTX->pkey.key_type;
if ((ta->pkey.key_type & 0x0F) != kt) {
continue;
}
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))
{
continue;
}
break;
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(CTX->pkey.key.ec.q,
ta->pkey.key.ec.q,
ta->pkey.key.ec.qlen) != 0)
{
continue;
}
break;
default:
continue;
}
/*
* Direct trust match!
*/
CTX->err = BR_ERR_X509_OK;
T0_CO();
}
}
break;
case 24: {
/* check-trust-anchor-CA */
size_t u;
for (u = 0; u < CTX->trust_anchors_num; u ++) {
const br_x509_trust_anchor *ta;
unsigned char hashed_DN[64];
ta = &CTX->trust_anchors[u];
if (!(ta->flags & BR_X509_TA_CA)) {
continue;
}
hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) {
continue;
}
if (verify_signature(CTX, &ta->pkey) == 0) {
CTX->err = BR_ERR_X509_OK;
T0_CO();
}
}
}
break;
case 25: {
/* co */
T0_CO();
}
break;
case 26: {
/* compute-dn-hash */
CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash);
CTX->do_dn_hash = 0;
}
break;
case 27: {
/* compute-tbs-hash */
int id = T0_POPi();
size_t len;
len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash);
T0_PUSH(len);
}
break;
case 28: {
/* copy-ee-ec-pkey */
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;
}
break;
case 29: {
/* copy-ee-rsa-pkey */
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;
}
break;
case 30: {
/* copy-name-SAN */
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;
}
}
}
break;
case 31: {
/* copy-name-element */
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;
}
}
}
break;
case 32: {
/* data-get8 */
size_t addr = T0_POP();
T0_PUSH(t0_datablock[addr]);
}
break;
case 33: {
/* dn-hash-length */
T0_PUSH(DNHASH_LEN);
}
break;
case 34: {
/* do-ecdsa-vrfy */
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));
}
break;
case 35: {
/* do-rsa-vrfy */
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));
}
break;
case 36: {
/* drop */
(void)T0_POP();
}
break;
case 37: {
/* dup */
T0_PUSH(T0_PEEK(0));
}
break;
case 38: {
/* eqOID */
const unsigned char *a2 = &t0_datablock[T0_POP()];
const unsigned char *a1 = &CTX->pad[0];
size_t len = a1[0];
int x;
if (len == a2[0]) {
x = -(memcmp(a1 + 1, a2 + 1, len) == 0);
} else {
x = 0;
}
T0_PUSH((uint32_t)x);
}
break;
case 39: {
/* eqblob */
size_t len = T0_POP();
const unsigned char *a2 = (const unsigned char *)CTX + T0_POP();
const unsigned char *a1 = (const unsigned char *)CTX + T0_POP();
T0_PUSHi(-(memcmp(a1, a2, len) == 0));
}
break;
case 40: {
/* 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: {
/* get16 */
uint32_t addr = T0_POP();
T0_PUSH(*(uint16_t *)(void *)((unsigned char *)CTX + addr));
}
break;
case 43: {
/* get32 */
uint32_t addr = T0_POP();
T0_PUSH(*(uint32_t *)(void *)((unsigned char *)CTX + addr));
}
break;
case 44: {
/* match-server-name */
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);
}
break;
case 45: {
/* neg */
uint32_t a = T0_POP();
T0_PUSH(-a);
}
break;
case 46: {
/* offset-name-element */
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);
}
break;
case 47: {
/* or */
uint32_t b = T0_POP();
uint32_t a = T0_POP();
T0_PUSH(a | b);
}
break;
case 48: {
/* over */
T0_PUSH(T0_PEEK(1));
}
break;
case 49: {
/* read-blob-inner */
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);
}
break;
case 50: {
/* read8-low */
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);
}
}
break;
case 51: {
/* roll */
T0_ROLL(T0_POP());
}
break;
case 52: {
/* rot */
T0_ROT();
}
break;
case 53: {
/* set16 */
uint32_t addr = T0_POP();
*(uint16_t *)(void *)((unsigned char *)CTX + addr) = T0_POP();
}
break;
case 54: {
/* set32 */
uint32_t addr = T0_POP();
*(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP();
}
break;
case 55: {
/* set8 */
uint32_t addr = T0_POP();
*((unsigned char *)CTX + addr) = (unsigned char)T0_POP();
}
break;
case 56: {
/* start-dn-hash */
CTX->dn_hash_impl->init(&CTX->dn_hash.vtable);
CTX->do_dn_hash = 1;
}
break;
case 57: {
/* start-tbs-hash */
br_multihash_init(&CTX->mhash);
CTX->do_mhash = 1;
}
break;
case 58: {
/* stop-tbs-hash */
CTX->do_mhash = 0;
}
break;
case 59: {
/* swap */
T0_SWAP();
}
break;
case 60: {
/* zero-server-name */
T0_PUSHi(-(CTX->server_name == NULL));
}
break;
}
} else {
T0_ENTER(ip, rp, t0x);
}
}
t0_exit:
((t0_context *)t0ctx)->dp = dp;
((t0_context *)t0ctx)->rp = rp;
((t0_context *)t0ctx)->ip = ip;
}
/*
* 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)
{
int kt;
kt = ctx->cert_signer_key_type;
if ((pk->key_type & 0x0F) != kt) {
return BR_ERR_X509_WRONG_KEY_TYPE;
}
switch (kt) {
unsigned char tmp[64];
case BR_KEYTYPE_RSA:
if (ctx->irsa == 0) {
return BR_ERR_X509_UNSUPPORTED;
}
if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len,
&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;
}
}