xref: /freebsd-src/contrib/bearssl/src/x509/x509_minimal.c (revision cc9e6590773dba57440750c124173ed531349a06)
10957b409SSimon J. Gerraty /* Automatically generated code; do not modify directly. */
20957b409SSimon J. Gerraty 
30957b409SSimon J. Gerraty #include <stddef.h>
40957b409SSimon J. Gerraty #include <stdint.h>
50957b409SSimon J. Gerraty 
60957b409SSimon J. Gerraty typedef struct {
70957b409SSimon J. Gerraty 	uint32_t *dp;
80957b409SSimon J. Gerraty 	uint32_t *rp;
90957b409SSimon J. Gerraty 	const unsigned char *ip;
100957b409SSimon J. Gerraty } t0_context;
110957b409SSimon J. Gerraty 
120957b409SSimon J. Gerraty static uint32_t
t0_parse7E_unsigned(const unsigned char ** p)130957b409SSimon J. Gerraty t0_parse7E_unsigned(const unsigned char **p)
140957b409SSimon J. Gerraty {
150957b409SSimon J. Gerraty 	uint32_t x;
160957b409SSimon J. Gerraty 
170957b409SSimon J. Gerraty 	x = 0;
180957b409SSimon J. Gerraty 	for (;;) {
190957b409SSimon J. Gerraty 		unsigned y;
200957b409SSimon J. Gerraty 
210957b409SSimon J. Gerraty 		y = *(*p) ++;
220957b409SSimon J. Gerraty 		x = (x << 7) | (uint32_t)(y & 0x7F);
230957b409SSimon J. Gerraty 		if (y < 0x80) {
240957b409SSimon J. Gerraty 			return x;
250957b409SSimon J. Gerraty 		}
260957b409SSimon J. Gerraty 	}
270957b409SSimon J. Gerraty }
280957b409SSimon J. Gerraty 
290957b409SSimon J. Gerraty static int32_t
t0_parse7E_signed(const unsigned char ** p)300957b409SSimon J. Gerraty t0_parse7E_signed(const unsigned char **p)
310957b409SSimon J. Gerraty {
320957b409SSimon J. Gerraty 	int neg;
330957b409SSimon J. Gerraty 	uint32_t x;
340957b409SSimon J. Gerraty 
350957b409SSimon J. Gerraty 	neg = ((**p) >> 6) & 1;
360957b409SSimon J. Gerraty 	x = (uint32_t)-neg;
370957b409SSimon J. Gerraty 	for (;;) {
380957b409SSimon J. Gerraty 		unsigned y;
390957b409SSimon J. Gerraty 
400957b409SSimon J. Gerraty 		y = *(*p) ++;
410957b409SSimon J. Gerraty 		x = (x << 7) | (uint32_t)(y & 0x7F);
420957b409SSimon J. Gerraty 		if (y < 0x80) {
430957b409SSimon J. Gerraty 			if (neg) {
440957b409SSimon J. Gerraty 				return -(int32_t)~x - 1;
450957b409SSimon J. Gerraty 			} else {
460957b409SSimon J. Gerraty 				return (int32_t)x;
470957b409SSimon J. Gerraty 			}
480957b409SSimon J. Gerraty 		}
490957b409SSimon J. Gerraty 	}
500957b409SSimon J. Gerraty }
510957b409SSimon J. Gerraty 
520957b409SSimon J. Gerraty #define T0_VBYTE(x, n)   (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80)
530957b409SSimon J. Gerraty #define T0_FBYTE(x, n)   (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F)
540957b409SSimon J. Gerraty #define T0_SBYTE(x)      (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8)
550957b409SSimon J. Gerraty #define T0_INT1(x)       T0_FBYTE(x, 0)
560957b409SSimon J. Gerraty #define T0_INT2(x)       T0_VBYTE(x, 7), T0_FBYTE(x, 0)
570957b409SSimon J. Gerraty #define T0_INT3(x)       T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
580957b409SSimon J. Gerraty #define T0_INT4(x)       T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
590957b409SSimon J. Gerraty #define T0_INT5(x)       T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0)
600957b409SSimon J. Gerraty 
610957b409SSimon J. Gerraty /* static const unsigned char t0_datablock[]; */
620957b409SSimon J. Gerraty 
630957b409SSimon J. Gerraty 
640957b409SSimon J. Gerraty void br_x509_minimal_init_main(void *t0ctx);
650957b409SSimon J. Gerraty 
660957b409SSimon J. Gerraty void br_x509_minimal_run(void *t0ctx);
670957b409SSimon J. Gerraty 
680957b409SSimon J. Gerraty 
690957b409SSimon J. Gerraty 
700957b409SSimon J. Gerraty #include "inner.h"
710957b409SSimon J. Gerraty 
720957b409SSimon J. Gerraty 
730957b409SSimon J. Gerraty 
740957b409SSimon J. Gerraty 
750957b409SSimon J. Gerraty 
760957b409SSimon J. Gerraty #include "inner.h"
770957b409SSimon J. Gerraty 
780957b409SSimon J. Gerraty /*
790957b409SSimon J. Gerraty  * Implementation Notes
800957b409SSimon J. Gerraty  * --------------------
810957b409SSimon J. Gerraty  *
820957b409SSimon J. Gerraty  * The C code pushes the data by chunks; all decoding is done in the
830957b409SSimon J. Gerraty  * T0 code. The cert_length value is set to the certificate length when
840957b409SSimon J. Gerraty  * a new certificate is started; the T0 code picks it up as outer limit,
850957b409SSimon J. Gerraty  * and decoding functions use it to ensure that no attempt is made at
860957b409SSimon J. Gerraty  * reading past it. The T0 code also checks that once the certificate is
870957b409SSimon J. Gerraty  * decoded, there are no trailing bytes.
880957b409SSimon J. Gerraty  *
890957b409SSimon J. Gerraty  * The T0 code sets cert_length to 0 when the certificate is fully
900957b409SSimon J. Gerraty  * decoded.
910957b409SSimon J. Gerraty  *
920957b409SSimon J. Gerraty  * The C code must still perform two checks:
930957b409SSimon J. Gerraty  *
940957b409SSimon J. Gerraty  *  -- If the certificate length is 0, then the T0 code will not be
950957b409SSimon J. Gerraty  *  invoked at all. This invalid condition must thus be reported by the
960957b409SSimon J. Gerraty  *  C code.
970957b409SSimon J. Gerraty  *
980957b409SSimon J. Gerraty  *  -- When reaching the end of certificate, the C code must verify that
990957b409SSimon J. Gerraty  *  the certificate length has been set to 0, thereby signaling that
1000957b409SSimon J. Gerraty  *  the T0 code properly decoded a certificate.
1010957b409SSimon J. Gerraty  *
1020957b409SSimon J. Gerraty  * Processing of a chain works in the following way:
1030957b409SSimon J. Gerraty  *
1040957b409SSimon J. Gerraty  *  -- The error flag is set to a non-zero value when validation is
1050957b409SSimon J. Gerraty  *  finished. The value is either BR_ERR_X509_OK (validation is
1060957b409SSimon J. Gerraty  *  successful) or another non-zero error code. When a non-zero error
1070957b409SSimon J. Gerraty  *  code is obtained, the remaining bytes in the current certificate and
1080957b409SSimon J. Gerraty  *  the subsequent certificates (if any) are completely ignored.
1090957b409SSimon J. Gerraty  *
1100957b409SSimon J. Gerraty  *  -- Each certificate is decoded in due course, with the following
1110957b409SSimon J. Gerraty  *  "interesting points":
1120957b409SSimon J. Gerraty  *
1130957b409SSimon J. Gerraty  *     -- Start of the TBS: the multihash engine is reset and activated.
1140957b409SSimon J. Gerraty  *
1150957b409SSimon J. Gerraty  *     -- Start of the issuer DN: the secondary hash engine is started,
1160957b409SSimon J. Gerraty  *     to process the encoded issuer DN.
1170957b409SSimon J. Gerraty  *
1180957b409SSimon J. Gerraty  *     -- End of the issuer DN: the secondary hash engine is stopped. The
1190957b409SSimon J. Gerraty  *     resulting hash value is computed and then copied into the
1200957b409SSimon J. Gerraty  *     next_dn_hash[] buffer.
1210957b409SSimon J. Gerraty  *
1220957b409SSimon J. Gerraty  *     -- Start of the subject DN: the secondary hash engine is started,
1230957b409SSimon J. Gerraty  *     to process the encoded subject DN.
1240957b409SSimon J. Gerraty  *
1250957b409SSimon J. Gerraty  *     -- For the EE certificate only: the Common Name, if any, is matched
1260957b409SSimon J. Gerraty  *     against the expected server name.
1270957b409SSimon J. Gerraty  *
1280957b409SSimon J. Gerraty  *     -- End of the subject DN: the secondary hash engine is stopped. The
1290957b409SSimon J. Gerraty  *     resulting hash value is computed into the pad. It is then processed:
1300957b409SSimon J. Gerraty  *
1310957b409SSimon J. Gerraty  *        -- If this is the EE certificate, then the hash is ignored
1320957b409SSimon J. Gerraty  *        (except for direct trust processing, see later; the hash is
1330957b409SSimon J. Gerraty  *        simply left in current_dn_hash[]).
1340957b409SSimon J. Gerraty  *
1350957b409SSimon J. Gerraty  *        -- Otherwise, the hashed subject DN is compared with the saved
1360957b409SSimon J. Gerraty  *        hash value (in saved_dn_hash[]). They must match.
1370957b409SSimon J. Gerraty  *
1380957b409SSimon J. Gerraty  *     Either way, the next_dn_hash[] value is then copied into the
1390957b409SSimon J. Gerraty  *     saved_dn_hash[] value. Thus, at that point, saved_dn_hash[]
1400957b409SSimon J. Gerraty  *     contains the hash of the issuer DN for the current certificate,
1410957b409SSimon J. Gerraty  *     and current_dn_hash[] contains the hash of the subject DN for the
1420957b409SSimon J. Gerraty  *     current certificate.
1430957b409SSimon J. Gerraty  *
1440957b409SSimon J. Gerraty  *     -- Public key: it is decoded into the cert_pkey[] buffer. Unknown
1450957b409SSimon J. Gerraty  *     key types are reported at that point.
1460957b409SSimon J. Gerraty  *
1470957b409SSimon J. Gerraty  *        -- If this is the EE certificate, then the key type is compared
1480957b409SSimon J. Gerraty  *        with the expected key type (initialization parameter). The public
1490957b409SSimon J. Gerraty  *        key data is copied to ee_pkey_data[]. The key and hashed subject
1500957b409SSimon J. Gerraty  *        DN are also compared with the "direct trust" keys; if the key
1510957b409SSimon J. Gerraty  *        and DN are matched, then validation ends with a success.
1520957b409SSimon J. Gerraty  *
1530957b409SSimon J. Gerraty  *        -- Otherwise, the saved signature (cert_sig[]) is verified
1540957b409SSimon J. Gerraty  *        against the saved TBS hash (tbs_hash[]) and that freshly
1550957b409SSimon J. Gerraty  *        decoded public key. Failure here ends validation with an error.
1560957b409SSimon J. Gerraty  *
1570957b409SSimon J. Gerraty  *     -- Extensions: extension values are processed in due order.
1580957b409SSimon J. Gerraty  *
1590957b409SSimon J. Gerraty  *        -- Basic Constraints: for all certificates except EE, must be
160*cc9e6590SSimon J. Gerraty  *        present, indicate a CA, and have a path length compatible with
1610957b409SSimon J. Gerraty  *        the chain length so far.
1620957b409SSimon J. Gerraty  *
1630957b409SSimon J. Gerraty  *        -- Key Usage: for the EE, if present, must allow signatures
1640957b409SSimon J. Gerraty  *        or encryption/key exchange, as required for the cipher suite.
1650957b409SSimon J. Gerraty  *        For non-EE, if present, must have the "certificate sign" bit.
1660957b409SSimon J. Gerraty  *
1670957b409SSimon J. Gerraty  *        -- Subject Alt Name: for the EE, dNSName names are matched
1680957b409SSimon J. Gerraty  *        against the server name. Ignored for non-EE.
1690957b409SSimon J. Gerraty  *
1700957b409SSimon J. Gerraty  *        -- Authority Key Identifier, Subject Key Identifier, Issuer
1710957b409SSimon J. Gerraty  *        Alt Name, Subject Directory Attributes, CRL Distribution Points
1720957b409SSimon J. Gerraty  *        Freshest CRL, Authority Info Access and Subject Info Access
1730957b409SSimon J. Gerraty  *        extensions are always ignored: they either contain only
1740957b409SSimon J. Gerraty  *        informative data, or they relate to revocation processing, which
1750957b409SSimon J. Gerraty  *        we explicitly do not support.
1760957b409SSimon J. Gerraty  *
1770957b409SSimon J. Gerraty  *        -- All other extensions are ignored if non-critical. If a
1780957b409SSimon J. Gerraty  *        critical extension other than the ones above is encountered,
1790957b409SSimon J. Gerraty  *        then a failure is reported.
1800957b409SSimon J. Gerraty  *
1810957b409SSimon J. Gerraty  *     -- End of the TBS: the multihash engine is stopped.
1820957b409SSimon J. Gerraty  *
1830957b409SSimon J. Gerraty  *     -- Signature algorithm: the signature algorithm on the
1840957b409SSimon J. Gerraty  *     certificate is decoded. A failure is reported if that algorithm
1850957b409SSimon J. Gerraty  *     is unknown. The hashed TBS corresponding to the signature hash
1860957b409SSimon J. Gerraty  *     function is computed and stored in tbs_hash[] (if not supported,
1870957b409SSimon J. Gerraty  *     then a failure is reported). The hash OID and length are stored
1880957b409SSimon J. Gerraty  *     in cert_sig_hash_oid and cert_sig_hash_len.
1890957b409SSimon J. Gerraty  *
1900957b409SSimon J. Gerraty  *     -- Signature value: the signature value is copied into the
1910957b409SSimon J. Gerraty  *     cert_sig[] array.
1920957b409SSimon J. Gerraty  *
1930957b409SSimon J. Gerraty  *     -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is
1940957b409SSimon J. Gerraty  *     looked up in the trust store (CA trust anchors only); for all
1950957b409SSimon J. Gerraty  *     that match, the signature (cert_sig[]) is verified against the
1960957b409SSimon J. Gerraty  *     anchor public key (hashed TBS is in tbs_hash[]). If one of these
1970957b409SSimon J. Gerraty  *     signatures is valid, then validation ends with a success.
1980957b409SSimon J. Gerraty  *
1990957b409SSimon J. Gerraty  *  -- If the chain end is reached without obtaining a validation success,
2000957b409SSimon J. Gerraty  *  then validation is reported as failed.
2010957b409SSimon J. Gerraty  */
2020957b409SSimon J. Gerraty 
2030957b409SSimon J. Gerraty #if BR_USE_UNIX_TIME
2040957b409SSimon J. Gerraty #include <time.h>
2050957b409SSimon J. Gerraty #endif
2060957b409SSimon J. Gerraty 
2070957b409SSimon J. Gerraty #if BR_USE_WIN32_TIME
2080957b409SSimon J. Gerraty #include <windows.h>
2090957b409SSimon J. Gerraty #endif
2100957b409SSimon J. Gerraty 
2110957b409SSimon J. Gerraty /*
2120957b409SSimon J. Gerraty  * The T0 compiler will produce these prototypes declarations in the
2130957b409SSimon J. Gerraty  * header.
2140957b409SSimon J. Gerraty  *
2150957b409SSimon J. Gerraty void br_x509_minimal_init_main(void *ctx);
2160957b409SSimon J. Gerraty void br_x509_minimal_run(void *ctx);
2170957b409SSimon J. Gerraty  */
2180957b409SSimon J. Gerraty 
2190957b409SSimon J. Gerraty /* see bearssl_x509.h */
2200957b409SSimon J. Gerraty 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)2210957b409SSimon J. Gerraty br_x509_minimal_init(br_x509_minimal_context *ctx,
2220957b409SSimon J. Gerraty 	const br_hash_class *dn_hash_impl,
2230957b409SSimon J. Gerraty 	const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num)
2240957b409SSimon J. Gerraty {
2250957b409SSimon J. Gerraty 	memset(ctx, 0, sizeof *ctx);
2260957b409SSimon J. Gerraty 	ctx->vtable = &br_x509_minimal_vtable;
2270957b409SSimon J. Gerraty 	ctx->dn_hash_impl = dn_hash_impl;
2280957b409SSimon J. Gerraty 	ctx->trust_anchors = trust_anchors;
2290957b409SSimon J. Gerraty 	ctx->trust_anchors_num = trust_anchors_num;
2300957b409SSimon J. Gerraty }
2310957b409SSimon J. Gerraty 
2320957b409SSimon J. Gerraty static void
xm_start_chain(const br_x509_class ** ctx,const char * server_name)2330957b409SSimon J. Gerraty xm_start_chain(const br_x509_class **ctx, const char *server_name)
2340957b409SSimon J. Gerraty {
2350957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
2360957b409SSimon J. Gerraty 	size_t u;
2370957b409SSimon J. Gerraty 
2380957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
2390957b409SSimon J. Gerraty 	for (u = 0; u < cc->num_name_elts; u ++) {
2400957b409SSimon J. Gerraty 		cc->name_elts[u].status = 0;
2410957b409SSimon J. Gerraty 		cc->name_elts[u].buf[0] = 0;
2420957b409SSimon J. Gerraty 	}
2430957b409SSimon J. Gerraty 	memset(&cc->pkey, 0, sizeof cc->pkey);
2440957b409SSimon J. Gerraty 	cc->num_certs = 0;
2450957b409SSimon J. Gerraty 	cc->err = 0;
2460957b409SSimon J. Gerraty 	cc->cpu.dp = cc->dp_stack;
2470957b409SSimon J. Gerraty 	cc->cpu.rp = cc->rp_stack;
2480957b409SSimon J. Gerraty 	br_x509_minimal_init_main(&cc->cpu);
2490957b409SSimon J. Gerraty 	if (server_name == NULL || *server_name == 0) {
2500957b409SSimon J. Gerraty 		cc->server_name = NULL;
2510957b409SSimon J. Gerraty 	} else {
2520957b409SSimon J. Gerraty 		cc->server_name = server_name;
2530957b409SSimon J. Gerraty 	}
2540957b409SSimon J. Gerraty }
2550957b409SSimon J. Gerraty 
2560957b409SSimon J. Gerraty static void
xm_start_cert(const br_x509_class ** ctx,uint32_t length)2570957b409SSimon J. Gerraty xm_start_cert(const br_x509_class **ctx, uint32_t length)
2580957b409SSimon J. Gerraty {
2590957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
2600957b409SSimon J. Gerraty 
2610957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
2620957b409SSimon J. Gerraty 	if (cc->err != 0) {
2630957b409SSimon J. Gerraty 		return;
2640957b409SSimon J. Gerraty 	}
2650957b409SSimon J. Gerraty 	if (length == 0) {
2660957b409SSimon J. Gerraty 		cc->err = BR_ERR_X509_TRUNCATED;
2670957b409SSimon J. Gerraty 		return;
2680957b409SSimon J. Gerraty 	}
2690957b409SSimon J. Gerraty 	cc->cert_length = length;
2700957b409SSimon J. Gerraty }
2710957b409SSimon J. Gerraty 
2720957b409SSimon J. Gerraty static void
xm_append(const br_x509_class ** ctx,const unsigned char * buf,size_t len)2730957b409SSimon J. Gerraty xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len)
2740957b409SSimon J. Gerraty {
2750957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
2760957b409SSimon J. Gerraty 
2770957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
2780957b409SSimon J. Gerraty 	if (cc->err != 0) {
2790957b409SSimon J. Gerraty 		return;
2800957b409SSimon J. Gerraty 	}
2810957b409SSimon J. Gerraty 	cc->hbuf = buf;
2820957b409SSimon J. Gerraty 	cc->hlen = len;
2830957b409SSimon J. Gerraty 	br_x509_minimal_run(&cc->cpu);
2840957b409SSimon J. Gerraty }
2850957b409SSimon J. Gerraty 
2860957b409SSimon J. Gerraty static void
xm_end_cert(const br_x509_class ** ctx)2870957b409SSimon J. Gerraty xm_end_cert(const br_x509_class **ctx)
2880957b409SSimon J. Gerraty {
2890957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
2900957b409SSimon J. Gerraty 
2910957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
2920957b409SSimon J. Gerraty 	if (cc->err == 0 && cc->cert_length != 0) {
2930957b409SSimon J. Gerraty 		cc->err = BR_ERR_X509_TRUNCATED;
2940957b409SSimon J. Gerraty 	}
2950957b409SSimon J. Gerraty 	cc->num_certs ++;
2960957b409SSimon J. Gerraty }
2970957b409SSimon J. Gerraty 
2980957b409SSimon J. Gerraty static unsigned
xm_end_chain(const br_x509_class ** ctx)2990957b409SSimon J. Gerraty xm_end_chain(const br_x509_class **ctx)
3000957b409SSimon J. Gerraty {
3010957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
3020957b409SSimon J. Gerraty 
3030957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
3040957b409SSimon J. Gerraty 	if (cc->err == 0) {
3050957b409SSimon J. Gerraty 		if (cc->num_certs == 0) {
3060957b409SSimon J. Gerraty 			cc->err = BR_ERR_X509_EMPTY_CHAIN;
3070957b409SSimon J. Gerraty 		} else {
3080957b409SSimon J. Gerraty 			cc->err = BR_ERR_X509_NOT_TRUSTED;
3090957b409SSimon J. Gerraty 		}
3100957b409SSimon J. Gerraty 	} else if (cc->err == BR_ERR_X509_OK) {
3110957b409SSimon J. Gerraty 		return 0;
3120957b409SSimon J. Gerraty 	}
3130957b409SSimon J. Gerraty 	return (unsigned)cc->err;
3140957b409SSimon J. Gerraty }
3150957b409SSimon J. Gerraty 
3160957b409SSimon J. Gerraty static const br_x509_pkey *
xm_get_pkey(const br_x509_class * const * ctx,unsigned * usages)3170957b409SSimon J. Gerraty xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages)
3180957b409SSimon J. Gerraty {
3190957b409SSimon J. Gerraty 	br_x509_minimal_context *cc;
3200957b409SSimon J. Gerraty 
3210957b409SSimon J. Gerraty 	cc = (br_x509_minimal_context *)(void *)ctx;
3220957b409SSimon J. Gerraty 	if (cc->err == BR_ERR_X509_OK
3230957b409SSimon J. Gerraty 		|| cc->err == BR_ERR_X509_NOT_TRUSTED)
3240957b409SSimon J. Gerraty 	{
3250957b409SSimon J. Gerraty 		if (usages != NULL) {
3260957b409SSimon J. Gerraty 			*usages = cc->key_usages;
3270957b409SSimon J. Gerraty 		}
3280957b409SSimon J. Gerraty 		return &((br_x509_minimal_context *)(void *)ctx)->pkey;
3290957b409SSimon J. Gerraty 	} else {
3300957b409SSimon J. Gerraty 		return NULL;
3310957b409SSimon J. Gerraty 	}
3320957b409SSimon J. Gerraty }
3330957b409SSimon J. Gerraty 
3340957b409SSimon J. Gerraty /* see bearssl_x509.h */
3350957b409SSimon J. Gerraty const br_x509_class br_x509_minimal_vtable = {
3360957b409SSimon J. Gerraty 	sizeof(br_x509_minimal_context),
3370957b409SSimon J. Gerraty 	xm_start_chain,
3380957b409SSimon J. Gerraty 	xm_start_cert,
3390957b409SSimon J. Gerraty 	xm_append,
3400957b409SSimon J. Gerraty 	xm_end_cert,
3410957b409SSimon J. Gerraty 	xm_end_chain,
3420957b409SSimon J. Gerraty 	xm_get_pkey
3430957b409SSimon J. Gerraty };
3440957b409SSimon J. Gerraty 
3450957b409SSimon J. Gerraty #define CTX   ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu)))
3460957b409SSimon J. Gerraty #define CONTEXT_NAME   br_x509_minimal_context
3470957b409SSimon J. Gerraty 
3480957b409SSimon J. Gerraty #define DNHASH_LEN   ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK)
3490957b409SSimon J. Gerraty 
3500957b409SSimon J. Gerraty /*
3510957b409SSimon J. Gerraty  * Hash a DN (from a trust anchor) into the provided buffer. This uses the
3520957b409SSimon J. Gerraty  * DN hash implementation and context structure from the X.509 engine
3530957b409SSimon J. Gerraty  * context.
3540957b409SSimon J. Gerraty  */
3550957b409SSimon J. Gerraty static void
hash_dn(br_x509_minimal_context * ctx,const void * dn,size_t len,unsigned char * out)3560957b409SSimon J. Gerraty hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len,
3570957b409SSimon J. Gerraty 	unsigned char *out)
3580957b409SSimon J. Gerraty {
3590957b409SSimon J. Gerraty 	ctx->dn_hash_impl->init(&ctx->dn_hash.vtable);
3600957b409SSimon J. Gerraty 	ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len);
3610957b409SSimon J. Gerraty 	ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out);
3620957b409SSimon J. Gerraty }
3630957b409SSimon J. Gerraty 
3640957b409SSimon J. Gerraty /*
3650957b409SSimon J. Gerraty  * Compare two big integers for equality. The integers use unsigned big-endian
3660957b409SSimon J. Gerraty  * encoding; extra leading bytes (of value 0) are allowed.
3670957b409SSimon J. Gerraty  */
3680957b409SSimon J. Gerraty static int
eqbigint(const unsigned char * b1,size_t len1,const unsigned char * b2,size_t len2)3690957b409SSimon J. Gerraty eqbigint(const unsigned char *b1, size_t len1,
3700957b409SSimon J. Gerraty 	const unsigned char *b2, size_t len2)
3710957b409SSimon J. Gerraty {
3720957b409SSimon J. Gerraty 	while (len1 > 0 && *b1 == 0) {
3730957b409SSimon J. Gerraty 		b1 ++;
3740957b409SSimon J. Gerraty 		len1 --;
3750957b409SSimon J. Gerraty 	}
3760957b409SSimon J. Gerraty 	while (len2 > 0 && *b2 == 0) {
3770957b409SSimon J. Gerraty 		b2 ++;
3780957b409SSimon J. Gerraty 		len2 --;
3790957b409SSimon J. Gerraty 	}
3800957b409SSimon J. Gerraty 	if (len1 != len2) {
3810957b409SSimon J. Gerraty 		return 0;
3820957b409SSimon J. Gerraty 	}
3830957b409SSimon J. Gerraty 	return memcmp(b1, b2, len1) == 0;
3840957b409SSimon J. Gerraty }
3850957b409SSimon J. Gerraty 
3860957b409SSimon J. Gerraty /*
3870957b409SSimon J. Gerraty  * Compare two strings for equality, in a case-insensitive way. This
3880957b409SSimon J. Gerraty  * function handles casing only for ASCII letters.
3890957b409SSimon J. Gerraty  */
3900957b409SSimon J. Gerraty static int
eqnocase(const void * s1,const void * s2,size_t len)3910957b409SSimon J. Gerraty eqnocase(const void *s1, const void *s2, size_t len)
3920957b409SSimon J. Gerraty {
3930957b409SSimon J. Gerraty 	const unsigned char *buf1, *buf2;
3940957b409SSimon J. Gerraty 
3950957b409SSimon J. Gerraty 	buf1 = s1;
3960957b409SSimon J. Gerraty 	buf2 = s2;
3970957b409SSimon J. Gerraty 	while (len -- > 0) {
3980957b409SSimon J. Gerraty 		int x1, x2;
3990957b409SSimon J. Gerraty 
4000957b409SSimon J. Gerraty 		x1 = *buf1 ++;
4010957b409SSimon J. Gerraty 		x2 = *buf2 ++;
4020957b409SSimon J. Gerraty 		if (x1 >= 'A' && x1 <= 'Z') {
4030957b409SSimon J. Gerraty 			x1 += 'a' - 'A';
4040957b409SSimon J. Gerraty 		}
4050957b409SSimon J. Gerraty 		if (x2 >= 'A' && x2 <= 'Z') {
4060957b409SSimon J. Gerraty 			x2 += 'a' - 'A';
4070957b409SSimon J. Gerraty 		}
4080957b409SSimon J. Gerraty 		if (x1 != x2) {
4090957b409SSimon J. Gerraty 			return 0;
4100957b409SSimon J. Gerraty 		}
4110957b409SSimon J. Gerraty 	}
4120957b409SSimon J. Gerraty 	return 1;
4130957b409SSimon J. Gerraty }
4140957b409SSimon J. Gerraty 
4150957b409SSimon J. Gerraty static int verify_signature(br_x509_minimal_context *ctx,
4160957b409SSimon J. Gerraty 	const br_x509_pkey *pk);
4170957b409SSimon J. Gerraty 
4180957b409SSimon J. Gerraty 
4190957b409SSimon J. Gerraty 
4200957b409SSimon J. Gerraty static const unsigned char t0_datablock[] = {
4210957b409SSimon J. Gerraty 	0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09,
4220957b409SSimon J. Gerraty 	0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86,
4230957b409SSimon J. Gerraty 	0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86,
4240957b409SSimon J. Gerraty 	0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
4250957b409SSimon J. Gerraty 	0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01,
4260957b409SSimon J. Gerraty 	0x0D, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x09, 0x60, 0x86, 0x48, 0x01,
4270957b409SSimon J. Gerraty 	0x65, 0x03, 0x04, 0x02, 0x04, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
4280957b409SSimon J. Gerraty 	0x04, 0x02, 0x01, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
4290957b409SSimon J. Gerraty 	0x02, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x07,
4300957b409SSimon J. Gerraty 	0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE,
4310957b409SSimon J. Gerraty 	0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B,
4320957b409SSimon J. Gerraty 	0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01,
4330957b409SSimon J. Gerraty 	0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, 0x2A, 0x86,
4340957b409SSimon J. Gerraty 	0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
4350957b409SSimon J. Gerraty 	0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04,
4360957b409SSimon J. Gerraty 	0x03, 0x55, 0x04, 0x03, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E,
4370957b409SSimon J. Gerraty 	0x0F, 0x1F, 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F,
4380957b409SSimon J. Gerraty 	0x26, 0x1E, 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E,
4390957b409SSimon J. Gerraty 	0x0F, 0x3F, 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F,
4400957b409SSimon J. Gerraty 	0x26, 0x3E, 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13, 0x03, 0x55, 0x1D, 0x0F,
4410957b409SSimon J. Gerraty 	0x03, 0x55, 0x1D, 0x11, 0x03, 0x55, 0x1D, 0x20, 0x08, 0x2B, 0x06, 0x01,
4420957b409SSimon J. Gerraty 	0x05, 0x05, 0x07, 0x02, 0x01, 0x03, 0x55, 0x1D, 0x23, 0x03, 0x55, 0x1D,
4430957b409SSimon J. Gerraty 	0x0E, 0x03, 0x55, 0x1D, 0x12, 0x03, 0x55, 0x1D, 0x09, 0x03, 0x55, 0x1D,
4440957b409SSimon J. Gerraty 	0x1F, 0x03, 0x55, 0x1D, 0x2E, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
4450957b409SSimon J. Gerraty 	0x01, 0x01, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0B
4460957b409SSimon J. Gerraty };
4470957b409SSimon J. Gerraty 
4480957b409SSimon J. Gerraty static const unsigned char t0_codeblock[] = {
4490957b409SSimon J. Gerraty 	0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01,
4500957b409SSimon J. Gerraty 	0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A,
451*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0x01,
4520957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01,
4530957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_DN), 0x00, 0x00, 0x01,
4540957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_SERVER_NAME), 0x00, 0x00, 0x01,
4550957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01,
4560957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01,
4570957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01,
4580957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_CRITICAL_EXTENSION), 0x00, 0x00, 0x01,
4590957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_DN_MISMATCH), 0x00, 0x00, 0x01,
4600957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_EXPIRED), 0x00, 0x00, 0x01,
4610957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01,
4620957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_FORBIDDEN_KEY_USAGE), 0x00, 0x00, 0x01,
4630957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01,
4640957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01,
4650957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01,
4660957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_NOT_CA), 0x00, 0x00, 0x01,
4670957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01,
4680957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01,
4690957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01,
4700957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01,
4710957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01,
4720957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01,
4730957b409SSimon J. Gerraty 	T0_INT1(BR_ERR_X509_WEAK_PUBLIC_KEY), 0x00, 0x00, 0x01,
4740957b409SSimon J. Gerraty 	T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA),
4750957b409SSimon J. Gerraty 	0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_length)), 0x00,
4760957b409SSimon J. Gerraty 	0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig)), 0x00, 0x00,
4770957b409SSimon J. Gerraty 	0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_len)), 0x00, 0x00,
4780957b409SSimon J. Gerraty 	0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_oid)), 0x00, 0x00,
4790957b409SSimon J. Gerraty 	0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_len)), 0x00, 0x00, 0x01,
4800957b409SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, cert_signer_key_type)), 0x00, 0x00,
4810957b409SSimon J. Gerraty 	0x01, T0_INT2(offsetof(CONTEXT_NAME, current_dn_hash)), 0x00, 0x00,
4820957b409SSimon J. Gerraty 	0x01, T0_INT2(offsetof(CONTEXT_NAME, key_usages)), 0x00, 0x00, 0x01,
4830957b409SSimon J. Gerraty 	T0_INT2(offsetof(br_x509_minimal_context, pkey_data)), 0x01,
4840957b409SSimon J. Gerraty 	T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01,
4850957b409SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, min_rsa_size)), 0x00, 0x00, 0x01,
4860957b409SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, next_dn_hash)), 0x00, 0x00, 0x01,
4870957b409SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, num_certs)), 0x00, 0x00, 0x01,
4880957b409SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01,
489*cc9e6590SSimon J. Gerraty 	T0_INT2(offsetof(CONTEXT_NAME, saved_dn_hash)), 0x00, 0x00, 0x01, 0x80,
490*cc9e6590SSimon J. Gerraty 	0x73, 0x00, 0x00, 0x01, 0x80, 0x7C, 0x00, 0x00, 0x01, 0x81, 0x02, 0x00,
491*cc9e6590SSimon J. Gerraty 	0x00, 0x8F, 0x05, 0x05, 0x33, 0x41, 0x01, 0x00, 0x00, 0x33, 0x01, 0x0A,
492*cc9e6590SSimon J. Gerraty 	0x0E, 0x09, 0x01, 0x9A, 0xFF, 0xB8, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x82,
493*cc9e6590SSimon J. Gerraty 	0x19, 0x00, 0x00, 0x01, 0x82, 0x01, 0x00, 0x00, 0x01, 0x81, 0x68, 0x00,
494*cc9e6590SSimon J. Gerraty 	0x02, 0x03, 0x00, 0x03, 0x01, 0x26, 0x02, 0x01, 0x13, 0x3A, 0x02, 0x00,
495*cc9e6590SSimon J. Gerraty 	0x0F, 0x15, 0x00, 0x00, 0x01, 0x81, 0x74, 0x00, 0x00, 0x05, 0x02, 0x51,
496*cc9e6590SSimon J. Gerraty 	0x29, 0x00, 0x00, 0x06, 0x02, 0x52, 0x29, 0x00, 0x00, 0x01, 0x10, 0x74,
497*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x11, 0x05, 0x02, 0x55, 0x29, 0x71, 0x00, 0x00, 0x11, 0x05,
498*cc9e6590SSimon J. Gerraty 	0x02, 0x55, 0x29, 0x72, 0x00, 0x00, 0x06, 0x02, 0x4B, 0x29, 0x00, 0x00,
499*cc9e6590SSimon J. Gerraty 	0x01, 0x82, 0x11, 0x00, 0x00, 0x26, 0x21, 0x01, 0x08, 0x0E, 0x3A, 0x3F,
500*cc9e6590SSimon J. Gerraty 	0x21, 0x09, 0x00, 0x0B, 0x03, 0x00, 0x5A, 0x2B, 0xAC, 0x38, 0xAC, 0xB0,
501*cc9e6590SSimon J. Gerraty 	0x26, 0x01, 0x20, 0x11, 0x06, 0x11, 0x25, 0x71, 0xAA, 0xB0, 0x01, 0x02,
502*cc9e6590SSimon J. Gerraty 	0x75, 0xAD, 0x01, 0x02, 0x12, 0x06, 0x02, 0x56, 0x29, 0x76, 0xB0, 0x01,
503*cc9e6590SSimon J. Gerraty 	0x02, 0x75, 0xAB, 0xAC, 0xBF, 0x99, 0x64, 0x60, 0x22, 0x16, 0xAC, 0xA4,
504*cc9e6590SSimon J. Gerraty 	0x03, 0x01, 0x03, 0x02, 0xA4, 0x02, 0x02, 0x02, 0x01, 0x19, 0x06, 0x02,
505*cc9e6590SSimon J. Gerraty 	0x4A, 0x29, 0x76, 0x02, 0x00, 0x06, 0x05, 0x9A, 0x03, 0x03, 0x04, 0x09,
506*cc9e6590SSimon J. Gerraty 	0x99, 0x60, 0x67, 0x22, 0x28, 0x05, 0x02, 0x49, 0x29, 0x67, 0x64, 0x22,
507*cc9e6590SSimon J. Gerraty 	0x16, 0xAC, 0xAC, 0x9B, 0x05, 0x02, 0x56, 0x29, 0xB9, 0x27, 0x06, 0x27,
508*cc9e6590SSimon J. Gerraty 	0xBF, 0xA1, 0xAC, 0x62, 0xA7, 0x03, 0x05, 0x62, 0x3A, 0x02, 0x05, 0x09,
509*cc9e6590SSimon J. Gerraty 	0x3A, 0x02, 0x05, 0x0A, 0xA7, 0x03, 0x06, 0x76, 0x63, 0x2A, 0x01, 0x81,
510*cc9e6590SSimon J. Gerraty 	0x00, 0x09, 0x02, 0x05, 0x12, 0x06, 0x02, 0x57, 0x29, 0x76, 0x59, 0x03,
511*cc9e6590SSimon J. Gerraty 	0x04, 0x04, 0x3A, 0x85, 0x27, 0x06, 0x34, 0x9B, 0x05, 0x02, 0x56, 0x29,
512*cc9e6590SSimon J. Gerraty 	0x68, 0x27, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x69, 0x27, 0x06, 0x04,
513*cc9e6590SSimon J. Gerraty 	0x01, 0x18, 0x04, 0x0A, 0x6A, 0x27, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02,
514*cc9e6590SSimon J. Gerraty 	0x56, 0x29, 0x03, 0x07, 0x76, 0xA1, 0x26, 0x03, 0x08, 0x26, 0x62, 0x33,
515*cc9e6590SSimon J. Gerraty 	0x0D, 0x06, 0x02, 0x4F, 0x29, 0xA2, 0x58, 0x03, 0x04, 0x04, 0x02, 0x56,
516*cc9e6590SSimon J. Gerraty 	0x29, 0x76, 0x02, 0x00, 0x06, 0x21, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06,
517*cc9e6590SSimon J. Gerraty 	0x08, 0x25, 0x02, 0x05, 0x02, 0x06, 0x1E, 0x04, 0x10, 0x58, 0x30, 0x11,
518*cc9e6590SSimon J. Gerraty 	0x06, 0x08, 0x25, 0x02, 0x07, 0x02, 0x08, 0x1D, 0x04, 0x03, 0x56, 0x29,
519*cc9e6590SSimon J. Gerraty 	0x25, 0x04, 0x24, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06, 0x08, 0x25, 0x02,
520*cc9e6590SSimon J. Gerraty 	0x05, 0x02, 0x06, 0x24, 0x04, 0x10, 0x58, 0x30, 0x11, 0x06, 0x08, 0x25,
521*cc9e6590SSimon J. Gerraty 	0x02, 0x07, 0x02, 0x08, 0x23, 0x04, 0x03, 0x56, 0x29, 0x25, 0x26, 0x06,
522*cc9e6590SSimon J. Gerraty 	0x01, 0x29, 0x25, 0x01, 0x00, 0x03, 0x09, 0xB1, 0x01, 0x21, 0x8C, 0x01,
523*cc9e6590SSimon J. Gerraty 	0x22, 0x8C, 0x26, 0x01, 0x23, 0x11, 0x06, 0x81, 0x26, 0x25, 0x71, 0xAA,
524*cc9e6590SSimon J. Gerraty 	0xAC, 0x26, 0x06, 0x81, 0x1A, 0x01, 0x00, 0x03, 0x0A, 0xAC, 0x9B, 0x25,
525*cc9e6590SSimon J. Gerraty 	0xB0, 0x26, 0x01, 0x01, 0x11, 0x06, 0x04, 0xA3, 0x03, 0x0A, 0xB0, 0x01,
526*cc9e6590SSimon J. Gerraty 	0x04, 0x75, 0xAA, 0x6E, 0x27, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC0,
527*cc9e6590SSimon J. Gerraty 	0x04, 0x05, 0x96, 0x01, 0x7F, 0x03, 0x09, 0x04, 0x80, 0x6C, 0x8E, 0x27,
528*cc9e6590SSimon J. Gerraty 	0x06, 0x06, 0x02, 0x00, 0x98, 0x04, 0x80, 0x62, 0xC2, 0x27, 0x06, 0x11,
529*cc9e6590SSimon J. Gerraty 	0x02, 0x00, 0x06, 0x09, 0x01, 0x00, 0x03, 0x03, 0x95, 0x03, 0x03, 0x04,
530*cc9e6590SSimon J. Gerraty 	0x01, 0xC0, 0x04, 0x80, 0x4D, 0x70, 0x27, 0x06, 0x0A, 0x02, 0x0A, 0x06,
531*cc9e6590SSimon J. Gerraty 	0x03, 0x97, 0x04, 0x01, 0xC0, 0x04, 0x3F, 0x6D, 0x27, 0x06, 0x03, 0xC0,
532*cc9e6590SSimon J. Gerraty 	0x04, 0x38, 0xC5, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x31, 0x8D, 0x27, 0x06,
533*cc9e6590SSimon J. Gerraty 	0x03, 0xC0, 0x04, 0x2A, 0xC3, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x23, 0x77,
534*cc9e6590SSimon J. Gerraty 	0x27, 0x06, 0x03, 0xC0, 0x04, 0x1C, 0x82, 0x27, 0x06, 0x03, 0xC0, 0x04,
535*cc9e6590SSimon J. Gerraty 	0x15, 0x6C, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x0E, 0xC4, 0x27, 0x06, 0x03,
536*cc9e6590SSimon J. Gerraty 	0xC0, 0x04, 0x07, 0x02, 0x0A, 0x06, 0x02, 0x48, 0x29, 0xC0, 0x76, 0x76,
537*cc9e6590SSimon J. Gerraty 	0x04, 0xFE, 0x62, 0x76, 0x76, 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02,
538*cc9e6590SSimon J. Gerraty 	0x55, 0x29, 0x25, 0x76, 0x39, 0x02, 0x00, 0x06, 0x08, 0x02, 0x03, 0x3B,
539*cc9e6590SSimon J. Gerraty 	0x2F, 0x05, 0x02, 0x44, 0x29, 0x02, 0x00, 0x06, 0x01, 0x17, 0x02, 0x00,
540*cc9e6590SSimon J. Gerraty 	0x02, 0x09, 0x2F, 0x05, 0x02, 0x50, 0x29, 0xB0, 0x73, 0xAA, 0x9B, 0x06,
541*cc9e6590SSimon J. Gerraty 	0x80, 0x77, 0xBA, 0x27, 0x06, 0x07, 0x01, 0x02, 0x59, 0x87, 0x04, 0x80,
542*cc9e6590SSimon J. Gerraty 	0x5E, 0xBB, 0x27, 0x06, 0x07, 0x01, 0x03, 0x59, 0x88, 0x04, 0x80, 0x53,
543*cc9e6590SSimon J. Gerraty 	0xBC, 0x27, 0x06, 0x07, 0x01, 0x04, 0x59, 0x89, 0x04, 0x80, 0x48, 0xBD,
544*cc9e6590SSimon J. Gerraty 	0x27, 0x06, 0x06, 0x01, 0x05, 0x59, 0x8A, 0x04, 0x3E, 0xBE, 0x27, 0x06,
545*cc9e6590SSimon J. Gerraty 	0x06, 0x01, 0x06, 0x59, 0x8B, 0x04, 0x34, 0x7C, 0x27, 0x06, 0x06, 0x01,
546*cc9e6590SSimon J. Gerraty 	0x02, 0x58, 0x87, 0x04, 0x2A, 0x7D, 0x27, 0x06, 0x06, 0x01, 0x03, 0x58,
547*cc9e6590SSimon J. Gerraty 	0x88, 0x04, 0x20, 0x7E, 0x27, 0x06, 0x06, 0x01, 0x04, 0x58, 0x89, 0x04,
548*cc9e6590SSimon J. Gerraty 	0x16, 0x7F, 0x27, 0x06, 0x06, 0x01, 0x05, 0x58, 0x8A, 0x04, 0x0C, 0x80,
549*cc9e6590SSimon J. Gerraty 	0x27, 0x06, 0x06, 0x01, 0x06, 0x58, 0x8B, 0x04, 0x02, 0x56, 0x29, 0x5D,
550*cc9e6590SSimon J. Gerraty 	0x34, 0x5F, 0x36, 0x1C, 0x26, 0x05, 0x02, 0x56, 0x29, 0x5C, 0x36, 0x04,
551*cc9e6590SSimon J. Gerraty 	0x02, 0x56, 0x29, 0xBF, 0xA1, 0x26, 0x01, T0_INT2(BR_X509_BUFSIZE_SIG),
552*cc9e6590SSimon J. Gerraty 	0x12, 0x06, 0x02, 0x4F, 0x29, 0x26, 0x5E, 0x34, 0x5B, 0xA2, 0x76, 0x76,
553*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x5A, 0x35, 0x18, 0x00, 0x00, 0x01, 0x30, 0x0A, 0x26, 0x01,
554*cc9e6590SSimon J. Gerraty 	0x00, 0x01, 0x09, 0x6F, 0x05, 0x02, 0x47, 0x29, 0x00, 0x00, 0x30, 0x30,
555*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x01, 0x81, 0x08, 0x00, 0x00, 0x01, 0x81, 0x10, 0x00, 0x00,
556*cc9e6590SSimon J. Gerraty 	0x01, 0x81, 0x19, 0x00, 0x00, 0x01, 0x81, 0x22, 0x00, 0x00, 0x01, 0x81,
557*cc9e6590SSimon J. Gerraty 	0x2B, 0x00, 0x01, 0x7B, 0x01, 0x01, 0x11, 0x3A, 0x01, 0x83, 0xFD, 0x7F,
558*cc9e6590SSimon J. Gerraty 	0x11, 0x15, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x3A, 0x26, 0x03, 0x00, 0x26,
559*cc9e6590SSimon J. Gerraty 	0xC6, 0x05, 0x04, 0x41, 0x01, 0x00, 0x00, 0x26, 0x01, 0x81, 0x00, 0x0D,
560*cc9e6590SSimon J. Gerraty 	0x06, 0x04, 0x93, 0x04, 0x80, 0x49, 0x26, 0x01, 0x90, 0x00, 0x0D, 0x06,
561*cc9e6590SSimon J. Gerraty 	0x0F, 0x01, 0x06, 0x14, 0x01, 0x81, 0x40, 0x2F, 0x93, 0x02, 0x00, 0x01,
562*cc9e6590SSimon J. Gerraty 	0x00, 0x94, 0x04, 0x33, 0x26, 0x01, 0x83, 0xFF, 0x7F, 0x0D, 0x06, 0x14,
563*cc9e6590SSimon J. Gerraty 	0x01, 0x0C, 0x14, 0x01, 0x81, 0x60, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x06,
564*cc9e6590SSimon J. Gerraty 	0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x04, 0x17, 0x01, 0x12, 0x14, 0x01,
565*cc9e6590SSimon J. Gerraty 	0x81, 0x70, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x0C, 0x94, 0x02, 0x00, 0x01,
566*cc9e6590SSimon J. Gerraty 	0x06, 0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x00, 0x00, 0x01, 0x82, 0x15,
567*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xB7, 0x7F, 0x6F,
568*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x01, 0x81, 0x34, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00,
569*cc9e6590SSimon J. Gerraty 	0x01, 0x81, 0x78, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, 0x01, 0x80, 0x43,
570*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x01, 0x80, 0x4D, 0x00, 0x00, 0x01, 0x80, 0x57, 0x00, 0x00,
571*cc9e6590SSimon J. Gerraty 	0x01, 0x80, 0x61, 0x00, 0x00, 0x30, 0x11, 0x06, 0x04, 0x41, 0xAA, 0xBF,
572*cc9e6590SSimon J. Gerraty 	0xB1, 0x00, 0x00, 0x01, 0x82, 0x09, 0x00, 0x00, 0x01, 0x81, 0x6C, 0x00,
573*cc9e6590SSimon J. Gerraty 	0x00, 0x26, 0x01, 0x83, 0xB8, 0x00, 0x01, 0x83, 0xBF, 0x7F, 0x6F, 0x00,
574*cc9e6590SSimon J. Gerraty 	0x00, 0x01, 0x30, 0x61, 0x36, 0x01, 0x7F, 0x79, 0x1A, 0x01, 0x00, 0x79,
575*cc9e6590SSimon J. Gerraty 	0x1A, 0x04, 0x7A, 0x00, 0x01, 0x81, 0x38, 0x00, 0x01, 0x7B, 0x0D, 0x06,
576*cc9e6590SSimon J. Gerraty 	0x02, 0x4E, 0x29, 0x26, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x30,
577*cc9e6590SSimon J. Gerraty 	0x26, 0x3E, 0x3A, 0x01, 0x82, 0x00, 0x13, 0x2F, 0x06, 0x04, 0x41, 0x01,
578*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x30, 0x66, 0x09, 0x36, 0x3F, 0x00, 0x00, 0x14, 0x01, 0x3F,
579*cc9e6590SSimon J. Gerraty 	0x15, 0x01, 0x81, 0x00, 0x2F, 0x93, 0x00, 0x02, 0x01, 0x00, 0x03, 0x00,
580*cc9e6590SSimon J. Gerraty 	0xAC, 0x26, 0x06, 0x80, 0x59, 0xB0, 0x01, 0x20, 0x30, 0x11, 0x06, 0x17,
581*cc9e6590SSimon J. Gerraty 	0x25, 0x71, 0xAA, 0x9B, 0x25, 0x01, 0x7F, 0x2E, 0x03, 0x01, 0xB0, 0x01,
582*cc9e6590SSimon J. Gerraty 	0x20, 0x74, 0xAA, 0xAF, 0x02, 0x01, 0x20, 0x76, 0x76, 0x04, 0x38, 0x01,
583*cc9e6590SSimon J. Gerraty 	0x21, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x01, 0x1F, 0x04,
584*cc9e6590SSimon J. Gerraty 	0x2A, 0x01, 0x22, 0x30, 0x11, 0x06, 0x11, 0x25, 0x72, 0xB3, 0x26, 0x06,
585*cc9e6590SSimon J. Gerraty 	0x06, 0x2C, 0x02, 0x00, 0x2F, 0x03, 0x00, 0x01, 0x02, 0x1F, 0x04, 0x13,
586*cc9e6590SSimon J. Gerraty 	0x01, 0x26, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x06, 0x1F,
587*cc9e6590SSimon J. Gerraty 	0x04, 0x05, 0x41, 0xAB, 0x01, 0x00, 0x25, 0x04, 0xFF, 0x23, 0x76, 0x02,
588*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x00, 0xAC, 0xB1, 0x26, 0x01, 0x01, 0x11, 0x06, 0x08, 0xA3,
589*cc9e6590SSimon J. Gerraty 	0x05, 0x02, 0x50, 0x29, 0xB1, 0x04, 0x02, 0x50, 0x29, 0x26, 0x01, 0x02,
590*cc9e6590SSimon J. Gerraty 	0x11, 0x06, 0x0C, 0x25, 0x72, 0xAD, 0x65, 0x2B, 0x40, 0x0D, 0x06, 0x02,
591*cc9e6590SSimon J. Gerraty 	0x50, 0x29, 0xB1, 0x01, 0x7F, 0x10, 0x06, 0x02, 0x55, 0x29, 0x25, 0x76,
592*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0xAC, 0x26, 0x06, 0x1A, 0xAC, 0x9B, 0x25, 0x26, 0x06, 0x11,
593*cc9e6590SSimon J. Gerraty 	0xAC, 0x26, 0x06, 0x0C, 0xAC, 0x9B, 0x25, 0x86, 0x27, 0x05, 0x02, 0x48,
594*cc9e6590SSimon J. Gerraty 	0x29, 0xBF, 0x04, 0x71, 0x76, 0x76, 0x04, 0x63, 0x76, 0x00, 0x02, 0x03,
595*cc9e6590SSimon J. Gerraty 	0x00, 0xB0, 0x01, 0x03, 0x75, 0xAA, 0xB7, 0x03, 0x01, 0x02, 0x01, 0x01,
596*cc9e6590SSimon J. Gerraty 	0x07, 0x12, 0x06, 0x02, 0x55, 0x29, 0x26, 0x01, 0x00, 0x30, 0x11, 0x06,
597*cc9e6590SSimon J. Gerraty 	0x05, 0x25, 0x4C, 0x29, 0x04, 0x15, 0x01, 0x01, 0x30, 0x11, 0x06, 0x0A,
598*cc9e6590SSimon J. Gerraty 	0x25, 0xB7, 0x02, 0x01, 0x14, 0x02, 0x01, 0x0E, 0x04, 0x05, 0x25, 0xB7,
599*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x25, 0x02, 0x00, 0x06, 0x19, 0x01, 0x00, 0x30, 0x01, 0x38,
600*cc9e6590SSimon J. Gerraty 	0x15, 0x06, 0x03, 0x01, 0x10, 0x2F, 0x3A, 0x01, 0x81, 0x40, 0x15, 0x06,
601*cc9e6590SSimon J. Gerraty 	0x03, 0x01, 0x20, 0x2F, 0x61, 0x36, 0x04, 0x07, 0x01, 0x04, 0x15, 0x05,
602*cc9e6590SSimon J. Gerraty 	0x02, 0x4C, 0x29, 0xBF, 0x00, 0x00, 0x37, 0xAC, 0xBF, 0x1B, 0x00, 0x03,
603*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x03, 0x00, 0x37, 0xAC, 0x26, 0x06, 0x30, 0xB0, 0x01, 0x11,
604*cc9e6590SSimon J. Gerraty 	0x74, 0xAA, 0x26, 0x05, 0x02, 0x43, 0x29, 0x26, 0x06, 0x20, 0xAC, 0x9B,
605*cc9e6590SSimon J. Gerraty 	0x25, 0x84, 0x27, 0x03, 0x01, 0x01, 0x00, 0x2E, 0x03, 0x02, 0xAF, 0x26,
606*cc9e6590SSimon J. Gerraty 	0x02, 0x01, 0x15, 0x06, 0x07, 0x2C, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00,
607*cc9e6590SSimon J. Gerraty 	0x02, 0x02, 0x20, 0x76, 0x04, 0x5D, 0x76, 0x04, 0x4D, 0x76, 0x1B, 0x02,
608*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x00, 0xB0, 0x01, 0x06, 0x75, 0xAE, 0x00, 0x00, 0xB5, 0x83,
609*cc9e6590SSimon J. Gerraty 	0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x00, 0x00,
610*cc9e6590SSimon J. Gerraty 	0xB5, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25, 0x01, 0x00, 0x04, 0x00,
611*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0xB6, 0x83, 0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01,
612*cc9e6590SSimon J. Gerraty 	0x00, 0x01, 0x00, 0x00, 0xB6, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25,
613*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D,
614*cc9e6590SSimon J. Gerraty 	0x06, 0x04, 0x00, 0x04, 0x80, 0x55, 0x26, 0x01, 0x81, 0x40, 0x0D, 0x06,
615*cc9e6590SSimon J. Gerraty 	0x07, 0x25, 0x01, 0x00, 0x00, 0x04, 0x80, 0x47, 0x26, 0x01, 0x81, 0x60,
616*cc9e6590SSimon J. Gerraty 	0x0D, 0x06, 0x0E, 0x01, 0x1F, 0x15, 0x01, 0x01, 0xA0, 0x01, 0x81, 0x00,
617*cc9e6590SSimon J. Gerraty 	0x01, 0x8F, 0x7F, 0x04, 0x32, 0x26, 0x01, 0x81, 0x70, 0x0D, 0x06, 0x0F,
618*cc9e6590SSimon J. Gerraty 	0x01, 0x0F, 0x15, 0x01, 0x02, 0xA0, 0x01, 0x90, 0x00, 0x01, 0x83, 0xFF,
619*cc9e6590SSimon J. Gerraty 	0x7F, 0x04, 0x1C, 0x26, 0x01, 0x81, 0x78, 0x0D, 0x06, 0x11, 0x01, 0x07,
620*cc9e6590SSimon J. Gerraty 	0x15, 0x01, 0x03, 0xA0, 0x01, 0x84, 0x80, 0x00, 0x01, 0x80, 0xC3, 0xFF,
621*cc9e6590SSimon J. Gerraty 	0x7F, 0x04, 0x04, 0x25, 0x01, 0x00, 0x00, 0x6F, 0x05, 0x03, 0x25, 0x01,
622*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x00, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x7F,
623*cc9e6590SSimon J. Gerraty 	0x00, 0xB7, 0x33, 0x26, 0x3C, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x01, 0x06,
624*cc9e6590SSimon J. Gerraty 	0x0E, 0x3A, 0x26, 0x01, 0x06, 0x14, 0x01, 0x02, 0x10, 0x06, 0x04, 0x41,
625*cc9e6590SSimon J. Gerraty 	0x01, 0x7F, 0x00, 0x01, 0x3F, 0x15, 0x09, 0x00, 0x00, 0x26, 0x06, 0x06,
626*cc9e6590SSimon J. Gerraty 	0x0B, 0x9F, 0x33, 0x40, 0x04, 0x77, 0x25, 0x26, 0x00, 0x00, 0xB0, 0x01,
627*cc9e6590SSimon J. Gerraty 	0x03, 0x75, 0xAA, 0xB7, 0x06, 0x02, 0x54, 0x29, 0x00, 0x00, 0x3A, 0x26,
628*cc9e6590SSimon J. Gerraty 	0x06, 0x07, 0x31, 0x26, 0x06, 0x01, 0x1A, 0x04, 0x76, 0x41, 0x00, 0x00,
629*cc9e6590SSimon J. Gerraty 	0x01, 0x01, 0x75, 0xA9, 0x01, 0x01, 0x10, 0x06, 0x02, 0x42, 0x29, 0xB7,
630*cc9e6590SSimon J. Gerraty 	0x3D, 0x00, 0x04, 0xB0, 0x26, 0x01, 0x17, 0x01, 0x18, 0x6F, 0x05, 0x02,
631*cc9e6590SSimon J. Gerraty 	0x47, 0x29, 0x01, 0x18, 0x11, 0x03, 0x00, 0x72, 0xAA, 0xA5, 0x02, 0x00,
632*cc9e6590SSimon J. Gerraty 	0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0xA5, 0x02, 0x01, 0x09,
633*cc9e6590SSimon J. Gerraty 	0x04, 0x0E, 0x26, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, 0x64, 0x09,
634*cc9e6590SSimon J. Gerraty 	0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, 0x6D, 0x08,
635*cc9e6590SSimon J. Gerraty 	0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, 0x01, 0x01,
636*cc9e6590SSimon J. Gerraty 	0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, 0x01, 0x83,
637*cc9e6590SSimon J. Gerraty 	0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, 0x01, 0x01,
638*cc9e6590SSimon J. Gerraty 	0x0C, 0xA6, 0x40, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, 0x07, 0x3E,
639*cc9e6590SSimon J. Gerraty 	0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x3D, 0x02, 0x01, 0x01, 0x83, 0x10,
640*cc9e6590SSimon J. Gerraty 	0x07, 0x3E, 0x2F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x91, 0x09, 0x78,
641*cc9e6590SSimon J. Gerraty 	0x26, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, 0x1F, 0x15,
642*cc9e6590SSimon J. Gerraty 	0x01, 0x01, 0x3A, 0xA6, 0x02, 0x03, 0x09, 0x40, 0x03, 0x03, 0x01, 0x00,
643*cc9e6590SSimon J. Gerraty 	0x01, 0x17, 0xA6, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, 0x00, 0x01,
644*cc9e6590SSimon J. Gerraty 	0x3B, 0xA6, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, 0x01, 0x00,
645*cc9e6590SSimon J. Gerraty 	0x01, 0x3C, 0xA6, 0x02, 0x02, 0x09, 0x03, 0x02, 0xB7, 0x26, 0x01, 0x2E,
646*cc9e6590SSimon J. Gerraty 	0x11, 0x06, 0x0D, 0x25, 0xB7, 0x26, 0x01, 0x30, 0x01, 0x39, 0x6F, 0x06,
647*cc9e6590SSimon J. Gerraty 	0x03, 0x25, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, 0x47, 0x29,
648*cc9e6590SSimon J. Gerraty 	0x76, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0xB7, 0x7A, 0x01, 0x0A, 0x08,
649*cc9e6590SSimon J. Gerraty 	0x03, 0x00, 0xB7, 0x7A, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, 0x00, 0x03,
650*cc9e6590SSimon J. Gerraty 	0x01, 0xA5, 0x26, 0x02, 0x01, 0x02, 0x00, 0x6F, 0x05, 0x02, 0x47, 0x29,
651*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x33, 0xB0, 0x01, 0x02, 0x75, 0x0B, 0xA8, 0x00, 0x03, 0x26,
652*cc9e6590SSimon J. Gerraty 	0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0xAA, 0xB7, 0x26, 0x01, 0x81, 0x00,
653*cc9e6590SSimon J. Gerraty 	0x13, 0x06, 0x02, 0x53, 0x29, 0x26, 0x01, 0x00, 0x11, 0x06, 0x0B, 0x25,
654*cc9e6590SSimon J. Gerraty 	0x26, 0x05, 0x04, 0x25, 0x01, 0x00, 0x00, 0xB7, 0x04, 0x6F, 0x02, 0x01,
655*cc9e6590SSimon J. Gerraty 	0x26, 0x05, 0x02, 0x4F, 0x29, 0x40, 0x03, 0x01, 0x02, 0x02, 0x36, 0x02,
656*cc9e6590SSimon J. Gerraty 	0x02, 0x3F, 0x03, 0x02, 0x26, 0x06, 0x03, 0xB7, 0x04, 0x68, 0x25, 0x02,
657*cc9e6590SSimon J. Gerraty 	0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D,
658*cc9e6590SSimon J. Gerraty 	0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x26, 0x05, 0x02, 0x4D, 0x29,
659*cc9e6590SSimon J. Gerraty 	0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, 0x19, 0x02,
660*cc9e6590SSimon J. Gerraty 	0x00, 0x40, 0x03, 0x00, 0x26, 0x01, 0x83, 0xFF, 0xFF, 0x7F, 0x12, 0x06,
661*cc9e6590SSimon J. Gerraty 	0x02, 0x4E, 0x29, 0x01, 0x08, 0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x04, 0x60,
662*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0xA9, 0x92, 0x00, 0x00, 0xAA, 0xBF, 0x00, 0x00, 0xB0, 0x73,
663*cc9e6590SSimon J. Gerraty 	0xAA, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x02, 0x53, 0x29, 0xB7, 0x26, 0x01,
664*cc9e6590SSimon J. Gerraty 	0x81, 0x00, 0x13, 0x06, 0x02, 0x53, 0x29, 0x03, 0x00, 0x26, 0x06, 0x16,
665*cc9e6590SSimon J. Gerraty 	0xB7, 0x02, 0x00, 0x26, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, 0x06, 0x02,
666*cc9e6590SSimon J. Gerraty 	0x53, 0x29, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, 0x25, 0x02,
667*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x00, 0xAA, 0x26, 0x01, 0x81, 0x7F, 0x12, 0x06, 0x08, 0xBF,
668*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x66, 0x36, 0x01, 0x00, 0x00, 0x26, 0x66, 0x36, 0x66, 0x3F,
669*cc9e6590SSimon J. Gerraty 	0xA2, 0x01, 0x7F, 0x00, 0x00, 0xB0, 0x01, 0x0C, 0x30, 0x11, 0x06, 0x05,
670*cc9e6590SSimon J. Gerraty 	0x25, 0x72, 0xB3, 0x04, 0x3E, 0x01, 0x12, 0x30, 0x11, 0x06, 0x05, 0x25,
671*cc9e6590SSimon J. Gerraty 	0x72, 0xB4, 0x04, 0x33, 0x01, 0x13, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72,
672*cc9e6590SSimon J. Gerraty 	0xB4, 0x04, 0x28, 0x01, 0x14, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4,
673*cc9e6590SSimon J. Gerraty 	0x04, 0x1D, 0x01, 0x16, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4, 0x04,
674*cc9e6590SSimon J. Gerraty 	0x12, 0x01, 0x1E, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB2, 0x04, 0x07,
675*cc9e6590SSimon J. Gerraty 	0x41, 0xAB, 0x01, 0x00, 0x01, 0x00, 0x25, 0x00, 0x01, 0xB7, 0x03, 0x00,
676*cc9e6590SSimon J. Gerraty 	0x02, 0x00, 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x2D, 0x02, 0x00, 0x01,
677*cc9e6590SSimon J. Gerraty 	0x06, 0x14, 0x26, 0x01, 0x01, 0x15, 0x06, 0x02, 0x45, 0x29, 0x01, 0x04,
678*cc9e6590SSimon J. Gerraty 	0x0E, 0x02, 0x00, 0x01, 0x1F, 0x15, 0x26, 0x01, 0x1F, 0x11, 0x06, 0x02,
679*cc9e6590SSimon J. Gerraty 	0x46, 0x29, 0x09, 0x00, 0x00, 0x26, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F,
680*cc9e6590SSimon J. Gerraty 	0x00, 0xB0, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x05, 0x66, 0x36, 0x01, 0x7F,
681*cc9e6590SSimon J. Gerraty 	0x00, 0x01, 0x01, 0x03, 0x00, 0x9C, 0x26, 0x01, 0x83, 0xFF, 0x7E, 0x11,
682*cc9e6590SSimon J. Gerraty 	0x06, 0x16, 0x25, 0x26, 0x06, 0x10, 0x9D, 0x26, 0x05, 0x05, 0x25, 0xBF,
683*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x04, 0x1B,
684*cc9e6590SSimon J. Gerraty 	0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03,
685*cc9e6590SSimon J. Gerraty 	0x00, 0x26, 0x06, 0x0B, 0x9C, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00,
686*cc9e6590SSimon J. Gerraty 	0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00, 0x40, 0x66,
687*cc9e6590SSimon J. Gerraty 	0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00, 0x26, 0x06,
688*cc9e6590SSimon J. Gerraty 	0x10, 0x9E, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00,
689*cc9e6590SSimon J. Gerraty 	0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00,
690*cc9e6590SSimon J. Gerraty 	0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00,
691*cc9e6590SSimon J. Gerraty 	0x26, 0x06, 0x10, 0xB7, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00,
692*cc9e6590SSimon J. Gerraty 	0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05,
693*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x00, 0xB7, 0x01, 0x08,
694*cc9e6590SSimon J. Gerraty 	0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x00, 0x00, 0xB7, 0x3A, 0xB7, 0x01, 0x08,
695*cc9e6590SSimon J. Gerraty 	0x0E, 0x33, 0x09, 0x00, 0x00, 0x26, 0x05, 0x02, 0x4E, 0x29, 0x40, 0xB8,
696*cc9e6590SSimon J. Gerraty 	0x00, 0x00, 0x32, 0x26, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x25, 0x1A,
697*cc9e6590SSimon J. Gerraty 	0x04, 0x74, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01,
698*cc9e6590SSimon J. Gerraty 	0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01,
699*cc9e6590SSimon J. Gerraty 	0x33, 0x00, 0x00, 0xC0, 0x25, 0x00, 0x00, 0x26, 0x06, 0x07, 0xC1, 0x26,
700*cc9e6590SSimon J. Gerraty 	0x06, 0x01, 0x1A, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B,
701*cc9e6590SSimon J. Gerraty 	0x41, 0x00, 0x00, 0x01, 0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00,
702*cc9e6590SSimon J. Gerraty 	0x00, 0x01, 0x82, 0x22, 0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x26,
703*cc9e6590SSimon J. Gerraty 	0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F, 0x6F, 0x06, 0x04, 0x25,
704*cc9e6590SSimon J. Gerraty 	0x01, 0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xBF, 0x7F,
705*cc9e6590SSimon J. Gerraty 	0x6F, 0x06, 0x04, 0x25, 0x01, 0x00, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x15,
706*cc9e6590SSimon J. Gerraty 	0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00
7070957b409SSimon J. Gerraty };
7080957b409SSimon J. Gerraty 
7090957b409SSimon J. Gerraty static const uint16_t t0_caddr[] = {
7100957b409SSimon J. Gerraty 	0,
7110957b409SSimon J. Gerraty 	5,
7120957b409SSimon J. Gerraty 	10,
7130957b409SSimon J. Gerraty 	15,
7140957b409SSimon J. Gerraty 	20,
7150957b409SSimon J. Gerraty 	25,
7160957b409SSimon J. Gerraty 	29,
7170957b409SSimon J. Gerraty 	33,
7180957b409SSimon J. Gerraty 	37,
7190957b409SSimon J. Gerraty 	41,
7200957b409SSimon J. Gerraty 	45,
7210957b409SSimon J. Gerraty 	49,
7220957b409SSimon J. Gerraty 	53,
7230957b409SSimon J. Gerraty 	57,
7240957b409SSimon J. Gerraty 	61,
7250957b409SSimon J. Gerraty 	65,
7260957b409SSimon J. Gerraty 	69,
7270957b409SSimon J. Gerraty 	73,
7280957b409SSimon J. Gerraty 	77,
7290957b409SSimon J. Gerraty 	81,
7300957b409SSimon J. Gerraty 	85,
7310957b409SSimon J. Gerraty 	89,
7320957b409SSimon J. Gerraty 	93,
7330957b409SSimon J. Gerraty 	97,
7340957b409SSimon J. Gerraty 	101,
7350957b409SSimon J. Gerraty 	105,
7360957b409SSimon J. Gerraty 	109,
7370957b409SSimon J. Gerraty 	113,
7380957b409SSimon J. Gerraty 	117,
7390957b409SSimon J. Gerraty 	121,
7400957b409SSimon J. Gerraty 	125,
7410957b409SSimon J. Gerraty 	130,
7420957b409SSimon J. Gerraty 	135,
7430957b409SSimon J. Gerraty 	140,
7440957b409SSimon J. Gerraty 	145,
7450957b409SSimon J. Gerraty 	150,
7460957b409SSimon J. Gerraty 	155,
7470957b409SSimon J. Gerraty 	160,
7480957b409SSimon J. Gerraty 	165,
7490957b409SSimon J. Gerraty 	173,
7500957b409SSimon J. Gerraty 	178,
7510957b409SSimon J. Gerraty 	183,
7520957b409SSimon J. Gerraty 	188,
7530957b409SSimon J. Gerraty 	193,
7540957b409SSimon J. Gerraty 	198,
755*cc9e6590SSimon J. Gerraty 	203,
756*cc9e6590SSimon J. Gerraty 	208,
757*cc9e6590SSimon J. Gerraty 	213,
758*cc9e6590SSimon J. Gerraty 	234,
759*cc9e6590SSimon J. Gerraty 	239,
760*cc9e6590SSimon J. Gerraty 	244,
761*cc9e6590SSimon J. Gerraty 	249,
762*cc9e6590SSimon J. Gerraty 	264,
763*cc9e6590SSimon J. Gerraty 	269,
764*cc9e6590SSimon J. Gerraty 	275,
765*cc9e6590SSimon J. Gerraty 	281,
766*cc9e6590SSimon J. Gerraty 	286,
767*cc9e6590SSimon J. Gerraty 	294,
7680957b409SSimon J. Gerraty 	302,
7690957b409SSimon J. Gerraty 	308,
770*cc9e6590SSimon J. Gerraty 	313,
771*cc9e6590SSimon J. Gerraty 	324,
772*cc9e6590SSimon J. Gerraty 	960,
773*cc9e6590SSimon J. Gerraty 	975,
774*cc9e6590SSimon J. Gerraty 	979,
775*cc9e6590SSimon J. Gerraty 	984,
776*cc9e6590SSimon J. Gerraty 	989,
777*cc9e6590SSimon J. Gerraty 	994,
778*cc9e6590SSimon J. Gerraty 	999,
779*cc9e6590SSimon J. Gerraty 	1004,
780*cc9e6590SSimon J. Gerraty 	1118,
781*cc9e6590SSimon J. Gerraty 	1123,
782*cc9e6590SSimon J. Gerraty 	1135,
783*cc9e6590SSimon J. Gerraty 	1140,
784*cc9e6590SSimon J. Gerraty 	1145,
7850957b409SSimon J. Gerraty 	1150,
786*cc9e6590SSimon J. Gerraty 	1154,
787*cc9e6590SSimon J. Gerraty 	1159,
788*cc9e6590SSimon J. Gerraty 	1164,
789*cc9e6590SSimon J. Gerraty 	1169,
790*cc9e6590SSimon J. Gerraty 	1174,
791*cc9e6590SSimon J. Gerraty 	1184,
792*cc9e6590SSimon J. Gerraty 	1189,
793*cc9e6590SSimon J. Gerraty 	1194,
7940957b409SSimon J. Gerraty 	1206,
7950957b409SSimon J. Gerraty 	1221,
7960957b409SSimon J. Gerraty 	1226,
797*cc9e6590SSimon J. Gerraty 	1240,
798*cc9e6590SSimon J. Gerraty 	1262,
799*cc9e6590SSimon J. Gerraty 	1273,
800*cc9e6590SSimon J. Gerraty 	1376,
801*cc9e6590SSimon J. Gerraty 	1423,
802*cc9e6590SSimon J. Gerraty 	1456,
803*cc9e6590SSimon J. Gerraty 	1547,
804*cc9e6590SSimon J. Gerraty 	1553,
805*cc9e6590SSimon J. Gerraty 	1616,
806*cc9e6590SSimon J. Gerraty 	1623,
807*cc9e6590SSimon J. Gerraty 	1651,
808*cc9e6590SSimon J. Gerraty 	1679,
809*cc9e6590SSimon J. Gerraty 	1784,
810*cc9e6590SSimon J. Gerraty 	1826,
811*cc9e6590SSimon J. Gerraty 	1839,
812*cc9e6590SSimon J. Gerraty 	1851,
813*cc9e6590SSimon J. Gerraty 	1865,
814*cc9e6590SSimon J. Gerraty 	1880,
815*cc9e6590SSimon J. Gerraty 	2100,
816*cc9e6590SSimon J. Gerraty 	2114,
817*cc9e6590SSimon J. Gerraty 	2131,
818*cc9e6590SSimon J. Gerraty 	2140,
819*cc9e6590SSimon J. Gerraty 	2207,
820*cc9e6590SSimon J. Gerraty 	2263,
821*cc9e6590SSimon J. Gerraty 	2267,
822*cc9e6590SSimon J. Gerraty 	2271,
823*cc9e6590SSimon J. Gerraty 	2276,
824*cc9e6590SSimon J. Gerraty 	2324,
825*cc9e6590SSimon J. Gerraty 	2350,
826*cc9e6590SSimon J. Gerraty 	2426,
827*cc9e6590SSimon J. Gerraty 	2470,
828*cc9e6590SSimon J. Gerraty 	2481,
829*cc9e6590SSimon J. Gerraty 	2566,
830*cc9e6590SSimon J. Gerraty 	2604,
831*cc9e6590SSimon J. Gerraty 	2642,
832*cc9e6590SSimon J. Gerraty 	2652,
833*cc9e6590SSimon J. Gerraty 	2662,
834*cc9e6590SSimon J. Gerraty 	2671,
8350957b409SSimon J. Gerraty 	2684,
836*cc9e6590SSimon J. Gerraty 	2688,
837*cc9e6590SSimon J. Gerraty 	2692,
838*cc9e6590SSimon J. Gerraty 	2696,
839*cc9e6590SSimon J. Gerraty 	2700,
840*cc9e6590SSimon J. Gerraty 	2704,
841*cc9e6590SSimon J. Gerraty 	2708,
842*cc9e6590SSimon J. Gerraty 	2712,
8430957b409SSimon J. Gerraty 	2724,
8440957b409SSimon J. Gerraty 	2732,
845*cc9e6590SSimon J. Gerraty 	2737,
846*cc9e6590SSimon J. Gerraty 	2742,
847*cc9e6590SSimon J. Gerraty 	2747,
848*cc9e6590SSimon J. Gerraty 	2752
8490957b409SSimon J. Gerraty };
8500957b409SSimon J. Gerraty 
851*cc9e6590SSimon J. Gerraty #define T0_INTERPRETED   60
8520957b409SSimon J. Gerraty 
8530957b409SSimon J. Gerraty #define T0_ENTER(ip, rp, slot)   do { \
8540957b409SSimon J. Gerraty 		const unsigned char *t0_newip; \
8550957b409SSimon J. Gerraty 		uint32_t t0_lnum; \
8560957b409SSimon J. Gerraty 		t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \
8570957b409SSimon J. Gerraty 		t0_lnum = t0_parse7E_unsigned(&t0_newip); \
8580957b409SSimon J. Gerraty 		(rp) += t0_lnum; \
8590957b409SSimon J. Gerraty 		*((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \
8600957b409SSimon J. Gerraty 		(ip) = t0_newip; \
8610957b409SSimon J. Gerraty 	} while (0)
8620957b409SSimon J. Gerraty 
8630957b409SSimon J. Gerraty #define T0_DEFENTRY(name, slot) \
8640957b409SSimon J. Gerraty void \
8650957b409SSimon J. Gerraty name(void *ctx) \
8660957b409SSimon J. Gerraty { \
8670957b409SSimon J. Gerraty 	t0_context *t0ctx = ctx; \
8680957b409SSimon J. Gerraty 	t0ctx->ip = &t0_codeblock[0]; \
8690957b409SSimon J. Gerraty 	T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \
8700957b409SSimon J. Gerraty }
8710957b409SSimon J. Gerraty 
872*cc9e6590SSimon J. Gerraty T0_DEFENTRY(br_x509_minimal_init_main, 144)
8730957b409SSimon J. Gerraty 
8740957b409SSimon J. Gerraty #define T0_NEXT(t0ipp)   (*(*(t0ipp)) ++)
8750957b409SSimon J. Gerraty 
8760957b409SSimon J. Gerraty void
br_x509_minimal_run(void * t0ctx)8770957b409SSimon J. Gerraty br_x509_minimal_run(void *t0ctx)
8780957b409SSimon J. Gerraty {
8790957b409SSimon J. Gerraty 	uint32_t *dp, *rp;
8800957b409SSimon J. Gerraty 	const unsigned char *ip;
8810957b409SSimon J. Gerraty 
8820957b409SSimon J. Gerraty #define T0_LOCAL(x)    (*(rp - 2 - (x)))
8830957b409SSimon J. Gerraty #define T0_POP()       (*-- dp)
8840957b409SSimon J. Gerraty #define T0_POPi()      (*(int32_t *)(-- dp))
8850957b409SSimon J. Gerraty #define T0_PEEK(x)     (*(dp - 1 - (x)))
8860957b409SSimon J. Gerraty #define T0_PEEKi(x)    (*(int32_t *)(dp - 1 - (x)))
8870957b409SSimon J. Gerraty #define T0_PUSH(v)     do { *dp = (v); dp ++; } while (0)
8880957b409SSimon J. Gerraty #define T0_PUSHi(v)    do { *(int32_t *)dp = (v); dp ++; } while (0)
8890957b409SSimon J. Gerraty #define T0_RPOP()      (*-- rp)
8900957b409SSimon J. Gerraty #define T0_RPOPi()     (*(int32_t *)(-- rp))
8910957b409SSimon J. Gerraty #define T0_RPUSH(v)    do { *rp = (v); rp ++; } while (0)
8920957b409SSimon J. Gerraty #define T0_RPUSHi(v)   do { *(int32_t *)rp = (v); rp ++; } while (0)
8930957b409SSimon J. Gerraty #define T0_ROLL(x)     do { \
8940957b409SSimon J. Gerraty 	size_t t0len = (size_t)(x); \
8950957b409SSimon J. Gerraty 	uint32_t t0tmp = *(dp - 1 - t0len); \
8960957b409SSimon J. Gerraty 	memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \
8970957b409SSimon J. Gerraty 	*(dp - 1) = t0tmp; \
8980957b409SSimon J. Gerraty } while (0)
8990957b409SSimon J. Gerraty #define T0_SWAP()      do { \
9000957b409SSimon J. Gerraty 	uint32_t t0tmp = *(dp - 2); \
9010957b409SSimon J. Gerraty 	*(dp - 2) = *(dp - 1); \
9020957b409SSimon J. Gerraty 	*(dp - 1) = t0tmp; \
9030957b409SSimon J. Gerraty } while (0)
9040957b409SSimon J. Gerraty #define T0_ROT()       do { \
9050957b409SSimon J. Gerraty 	uint32_t t0tmp = *(dp - 3); \
9060957b409SSimon J. Gerraty 	*(dp - 3) = *(dp - 2); \
9070957b409SSimon J. Gerraty 	*(dp - 2) = *(dp - 1); \
9080957b409SSimon J. Gerraty 	*(dp - 1) = t0tmp; \
9090957b409SSimon J. Gerraty } while (0)
9100957b409SSimon J. Gerraty #define T0_NROT()       do { \
9110957b409SSimon J. Gerraty 	uint32_t t0tmp = *(dp - 1); \
9120957b409SSimon J. Gerraty 	*(dp - 1) = *(dp - 2); \
9130957b409SSimon J. Gerraty 	*(dp - 2) = *(dp - 3); \
9140957b409SSimon J. Gerraty 	*(dp - 3) = t0tmp; \
9150957b409SSimon J. Gerraty } while (0)
9160957b409SSimon J. Gerraty #define T0_PICK(x)      do { \
9170957b409SSimon J. Gerraty 	uint32_t t0depth = (x); \
9180957b409SSimon J. Gerraty 	T0_PUSH(T0_PEEK(t0depth)); \
9190957b409SSimon J. Gerraty } while (0)
9200957b409SSimon J. Gerraty #define T0_CO()         do { \
9210957b409SSimon J. Gerraty 	goto t0_exit; \
9220957b409SSimon J. Gerraty } while (0)
9230957b409SSimon J. Gerraty #define T0_RET()        goto t0_next
9240957b409SSimon J. Gerraty 
9250957b409SSimon J. Gerraty 	dp = ((t0_context *)t0ctx)->dp;
9260957b409SSimon J. Gerraty 	rp = ((t0_context *)t0ctx)->rp;
9270957b409SSimon J. Gerraty 	ip = ((t0_context *)t0ctx)->ip;
9280957b409SSimon J. Gerraty 	goto t0_next;
9290957b409SSimon J. Gerraty 	for (;;) {
9300957b409SSimon J. Gerraty 		uint32_t t0x;
9310957b409SSimon J. Gerraty 
9320957b409SSimon J. Gerraty 	t0_next:
9330957b409SSimon J. Gerraty 		t0x = T0_NEXT(&ip);
9340957b409SSimon J. Gerraty 		if (t0x < T0_INTERPRETED) {
9350957b409SSimon J. Gerraty 			switch (t0x) {
9360957b409SSimon J. Gerraty 				int32_t t0off;
9370957b409SSimon J. Gerraty 
9380957b409SSimon J. Gerraty 			case 0: /* ret */
9390957b409SSimon J. Gerraty 				t0x = T0_RPOP();
9400957b409SSimon J. Gerraty 				rp -= (t0x >> 16);
9410957b409SSimon J. Gerraty 				t0x &= 0xFFFF;
9420957b409SSimon J. Gerraty 				if (t0x == 0) {
9430957b409SSimon J. Gerraty 					ip = NULL;
9440957b409SSimon J. Gerraty 					goto t0_exit;
9450957b409SSimon J. Gerraty 				}
9460957b409SSimon J. Gerraty 				ip = &t0_codeblock[t0x];
9470957b409SSimon J. Gerraty 				break;
9480957b409SSimon J. Gerraty 			case 1: /* literal constant */
9490957b409SSimon J. Gerraty 				T0_PUSHi(t0_parse7E_signed(&ip));
9500957b409SSimon J. Gerraty 				break;
9510957b409SSimon J. Gerraty 			case 2: /* read local */
9520957b409SSimon J. Gerraty 				T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip)));
9530957b409SSimon J. Gerraty 				break;
9540957b409SSimon J. Gerraty 			case 3: /* write local */
9550957b409SSimon J. Gerraty 				T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP();
9560957b409SSimon J. Gerraty 				break;
9570957b409SSimon J. Gerraty 			case 4: /* jump */
9580957b409SSimon J. Gerraty 				t0off = t0_parse7E_signed(&ip);
9590957b409SSimon J. Gerraty 				ip += t0off;
9600957b409SSimon J. Gerraty 				break;
9610957b409SSimon J. Gerraty 			case 5: /* jump if */
9620957b409SSimon J. Gerraty 				t0off = t0_parse7E_signed(&ip);
9630957b409SSimon J. Gerraty 				if (T0_POP()) {
9640957b409SSimon J. Gerraty 					ip += t0off;
9650957b409SSimon J. Gerraty 				}
9660957b409SSimon J. Gerraty 				break;
9670957b409SSimon J. Gerraty 			case 6: /* jump if not */
9680957b409SSimon J. Gerraty 				t0off = t0_parse7E_signed(&ip);
9690957b409SSimon J. Gerraty 				if (!T0_POP()) {
9700957b409SSimon J. Gerraty 					ip += t0off;
9710957b409SSimon J. Gerraty 				}
9720957b409SSimon J. Gerraty 				break;
9730957b409SSimon J. Gerraty 			case 7: {
9740957b409SSimon J. Gerraty 				/* %25 */
9750957b409SSimon J. Gerraty 
9760957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
9770957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
9780957b409SSimon J. Gerraty 	T0_PUSHi(a % b);
9790957b409SSimon J. Gerraty 
9800957b409SSimon J. Gerraty 				}
9810957b409SSimon J. Gerraty 				break;
9820957b409SSimon J. Gerraty 			case 8: {
9830957b409SSimon J. Gerraty 				/* * */
9840957b409SSimon J. Gerraty 
9850957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
9860957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
9870957b409SSimon J. Gerraty 	T0_PUSH(a * b);
9880957b409SSimon J. Gerraty 
9890957b409SSimon J. Gerraty 				}
9900957b409SSimon J. Gerraty 				break;
9910957b409SSimon J. Gerraty 			case 9: {
9920957b409SSimon J. Gerraty 				/* + */
9930957b409SSimon J. Gerraty 
9940957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
9950957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
9960957b409SSimon J. Gerraty 	T0_PUSH(a + b);
9970957b409SSimon J. Gerraty 
9980957b409SSimon J. Gerraty 				}
9990957b409SSimon J. Gerraty 				break;
10000957b409SSimon J. Gerraty 			case 10: {
10010957b409SSimon J. Gerraty 				/* - */
10020957b409SSimon J. Gerraty 
10030957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
10040957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
10050957b409SSimon J. Gerraty 	T0_PUSH(a - b);
10060957b409SSimon J. Gerraty 
10070957b409SSimon J. Gerraty 				}
10080957b409SSimon J. Gerraty 				break;
10090957b409SSimon J. Gerraty 			case 11: {
10100957b409SSimon J. Gerraty 				/* -rot */
10110957b409SSimon J. Gerraty  T0_NROT();
10120957b409SSimon J. Gerraty 				}
10130957b409SSimon J. Gerraty 				break;
10140957b409SSimon J. Gerraty 			case 12: {
10150957b409SSimon J. Gerraty 				/* / */
10160957b409SSimon J. Gerraty 
10170957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
10180957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
10190957b409SSimon J. Gerraty 	T0_PUSHi(a / b);
10200957b409SSimon J. Gerraty 
10210957b409SSimon J. Gerraty 				}
10220957b409SSimon J. Gerraty 				break;
10230957b409SSimon J. Gerraty 			case 13: {
10240957b409SSimon J. Gerraty 				/* < */
10250957b409SSimon J. Gerraty 
10260957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
10270957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
10280957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a < b));
10290957b409SSimon J. Gerraty 
10300957b409SSimon J. Gerraty 				}
10310957b409SSimon J. Gerraty 				break;
10320957b409SSimon J. Gerraty 			case 14: {
10330957b409SSimon J. Gerraty 				/* << */
10340957b409SSimon J. Gerraty 
10350957b409SSimon J. Gerraty 	int c = (int)T0_POPi();
10360957b409SSimon J. Gerraty 	uint32_t x = T0_POP();
10370957b409SSimon J. Gerraty 	T0_PUSH(x << c);
10380957b409SSimon J. Gerraty 
10390957b409SSimon J. Gerraty 				}
10400957b409SSimon J. Gerraty 				break;
10410957b409SSimon J. Gerraty 			case 15: {
10420957b409SSimon J. Gerraty 				/* <= */
10430957b409SSimon J. Gerraty 
10440957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
10450957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
10460957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a <= b));
10470957b409SSimon J. Gerraty 
10480957b409SSimon J. Gerraty 				}
10490957b409SSimon J. Gerraty 				break;
10500957b409SSimon J. Gerraty 			case 16: {
10510957b409SSimon J. Gerraty 				/* <> */
10520957b409SSimon J. Gerraty 
10530957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
10540957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
10550957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a != b));
10560957b409SSimon J. Gerraty 
10570957b409SSimon J. Gerraty 				}
10580957b409SSimon J. Gerraty 				break;
10590957b409SSimon J. Gerraty 			case 17: {
10600957b409SSimon J. Gerraty 				/* = */
10610957b409SSimon J. Gerraty 
10620957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
10630957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
10640957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a == b));
10650957b409SSimon J. Gerraty 
10660957b409SSimon J. Gerraty 				}
10670957b409SSimon J. Gerraty 				break;
10680957b409SSimon J. Gerraty 			case 18: {
10690957b409SSimon J. Gerraty 				/* > */
10700957b409SSimon J. Gerraty 
10710957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
10720957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
10730957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a > b));
10740957b409SSimon J. Gerraty 
10750957b409SSimon J. Gerraty 				}
10760957b409SSimon J. Gerraty 				break;
10770957b409SSimon J. Gerraty 			case 19: {
10780957b409SSimon J. Gerraty 				/* >= */
10790957b409SSimon J. Gerraty 
10800957b409SSimon J. Gerraty 	int32_t b = T0_POPi();
10810957b409SSimon J. Gerraty 	int32_t a = T0_POPi();
10820957b409SSimon J. Gerraty 	T0_PUSH(-(uint32_t)(a >= b));
10830957b409SSimon J. Gerraty 
10840957b409SSimon J. Gerraty 				}
10850957b409SSimon J. Gerraty 				break;
10860957b409SSimon J. Gerraty 			case 20: {
10870957b409SSimon J. Gerraty 				/* >> */
10880957b409SSimon J. Gerraty 
10890957b409SSimon J. Gerraty 	int c = (int)T0_POPi();
10900957b409SSimon J. Gerraty 	int32_t x = T0_POPi();
10910957b409SSimon J. Gerraty 	T0_PUSHi(x >> c);
10920957b409SSimon J. Gerraty 
10930957b409SSimon J. Gerraty 				}
10940957b409SSimon J. Gerraty 				break;
10950957b409SSimon J. Gerraty 			case 21: {
10960957b409SSimon J. Gerraty 				/* and */
10970957b409SSimon J. Gerraty 
10980957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
10990957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
11000957b409SSimon J. Gerraty 	T0_PUSH(a & b);
11010957b409SSimon J. Gerraty 
11020957b409SSimon J. Gerraty 				}
11030957b409SSimon J. Gerraty 				break;
11040957b409SSimon J. Gerraty 			case 22: {
11050957b409SSimon J. Gerraty 				/* blobcopy */
11060957b409SSimon J. Gerraty 
11070957b409SSimon J. Gerraty 	size_t len = T0_POP();
11080957b409SSimon J. Gerraty 	unsigned char *src = (unsigned char *)CTX + T0_POP();
11090957b409SSimon J. Gerraty 	unsigned char *dst = (unsigned char *)CTX + T0_POP();
11100957b409SSimon J. Gerraty 	memcpy(dst, src, len);
11110957b409SSimon J. Gerraty 
11120957b409SSimon J. Gerraty 				}
11130957b409SSimon J. Gerraty 				break;
11140957b409SSimon J. Gerraty 			case 23: {
11150957b409SSimon J. Gerraty 				/* check-direct-trust */
11160957b409SSimon J. Gerraty 
11170957b409SSimon J. Gerraty 	size_t u;
11180957b409SSimon J. Gerraty 
11190957b409SSimon J. Gerraty 	for (u = 0; u < CTX->trust_anchors_num; u ++) {
11200957b409SSimon J. Gerraty 		const br_x509_trust_anchor *ta;
11210957b409SSimon J. Gerraty 		unsigned char hashed_DN[64];
11220957b409SSimon J. Gerraty 		int kt;
11230957b409SSimon J. Gerraty 
11240957b409SSimon J. Gerraty 		ta = &CTX->trust_anchors[u];
11250957b409SSimon J. Gerraty 		if (ta->flags & BR_X509_TA_CA) {
11260957b409SSimon J. Gerraty 			continue;
11270957b409SSimon J. Gerraty 		}
11280957b409SSimon J. Gerraty 		hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
11290957b409SSimon J. Gerraty 		if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) {
11300957b409SSimon J. Gerraty 			continue;
11310957b409SSimon J. Gerraty 		}
11320957b409SSimon J. Gerraty 		kt = CTX->pkey.key_type;
11330957b409SSimon J. Gerraty 		if ((ta->pkey.key_type & 0x0F) != kt) {
11340957b409SSimon J. Gerraty 			continue;
11350957b409SSimon J. Gerraty 		}
11360957b409SSimon J. Gerraty 		switch (kt) {
11370957b409SSimon J. Gerraty 
11380957b409SSimon J. Gerraty 		case BR_KEYTYPE_RSA:
11390957b409SSimon J. Gerraty 			if (!eqbigint(CTX->pkey.key.rsa.n,
11400957b409SSimon J. Gerraty 				CTX->pkey.key.rsa.nlen,
11410957b409SSimon J. Gerraty 				ta->pkey.key.rsa.n,
11420957b409SSimon J. Gerraty 				ta->pkey.key.rsa.nlen)
11430957b409SSimon J. Gerraty 				|| !eqbigint(CTX->pkey.key.rsa.e,
11440957b409SSimon J. Gerraty 				CTX->pkey.key.rsa.elen,
11450957b409SSimon J. Gerraty 				ta->pkey.key.rsa.e,
11460957b409SSimon J. Gerraty 				ta->pkey.key.rsa.elen))
11470957b409SSimon J. Gerraty 			{
11480957b409SSimon J. Gerraty 				continue;
11490957b409SSimon J. Gerraty 			}
11500957b409SSimon J. Gerraty 			break;
11510957b409SSimon J. Gerraty 
11520957b409SSimon J. Gerraty 		case BR_KEYTYPE_EC:
11530957b409SSimon J. Gerraty 			if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve
11540957b409SSimon J. Gerraty 				|| CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen
11550957b409SSimon J. Gerraty 				|| memcmp(CTX->pkey.key.ec.q,
11560957b409SSimon J. Gerraty 					ta->pkey.key.ec.q,
11570957b409SSimon J. Gerraty 					ta->pkey.key.ec.qlen) != 0)
11580957b409SSimon J. Gerraty 			{
11590957b409SSimon J. Gerraty 				continue;
11600957b409SSimon J. Gerraty 			}
11610957b409SSimon J. Gerraty 			break;
11620957b409SSimon J. Gerraty 
11630957b409SSimon J. Gerraty 		default:
11640957b409SSimon J. Gerraty 			continue;
11650957b409SSimon J. Gerraty 		}
11660957b409SSimon J. Gerraty 
11670957b409SSimon J. Gerraty 		/*
11680957b409SSimon J. Gerraty 		 * Direct trust match!
11690957b409SSimon J. Gerraty 		 */
11700957b409SSimon J. Gerraty 		CTX->err = BR_ERR_X509_OK;
11710957b409SSimon J. Gerraty 		T0_CO();
11720957b409SSimon J. Gerraty 	}
11730957b409SSimon J. Gerraty 
11740957b409SSimon J. Gerraty 				}
11750957b409SSimon J. Gerraty 				break;
11760957b409SSimon J. Gerraty 			case 24: {
11770957b409SSimon J. Gerraty 				/* check-trust-anchor-CA */
11780957b409SSimon J. Gerraty 
11790957b409SSimon J. Gerraty 	size_t u;
11800957b409SSimon J. Gerraty 
11810957b409SSimon J. Gerraty 	for (u = 0; u < CTX->trust_anchors_num; u ++) {
11820957b409SSimon J. Gerraty 		const br_x509_trust_anchor *ta;
11830957b409SSimon J. Gerraty 		unsigned char hashed_DN[64];
11840957b409SSimon J. Gerraty 
11850957b409SSimon J. Gerraty 		ta = &CTX->trust_anchors[u];
11860957b409SSimon J. Gerraty 		if (!(ta->flags & BR_X509_TA_CA)) {
11870957b409SSimon J. Gerraty 			continue;
11880957b409SSimon J. Gerraty 		}
11890957b409SSimon J. Gerraty 		hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
11900957b409SSimon J. Gerraty 		if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) {
11910957b409SSimon J. Gerraty 			continue;
11920957b409SSimon J. Gerraty 		}
11930957b409SSimon J. Gerraty 		if (verify_signature(CTX, &ta->pkey) == 0) {
11940957b409SSimon J. Gerraty 			CTX->err = BR_ERR_X509_OK;
11950957b409SSimon J. Gerraty 			T0_CO();
11960957b409SSimon J. Gerraty 		}
11970957b409SSimon J. Gerraty 	}
11980957b409SSimon J. Gerraty 
11990957b409SSimon J. Gerraty 				}
12000957b409SSimon J. Gerraty 				break;
12010957b409SSimon J. Gerraty 			case 25: {
1202*cc9e6590SSimon J. Gerraty 				/* check-validity-range */
1203*cc9e6590SSimon J. Gerraty 
1204*cc9e6590SSimon J. Gerraty 	uint32_t nbs = T0_POP();
1205*cc9e6590SSimon J. Gerraty 	uint32_t nbd = T0_POP();
1206*cc9e6590SSimon J. Gerraty 	uint32_t nas = T0_POP();
1207*cc9e6590SSimon J. Gerraty 	uint32_t nad = T0_POP();
1208*cc9e6590SSimon J. Gerraty 	int r;
1209*cc9e6590SSimon J. Gerraty 	if (CTX->itime != 0) {
1210*cc9e6590SSimon J. Gerraty 		r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas);
1211*cc9e6590SSimon J. Gerraty 		if (r < -1 || r > 1) {
1212*cc9e6590SSimon J. Gerraty 			CTX->err = BR_ERR_X509_TIME_UNKNOWN;
1213*cc9e6590SSimon J. Gerraty 			T0_CO();
1214*cc9e6590SSimon J. Gerraty 		}
1215*cc9e6590SSimon J. Gerraty 	} else {
1216*cc9e6590SSimon J. Gerraty 		uint32_t vd = CTX->days;
1217*cc9e6590SSimon J. Gerraty 		uint32_t vs = CTX->seconds;
1218*cc9e6590SSimon J. Gerraty 		if (vd == 0 && vs == 0) {
1219*cc9e6590SSimon J. Gerraty #if BR_USE_UNIX_TIME
1220*cc9e6590SSimon J. Gerraty 			time_t x = time(NULL);
1221*cc9e6590SSimon J. Gerraty 
1222*cc9e6590SSimon J. Gerraty 			vd = (uint32_t)(x / 86400) + 719528;
1223*cc9e6590SSimon J. Gerraty 			vs = (uint32_t)(x % 86400);
1224*cc9e6590SSimon J. Gerraty #elif BR_USE_WIN32_TIME
1225*cc9e6590SSimon J. Gerraty 			FILETIME ft;
1226*cc9e6590SSimon J. Gerraty 			uint64_t x;
1227*cc9e6590SSimon J. Gerraty 
1228*cc9e6590SSimon J. Gerraty 			GetSystemTimeAsFileTime(&ft);
1229*cc9e6590SSimon J. Gerraty 			x = ((uint64_t)ft.dwHighDateTime << 32)
1230*cc9e6590SSimon J. Gerraty 				+ (uint64_t)ft.dwLowDateTime;
1231*cc9e6590SSimon J. Gerraty 			x = (x / 10000000);
1232*cc9e6590SSimon J. Gerraty 			vd = (uint32_t)(x / 86400) + 584754;
1233*cc9e6590SSimon J. Gerraty 			vs = (uint32_t)(x % 86400);
1234*cc9e6590SSimon J. Gerraty #else
1235*cc9e6590SSimon J. Gerraty 			CTX->err = BR_ERR_X509_TIME_UNKNOWN;
1236*cc9e6590SSimon J. Gerraty 			T0_CO();
1237*cc9e6590SSimon J. Gerraty #endif
1238*cc9e6590SSimon J. Gerraty 		}
1239*cc9e6590SSimon J. Gerraty 		if (vd < nbd || (vd == nbd && vs < nbs)) {
1240*cc9e6590SSimon J. Gerraty 			r = -1;
1241*cc9e6590SSimon J. Gerraty 		} else if (vd > nad || (vd == nad && vs > nas)) {
1242*cc9e6590SSimon J. Gerraty 			r = 1;
1243*cc9e6590SSimon J. Gerraty 		} else {
1244*cc9e6590SSimon J. Gerraty 			r = 0;
1245*cc9e6590SSimon J. Gerraty 		}
1246*cc9e6590SSimon J. Gerraty 	}
1247*cc9e6590SSimon J. Gerraty 	T0_PUSHi(r);
1248*cc9e6590SSimon J. Gerraty 
1249*cc9e6590SSimon J. Gerraty 				}
1250*cc9e6590SSimon J. Gerraty 				break;
1251*cc9e6590SSimon J. Gerraty 			case 26: {
12520957b409SSimon J. Gerraty 				/* co */
12530957b409SSimon J. Gerraty  T0_CO();
12540957b409SSimon J. Gerraty 				}
12550957b409SSimon J. Gerraty 				break;
1256*cc9e6590SSimon J. Gerraty 			case 27: {
12570957b409SSimon J. Gerraty 				/* compute-dn-hash */
12580957b409SSimon J. Gerraty 
12590957b409SSimon J. Gerraty 	CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash);
12600957b409SSimon J. Gerraty 	CTX->do_dn_hash = 0;
12610957b409SSimon J. Gerraty 
12620957b409SSimon J. Gerraty 				}
12630957b409SSimon J. Gerraty 				break;
1264*cc9e6590SSimon J. Gerraty 			case 28: {
12650957b409SSimon J. Gerraty 				/* compute-tbs-hash */
12660957b409SSimon J. Gerraty 
12670957b409SSimon J. Gerraty 	int id = T0_POPi();
12680957b409SSimon J. Gerraty 	size_t len;
12690957b409SSimon J. Gerraty 	len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash);
12700957b409SSimon J. Gerraty 	T0_PUSH(len);
12710957b409SSimon J. Gerraty 
12720957b409SSimon J. Gerraty 				}
12730957b409SSimon J. Gerraty 				break;
1274*cc9e6590SSimon J. Gerraty 			case 29: {
12750957b409SSimon J. Gerraty 				/* copy-ee-ec-pkey */
12760957b409SSimon J. Gerraty 
12770957b409SSimon J. Gerraty 	size_t qlen = T0_POP();
12780957b409SSimon J. Gerraty 	uint32_t curve = T0_POP();
12790957b409SSimon J. Gerraty 	memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen);
12800957b409SSimon J. Gerraty 	CTX->pkey.key_type = BR_KEYTYPE_EC;
12810957b409SSimon J. Gerraty 	CTX->pkey.key.ec.curve = curve;
12820957b409SSimon J. Gerraty 	CTX->pkey.key.ec.q = CTX->ee_pkey_data;
12830957b409SSimon J. Gerraty 	CTX->pkey.key.ec.qlen = qlen;
12840957b409SSimon J. Gerraty 
12850957b409SSimon J. Gerraty 				}
12860957b409SSimon J. Gerraty 				break;
1287*cc9e6590SSimon J. Gerraty 			case 30: {
12880957b409SSimon J. Gerraty 				/* copy-ee-rsa-pkey */
12890957b409SSimon J. Gerraty 
12900957b409SSimon J. Gerraty 	size_t elen = T0_POP();
12910957b409SSimon J. Gerraty 	size_t nlen = T0_POP();
12920957b409SSimon J. Gerraty 	memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen);
12930957b409SSimon J. Gerraty 	CTX->pkey.key_type = BR_KEYTYPE_RSA;
12940957b409SSimon J. Gerraty 	CTX->pkey.key.rsa.n = CTX->ee_pkey_data;
12950957b409SSimon J. Gerraty 	CTX->pkey.key.rsa.nlen = nlen;
12960957b409SSimon J. Gerraty 	CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen;
12970957b409SSimon J. Gerraty 	CTX->pkey.key.rsa.elen = elen;
12980957b409SSimon J. Gerraty 
12990957b409SSimon J. Gerraty 				}
13000957b409SSimon J. Gerraty 				break;
1301*cc9e6590SSimon J. Gerraty 			case 31: {
13020957b409SSimon J. Gerraty 				/* copy-name-SAN */
13030957b409SSimon J. Gerraty 
13040957b409SSimon J. Gerraty 	unsigned tag = T0_POP();
13050957b409SSimon J. Gerraty 	unsigned ok = T0_POP();
13060957b409SSimon J. Gerraty 	size_t u, len;
13070957b409SSimon J. Gerraty 
13080957b409SSimon J. Gerraty 	len = CTX->pad[0];
13090957b409SSimon J. Gerraty 	for (u = 0; u < CTX->num_name_elts; u ++) {
13100957b409SSimon J. Gerraty 		br_name_element *ne;
13110957b409SSimon J. Gerraty 
13120957b409SSimon J. Gerraty 		ne = &CTX->name_elts[u];
13130957b409SSimon J. Gerraty 		if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) {
13140957b409SSimon J. Gerraty 			if (ok && ne->len > len) {
13150957b409SSimon J. Gerraty 				memcpy(ne->buf, CTX->pad + 1, len);
13160957b409SSimon J. Gerraty 				ne->buf[len] = 0;
13170957b409SSimon J. Gerraty 				ne->status = 1;
13180957b409SSimon J. Gerraty 			} else {
13190957b409SSimon J. Gerraty 				ne->status = -1;
13200957b409SSimon J. Gerraty 			}
13210957b409SSimon J. Gerraty 			break;
13220957b409SSimon J. Gerraty 		}
13230957b409SSimon J. Gerraty 	}
13240957b409SSimon J. Gerraty 
13250957b409SSimon J. Gerraty 				}
13260957b409SSimon J. Gerraty 				break;
1327*cc9e6590SSimon J. Gerraty 			case 32: {
13280957b409SSimon J. Gerraty 				/* copy-name-element */
13290957b409SSimon J. Gerraty 
13300957b409SSimon J. Gerraty 	size_t len;
13310957b409SSimon J. Gerraty 	int32_t off = T0_POPi();
13320957b409SSimon J. Gerraty 	int ok = T0_POPi();
13330957b409SSimon J. Gerraty 
13340957b409SSimon J. Gerraty 	if (off >= 0) {
13350957b409SSimon J. Gerraty 		br_name_element *ne = &CTX->name_elts[off];
13360957b409SSimon J. Gerraty 
13370957b409SSimon J. Gerraty 		if (ok) {
13380957b409SSimon J. Gerraty 			len = CTX->pad[0];
13390957b409SSimon J. Gerraty 			if (len < ne->len) {
13400957b409SSimon J. Gerraty 				memcpy(ne->buf, CTX->pad + 1, len);
13410957b409SSimon J. Gerraty 				ne->buf[len] = 0;
13420957b409SSimon J. Gerraty 				ne->status = 1;
13430957b409SSimon J. Gerraty 			} else {
13440957b409SSimon J. Gerraty 				ne->status = -1;
13450957b409SSimon J. Gerraty 			}
13460957b409SSimon J. Gerraty 		} else {
13470957b409SSimon J. Gerraty 			ne->status = -1;
13480957b409SSimon J. Gerraty 		}
13490957b409SSimon J. Gerraty 	}
13500957b409SSimon J. Gerraty 
13510957b409SSimon J. Gerraty 				}
13520957b409SSimon J. Gerraty 				break;
1353*cc9e6590SSimon J. Gerraty 			case 33: {
13540957b409SSimon J. Gerraty 				/* data-get8 */
13550957b409SSimon J. Gerraty 
13560957b409SSimon J. Gerraty 	size_t addr = T0_POP();
13570957b409SSimon J. Gerraty 	T0_PUSH(t0_datablock[addr]);
13580957b409SSimon J. Gerraty 
13590957b409SSimon J. Gerraty 				}
13600957b409SSimon J. Gerraty 				break;
1361*cc9e6590SSimon J. Gerraty 			case 34: {
13620957b409SSimon J. Gerraty 				/* dn-hash-length */
13630957b409SSimon J. Gerraty 
13640957b409SSimon J. Gerraty 	T0_PUSH(DNHASH_LEN);
13650957b409SSimon J. Gerraty 
13660957b409SSimon J. Gerraty 				}
13670957b409SSimon J. Gerraty 				break;
1368*cc9e6590SSimon J. Gerraty 			case 35: {
13690957b409SSimon J. Gerraty 				/* do-ecdsa-vrfy */
13700957b409SSimon J. Gerraty 
13710957b409SSimon J. Gerraty 	size_t qlen = T0_POP();
13720957b409SSimon J. Gerraty 	int curve = T0_POP();
13730957b409SSimon J. Gerraty 	br_x509_pkey pk;
13740957b409SSimon J. Gerraty 
13750957b409SSimon J. Gerraty 	pk.key_type = BR_KEYTYPE_EC;
13760957b409SSimon J. Gerraty 	pk.key.ec.curve = curve;
13770957b409SSimon J. Gerraty 	pk.key.ec.q = CTX->pkey_data;
13780957b409SSimon J. Gerraty 	pk.key.ec.qlen = qlen;
13790957b409SSimon J. Gerraty 	T0_PUSH(verify_signature(CTX, &pk));
13800957b409SSimon J. Gerraty 
13810957b409SSimon J. Gerraty 				}
13820957b409SSimon J. Gerraty 				break;
1383*cc9e6590SSimon J. Gerraty 			case 36: {
13840957b409SSimon J. Gerraty 				/* do-rsa-vrfy */
13850957b409SSimon J. Gerraty 
13860957b409SSimon J. Gerraty 	size_t elen = T0_POP();
13870957b409SSimon J. Gerraty 	size_t nlen = T0_POP();
13880957b409SSimon J. Gerraty 	br_x509_pkey pk;
13890957b409SSimon J. Gerraty 
13900957b409SSimon J. Gerraty 	pk.key_type = BR_KEYTYPE_RSA;
13910957b409SSimon J. Gerraty 	pk.key.rsa.n = CTX->pkey_data;
13920957b409SSimon J. Gerraty 	pk.key.rsa.nlen = nlen;
13930957b409SSimon J. Gerraty 	pk.key.rsa.e = CTX->pkey_data + nlen;
13940957b409SSimon J. Gerraty 	pk.key.rsa.elen = elen;
13950957b409SSimon J. Gerraty 	T0_PUSH(verify_signature(CTX, &pk));
13960957b409SSimon J. Gerraty 
13970957b409SSimon J. Gerraty 				}
13980957b409SSimon J. Gerraty 				break;
1399*cc9e6590SSimon J. Gerraty 			case 37: {
14000957b409SSimon J. Gerraty 				/* drop */
14010957b409SSimon J. Gerraty  (void)T0_POP();
14020957b409SSimon J. Gerraty 				}
14030957b409SSimon J. Gerraty 				break;
1404*cc9e6590SSimon J. Gerraty 			case 38: {
14050957b409SSimon J. Gerraty 				/* dup */
14060957b409SSimon J. Gerraty  T0_PUSH(T0_PEEK(0));
14070957b409SSimon J. Gerraty 				}
14080957b409SSimon J. Gerraty 				break;
1409*cc9e6590SSimon J. Gerraty 			case 39: {
14100957b409SSimon J. Gerraty 				/* eqOID */
14110957b409SSimon J. Gerraty 
14120957b409SSimon J. Gerraty 	const unsigned char *a2 = &t0_datablock[T0_POP()];
14130957b409SSimon J. Gerraty 	const unsigned char *a1 = &CTX->pad[0];
14140957b409SSimon J. Gerraty 	size_t len = a1[0];
14150957b409SSimon J. Gerraty 	int x;
14160957b409SSimon J. Gerraty 	if (len == a2[0]) {
14170957b409SSimon J. Gerraty 		x = -(memcmp(a1 + 1, a2 + 1, len) == 0);
14180957b409SSimon J. Gerraty 	} else {
14190957b409SSimon J. Gerraty 		x = 0;
14200957b409SSimon J. Gerraty 	}
14210957b409SSimon J. Gerraty 	T0_PUSH((uint32_t)x);
14220957b409SSimon J. Gerraty 
14230957b409SSimon J. Gerraty 				}
14240957b409SSimon J. Gerraty 				break;
1425*cc9e6590SSimon J. Gerraty 			case 40: {
14260957b409SSimon J. Gerraty 				/* eqblob */
14270957b409SSimon J. Gerraty 
14280957b409SSimon J. Gerraty 	size_t len = T0_POP();
14290957b409SSimon J. Gerraty 	const unsigned char *a2 = (const unsigned char *)CTX + T0_POP();
14300957b409SSimon J. Gerraty 	const unsigned char *a1 = (const unsigned char *)CTX + T0_POP();
14310957b409SSimon J. Gerraty 	T0_PUSHi(-(memcmp(a1, a2, len) == 0));
14320957b409SSimon J. Gerraty 
14330957b409SSimon J. Gerraty 				}
14340957b409SSimon J. Gerraty 				break;
1435*cc9e6590SSimon J. Gerraty 			case 41: {
14360957b409SSimon J. Gerraty 				/* fail */
14370957b409SSimon J. Gerraty 
14380957b409SSimon J. Gerraty 	CTX->err = T0_POPi();
14390957b409SSimon J. Gerraty 	T0_CO();
14400957b409SSimon J. Gerraty 
14410957b409SSimon J. Gerraty 				}
14420957b409SSimon J. Gerraty 				break;
14430957b409SSimon J. Gerraty 			case 42: {
14440957b409SSimon J. Gerraty 				/* get16 */
14450957b409SSimon J. Gerraty 
14460957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
14470957b409SSimon J. Gerraty 	T0_PUSH(*(uint16_t *)(void *)((unsigned char *)CTX + addr));
14480957b409SSimon J. Gerraty 
14490957b409SSimon J. Gerraty 				}
14500957b409SSimon J. Gerraty 				break;
14510957b409SSimon J. Gerraty 			case 43: {
14520957b409SSimon J. Gerraty 				/* get32 */
14530957b409SSimon J. Gerraty 
14540957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
14550957b409SSimon J. Gerraty 	T0_PUSH(*(uint32_t *)(void *)((unsigned char *)CTX + addr));
14560957b409SSimon J. Gerraty 
14570957b409SSimon J. Gerraty 				}
14580957b409SSimon J. Gerraty 				break;
14590957b409SSimon J. Gerraty 			case 44: {
14600957b409SSimon J. Gerraty 				/* match-server-name */
14610957b409SSimon J. Gerraty 
14620957b409SSimon J. Gerraty 	size_t n1, n2;
14630957b409SSimon J. Gerraty 
14640957b409SSimon J. Gerraty 	if (CTX->server_name == NULL) {
14650957b409SSimon J. Gerraty 		T0_PUSH(0);
14660957b409SSimon J. Gerraty 		T0_RET();
14670957b409SSimon J. Gerraty 	}
14680957b409SSimon J. Gerraty 	n1 = strlen(CTX->server_name);
14690957b409SSimon J. Gerraty 	n2 = CTX->pad[0];
14700957b409SSimon J. Gerraty 	if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) {
14710957b409SSimon J. Gerraty 		T0_PUSHi(-1);
14720957b409SSimon J. Gerraty 		T0_RET();
14730957b409SSimon J. Gerraty 	}
14740957b409SSimon J. Gerraty 	if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') {
14750957b409SSimon J. Gerraty 		size_t u;
14760957b409SSimon J. Gerraty 
14770957b409SSimon J. Gerraty 		u = 0;
14780957b409SSimon J. Gerraty 		while (u < n1 && CTX->server_name[u] != '.') {
14790957b409SSimon J. Gerraty 			u ++;
14800957b409SSimon J. Gerraty 		}
14810957b409SSimon J. Gerraty 		u ++;
14820957b409SSimon J. Gerraty 		n1 -= u;
14830957b409SSimon J. Gerraty 		if ((n2 - 2) == n1
14840957b409SSimon J. Gerraty 			&& eqnocase(&CTX->pad[3], CTX->server_name + u, n1))
14850957b409SSimon J. Gerraty 		{
14860957b409SSimon J. Gerraty 			T0_PUSHi(-1);
14870957b409SSimon J. Gerraty 			T0_RET();
14880957b409SSimon J. Gerraty 		}
14890957b409SSimon J. Gerraty 	}
14900957b409SSimon J. Gerraty 	T0_PUSH(0);
14910957b409SSimon J. Gerraty 
14920957b409SSimon J. Gerraty 				}
14930957b409SSimon J. Gerraty 				break;
14940957b409SSimon J. Gerraty 			case 45: {
14950957b409SSimon J. Gerraty 				/* neg */
14960957b409SSimon J. Gerraty 
14970957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
14980957b409SSimon J. Gerraty 	T0_PUSH(-a);
14990957b409SSimon J. Gerraty 
15000957b409SSimon J. Gerraty 				}
15010957b409SSimon J. Gerraty 				break;
15020957b409SSimon J. Gerraty 			case 46: {
15030957b409SSimon J. Gerraty 				/* offset-name-element */
15040957b409SSimon J. Gerraty 
15050957b409SSimon J. Gerraty 	unsigned san = T0_POP();
15060957b409SSimon J. Gerraty 	size_t u;
15070957b409SSimon J. Gerraty 
15080957b409SSimon J. Gerraty 	for (u = 0; u < CTX->num_name_elts; u ++) {
15090957b409SSimon J. Gerraty 		if (CTX->name_elts[u].status == 0) {
15100957b409SSimon J. Gerraty 			const unsigned char *oid;
15110957b409SSimon J. Gerraty 			size_t len, off;
15120957b409SSimon J. Gerraty 
15130957b409SSimon J. Gerraty 			oid = CTX->name_elts[u].oid;
15140957b409SSimon J. Gerraty 			if (san) {
15150957b409SSimon J. Gerraty 				if (oid[0] != 0 || oid[1] != 0) {
15160957b409SSimon J. Gerraty 					continue;
15170957b409SSimon J. Gerraty 				}
15180957b409SSimon J. Gerraty 				off = 2;
15190957b409SSimon J. Gerraty 			} else {
15200957b409SSimon J. Gerraty 				off = 0;
15210957b409SSimon J. Gerraty 			}
15220957b409SSimon J. Gerraty 			len = oid[off];
15230957b409SSimon J. Gerraty 			if (len != 0 && len == CTX->pad[0]
15240957b409SSimon J. Gerraty 				&& memcmp(oid + off + 1,
15250957b409SSimon J. Gerraty 					CTX->pad + 1, len) == 0)
15260957b409SSimon J. Gerraty 			{
15270957b409SSimon J. Gerraty 				T0_PUSH(u);
15280957b409SSimon J. Gerraty 				T0_RET();
15290957b409SSimon J. Gerraty 			}
15300957b409SSimon J. Gerraty 		}
15310957b409SSimon J. Gerraty 	}
15320957b409SSimon J. Gerraty 	T0_PUSHi(-1);
15330957b409SSimon J. Gerraty 
15340957b409SSimon J. Gerraty 				}
15350957b409SSimon J. Gerraty 				break;
15360957b409SSimon J. Gerraty 			case 47: {
15370957b409SSimon J. Gerraty 				/* or */
15380957b409SSimon J. Gerraty 
15390957b409SSimon J. Gerraty 	uint32_t b = T0_POP();
15400957b409SSimon J. Gerraty 	uint32_t a = T0_POP();
15410957b409SSimon J. Gerraty 	T0_PUSH(a | b);
15420957b409SSimon J. Gerraty 
15430957b409SSimon J. Gerraty 				}
15440957b409SSimon J. Gerraty 				break;
15450957b409SSimon J. Gerraty 			case 48: {
15460957b409SSimon J. Gerraty 				/* over */
15470957b409SSimon J. Gerraty  T0_PUSH(T0_PEEK(1));
15480957b409SSimon J. Gerraty 				}
15490957b409SSimon J. Gerraty 				break;
15500957b409SSimon J. Gerraty 			case 49: {
15510957b409SSimon J. Gerraty 				/* read-blob-inner */
15520957b409SSimon J. Gerraty 
15530957b409SSimon J. Gerraty 	uint32_t len = T0_POP();
15540957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
15550957b409SSimon J. Gerraty 	size_t clen = CTX->hlen;
15560957b409SSimon J. Gerraty 	if (clen > len) {
15570957b409SSimon J. Gerraty 		clen = (size_t)len;
15580957b409SSimon J. Gerraty 	}
15590957b409SSimon J. Gerraty 	if (addr != 0) {
15600957b409SSimon J. Gerraty 		memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen);
15610957b409SSimon J. Gerraty 	}
15620957b409SSimon J. Gerraty 	if (CTX->do_mhash) {
15630957b409SSimon J. Gerraty 		br_multihash_update(&CTX->mhash, CTX->hbuf, clen);
15640957b409SSimon J. Gerraty 	}
15650957b409SSimon J. Gerraty 	if (CTX->do_dn_hash) {
15660957b409SSimon J. Gerraty 		CTX->dn_hash_impl->update(
15670957b409SSimon J. Gerraty 			&CTX->dn_hash.vtable, CTX->hbuf, clen);
15680957b409SSimon J. Gerraty 	}
15690957b409SSimon J. Gerraty 	CTX->hbuf += clen;
15700957b409SSimon J. Gerraty 	CTX->hlen -= clen;
15710957b409SSimon J. Gerraty 	T0_PUSH(addr + clen);
15720957b409SSimon J. Gerraty 	T0_PUSH(len - clen);
15730957b409SSimon J. Gerraty 
15740957b409SSimon J. Gerraty 				}
15750957b409SSimon J. Gerraty 				break;
15760957b409SSimon J. Gerraty 			case 50: {
15770957b409SSimon J. Gerraty 				/* read8-low */
15780957b409SSimon J. Gerraty 
15790957b409SSimon J. Gerraty 	if (CTX->hlen == 0) {
15800957b409SSimon J. Gerraty 		T0_PUSHi(-1);
15810957b409SSimon J. Gerraty 	} else {
15820957b409SSimon J. Gerraty 		unsigned char x = *CTX->hbuf ++;
15830957b409SSimon J. Gerraty 		if (CTX->do_mhash) {
15840957b409SSimon J. Gerraty 			br_multihash_update(&CTX->mhash, &x, 1);
15850957b409SSimon J. Gerraty 		}
15860957b409SSimon J. Gerraty 		if (CTX->do_dn_hash) {
15870957b409SSimon J. Gerraty 			CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1);
15880957b409SSimon J. Gerraty 		}
15890957b409SSimon J. Gerraty 		CTX->hlen --;
15900957b409SSimon J. Gerraty 		T0_PUSH(x);
15910957b409SSimon J. Gerraty 	}
15920957b409SSimon J. Gerraty 
15930957b409SSimon J. Gerraty 				}
15940957b409SSimon J. Gerraty 				break;
15950957b409SSimon J. Gerraty 			case 51: {
15960957b409SSimon J. Gerraty 				/* rot */
15970957b409SSimon J. Gerraty  T0_ROT();
15980957b409SSimon J. Gerraty 				}
15990957b409SSimon J. Gerraty 				break;
1600*cc9e6590SSimon J. Gerraty 			case 52: {
16010957b409SSimon J. Gerraty 				/* set16 */
16020957b409SSimon J. Gerraty 
16030957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
16040957b409SSimon J. Gerraty 	*(uint16_t *)(void *)((unsigned char *)CTX + addr) = T0_POP();
16050957b409SSimon J. Gerraty 
16060957b409SSimon J. Gerraty 				}
16070957b409SSimon J. Gerraty 				break;
1608*cc9e6590SSimon J. Gerraty 			case 53: {
16090957b409SSimon J. Gerraty 				/* set32 */
16100957b409SSimon J. Gerraty 
16110957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
16120957b409SSimon J. Gerraty 	*(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP();
16130957b409SSimon J. Gerraty 
16140957b409SSimon J. Gerraty 				}
16150957b409SSimon J. Gerraty 				break;
1616*cc9e6590SSimon J. Gerraty 			case 54: {
16170957b409SSimon J. Gerraty 				/* set8 */
16180957b409SSimon J. Gerraty 
16190957b409SSimon J. Gerraty 	uint32_t addr = T0_POP();
16200957b409SSimon J. Gerraty 	*((unsigned char *)CTX + addr) = (unsigned char)T0_POP();
16210957b409SSimon J. Gerraty 
16220957b409SSimon J. Gerraty 				}
16230957b409SSimon J. Gerraty 				break;
1624*cc9e6590SSimon J. Gerraty 			case 55: {
16250957b409SSimon J. Gerraty 				/* start-dn-hash */
16260957b409SSimon J. Gerraty 
16270957b409SSimon J. Gerraty 	CTX->dn_hash_impl->init(&CTX->dn_hash.vtable);
16280957b409SSimon J. Gerraty 	CTX->do_dn_hash = 1;
16290957b409SSimon J. Gerraty 
16300957b409SSimon J. Gerraty 				}
16310957b409SSimon J. Gerraty 				break;
1632*cc9e6590SSimon J. Gerraty 			case 56: {
16330957b409SSimon J. Gerraty 				/* start-tbs-hash */
16340957b409SSimon J. Gerraty 
16350957b409SSimon J. Gerraty 	br_multihash_init(&CTX->mhash);
16360957b409SSimon J. Gerraty 	CTX->do_mhash = 1;
16370957b409SSimon J. Gerraty 
16380957b409SSimon J. Gerraty 				}
16390957b409SSimon J. Gerraty 				break;
1640*cc9e6590SSimon J. Gerraty 			case 57: {
16410957b409SSimon J. Gerraty 				/* stop-tbs-hash */
16420957b409SSimon J. Gerraty 
16430957b409SSimon J. Gerraty 	CTX->do_mhash = 0;
16440957b409SSimon J. Gerraty 
16450957b409SSimon J. Gerraty 				}
16460957b409SSimon J. Gerraty 				break;
1647*cc9e6590SSimon J. Gerraty 			case 58: {
16480957b409SSimon J. Gerraty 				/* swap */
16490957b409SSimon J. Gerraty  T0_SWAP();
16500957b409SSimon J. Gerraty 				}
16510957b409SSimon J. Gerraty 				break;
1652*cc9e6590SSimon J. Gerraty 			case 59: {
16530957b409SSimon J. Gerraty 				/* zero-server-name */
16540957b409SSimon J. Gerraty 
16550957b409SSimon J. Gerraty 	T0_PUSHi(-(CTX->server_name == NULL));
16560957b409SSimon J. Gerraty 
16570957b409SSimon J. Gerraty 				}
16580957b409SSimon J. Gerraty 				break;
16590957b409SSimon J. Gerraty 			}
16600957b409SSimon J. Gerraty 
16610957b409SSimon J. Gerraty 		} else {
16620957b409SSimon J. Gerraty 			T0_ENTER(ip, rp, t0x);
16630957b409SSimon J. Gerraty 		}
16640957b409SSimon J. Gerraty 	}
16650957b409SSimon J. Gerraty t0_exit:
16660957b409SSimon J. Gerraty 	((t0_context *)t0ctx)->dp = dp;
16670957b409SSimon J. Gerraty 	((t0_context *)t0ctx)->rp = rp;
16680957b409SSimon J. Gerraty 	((t0_context *)t0ctx)->ip = ip;
16690957b409SSimon J. Gerraty }
16700957b409SSimon J. Gerraty 
16710957b409SSimon J. Gerraty 
16720957b409SSimon J. Gerraty 
16730957b409SSimon J. Gerraty /*
16740957b409SSimon J. Gerraty  * Verify the signature on the certificate with the provided public key.
16750957b409SSimon J. Gerraty  * This function checks the public key type with regards to the expected
16760957b409SSimon J. Gerraty  * type. Returned value is either 0 on success, or a non-zero error code.
16770957b409SSimon J. Gerraty  */
16780957b409SSimon J. Gerraty static int
verify_signature(br_x509_minimal_context * ctx,const br_x509_pkey * pk)16790957b409SSimon J. Gerraty verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk)
16800957b409SSimon J. Gerraty {
16810957b409SSimon J. Gerraty 	int kt;
16820957b409SSimon J. Gerraty 
16830957b409SSimon J. Gerraty 	kt = ctx->cert_signer_key_type;
16840957b409SSimon J. Gerraty 	if ((pk->key_type & 0x0F) != kt) {
16850957b409SSimon J. Gerraty 		return BR_ERR_X509_WRONG_KEY_TYPE;
16860957b409SSimon J. Gerraty 	}
16870957b409SSimon J. Gerraty 	switch (kt) {
16880957b409SSimon J. Gerraty 		unsigned char tmp[64];
16890957b409SSimon J. Gerraty 
16900957b409SSimon J. Gerraty 	case BR_KEYTYPE_RSA:
16910957b409SSimon J. Gerraty 		if (ctx->irsa == 0) {
16920957b409SSimon J. Gerraty 			return BR_ERR_X509_UNSUPPORTED;
16930957b409SSimon J. Gerraty 		}
16940957b409SSimon J. Gerraty 		if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len,
16950957b409SSimon J. Gerraty 			&t0_datablock[ctx->cert_sig_hash_oid],
16960957b409SSimon J. Gerraty 			ctx->cert_sig_hash_len, &pk->key.rsa, tmp))
16970957b409SSimon J. Gerraty 		{
16980957b409SSimon J. Gerraty 			return BR_ERR_X509_BAD_SIGNATURE;
16990957b409SSimon J. Gerraty 		}
17000957b409SSimon J. Gerraty 		if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) {
17010957b409SSimon J. Gerraty 			return BR_ERR_X509_BAD_SIGNATURE;
17020957b409SSimon J. Gerraty 		}
17030957b409SSimon J. Gerraty 		return 0;
17040957b409SSimon J. Gerraty 
17050957b409SSimon J. Gerraty 	case BR_KEYTYPE_EC:
17060957b409SSimon J. Gerraty 		if (ctx->iecdsa == 0) {
17070957b409SSimon J. Gerraty 			return BR_ERR_X509_UNSUPPORTED;
17080957b409SSimon J. Gerraty 		}
17090957b409SSimon J. Gerraty 		if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash,
17100957b409SSimon J. Gerraty 			ctx->cert_sig_hash_len, &pk->key.ec,
17110957b409SSimon J. Gerraty 			ctx->cert_sig, ctx->cert_sig_len))
17120957b409SSimon J. Gerraty 		{
17130957b409SSimon J. Gerraty 			return BR_ERR_X509_BAD_SIGNATURE;
17140957b409SSimon J. Gerraty 		}
17150957b409SSimon J. Gerraty 		return 0;
17160957b409SSimon J. Gerraty 
17170957b409SSimon J. Gerraty 	default:
17180957b409SSimon J. Gerraty 		return BR_ERR_X509_UNSUPPORTED;
17190957b409SSimon J. Gerraty 	}
17200957b409SSimon J. Gerraty }
17210957b409SSimon J. Gerraty 
17220957b409SSimon J. Gerraty 
1723