diff --git a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c index b648d7a2b..12e4cd2d4 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c +++ b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.c @@ -158,7 +158,7 @@ void br_x509_minimal_run(void *t0ctx); * -- Extensions: extension values are processed in due order. * * -- Basic Constraints: for all certificates except EE, must be - * present, indicate a CA, and have a path legnth compatible with + * present, indicate a CA, and have a path length compatible with * the chain length so far. * * -- Key Usage: for the EE, if present, must allow signatures @@ -600,190 +600,190 @@ static const unsigned char t0_codeblock[] PROGMEM = { 0x04, 0x10, 0x59, 0x30, 0x11, 0x06, 0x08, 0x24, 0x02, 0x05, 0x02, 0x06, 0x22, 0x04, 0x03, 0x57, 0x28, 0x24, 0x25, 0x06, 0x01, 0x28, 0x24, 0x01, 0x00, 0x03, 0x07, 0xB4, 0x01, 0x21, 0x8F, 0x01, 0x22, 0x8F, 0x25, 0x01, - 0x23, 0x11, 0x06, 0x81, 0x26, 0x24, 0x74, 0xAD, 0xAF, 0x25, 0x06, 0x81, - 0x1A, 0x01, 0x00, 0x03, 0x08, 0xAF, 0x9E, 0x24, 0xB3, 0x25, 0x01, 0x01, + 0x23, 0x11, 0x06, 0x81, 0x20, 0x24, 0x74, 0xAD, 0xAF, 0x25, 0x06, 0x81, + 0x14, 0x01, 0x00, 0x03, 0x08, 0xAF, 0x9E, 0x24, 0xB3, 0x25, 0x01, 0x01, 0x11, 0x06, 0x04, 0xA6, 0x03, 0x08, 0xB3, 0x01, 0x04, 0x78, 0xAD, 0x70, 0x26, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC3, 0x04, 0x05, 0x99, 0x01, - 0x7F, 0x03, 0x07, 0x04, 0x80, 0x6C, 0x91, 0x26, 0x06, 0x06, 0x02, 0x00, - 0x9B, 0x04, 0x80, 0x62, 0xC5, 0x26, 0x06, 0x11, 0x02, 0x00, 0x06, 0x09, + 0x7F, 0x03, 0x07, 0x04, 0x80, 0x66, 0x91, 0x26, 0x06, 0x06, 0x02, 0x00, + 0x9B, 0x04, 0x80, 0x5C, 0xC5, 0x26, 0x06, 0x11, 0x02, 0x00, 0x06, 0x09, 0x01, 0x00, 0x03, 0x01, 0x98, 0x03, 0x01, 0x04, 0x01, 0xC3, 0x04, 0x80, - 0x4D, 0x73, 0x26, 0x06, 0x0A, 0x02, 0x08, 0x06, 0x03, 0x9A, 0x04, 0x01, - 0xC3, 0x04, 0x3F, 0x6F, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x38, 0xC8, 0x26, - 0x06, 0x03, 0xC3, 0x04, 0x31, 0x90, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x2A, - 0xC6, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x23, 0x7A, 0x26, 0x06, 0x03, 0xC3, - 0x04, 0x1C, 0x85, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x15, 0x6E, 0x26, 0x06, - 0x03, 0xC3, 0x04, 0x0E, 0xC7, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x07, 0x02, - 0x08, 0x06, 0x02, 0x49, 0x28, 0xC3, 0x79, 0x79, 0x04, 0xFE, 0x62, 0x79, - 0x79, 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x56, 0x28, 0x24, 0x79, - 0x3A, 0x02, 0x00, 0x06, 0x08, 0x02, 0x01, 0x3C, 0x2F, 0x05, 0x02, 0x45, - 0x28, 0x02, 0x00, 0x06, 0x01, 0x17, 0x02, 0x00, 0x02, 0x07, 0x2F, 0x05, - 0x02, 0x51, 0x28, 0xB3, 0x76, 0xAD, 0x9E, 0x06, 0x80, 0x77, 0xBD, 0x26, - 0x06, 0x07, 0x01, 0x02, 0x5A, 0x8A, 0x04, 0x80, 0x5E, 0xBE, 0x26, 0x06, - 0x07, 0x01, 0x03, 0x5A, 0x8B, 0x04, 0x80, 0x53, 0xBF, 0x26, 0x06, 0x07, - 0x01, 0x04, 0x5A, 0x8C, 0x04, 0x80, 0x48, 0xC0, 0x26, 0x06, 0x06, 0x01, - 0x05, 0x5A, 0x8D, 0x04, 0x3E, 0xC1, 0x26, 0x06, 0x06, 0x01, 0x06, 0x5A, - 0x8E, 0x04, 0x34, 0x7F, 0x26, 0x06, 0x06, 0x01, 0x02, 0x59, 0x8A, 0x04, - 0x2A, 0x80, 0x26, 0x06, 0x06, 0x01, 0x03, 0x59, 0x8B, 0x04, 0x20, 0x81, - 0x26, 0x06, 0x06, 0x01, 0x04, 0x59, 0x8C, 0x04, 0x16, 0x82, 0x26, 0x06, - 0x06, 0x01, 0x05, 0x59, 0x8D, 0x04, 0x0C, 0x83, 0x26, 0x06, 0x06, 0x01, - 0x06, 0x59, 0x8E, 0x04, 0x02, 0x57, 0x28, 0x5E, 0x35, 0x60, 0x37, 0x1B, - 0x25, 0x05, 0x02, 0x57, 0x28, 0x5D, 0x37, 0x04, 0x02, 0x57, 0x28, 0xC2, - 0xA4, 0x25, 0x01, T0_INT2(BR_X509_BUFSIZE_SIG), 0x12, 0x06, 0x02, 0x50, - 0x28, 0x25, 0x5F, 0x35, 0x5C, 0xA5, 0x79, 0x79, 0x01, 0x00, 0x5B, 0x36, - 0x18, 0x00, 0x00, 0x01, 0x30, 0x0A, 0x25, 0x01, 0x00, 0x01, 0x09, 0x72, - 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x01, 0x81, - 0x08, 0x00, 0x00, 0x01, 0x81, 0x10, 0x00, 0x00, 0x01, 0x81, 0x19, 0x00, - 0x00, 0x01, 0x81, 0x22, 0x00, 0x00, 0x01, 0x81, 0x2B, 0x00, 0x01, 0x7E, - 0x01, 0x01, 0x11, 0x3B, 0x01, 0x83, 0xFD, 0x7F, 0x11, 0x15, 0x06, 0x03, - 0x3B, 0x24, 0x00, 0x3B, 0x25, 0x03, 0x00, 0x25, 0xCA, 0x05, 0x04, 0x42, - 0x01, 0x00, 0x00, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x96, 0x04, - 0x80, 0x49, 0x25, 0x01, 0x90, 0x00, 0x0D, 0x06, 0x0F, 0x01, 0x06, 0x14, - 0x01, 0x81, 0x40, 0x2F, 0x96, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, 0x33, - 0x25, 0x01, 0x83, 0xFF, 0x7F, 0x0D, 0x06, 0x14, 0x01, 0x0C, 0x14, 0x01, - 0x81, 0x60, 0x2F, 0x96, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, - 0x00, 0x97, 0x04, 0x17, 0x01, 0x12, 0x14, 0x01, 0x81, 0x70, 0x2F, 0x96, - 0x02, 0x00, 0x01, 0x0C, 0x97, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, - 0x01, 0x00, 0x97, 0x00, 0x00, 0x01, 0x82, 0x15, 0x00, 0x00, 0x25, 0x01, - 0x83, 0xB0, 0x00, 0x01, 0x83, 0xB7, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x81, - 0x34, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x81, 0x78, 0x00, - 0x00, 0x01, 0x3D, 0x00, 0x00, 0x01, 0x80, 0x43, 0x00, 0x00, 0x01, 0x80, - 0x4D, 0x00, 0x00, 0x01, 0x80, 0x57, 0x00, 0x00, 0x01, 0x80, 0x61, 0x00, - 0x00, 0x30, 0x11, 0x06, 0x04, 0x42, 0xAD, 0xC2, 0xB4, 0x00, 0x00, 0x01, - 0x82, 0x09, 0x00, 0x00, 0x01, 0x81, 0x6C, 0x00, 0x00, 0x25, 0x01, 0x83, - 0xB8, 0x00, 0x01, 0x83, 0xBF, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x30, 0x62, - 0x37, 0x01, 0x7F, 0x7C, 0x19, 0x01, 0x00, 0x7C, 0x19, 0x04, 0x7A, 0x00, - 0x01, 0x81, 0x38, 0x00, 0x01, 0x7E, 0x0D, 0x06, 0x02, 0x4F, 0x28, 0x25, - 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x30, 0x25, 0x3F, 0x3B, 0x01, - 0x82, 0x00, 0x13, 0x2F, 0x06, 0x04, 0x42, 0x01, 0x00, 0x00, 0x30, 0x67, - 0x09, 0x37, 0x40, 0x00, 0x00, 0x14, 0x01, 0x3F, 0x15, 0x01, 0x81, 0x00, - 0x2F, 0x96, 0x00, 0x02, 0x01, 0x00, 0x03, 0x00, 0xAF, 0x25, 0x06, 0x80, - 0x59, 0xB3, 0x01, 0x20, 0x30, 0x11, 0x06, 0x17, 0x24, 0x74, 0xAD, 0x9E, - 0x24, 0x01, 0x7F, 0x2E, 0x03, 0x01, 0xB3, 0x01, 0x20, 0x77, 0xAD, 0xB2, - 0x02, 0x01, 0x1F, 0x79, 0x79, 0x04, 0x38, 0x01, 0x21, 0x30, 0x11, 0x06, - 0x08, 0x24, 0x75, 0xB6, 0x01, 0x01, 0x1E, 0x04, 0x2A, 0x01, 0x22, 0x30, - 0x11, 0x06, 0x11, 0x24, 0x75, 0xB6, 0x25, 0x06, 0x06, 0x2C, 0x02, 0x00, - 0x2F, 0x03, 0x00, 0x01, 0x02, 0x1E, 0x04, 0x13, 0x01, 0x26, 0x30, 0x11, - 0x06, 0x08, 0x24, 0x75, 0xB6, 0x01, 0x06, 0x1E, 0x04, 0x05, 0x42, 0xAE, - 0x01, 0x00, 0x24, 0x04, 0xFF, 0x23, 0x79, 0x02, 0x00, 0x00, 0x00, 0xAF, - 0xB4, 0x25, 0x01, 0x01, 0x11, 0x06, 0x08, 0xA6, 0x05, 0x02, 0x51, 0x28, - 0xB4, 0x04, 0x02, 0x51, 0x28, 0x25, 0x01, 0x02, 0x11, 0x06, 0x0C, 0x24, - 0x75, 0xB0, 0x66, 0x2B, 0x41, 0x0D, 0x06, 0x02, 0x51, 0x28, 0xB4, 0x01, - 0x7F, 0x10, 0x06, 0x02, 0x56, 0x28, 0x24, 0x79, 0x00, 0x00, 0xAF, 0x25, - 0x06, 0x1A, 0xAF, 0x9E, 0x24, 0x25, 0x06, 0x11, 0xAF, 0x25, 0x06, 0x0C, - 0xAF, 0x9E, 0x24, 0x89, 0x26, 0x05, 0x02, 0x49, 0x28, 0xC2, 0x04, 0x71, - 0x79, 0x79, 0x04, 0x63, 0x79, 0x00, 0x02, 0x03, 0x00, 0xB3, 0x01, 0x03, - 0x78, 0xAD, 0xBA, 0x03, 0x01, 0x02, 0x01, 0x01, 0x07, 0x12, 0x06, 0x02, - 0x56, 0x28, 0x25, 0x01, 0x00, 0x30, 0x11, 0x06, 0x05, 0x24, 0x4D, 0x28, - 0x04, 0x15, 0x01, 0x01, 0x30, 0x11, 0x06, 0x0A, 0x24, 0xBA, 0x02, 0x01, - 0x14, 0x02, 0x01, 0x0E, 0x04, 0x05, 0x24, 0xBA, 0x01, 0x00, 0x24, 0x02, - 0x00, 0x06, 0x19, 0x01, 0x00, 0x30, 0x01, 0x38, 0x15, 0x06, 0x03, 0x01, - 0x10, 0x2F, 0x3B, 0x01, 0x81, 0x40, 0x15, 0x06, 0x03, 0x01, 0x20, 0x2F, - 0x62, 0x37, 0x04, 0x07, 0x01, 0x04, 0x15, 0x05, 0x02, 0x4D, 0x28, 0xC2, - 0x00, 0x00, 0x38, 0xAF, 0xC2, 0x1A, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, - 0x38, 0xAF, 0x25, 0x06, 0x30, 0xB3, 0x01, 0x11, 0x77, 0xAD, 0x25, 0x05, - 0x02, 0x44, 0x28, 0x25, 0x06, 0x20, 0xAF, 0x9E, 0x24, 0x87, 0x26, 0x03, - 0x01, 0x01, 0x00, 0x2E, 0x03, 0x02, 0xB2, 0x25, 0x02, 0x01, 0x15, 0x06, - 0x07, 0x2C, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x02, 0x1F, 0x79, - 0x04, 0x5D, 0x79, 0x04, 0x4D, 0x79, 0x1A, 0x02, 0x00, 0x00, 0x00, 0xB3, - 0x01, 0x06, 0x78, 0xB1, 0x00, 0x00, 0xB8, 0x86, 0x06, 0x0E, 0x3B, 0x25, - 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0xB8, 0x6D, 0x04, 0x08, - 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB9, 0x86, - 0x06, 0x0E, 0x3B, 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, - 0xB9, 0x6D, 0x04, 0x08, 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, - 0x00, 0x00, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x00, 0x04, - 0x80, 0x55, 0x25, 0x01, 0x81, 0x40, 0x0D, 0x06, 0x07, 0x24, 0x01, 0x00, - 0x00, 0x04, 0x80, 0x47, 0x25, 0x01, 0x81, 0x60, 0x0D, 0x06, 0x0E, 0x01, - 0x1F, 0x15, 0x01, 0x01, 0xA3, 0x01, 0x81, 0x00, 0x01, 0x8F, 0x7F, 0x04, - 0x32, 0x25, 0x01, 0x81, 0x70, 0x0D, 0x06, 0x0F, 0x01, 0x0F, 0x15, 0x01, - 0x02, 0xA3, 0x01, 0x90, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x04, 0x1C, 0x25, - 0x01, 0x81, 0x78, 0x0D, 0x06, 0x11, 0x01, 0x07, 0x15, 0x01, 0x03, 0xA3, - 0x01, 0x84, 0x80, 0x00, 0x01, 0x80, 0xC3, 0xFF, 0x7F, 0x04, 0x04, 0x24, - 0x01, 0x00, 0x00, 0x72, 0x05, 0x03, 0x24, 0x01, 0x00, 0x00, 0x00, 0x3B, - 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xBA, 0x34, 0x25, - 0x3D, 0x06, 0x03, 0x3B, 0x24, 0x00, 0x01, 0x06, 0x0E, 0x3B, 0x25, 0x01, - 0x06, 0x14, 0x01, 0x02, 0x10, 0x06, 0x04, 0x42, 0x01, 0x7F, 0x00, 0x01, - 0x3F, 0x15, 0x09, 0x00, 0x00, 0x25, 0x06, 0x06, 0x0B, 0xA2, 0x34, 0x41, - 0x04, 0x77, 0x24, 0x25, 0x00, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, - 0x06, 0x02, 0x55, 0x28, 0x00, 0x00, 0x3B, 0x25, 0x06, 0x07, 0x31, 0x25, - 0x06, 0x01, 0x19, 0x04, 0x76, 0x42, 0x00, 0x00, 0x01, 0x01, 0x78, 0xAC, - 0x01, 0x01, 0x10, 0x06, 0x02, 0x43, 0x28, 0xBA, 0x3E, 0x00, 0x04, 0xB3, - 0x25, 0x01, 0x17, 0x01, 0x18, 0x72, 0x05, 0x02, 0x48, 0x28, 0x01, 0x18, - 0x11, 0x03, 0x00, 0x75, 0xAD, 0xA8, 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, - 0x64, 0x08, 0x03, 0x01, 0xA8, 0x02, 0x01, 0x09, 0x04, 0x0E, 0x25, 0x01, - 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, - 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, - 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, - 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, - 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, 0x01, 0x01, 0x0C, 0xA9, 0x41, 0x01, - 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, 0x07, 0x3F, 0x02, 0x01, 0x01, 0x80, - 0x64, 0x07, 0x3E, 0x02, 0x01, 0x01, 0x83, 0x10, 0x07, 0x3F, 0x2F, 0x15, - 0x06, 0x03, 0x01, 0x18, 0x09, 0x94, 0x09, 0x7B, 0x25, 0x01, 0x05, 0x14, - 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, 0x1F, 0x15, 0x01, 0x01, 0x3B, 0xA9, - 0x02, 0x03, 0x09, 0x41, 0x03, 0x03, 0x01, 0x00, 0x01, 0x17, 0xA9, 0x01, - 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3B, 0xA9, 0x01, 0x3C, - 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3C, 0xA9, 0x02, - 0x02, 0x09, 0x03, 0x02, 0xBA, 0x25, 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x24, - 0xBA, 0x25, 0x01, 0x30, 0x01, 0x39, 0x72, 0x06, 0x03, 0x24, 0x04, 0x74, - 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, 0x48, 0x28, 0x79, 0x02, 0x03, 0x02, - 0x02, 0x00, 0x01, 0xBA, 0x7D, 0x01, 0x0A, 0x08, 0x03, 0x00, 0xBA, 0x7D, - 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0xA8, 0x25, 0x02, - 0x01, 0x02, 0x00, 0x72, 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x34, 0xB3, - 0x01, 0x02, 0x78, 0x0B, 0xAB, 0x00, 0x03, 0x25, 0x03, 0x00, 0x03, 0x01, - 0x03, 0x02, 0xAD, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, - 0x28, 0x25, 0x01, 0x00, 0x11, 0x06, 0x0B, 0x24, 0x25, 0x05, 0x04, 0x24, - 0x01, 0x00, 0x00, 0xBA, 0x04, 0x6F, 0x02, 0x01, 0x25, 0x05, 0x02, 0x50, - 0x28, 0x41, 0x03, 0x01, 0x02, 0x02, 0x37, 0x02, 0x02, 0x40, 0x03, 0x02, - 0x25, 0x06, 0x03, 0xBA, 0x04, 0x68, 0x24, 0x02, 0x00, 0x02, 0x01, 0x0A, - 0x00, 0x01, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, - 0x81, 0x00, 0x0A, 0x25, 0x05, 0x02, 0x4E, 0x28, 0x03, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, 0x19, 0x02, 0x00, 0x41, 0x03, 0x00, - 0x25, 0x01, 0x83, 0xFF, 0xFF, 0x7F, 0x12, 0x06, 0x02, 0x4F, 0x28, 0x01, - 0x08, 0x0E, 0x3B, 0xBA, 0x34, 0x09, 0x04, 0x60, 0x00, 0x00, 0xAC, 0x95, - 0x00, 0x00, 0xAD, 0xC2, 0x00, 0x00, 0xB3, 0x76, 0xAD, 0x00, 0x01, 0xAD, - 0x25, 0x05, 0x02, 0x54, 0x28, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, - 0x02, 0x54, 0x28, 0x03, 0x00, 0x25, 0x06, 0x16, 0xBA, 0x02, 0x00, 0x25, - 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, 0x06, 0x02, 0x54, 0x28, 0x01, 0x08, - 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, 0x24, 0x02, 0x00, 0x00, 0x00, 0xAD, - 0x25, 0x01, 0x81, 0x7F, 0x12, 0x06, 0x08, 0xC2, 0x01, 0x00, 0x67, 0x37, - 0x01, 0x00, 0x00, 0x25, 0x67, 0x37, 0x67, 0x40, 0xA5, 0x01, 0x7F, 0x00, - 0x00, 0xB3, 0x01, 0x0C, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB6, 0x04, - 0x3E, 0x01, 0x12, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x33, - 0x01, 0x13, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x28, 0x01, - 0x14, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x1D, 0x01, 0x16, - 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x12, 0x01, 0x1E, 0x30, - 0x11, 0x06, 0x05, 0x24, 0x75, 0xB5, 0x04, 0x07, 0x42, 0xAE, 0x01, 0x00, - 0x01, 0x00, 0x24, 0x00, 0x01, 0xBA, 0x03, 0x00, 0x02, 0x00, 0x01, 0x05, - 0x14, 0x01, 0x01, 0x15, 0x2D, 0x02, 0x00, 0x01, 0x06, 0x14, 0x25, 0x01, - 0x01, 0x15, 0x06, 0x02, 0x46, 0x28, 0x01, 0x04, 0x0E, 0x02, 0x00, 0x01, - 0x1F, 0x15, 0x25, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x47, 0x28, 0x09, 0x00, - 0x00, 0x25, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xB3, 0x00, 0x01, - 0xAD, 0x25, 0x05, 0x05, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0x01, 0x03, - 0x00, 0x9F, 0x25, 0x01, 0x83, 0xFF, 0x7E, 0x11, 0x06, 0x16, 0x24, 0x25, - 0x06, 0x10, 0xA0, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, - 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, 0x04, 0x1B, 0x25, 0x05, 0x05, 0x24, - 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x25, 0x06, 0x0B, - 0x9F, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x6D, 0x24, - 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, - 0x01, 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xA1, 0x25, 0x05, - 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, - 0x6D, 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, - 0x7F, 0x00, 0x01, 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xBA, + 0x47, 0x73, 0x26, 0x06, 0x0A, 0x02, 0x08, 0x06, 0x03, 0x9A, 0x04, 0x01, + 0xC3, 0x04, 0x39, 0x6F, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x32, 0xC8, 0x26, + 0x06, 0x03, 0xC3, 0x04, 0x2B, 0x90, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x24, + 0xC6, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x1D, 0x7A, 0x26, 0x06, 0x03, 0xC3, + 0x04, 0x16, 0x85, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x0F, 0x6E, 0x26, 0x06, + 0x03, 0xC3, 0x04, 0x08, 0xC7, 0x26, 0x06, 0x03, 0xC3, 0x04, 0x01, 0xC3, + 0x79, 0x79, 0x04, 0xFE, 0x68, 0x79, 0x79, 0x04, 0x08, 0x01, 0x7F, 0x11, + 0x05, 0x02, 0x56, 0x28, 0x24, 0x79, 0x3A, 0x02, 0x00, 0x06, 0x08, 0x02, + 0x01, 0x3C, 0x2F, 0x05, 0x02, 0x45, 0x28, 0x02, 0x00, 0x06, 0x01, 0x17, + 0x02, 0x00, 0x02, 0x07, 0x2F, 0x05, 0x02, 0x51, 0x28, 0xB3, 0x76, 0xAD, + 0x9E, 0x06, 0x80, 0x77, 0xBD, 0x26, 0x06, 0x07, 0x01, 0x02, 0x5A, 0x8A, + 0x04, 0x80, 0x5E, 0xBE, 0x26, 0x06, 0x07, 0x01, 0x03, 0x5A, 0x8B, 0x04, + 0x80, 0x53, 0xBF, 0x26, 0x06, 0x07, 0x01, 0x04, 0x5A, 0x8C, 0x04, 0x80, + 0x48, 0xC0, 0x26, 0x06, 0x06, 0x01, 0x05, 0x5A, 0x8D, 0x04, 0x3E, 0xC1, + 0x26, 0x06, 0x06, 0x01, 0x06, 0x5A, 0x8E, 0x04, 0x34, 0x7F, 0x26, 0x06, + 0x06, 0x01, 0x02, 0x59, 0x8A, 0x04, 0x2A, 0x80, 0x26, 0x06, 0x06, 0x01, + 0x03, 0x59, 0x8B, 0x04, 0x20, 0x81, 0x26, 0x06, 0x06, 0x01, 0x04, 0x59, + 0x8C, 0x04, 0x16, 0x82, 0x26, 0x06, 0x06, 0x01, 0x05, 0x59, 0x8D, 0x04, + 0x0C, 0x83, 0x26, 0x06, 0x06, 0x01, 0x06, 0x59, 0x8E, 0x04, 0x02, 0x57, + 0x28, 0x5E, 0x35, 0x60, 0x37, 0x1B, 0x25, 0x05, 0x02, 0x57, 0x28, 0x5D, + 0x37, 0x04, 0x02, 0x57, 0x28, 0xC2, 0xA4, 0x25, 0x01, + T0_INT2(BR_X509_BUFSIZE_SIG), 0x12, 0x06, 0x02, 0x50, 0x28, 0x25, 0x5F, + 0x35, 0x5C, 0xA5, 0x79, 0x79, 0x01, 0x00, 0x5B, 0x36, 0x18, 0x00, 0x00, + 0x01, 0x30, 0x0A, 0x25, 0x01, 0x00, 0x01, 0x09, 0x72, 0x05, 0x02, 0x48, + 0x28, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x01, 0x81, 0x08, 0x00, 0x00, + 0x01, 0x81, 0x10, 0x00, 0x00, 0x01, 0x81, 0x19, 0x00, 0x00, 0x01, 0x81, + 0x22, 0x00, 0x00, 0x01, 0x81, 0x2B, 0x00, 0x01, 0x7E, 0x01, 0x01, 0x11, + 0x3B, 0x01, 0x83, 0xFD, 0x7F, 0x11, 0x15, 0x06, 0x03, 0x3B, 0x24, 0x00, + 0x3B, 0x25, 0x03, 0x00, 0x25, 0xCA, 0x05, 0x04, 0x42, 0x01, 0x00, 0x00, + 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x96, 0x04, 0x80, 0x49, 0x25, + 0x01, 0x90, 0x00, 0x0D, 0x06, 0x0F, 0x01, 0x06, 0x14, 0x01, 0x81, 0x40, + 0x2F, 0x96, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, 0x33, 0x25, 0x01, 0x83, + 0xFF, 0x7F, 0x0D, 0x06, 0x14, 0x01, 0x0C, 0x14, 0x01, 0x81, 0x60, 0x2F, + 0x96, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, 0x00, 0x97, 0x04, + 0x17, 0x01, 0x12, 0x14, 0x01, 0x81, 0x70, 0x2F, 0x96, 0x02, 0x00, 0x01, + 0x0C, 0x97, 0x02, 0x00, 0x01, 0x06, 0x97, 0x02, 0x00, 0x01, 0x00, 0x97, + 0x00, 0x00, 0x01, 0x82, 0x15, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, + 0x01, 0x83, 0xB7, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x81, 0x34, 0x00, 0x00, + 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x81, 0x78, 0x00, 0x00, 0x01, 0x3D, + 0x00, 0x00, 0x01, 0x80, 0x43, 0x00, 0x00, 0x01, 0x80, 0x4D, 0x00, 0x00, + 0x01, 0x80, 0x57, 0x00, 0x00, 0x01, 0x80, 0x61, 0x00, 0x00, 0x30, 0x11, + 0x06, 0x04, 0x42, 0xAD, 0xC2, 0xB4, 0x00, 0x00, 0x01, 0x82, 0x09, 0x00, + 0x00, 0x01, 0x81, 0x6C, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB8, 0x00, 0x01, + 0x83, 0xBF, 0x7F, 0x72, 0x00, 0x00, 0x01, 0x30, 0x62, 0x37, 0x01, 0x7F, + 0x7C, 0x19, 0x01, 0x00, 0x7C, 0x19, 0x04, 0x7A, 0x00, 0x01, 0x81, 0x38, + 0x00, 0x01, 0x7E, 0x0D, 0x06, 0x02, 0x4F, 0x28, 0x25, 0x03, 0x00, 0x0A, + 0x02, 0x00, 0x00, 0x00, 0x30, 0x25, 0x3F, 0x3B, 0x01, 0x82, 0x00, 0x13, + 0x2F, 0x06, 0x04, 0x42, 0x01, 0x00, 0x00, 0x30, 0x67, 0x09, 0x37, 0x40, + 0x00, 0x00, 0x14, 0x01, 0x3F, 0x15, 0x01, 0x81, 0x00, 0x2F, 0x96, 0x00, + 0x02, 0x01, 0x00, 0x03, 0x00, 0xAF, 0x25, 0x06, 0x80, 0x59, 0xB3, 0x01, + 0x20, 0x30, 0x11, 0x06, 0x17, 0x24, 0x74, 0xAD, 0x9E, 0x24, 0x01, 0x7F, + 0x2E, 0x03, 0x01, 0xB3, 0x01, 0x20, 0x77, 0xAD, 0xB2, 0x02, 0x01, 0x1F, + 0x79, 0x79, 0x04, 0x38, 0x01, 0x21, 0x30, 0x11, 0x06, 0x08, 0x24, 0x75, + 0xB6, 0x01, 0x01, 0x1E, 0x04, 0x2A, 0x01, 0x22, 0x30, 0x11, 0x06, 0x11, + 0x24, 0x75, 0xB6, 0x25, 0x06, 0x06, 0x2C, 0x02, 0x00, 0x2F, 0x03, 0x00, + 0x01, 0x02, 0x1E, 0x04, 0x13, 0x01, 0x26, 0x30, 0x11, 0x06, 0x08, 0x24, + 0x75, 0xB6, 0x01, 0x06, 0x1E, 0x04, 0x05, 0x42, 0xAE, 0x01, 0x00, 0x24, + 0x04, 0xFF, 0x23, 0x79, 0x02, 0x00, 0x00, 0x00, 0xAF, 0xB4, 0x25, 0x01, + 0x01, 0x11, 0x06, 0x08, 0xA6, 0x05, 0x02, 0x51, 0x28, 0xB4, 0x04, 0x02, + 0x51, 0x28, 0x25, 0x01, 0x02, 0x11, 0x06, 0x0C, 0x24, 0x75, 0xB0, 0x66, + 0x2B, 0x41, 0x0D, 0x06, 0x02, 0x51, 0x28, 0xB4, 0x01, 0x7F, 0x10, 0x06, + 0x02, 0x56, 0x28, 0x24, 0x79, 0x00, 0x00, 0xAF, 0x25, 0x06, 0x1A, 0xAF, + 0x9E, 0x24, 0x25, 0x06, 0x11, 0xAF, 0x25, 0x06, 0x0C, 0xAF, 0x9E, 0x24, + 0x89, 0x26, 0x05, 0x02, 0x49, 0x28, 0xC2, 0x04, 0x71, 0x79, 0x79, 0x04, + 0x63, 0x79, 0x00, 0x02, 0x03, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, + 0x03, 0x01, 0x02, 0x01, 0x01, 0x07, 0x12, 0x06, 0x02, 0x56, 0x28, 0x25, + 0x01, 0x00, 0x30, 0x11, 0x06, 0x05, 0x24, 0x4D, 0x28, 0x04, 0x15, 0x01, + 0x01, 0x30, 0x11, 0x06, 0x0A, 0x24, 0xBA, 0x02, 0x01, 0x14, 0x02, 0x01, + 0x0E, 0x04, 0x05, 0x24, 0xBA, 0x01, 0x00, 0x24, 0x02, 0x00, 0x06, 0x19, + 0x01, 0x00, 0x30, 0x01, 0x38, 0x15, 0x06, 0x03, 0x01, 0x10, 0x2F, 0x3B, + 0x01, 0x81, 0x40, 0x15, 0x06, 0x03, 0x01, 0x20, 0x2F, 0x62, 0x37, 0x04, + 0x07, 0x01, 0x04, 0x15, 0x05, 0x02, 0x4D, 0x28, 0xC2, 0x00, 0x00, 0x38, + 0xAF, 0xC2, 0x1A, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0x38, 0xAF, 0x25, + 0x06, 0x30, 0xB3, 0x01, 0x11, 0x77, 0xAD, 0x25, 0x05, 0x02, 0x44, 0x28, + 0x25, 0x06, 0x20, 0xAF, 0x9E, 0x24, 0x87, 0x26, 0x03, 0x01, 0x01, 0x00, + 0x2E, 0x03, 0x02, 0xB2, 0x25, 0x02, 0x01, 0x15, 0x06, 0x07, 0x2C, 0x06, + 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x02, 0x1F, 0x79, 0x04, 0x5D, 0x79, + 0x04, 0x4D, 0x79, 0x1A, 0x02, 0x00, 0x00, 0x00, 0xB3, 0x01, 0x06, 0x78, + 0xB1, 0x00, 0x00, 0xB8, 0x86, 0x06, 0x0E, 0x3B, 0x25, 0x05, 0x06, 0x42, + 0x01, 0x00, 0x01, 0x00, 0x00, 0xB8, 0x6D, 0x04, 0x08, 0x92, 0x06, 0x05, + 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB9, 0x86, 0x06, 0x0E, 0x3B, + 0x25, 0x05, 0x06, 0x42, 0x01, 0x00, 0x01, 0x00, 0x00, 0xB9, 0x6D, 0x04, + 0x08, 0x92, 0x06, 0x05, 0x24, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xBA, + 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x04, 0x00, 0x04, 0x80, 0x55, 0x25, + 0x01, 0x81, 0x40, 0x0D, 0x06, 0x07, 0x24, 0x01, 0x00, 0x00, 0x04, 0x80, + 0x47, 0x25, 0x01, 0x81, 0x60, 0x0D, 0x06, 0x0E, 0x01, 0x1F, 0x15, 0x01, + 0x01, 0xA3, 0x01, 0x81, 0x00, 0x01, 0x8F, 0x7F, 0x04, 0x32, 0x25, 0x01, + 0x81, 0x70, 0x0D, 0x06, 0x0F, 0x01, 0x0F, 0x15, 0x01, 0x02, 0xA3, 0x01, + 0x90, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x04, 0x1C, 0x25, 0x01, 0x81, 0x78, + 0x0D, 0x06, 0x11, 0x01, 0x07, 0x15, 0x01, 0x03, 0xA3, 0x01, 0x84, 0x80, + 0x00, 0x01, 0x80, 0xC3, 0xFF, 0x7F, 0x04, 0x04, 0x24, 0x01, 0x00, 0x00, + 0x72, 0x05, 0x03, 0x24, 0x01, 0x00, 0x00, 0x00, 0x3B, 0x25, 0x05, 0x06, + 0x42, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xBA, 0x34, 0x25, 0x3D, 0x06, 0x03, + 0x3B, 0x24, 0x00, 0x01, 0x06, 0x0E, 0x3B, 0x25, 0x01, 0x06, 0x14, 0x01, + 0x02, 0x10, 0x06, 0x04, 0x42, 0x01, 0x7F, 0x00, 0x01, 0x3F, 0x15, 0x09, + 0x00, 0x00, 0x25, 0x06, 0x06, 0x0B, 0xA2, 0x34, 0x41, 0x04, 0x77, 0x24, + 0x25, 0x00, 0x00, 0xB3, 0x01, 0x03, 0x78, 0xAD, 0xBA, 0x06, 0x02, 0x55, + 0x28, 0x00, 0x00, 0x3B, 0x25, 0x06, 0x07, 0x31, 0x25, 0x06, 0x01, 0x19, + 0x04, 0x76, 0x42, 0x00, 0x00, 0x01, 0x01, 0x78, 0xAC, 0x01, 0x01, 0x10, + 0x06, 0x02, 0x43, 0x28, 0xBA, 0x3E, 0x00, 0x04, 0xB3, 0x25, 0x01, 0x17, + 0x01, 0x18, 0x72, 0x05, 0x02, 0x48, 0x28, 0x01, 0x18, 0x11, 0x03, 0x00, + 0x75, 0xAD, 0xA8, 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, + 0x01, 0xA8, 0x02, 0x01, 0x09, 0x04, 0x0E, 0x25, 0x01, 0x32, 0x0D, 0x06, + 0x04, 0x01, 0x80, 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, + 0x01, 0x01, 0x82, 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, + 0x0C, 0x09, 0x02, 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, + 0x0A, 0x02, 0x01, 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, + 0x03, 0x03, 0x01, 0x01, 0x01, 0x0C, 0xA9, 0x41, 0x01, 0x01, 0x0E, 0x02, + 0x01, 0x01, 0x04, 0x07, 0x3F, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x3E, + 0x02, 0x01, 0x01, 0x83, 0x10, 0x07, 0x3F, 0x2F, 0x15, 0x06, 0x03, 0x01, + 0x18, 0x09, 0x94, 0x09, 0x7B, 0x25, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, + 0x03, 0x03, 0x01, 0x1F, 0x15, 0x01, 0x01, 0x3B, 0xA9, 0x02, 0x03, 0x09, + 0x41, 0x03, 0x03, 0x01, 0x00, 0x01, 0x17, 0xA9, 0x01, 0x9C, 0x10, 0x08, + 0x03, 0x02, 0x01, 0x00, 0x01, 0x3B, 0xA9, 0x01, 0x3C, 0x08, 0x02, 0x02, + 0x09, 0x03, 0x02, 0x01, 0x00, 0x01, 0x3C, 0xA9, 0x02, 0x02, 0x09, 0x03, + 0x02, 0xBA, 0x25, 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x24, 0xBA, 0x25, 0x01, + 0x30, 0x01, 0x39, 0x72, 0x06, 0x03, 0x24, 0x04, 0x74, 0x01, 0x80, 0x5A, + 0x10, 0x06, 0x02, 0x48, 0x28, 0x79, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, + 0xBA, 0x7D, 0x01, 0x0A, 0x08, 0x03, 0x00, 0xBA, 0x7D, 0x02, 0x00, 0x09, + 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0xA8, 0x25, 0x02, 0x01, 0x02, 0x00, + 0x72, 0x05, 0x02, 0x48, 0x28, 0x00, 0x00, 0x34, 0xB3, 0x01, 0x02, 0x78, + 0x0B, 0xAB, 0x00, 0x03, 0x25, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0xAD, + 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, 0x28, 0x25, 0x01, + 0x00, 0x11, 0x06, 0x0B, 0x24, 0x25, 0x05, 0x04, 0x24, 0x01, 0x00, 0x00, + 0xBA, 0x04, 0x6F, 0x02, 0x01, 0x25, 0x05, 0x02, 0x50, 0x28, 0x41, 0x03, + 0x01, 0x02, 0x02, 0x37, 0x02, 0x02, 0x40, 0x03, 0x02, 0x25, 0x06, 0x03, + 0xBA, 0x04, 0x68, 0x24, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0xBA, + 0x25, 0x01, 0x81, 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, + 0x25, 0x05, 0x02, 0x4E, 0x28, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, + 0x00, 0x12, 0x06, 0x19, 0x02, 0x00, 0x41, 0x03, 0x00, 0x25, 0x01, 0x83, + 0xFF, 0xFF, 0x7F, 0x12, 0x06, 0x02, 0x4F, 0x28, 0x01, 0x08, 0x0E, 0x3B, + 0xBA, 0x34, 0x09, 0x04, 0x60, 0x00, 0x00, 0xAC, 0x95, 0x00, 0x00, 0xAD, + 0xC2, 0x00, 0x00, 0xB3, 0x76, 0xAD, 0x00, 0x01, 0xAD, 0x25, 0x05, 0x02, + 0x54, 0x28, 0xBA, 0x25, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x54, 0x28, + 0x03, 0x00, 0x25, 0x06, 0x16, 0xBA, 0x02, 0x00, 0x25, 0x01, 0x87, 0xFF, + 0xFF, 0x7F, 0x13, 0x06, 0x02, 0x54, 0x28, 0x01, 0x08, 0x0E, 0x09, 0x03, + 0x00, 0x04, 0x67, 0x24, 0x02, 0x00, 0x00, 0x00, 0xAD, 0x25, 0x01, 0x81, + 0x7F, 0x12, 0x06, 0x08, 0xC2, 0x01, 0x00, 0x67, 0x37, 0x01, 0x00, 0x00, + 0x25, 0x67, 0x37, 0x67, 0x40, 0xA5, 0x01, 0x7F, 0x00, 0x00, 0xB3, 0x01, + 0x0C, 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB6, 0x04, 0x3E, 0x01, 0x12, + 0x30, 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x33, 0x01, 0x13, 0x30, + 0x11, 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x28, 0x01, 0x14, 0x30, 0x11, + 0x06, 0x05, 0x24, 0x75, 0xB7, 0x04, 0x1D, 0x01, 0x16, 0x30, 0x11, 0x06, + 0x05, 0x24, 0x75, 0xB7, 0x04, 0x12, 0x01, 0x1E, 0x30, 0x11, 0x06, 0x05, + 0x24, 0x75, 0xB5, 0x04, 0x07, 0x42, 0xAE, 0x01, 0x00, 0x01, 0x00, 0x24, + 0x00, 0x01, 0xBA, 0x03, 0x00, 0x02, 0x00, 0x01, 0x05, 0x14, 0x01, 0x01, + 0x15, 0x2D, 0x02, 0x00, 0x01, 0x06, 0x14, 0x25, 0x01, 0x01, 0x15, 0x06, + 0x02, 0x46, 0x28, 0x01, 0x04, 0x0E, 0x02, 0x00, 0x01, 0x1F, 0x15, 0x25, + 0x01, 0x1F, 0x11, 0x06, 0x02, 0x47, 0x28, 0x09, 0x00, 0x00, 0x25, 0x05, + 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0xB3, 0x00, 0x01, 0xAD, 0x25, 0x05, + 0x05, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0x01, 0x03, 0x00, 0x9F, 0x25, + 0x01, 0x83, 0xFF, 0x7E, 0x11, 0x06, 0x16, 0x24, 0x25, 0x06, 0x10, 0xA0, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, - 0x00, 0x04, 0x6D, 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, - 0x37, 0x01, 0x7F, 0x00, 0x00, 0xBA, 0x01, 0x08, 0x0E, 0x3B, 0xBA, 0x34, - 0x09, 0x00, 0x00, 0xBA, 0x3B, 0xBA, 0x01, 0x08, 0x0E, 0x34, 0x09, 0x00, - 0x00, 0x25, 0x05, 0x02, 0x4F, 0x28, 0x41, 0xBB, 0x00, 0x00, 0x32, 0x25, - 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x24, 0x19, 0x04, 0x74, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, - 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0xC3, - 0x24, 0x00, 0x00, 0x25, 0x06, 0x07, 0xC4, 0x25, 0x06, 0x01, 0x19, 0x04, - 0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B, 0x42, 0x00, 0x00, 0x01, - 0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00, 0x00, 0x01, 0x82, 0x22, - 0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x01, 0x03, 0x33, 0x01, 0x03, - 0x33, 0x00, 0x00, 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFD, 0x5F, - 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, - 0x01, 0x83, 0xBF, 0x7F, 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x01, - 0x83, 0xFF, 0x7F, 0x15, 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 + 0x00, 0x04, 0x6D, 0x04, 0x1B, 0x25, 0x05, 0x05, 0x24, 0xC2, 0x01, 0x00, + 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x25, 0x06, 0x0B, 0x9F, 0x25, 0x05, + 0x05, 0x24, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x6D, 0x24, 0x02, 0x00, 0x25, + 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, 0xAD, 0x01, + 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xA1, 0x25, 0x05, 0x05, 0x24, 0xC2, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, 0x24, 0x02, + 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, 0x00, 0x01, + 0xAD, 0x01, 0x01, 0x03, 0x00, 0x25, 0x06, 0x10, 0xBA, 0x25, 0x05, 0x05, + 0x24, 0xC2, 0x01, 0x00, 0x00, 0x02, 0x00, 0x84, 0x03, 0x00, 0x04, 0x6D, + 0x24, 0x02, 0x00, 0x25, 0x05, 0x01, 0x00, 0x41, 0x67, 0x37, 0x01, 0x7F, + 0x00, 0x00, 0xBA, 0x01, 0x08, 0x0E, 0x3B, 0xBA, 0x34, 0x09, 0x00, 0x00, + 0xBA, 0x3B, 0xBA, 0x01, 0x08, 0x0E, 0x34, 0x09, 0x00, 0x00, 0x25, 0x05, + 0x02, 0x4F, 0x28, 0x41, 0xBB, 0x00, 0x00, 0x32, 0x25, 0x01, 0x00, 0x13, + 0x06, 0x01, 0x00, 0x24, 0x19, 0x04, 0x74, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, + 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0xC3, 0x24, 0x00, 0x00, + 0x25, 0x06, 0x07, 0xC4, 0x25, 0x06, 0x01, 0x19, 0x04, 0x76, 0x00, 0x00, + 0x01, 0x00, 0x30, 0x31, 0x0B, 0x42, 0x00, 0x00, 0x01, 0x81, 0x70, 0x00, + 0x00, 0x01, 0x82, 0x0D, 0x00, 0x00, 0x01, 0x82, 0x22, 0x00, 0x00, 0x01, + 0x82, 0x05, 0x00, 0x00, 0x01, 0x03, 0x33, 0x01, 0x03, 0x33, 0x00, 0x00, + 0x25, 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F, 0x72, 0x06, 0x04, + 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xBF, + 0x7F, 0x72, 0x06, 0x04, 0x24, 0x01, 0x00, 0x00, 0x01, 0x83, 0xFF, 0x7F, + 0x15, 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 }; static const uint16_t t0_caddr[] PROGMEM = { @@ -852,84 +852,84 @@ static const uint16_t t0_caddr[] PROGMEM = { 341, 346, 357, - 992, - 1007, - 1011, - 1016, - 1021, - 1026, - 1031, - 1036, - 1150, - 1155, - 1167, - 1172, - 1177, - 1182, - 1186, - 1191, - 1196, - 1201, - 1206, - 1216, - 1221, - 1226, - 1238, - 1253, - 1258, - 1272, - 1294, - 1305, - 1408, - 1455, - 1488, + 986, + 1001, + 1005, + 1010, + 1015, + 1020, + 1025, + 1030, + 1144, + 1149, + 1161, + 1166, + 1171, + 1176, + 1180, + 1185, + 1190, + 1195, + 1200, + 1210, + 1215, + 1220, + 1232, + 1247, + 1252, + 1266, + 1288, + 1299, + 1402, + 1449, + 1482, + 1573, 1579, - 1585, - 1648, - 1655, - 1683, - 1711, - 1816, - 1858, - 1871, - 1883, - 1897, - 1912, - 2132, - 2146, - 2163, - 2172, - 2239, - 2295, - 2299, - 2303, - 2308, - 2356, - 2382, - 2458, - 2502, - 2513, - 2598, - 2636, - 2674, - 2684, - 2694, - 2703, - 2716, - 2720, - 2724, - 2728, - 2732, - 2736, - 2740, - 2744, - 2756, - 2764, - 2769, - 2774, - 2779, - 2784, - 2792 + 1642, + 1649, + 1677, + 1705, + 1810, + 1852, + 1865, + 1877, + 1891, + 1906, + 2126, + 2140, + 2157, + 2166, + 2233, + 2289, + 2293, + 2297, + 2302, + 2350, + 2376, + 2452, + 2496, + 2507, + 2592, + 2630, + 2668, + 2678, + 2688, + 2697, + 2710, + 2714, + 2718, + 2722, + 2726, + 2730, + 2734, + 2738, + 2750, + 2758, + 2763, + 2768, + 2773, + 2778, + 2786 }; #define T0_INTERPRETED 61 diff --git a/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 new file mode 100644 index 000000000..62a93e74c --- /dev/null +++ b/lib/lib_ssl/bearssl-esp8266/src/x509/x509_minimal.t0 @@ -0,0 +1,1570 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +preamble { + +#include "inner.h" + +/* + * Implementation Notes + * -------------------- + * + * The C code pushes the data by chunks; all decoding is done in the + * T0 code. The cert_length value is set to the certificate length when + * a new certificate is started; the T0 code picks it up as outer limit, + * and decoding functions use it to ensure that no attempt is made at + * reading past it. The T0 code also checks that once the certificate is + * decoded, there are no trailing bytes. + * + * The T0 code sets cert_length to 0 when the certificate is fully + * decoded. + * + * The C code must still perform two checks: + * + * -- If the certificate length is 0, then the T0 code will not be + * invoked at all. This invalid condition must thus be reported by the + * C code. + * + * -- When reaching the end of certificate, the C code must verify that + * the certificate length has been set to 0, thereby signaling that + * the T0 code properly decoded a certificate. + * + * Processing of a chain works in the following way: + * + * -- The error flag is set to a non-zero value when validation is + * finished. The value is either BR_ERR_X509_OK (validation is + * successful) or another non-zero error code. When a non-zero error + * code is obtained, the remaining bytes in the current certificate and + * the subsequent certificates (if any) are completely ignored. + * + * -- Each certificate is decoded in due course, with the following + * "interesting points": + * + * -- Start of the TBS: the multihash engine is reset and activated. + * + * -- Start of the issuer DN: the secondary hash engine is started, + * to process the encoded issuer DN. + * + * -- End of the issuer DN: the secondary hash engine is stopped. The + * resulting hash value is computed and then copied into the + * next_dn_hash[] buffer. + * + * -- Start of the subject DN: the secondary hash engine is started, + * to process the encoded subject DN. + * + * -- For the EE certificate only: the Common Name, if any, is matched + * against the expected server name. + * + * -- End of the subject DN: the secondary hash engine is stopped. The + * resulting hash value is computed into the pad. It is then processed: + * + * -- If this is the EE certificate, then the hash is ignored + * (except for direct trust processing, see later; the hash is + * simply left in current_dn_hash[]). + * + * -- Otherwise, the hashed subject DN is compared with the saved + * hash value (in saved_dn_hash[]). They must match. + * + * Either way, the next_dn_hash[] value is then copied into the + * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] + * contains the hash of the issuer DN for the current certificate, + * and current_dn_hash[] contains the hash of the subject DN for the + * current certificate. + * + * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown + * key types are reported at that point. + * + * -- If this is the EE certificate, then the key type is compared + * with the expected key type (initialization parameter). The public + * key data is copied to ee_pkey_data[]. The key and hashed subject + * DN are also compared with the "direct trust" keys; if the key + * and DN are matched, then validation ends with a success. + * + * -- Otherwise, the saved signature (cert_sig[]) is verified + * against the saved TBS hash (tbs_hash[]) and that freshly + * decoded public key. Failure here ends validation with an error. + * + * -- Extensions: extension values are processed in due order. + * + * -- Basic Constraints: for all certificates except EE, must be + * present, indicate a CA, and have a path length compatible with + * the chain length so far. + * + * -- Key Usage: for the EE, if present, must allow signatures + * or encryption/key exchange, as required for the cipher suite. + * For non-EE, if present, must have the "certificate sign" bit. + * + * -- Subject Alt Name: for the EE, dNSName names are matched + * against the server name. Ignored for non-EE. + * + * -- Authority Key Identifier, Subject Key Identifier, Issuer + * Alt Name, Subject Directory Attributes, CRL Distribution Points + * Freshest CRL, Authority Info Access and Subject Info Access + * extensions are always ignored: they either contain only + * informative data, or they relate to revocation processing, which + * we explicitly do not support. + * + * -- All other extensions are ignored if non-critical. If a + * critical extension other than the ones above is encountered, + * then a failure is reported. + * + * -- End of the TBS: the multihash engine is stopped. + * + * -- Signature algorithm: the signature algorithm on the + * certificate is decoded. A failure is reported if that algorithm + * is unknown. The hashed TBS corresponding to the signature hash + * function is computed and stored in tbs_hash[] (if not supported, + * then a failure is reported). The hash OID and length are stored + * in cert_sig_hash_oid and cert_sig_hash_len. + * + * -- Signature value: the signature value is copied into the + * cert_sig[] array. + * + * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is + * looked up in the trust store (CA trust anchors only); for all + * that match, the signature (cert_sig[]) is verified against the + * anchor public key (hashed TBS is in tbs_hash[]). If one of these + * signatures is valid, then validation ends with a success. + * + * -- If the chain end is reached without obtaining a validation success, + * then validation is reported as failed. + */ + +#if BR_USE_UNIX_TIME +#include +#endif + +#if BR_USE_WIN32_TIME +#include +#endif + +/* + * The T0 compiler will produce these prototypes declarations in the + * header. + * +void br_x509_minimal_init_main(void *ctx); +void br_x509_minimal_run(void *ctx); + */ + +/* see bearssl_x509.h */ +void +br_x509_minimal_init(br_x509_minimal_context *ctx, + const br_hash_class *dn_hash_impl, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + memset(ctx, 0, sizeof *ctx); + ctx->vtable = &br_x509_minimal_vtable; + ctx->dn_hash_impl = dn_hash_impl; + ctx->trust_anchors = trust_anchors; + ctx->trust_anchors_num = trust_anchors_num; +} + +static void +xm_start_chain(const br_x509_class **ctx, const char *server_name) +{ + br_x509_minimal_context *cc; + size_t u; + + cc = (br_x509_minimal_context *)(void *)ctx; + for (u = 0; u < cc->num_name_elts; u ++) { + cc->name_elts[u].status = 0; + cc->name_elts[u].buf[0] = 0; + } + memset(&cc->pkey, 0, sizeof cc->pkey); + cc->num_certs = 0; + cc->err = 0; + cc->cpu.dp = cc->dp_stack; + cc->cpu.rp = cc->rp_stack; + br_x509_minimal_init_main(&cc->cpu); + if (server_name == NULL || *server_name == 0) { + cc->server_name = NULL; + } else { + cc->server_name = server_name; + } +} + +static void +xm_start_cert(const br_x509_class **ctx, uint32_t length) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + if (length == 0) { + cc->err = BR_ERR_X509_TRUNCATED; + return; + } + cc->cert_length = length; +} + +static void +xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + cc->hbuf = buf; + cc->hlen = len; + br_x509_minimal_run(&cc->cpu); +} + +static void +xm_end_cert(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0 && cc->cert_length != 0) { + cc->err = BR_ERR_X509_TRUNCATED; + } + cc->num_certs ++; +} + +static unsigned +xm_end_chain(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0) { + if (cc->num_certs == 0) { + cc->err = BR_ERR_X509_EMPTY_CHAIN; + } else { + cc->err = BR_ERR_X509_NOT_TRUSTED; + } + } else if (cc->err == BR_ERR_X509_OK) { + return 0; + } + return (unsigned)cc->err; +} + +static const br_x509_pkey * +xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == BR_ERR_X509_OK + || cc->err == BR_ERR_X509_NOT_TRUSTED) + { + if (usages != NULL) { + *usages = cc->key_usages; + } + return &((br_x509_minimal_context *)(void *)ctx)->pkey; + } else { + return NULL; + } +} + +/* see bearssl_x509.h */ +const br_x509_class br_x509_minimal_vtable PROGMEM = { + sizeof(br_x509_minimal_context), + xm_start_chain, + xm_start_cert, + xm_append, + xm_end_cert, + xm_end_chain, + xm_get_pkey +}; + +#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) +#define CONTEXT_NAME br_x509_minimal_context + +#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) +#define dnhash_len ((ctx->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) + +/* + * Hash a DN (from a trust anchor) into the provided buffer. This uses the + * DN hash implementation and context structure from the X.509 engine + * context. + */ +static void +hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, + unsigned char *out) +{ + ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); + ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); + ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); +} + +/* + * Compare two big integers for equality. The integers use unsigned big-endian + * encoding; extra leading bytes (of value 0) are allowed. + */ +static int +eqbigint(const unsigned char *b1, size_t len1, + const unsigned char *b2, size_t len2) +{ + while (len1 > 0 && *b1 == 0) { + b1 ++; + len1 --; + } + while (len2 > 0 && pgm_read_byte(b2) == 0) { + b2 ++; + len2 --; + } + if (len1 != len2) { + return 0; + } + return memcmp_P(b1, b2, len1) == 0; +} + +/* + * Compare two strings for equality, in a case-insensitive way. This + * function handles casing only for ASCII letters. + */ +static int +eqnocase(const void *s1, const void *s2, size_t len) +{ + const unsigned char *buf1, *buf2; + + buf1 = s1; + buf2 = s2; + while (len -- > 0) { + int x1, x2; + + x1 = *buf1 ++; + x2 = *buf2 ++; + if (x1 >= 'A' && x1 <= 'Z') { + x1 += 'a' - 'A'; + } + if (x2 >= 'A' && x2 <= 'Z') { + x2 += 'a' - 'A'; + } + if (x1 != x2) { + return 0; + } + } + return 1; +} + +static int verify_signature(br_x509_minimal_context *ctx, + const br_x509_pkey *pk); + +/* + * Check whether the current certificate (EE) is directly trusted against + * a single trust anchor + */ +static int check_single_direct_trust(br_x509_minimal_context *ctx, + unsigned char hashed_DN[64], + const br_x509_trust_anchor *ta) +{ + int kt; + + if (ta->flags & BR_X509_TA_CA) { + return 0; + } + if (memcmp(hashed_DN, ctx->current_dn_hash, dnhash_len)) { + return 0; + } + kt = ctx->pkey.key_type; + if ((pgm_read_byte(&ta->pkey.key_type) & 0x0F) != kt) { + return 0; + } + switch (kt) { + case BR_KEYTYPE_RSA: + if (!eqbigint(ctx->pkey.key.rsa.n, + ctx->pkey.key.rsa.nlen, + ta->pkey.key.rsa.n, + ta->pkey.key.rsa.nlen) + || !eqbigint(ctx->pkey.key.rsa.e, + ctx->pkey.key.rsa.elen, + ta->pkey.key.rsa.e, + ta->pkey.key.rsa.elen)) + { + return 0; + } + return 1; + case BR_KEYTYPE_EC: + if (ctx->pkey.key.ec.curve != ta->pkey.key.ec.curve + || ctx->pkey.key.ec.qlen != ta->pkey.key.ec.qlen + || memcmp_P(ctx->pkey.key.ec.q, + ta->pkey.key.ec.q, + ta->pkey.key.ec.qlen) != 0) + { + return 0; + } + return 1; + default: + return 0; + } + return 0; /* Should not get here */ +} + + +/* + * Check whether the current certificate (EE) is directly trusted against + * a single CA trust anchor. We use the issuer hash (in saved_dn_hash[]) + * as the CA identifier. + */ +static int check_single_trust_anchor_CA(br_x509_minimal_context *ctx, + unsigned char hashed_DN[64], + const br_x509_trust_anchor *ta) +{ + if (!(ta->flags & BR_X509_TA_CA)) { + return 0; + } + if (memcmp(hashed_DN, ctx->saved_dn_hash, dnhash_len)) { + return 0; + } + if (verify_signature(ctx, &ta->pkey) == 0) { + return 1; + } + return 0; +} + +} + + +postamble { + +/* + * Verify the signature on the certificate with the provided public key. + * This function checks the public key type with regards to the expected + * type. Returned value is either 0 on success, or a non-zero error code. + */ +static int +verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) +{ + unsigned char tmp[64]; + unsigned char tmp2[64]; + int kt; + + kt = ctx->cert_signer_key_type; + if ((pgm_read_byte(&pk->key_type) & 0x0F) != kt) { + return BR_ERR_X509_WRONG_KEY_TYPE; + } + switch (kt) { + + case BR_KEYTYPE_RSA: + if (ctx->irsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + memcpy_P(tmp2, &t0_datablock[ctx->cert_sig_hash_oid], ctx->cert_sig_hash_len); + if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, + tmp2, //&t0_datablock[ctx->cert_sig_hash_oid], + ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + case BR_KEYTYPE_EC: + if (ctx->iecdsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, + ctx->cert_sig_hash_len, &pk->key.ec, + ctx->cert_sig, ctx->cert_sig_len)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + default: + return BR_ERR_X509_UNSUPPORTED; + } +} + +} + +cc: read8-low ( -- x ) { + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, &x, 1); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } +} + +addr: cert_length +addr: num_certs + +cc: read-blob-inner ( addr len -- addr len ) { + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, CTX->hbuf, clen); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update( + &CTX->dn_hash.vtable, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); +} + +\ Compute the TBS hash, using the provided hash ID. The hash value is +\ written in the tbs_hash[] array, and the hash length is returned. If +\ the requested hash function is not supported, then 0 is returned. +cc: compute-tbs-hash ( id -- hashlen ) { + int id = T0_POPi(); + size_t len; + len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); + T0_PUSH(len); +} + +\ Push true (-1) if no server name is expected in the EE certificate. +cc: zero-server-name ( -- bool ) { + T0_PUSHi(-(CTX->server_name == NULL)); +} + +addr: key_usages +addr: cert_sig +addr: cert_sig_len +addr: cert_signer_key_type +addr: cert_sig_hash_oid +addr: cert_sig_hash_len +addr: tbs_hash +addr: min_rsa_size + +\ Start TBS hash computation. The hash functions are reinitialised. +cc: start-tbs-hash ( -- ) { + br_multihash_init(&CTX->mhash); + CTX->do_mhash = 1; +} + +\ Stop TBS hash computation. +cc: stop-tbs-hash ( -- ) { + CTX->do_mhash = 0; +} + +\ Start DN hash computation. +cc: start-dn-hash ( -- ) { + CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); + CTX->do_dn_hash = 1; +} + +\ Terminate DN hash computation and write the DN hash into the +\ current_dn_hash buffer. +cc: compute-dn-hash ( -- ) { + CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); + CTX->do_dn_hash = 0; +} + +\ Get the length of hash values obtained with the DN hasher. +cc: dn-hash-length ( -- len ) { + T0_PUSH(DNHASH_LEN); +} + +\ Copy data between two areas in the context. +cc: blobcopy ( addr-dst addr-src len -- ) { + size_t len = T0_POP(); + unsigned char *src = (unsigned char *)CTX + T0_POP(); + unsigned char *dst = (unsigned char *)CTX + T0_POP(); + memcpy(dst, src, len); +} + +addr: current_dn_hash +addr: next_dn_hash +addr: saved_dn_hash + +\ Read a DN, hashing it into current_dn_hash. The DN contents are not +\ inspected (only the outer tag, for SEQUENCE, is checked). +: read-DN ( lim -- lim ) + start-dn-hash + read-sequence-open skip-close-elt + compute-dn-hash ; + +cc: offset-name-element ( san -- n ) { + unsigned san = T0_POP(); + size_t u; + + for (u = 0; u < CTX->num_name_elts; u ++) { + if (CTX->name_elts[u].status == 0) { + const unsigned char *oid; + size_t len, off; + + oid = CTX->name_elts[u].oid; + if (san) { + if (oid[0] != 0 || oid[1] != 0) { + continue; + } + off = 2; + } else { + off = 0; + } + len = oid[off]; + if (len != 0 && len == CTX->pad[0] + && memcmp(oid + off + 1, + CTX->pad + 1, len) == 0) + { + T0_PUSH(u); + T0_RET(); + } + } + } + T0_PUSHi(-1); +} + +cc: copy-name-element ( bool offbuf -- ) { + size_t len; + int32_t off = T0_POPi(); + int ok = T0_POPi(); + + if (off >= 0) { + br_name_element *ne = &CTX->name_elts[off]; + + if (ok) { + len = CTX->pad[0]; + if (len < ne->len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + } else { + ne->status = -1; + } + } +} + +cc: copy-name-SAN ( bool tag -- ) { + unsigned tag = T0_POP(); + unsigned ok = T0_POP(); + size_t u, len; + + len = CTX->pad[0]; + for (u = 0; u < CTX->num_name_elts; u ++) { + br_name_element *ne; + + ne = &CTX->name_elts[u]; + if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { + if (ok && ne->len > len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + break; + } + } +} + +\ Read a value, decoding string types. If the string type is recognised +\ and the value could be converted to UTF-8 into the pad, then true (-1) +\ is returned; in all other cases, false (0) is returned. Either way, the +\ object is consumed. +: read-string ( lim -- lim bool ) + read-tag case + \ UTF8String + 12 of check-primitive read-value-UTF8 endof + \ NumericString + 18 of check-primitive read-value-latin1 endof + \ PrintableString + 19 of check-primitive read-value-latin1 endof + \ TeletexString + 20 of check-primitive read-value-latin1 endof + \ IA5String + 22 of check-primitive read-value-latin1 endof + \ BMPString + 30 of check-primitive read-value-UTF16 endof + 2drop read-length-skip 0 0 + endcase ; + +\ Read a DN for the EE. The normalized DN hash is computed and stored in the +\ current_dn_hash. +\ Name elements are gathered. Also, the Common Name is matched against the +\ intended server name. +\ Returned value is true (-1) if the CN matches the intended server name, +\ false (0) otherwise. +: read-DN-EE ( lim -- lim bool ) + \ Flag will be set to true if there is a CN and it matches the + \ intended server name. + 0 { eename-matches } + + \ Activate DN hashing. + start-dn-hash + + \ Parse the DN structure: it is a SEQUENCE of SET of + \ AttributeTypeAndValue. Each AttributeTypeAndValue is a + \ SEQUENCE { OBJECT IDENTIFIER, ANY }. + read-sequence-open + begin + dup while + + read-tag 0x11 check-tag-constructed read-length-open-elt + dup ifnot ERR_X509_BAD_DN fail then + begin + dup while + + read-sequence-open + + \ Read the OID. If the OID could not be read (too + \ long) then the first pad byte will be 0. + read-OID drop + + \ If it is the Common Name then we'll need to + \ match it against the intended server name (if + \ applicable). + id-at-commonName eqOID { isCN } + + \ Get offset for reception buffer for that element + \ (or -1). + 0 offset-name-element { offbuf } + + \ Try to read the value as a string. + read-string + + \ If the value could be decoded as a string, + \ copy it and/or match it, as appropriate. + dup isCN and if + match-server-name if + -1 >eename-matches + then + then + offbuf copy-name-element + + \ Close the SEQUENCE + close-elt + + repeat + close-elt + repeat + close-elt + + \ Compute DN hash and deactivate DN hashing. + compute-dn-hash + + \ Return the CN match flag. + eename-matches ; + +\ Get the validation date and time from the context or system. +cc: get-system-date ( -- days seconds ) { + if (CTX->days == 0 && CTX->seconds == 0) { +#if BR_USE_UNIX_TIME + time_t x = time(NULL); + + T0_PUSH((uint32_t)(x / 86400) + 719528); + T0_PUSH((uint32_t)(x % 86400)); +#elif BR_USE_WIN32_TIME + FILETIME ft; + uint64_t x; + + GetSystemTimeAsFileTime(&ft); + x = ((uint64_t)ft.dwHighDateTime << 32) + + (uint64_t)ft.dwLowDateTime; + x = (x / 10000000); + T0_PUSH((uint32_t)(x / 86400) + 584754); + T0_PUSH((uint32_t)(x % 86400)); +#else + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); +#endif + } else { + T0_PUSH(CTX->days); + T0_PUSH(CTX->seconds); + } +} + +\ Compare two dates (days+seconds) together. +: before ( days1 seconds1 days2 seconds2 -- bool ) + { d1 s1 d2 s2 } + d1 d2 = if s1 s2 < else d1 d2 < then ; + +: after ( days1 seconds1 days2 seconds2 -- bool ) + swap2 before ; + +\ Swap the top two elements with the two elements immediately below. +: swap2 ( a b c d -- c d a b ) + 3 roll 3 roll ; + +\ Match the name in the pad with the expected server name. Returned value +\ is true (-1) on match, false (0) otherwise. If there is no expected +\ server name, then 0 is returned. +\ Match conditions: either an exact match (case insensitive), or a +\ wildcard match, if the found name starts with "*.". We only match a +\ starting wildcard, and only against a complete DN name component. +cc: match-server-name ( -- bool ) { + size_t n1, n2; + + if (CTX->server_name == NULL) { + T0_PUSH(0); + T0_RET(); + } + n1 = strlen(CTX->server_name); + n2 = CTX->pad[0]; + if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { + T0_PUSHi(-1); + T0_RET(); + } + if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { + size_t u; + + u = 0; + while (u < n1 && CTX->server_name[u] != '.') { + u ++; + } + u ++; + n1 -= u; + if ((n2 - 2) == n1 + && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) + { + T0_PUSHi(-1); + T0_RET(); + } + } + T0_PUSH(0); +} + +\ Get the address and length for the pkey_data buffer. +: addr-len-pkey_data ( -- addr len ) + CX 0 8191 { offsetof(br_x509_minimal_context, pkey_data) } + CX 0 8191 { BR_X509_BUFSIZE_KEY } ; + +\ Copy the EE public key to the permanent buffer (RSA). +cc: copy-ee-rsa-pkey ( nlen elen -- ) { + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->ee_pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; +} + +\ Copy the EE public key to the permanent buffer (EC). +cc: copy-ee-ec-pkey ( curve qlen -- ) { + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->ee_pkey_data; + CTX->pkey.key.ec.qlen = qlen; +} + + +\ Check whether the current certificate (EE) is directly trusted. +cc: check-direct-trust ( -- ) { + size_t u; + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + ta = &CTX->trust_anchors[u]; + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (check_single_direct_trust(CTX, hashed_DN, ta)) { + /* + * Direct trust match! + */ + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } + if (CTX->err != BR_ERR_X509_OK && CTX->trust_anchor_dynamic) { + ta = CTX->trust_anchor_dynamic(CTX->trust_anchor_dynamic_ctx, CTX->current_dn_hash, DNHASH_LEN); + if (ta) { + memcpy(hashed_DN, ta->dn.data, DNHASH_LEN); + int ret = check_single_direct_trust(CTX, hashed_DN, ta); + if (CTX->trust_anchor_dynamic_free) { + CTX->trust_anchor_dynamic_free(CTX->trust_anchor_dynamic_ctx, ta); + } + if (ret) { + /* + * Direct trust match! + */ + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } + } +} + +\ Check the signature on the certificate with regards to all trusted CA. +\ We use the issuer hash (in saved_dn_hash[]) as CA identifier. +cc: check-trust-anchor-CA ( -- ) { + size_t u; + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + ta = &CTX->trust_anchors[u]; + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (check_single_trust_anchor_CA(CTX, hashed_DN, ta)) { + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } + if (CTX->err != BR_ERR_X509_OK && CTX->trust_anchor_dynamic) { + ta = CTX->trust_anchor_dynamic(CTX->trust_anchor_dynamic_ctx, CTX->saved_dn_hash, DNHASH_LEN); + if (ta) { + memcpy(hashed_DN, ta->dn.data, DNHASH_LEN); + int ret; + ret = check_single_trust_anchor_CA(CTX, hashed_DN, ta); + if (CTX->trust_anchor_dynamic_free) { + CTX->trust_anchor_dynamic_free(CTX->trust_anchor_dynamic_ctx, ta); + } + if (ret) { + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } + + } +} + +\ Verify RSA signature. This uses the public key that was just decoded +\ into CTX->pkey_data; the modulus and exponent length are provided as +\ parameters. The resulting hash value is compared with the one in +\ tbs_hash. Returned value is 0 on success, or a non-zero error code. +cc: do-rsa-vrfy ( nlen elen -- err ) { + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_RSA; + pk.key.rsa.n = CTX->pkey_data; + pk.key.rsa.nlen = nlen; + pk.key.rsa.e = CTX->pkey_data + nlen; + pk.key.rsa.elen = elen; + T0_PUSH(verify_signature(CTX, &pk)); +} + +\ Verify ECDSA signature. This uses the public key that was just decoded +\ into CTX->pkey_dayta; the curve ID and public point length are provided +\ as parameters. The hash value in tbs_hash is used. Returned value is 0 +\ on success, or non-zero error code. +cc: do-ecdsa-vrfy ( curve qlen -- err ) { + size_t qlen = T0_POP(); + int curve = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_EC; + pk.key.ec.curve = curve; + pk.key.ec.q = CTX->pkey_data; + pk.key.ec.qlen = qlen; + T0_PUSH(verify_signature(CTX, &pk)); +} + +cc: print-bytes ( addr len -- ) { + extern int printf(const char *fmt, ...); + size_t len = T0_POP(); + unsigned char *buf = (unsigned char *)CTX + T0_POP(); + size_t u; + + for (u = 0; u < len; u ++) { + printf("%02X", buf[u]); + } +} + +cc: printOID ( -- ) { + extern int printf(const char *fmt, ...); + size_t u, len; + + len = CTX->pad[0]; + if (len == 0) { + printf("*"); + T0_RET(); + } + printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40); + u = 2; + while (u <= len) { + unsigned long ul; + + ul = 0; + for (;;) { + int x; + + if (u > len) { + printf("BAD"); + T0_RET(); + } + x = CTX->pad[u ++]; + ul = (ul << 7) + (x & 0x7F); + if (!(x & 0x80)) { + break; + } + } + printf(".%lu", ul); + } +} + +\ Extensions with specific processing. +OID: basicConstraints 2.5.29.19 +OID: keyUsage 2.5.29.15 +OID: subjectAltName 2.5.29.17 +OID: certificatePolicies 2.5.29.32 + +\ Policy qualifier "pointer to CPS" +OID: id-qt-cps 1.3.6.1.5.5.7.2.1 + +\ Extensions which are ignored when encountered, even if critical. +OID: authorityKeyIdentifier 2.5.29.35 +OID: subjectKeyIdentifier 2.5.29.14 +OID: issuerAltName 2.5.29.18 +OID: subjectDirectoryAttributes 2.5.29.9 +OID: crlDistributionPoints 2.5.29.31 +OID: freshestCRL 2.5.29.46 +OID: authorityInfoAccess 1.3.6.1.5.5.7.1.1 +OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 + +\ Process a Basic Constraints extension. This should be called only if +\ the certificate is not the EE. We check that the extension contains +\ the "CA" flag, and that the path length, if specified, is compatible +\ with the current chain length. +: process-basicConstraints ( lim -- lim ) + read-sequence-open + read-tag-or-end + dup 0x01 = if + read-boolean ifnot ERR_X509_NOT_CA fail then + read-tag-or-end + else + ERR_X509_NOT_CA fail + then + dup 0x02 = if + drop check-primitive read-small-int-value + addr-num_certs get32 1- < if ERR_X509_NOT_CA fail then + read-tag-or-end + then + -1 <> if ERR_X509_UNEXPECTED fail then + drop + close-elt + ; + +\ Process a Key Usage extension. +\ For the EE certificate: +\ -- if the key usage contains keyEncipherment (2), dataEncipherment (3) +\ or keyAgreement (4), then the "key exchange" usage is allowed; +\ -- if the key usage contains digitalSignature (0) or nonRepudiation (1), +\ then the "signature" usage is allowed. +\ For CA certificates, the extension must contain keyCertSign (5). +: process-keyUsage ( lim ee -- lim ) + { ee } + + \ Read tag for the BIT STRING and open it. + read-tag 0x03 check-tag-primitive + read-length-open-elt + \ First byte indicates number of ignored bits in the last byte. It + \ must be between 0 and 7. + read8 { ign } + ign 7 > if ERR_X509_UNEXPECTED fail then + \ Depending on length, we have either 0, 1 or more bytes to read. + dup case + 0 of ERR_X509_FORBIDDEN_KEY_USAGE fail endof + 1 of read8 ign >> ign << endof + drop read8 0 + endcase + + \ Check bits. + ee if + \ EE: get usages. + 0 + over 0x38 and if 0x10 or then + swap 0xC0 and if 0x20 or then + addr-key_usages set8 + else + \ Not EE: keyCertSign must be set. + 0x04 and ifnot ERR_X509_FORBIDDEN_KEY_USAGE fail then + then + + \ We don't care about subsequent bytes. + skip-close-elt ; + +\ Process a Certificate Policies extension. +\ +\ Since we don't actually support full policies processing, this function +\ only checks that the extension contents can be safely ignored. Indeed, +\ we don't validate against a specific set of policies (in RFC 5280 +\ terminology, user-initial-policy-set only contains the special value +\ any-policy). Moreover, we don't support policy constraints (if a +\ critical Policy Constraints extension is encountered, the validation +\ will fail). Therefore, we can safely ignore the contents of this +\ extension, except if it is critical AND one of the policy OID has a +\ qualifier which is distinct from id-qt-cps (because id-qt-cps is +\ specially designated by RFC 5280 has having no mandated action). +\ +\ This function is called only if the extension is critical. +: process-certPolicies ( lim -- lim ) + \ Extension value is a SEQUENCE OF PolicyInformation. + read-sequence-open + begin dup while + \ PolicyInformation ::= SEQUENCE { + \ policyIdentifier OBJECT IDENTIFIER, + \ policyQualifiers SEQUENCE OF PolicyQualifierInfo OPTIONAL + \ } + read-sequence-open + read-OID drop + dup if + read-sequence-open + begin dup while + \ PolicyQualifierInfo ::= SEQUENCE { + \ policyQualifierId OBJECT IDENTIFIER, + \ qualifier ANY + \ } + read-sequence-open + read-OID drop id-qt-cps eqOID ifnot + ERR_X509_CRITICAL_EXTENSION fail + then + skip-close-elt + repeat + close-elt + then + close-elt + repeat + close-elt ; + +\ Process a Subject Alt Name extension. Returned value is a boolean set +\ to true if the expected server name was matched against a dNSName in +\ the extension. +: process-SAN ( lim -- lim bool ) + 0 { m } + read-sequence-open + begin dup while + \ Read the tag. If the tag is context-0, then parse an + \ 'otherName'. If the tag is context-2, then parse a + \ dNSName. If the tag is context-1 or context-6, + \ parse + read-tag case + \ OtherName + 0x20 of + \ OtherName ::= SEQUENCE { + \ type-id OBJECT IDENTIFIER, + \ value [0] EXPLICIT ANY + \ } + check-constructed read-length-open-elt + read-OID drop + -1 offset-name-element { offbuf } + read-tag 0x20 check-tag-constructed + read-length-open-elt + read-string offbuf copy-name-element + close-elt + close-elt + endof + \ rfc822Name (IA5String) + 0x21 of + check-primitive + read-value-UTF8 1 copy-name-SAN + endof + \ dNSName (IA5String) + 0x22 of + check-primitive + read-value-UTF8 + dup if match-server-name m or >m then + 2 copy-name-SAN + endof + \ uniformResourceIdentifier (IA5String) + 0x26 of + check-primitive + read-value-UTF8 6 copy-name-SAN + endof + 2drop read-length-skip 0 + endcase + + \ We check only names of type dNSName; they use IA5String, + \ which is basically ASCII. + \ read-tag 0x22 = if + \ check-primitive + \ read-small-value drop + \ match-server-name m or >m + \ else + \ drop read-length-skip + \ then + repeat + close-elt + m ; + +\ Decode a certificate. The "ee" boolean must be true for the EE. +: decode-certificate ( ee -- ) + { ee } + + \ Obtain the total certificate length. + addr-cert_length get32 + + \ Open the outer SEQUENCE. + read-sequence-open + + \ TBS + \ Activate hashing. + start-tbs-hash + read-sequence-open + + \ First element may be an explicit version. We accept only + \ versions 0 to 2 (certificates v1 to v3). + read-tag dup 0x20 = if + drop check-constructed read-length-open-elt + read-tag + 0x02 check-tag-primitive + read-small-int-value + 2 > if ERR_X509_UNSUPPORTED fail then + close-elt + read-tag + then + + \ Serial number. We just check that the tag is correct. + 0x02 check-tag-primitive + read-length-skip + + \ Signature algorithm. This structure is redundant with the one + \ on the outside; we just skip it. + read-sequence-open skip-close-elt + + \ Issuer name: hashed, then copied into next_dn_hash[]. + read-DN + addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy + + \ Validity dates. + read-sequence-open + read-date get-system-date after if ERR_X509_EXPIRED fail then + read-date get-system-date before if ERR_X509_EXPIRED fail then + close-elt + + \ Subject name. + ee if + \ For the EE, we must check whether the Common Name, if + \ any, matches the expected server name. + read-DN-EE { eename } + else + \ For a non-EE certificate, the hashed subject DN must match + \ the saved hashed issuer DN from the previous certificate. + read-DN + addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob + ifnot ERR_X509_DN_MISMATCH fail then + then + \ Move the hashed issuer DN for this certificate into the + \ saved_dn_hash[] array. + addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy + + \ Public Key. + read-sequence-open + \ Algorithm Identifier. Right now we are only interested in the + \ OID, since we only support RSA keys. + read-sequence-open + read-OID ifnot ERR_X509_UNSUPPORTED fail then + { ; pkey-type } + choice + \ RSA public key. + rsaEncryption eqOID uf + skip-close-elt + \ Public key itself: the BIT STRING contains bytes + \ (no partial byte) and these bytes encode the + \ actual value. + read-bits-open + \ RSA public key is a SEQUENCE of two + \ INTEGER. We get both INTEGER values into + \ the pkey_data[] buffer, if they fit. + read-sequence-open + addr-len-pkey_data + read-integer { nlen } + addr-len-pkey_data swap nlen + swap nlen - + read-integer { elen } + close-elt + + \ Check that the public key fits our minimal + \ size requirements. Note that the integer + \ decoder already skipped the leading bytes + \ of value 0, so we are working on the true + \ modulus length here. + addr-min_rsa_size get16 128 + nlen > if + ERR_X509_WEAK_PUBLIC_KEY fail + then + close-elt + KEYTYPE_RSA >pkey-type + enduf + + \ EC public key. + id-ecPublicKey eqOID uf + \ We support only named curves, for which the + \ "parameters" field in the AlgorithmIdentifier + \ field should be an OID. + read-OID ifnot ERR_X509_UNSUPPORTED fail then + choice + ansix9p256r1 eqOID uf 23 enduf + ansix9p384r1 eqOID uf 24 enduf + ansix9p521r1 eqOID uf 25 enduf + ERR_X509_UNSUPPORTED fail + endchoice + { curve } + close-elt + read-bits-open + dup { qlen } + dup addr-len-pkey_data rot < if + ERR_X509_LIMIT_EXCEEDED fail + then + read-blob + KEYTYPE_EC >pkey-type + enduf + + \ Not a recognised public key type. + ERR_X509_UNSUPPORTED fail + endchoice + close-elt + + \ Process public key. + ee if + \ For the EE certificate, copy the key data to the + \ relevant buffer. + pkey-type case + KEYTYPE_RSA of nlen elen copy-ee-rsa-pkey endof + KEYTYPE_EC of curve qlen copy-ee-ec-pkey endof + ERR_X509_UNSUPPORTED fail + endcase + else + \ Verify signature on previous certificate. We invoke + \ the RSA implementation. + pkey-type case + KEYTYPE_RSA of nlen elen do-rsa-vrfy endof + KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof + ERR_X509_UNSUPPORTED fail + endcase + dup if fail then + drop + then + + \ This flag will be set to true if the Basic Constraints extension + \ is encountered. + 0 { seenBC } + + \ Skip issuerUniqueID and subjectUniqueID, and process extensions + \ if present. Extensions are an explicit context tag of value 3 + \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE + \ with an OID, an optional boolean, and a value; the value is + \ an OCTET STRING. + read-tag-or-end + 0x21 iftag-skip + 0x22 iftag-skip + dup 0x23 = if + drop + check-constructed read-length-open-elt + read-sequence-open + begin dup while + 0 { critical } + read-sequence-open + read-OID drop + read-tag dup 0x01 = if + read-boolean >critical + read-tag + then + 0x04 check-tag-primitive read-length-open-elt + choice + \ Extensions with specific processing. + basicConstraints eqOID uf + ee if + skip-remaining + else + process-basicConstraints + -1 >seenBC + then + enduf + keyUsage eqOID uf + ee process-keyUsage + enduf + subjectAltName eqOID uf + ee if + 0 >eename + process-SAN >eename + else + skip-remaining + then + enduf + + \ We don't implement full processing of + \ policies. The call below mostly checks + \ that the contents of the Certificate + \ Policies extension can be safely ignored. + certificatePolicies eqOID uf + critical if + process-certPolicies + else + skip-remaining + then + enduf + + \ Extensions which are always ignored, + \ even if critical. + authorityKeyIdentifier eqOID uf + skip-remaining + enduf + subjectKeyIdentifier eqOID uf + skip-remaining + enduf + issuerAltName eqOID uf + skip-remaining + enduf + subjectDirectoryAttributes eqOID uf + skip-remaining + enduf + crlDistributionPoints eqOID uf + skip-remaining + enduf + freshestCRL eqOID uf + skip-remaining + enduf + authorityInfoAccess eqOID uf + skip-remaining + enduf + subjectInfoAccess eqOID uf + skip-remaining + enduf + + \ Unrecognized extensions trigger a failure + \ if critical; otherwise, they are just + \ ignored. + \ critical if + \ ERR_X509_CRITICAL_EXTENSION fail + \ then + skip-remaining + endchoice + close-elt + close-elt + repeat + close-elt + close-elt + else + -1 = ifnot ERR_X509_UNEXPECTED fail then + drop + then + + close-elt + \ Terminate hashing. + stop-tbs-hash + + \ For the EE certificate, verify that the intended server name + \ was matched. + ee if + eename zero-server-name or ifnot + ERR_X509_BAD_SERVER_NAME fail + then + then + + \ If this is the EE certificate, then direct trust may apply. + \ Note: we do this at this point, not immediately after decoding + \ the public key, because even in case of direct trust we still + \ want to check the server name with regards to the SAN extension. + \ However, we want to check direct trust before trying to decode + \ the signature algorithm, because it should work even if that + \ algorithm is not supported. + ee if check-direct-trust then + + \ Non-EE certificates MUST have a Basic Constraints extension + \ (that marks them as being CA). + ee seenBC or ifnot ERR_X509_NOT_CA fail then + + \ signature algorithm + read-tag check-sequence read-length-open-elt + \ Read and understand the OID. Right now, we support only + \ RSA with PKCS#1 v1.5 padding, and hash functions SHA-1, + \ SHA-224, SHA-256, SHA-384 and SHA-512. We purposely do NOT + \ support MD5 here. + \ TODO: add support for RSA/PSS + read-OID if + \ Based on the signature OID, we get: + \ -- the signing key type + \ -- the hash function numeric identifier + \ -- the hash function OID + choice + sha1WithRSAEncryption eqOID + uf 2 KEYTYPE_RSA id-sha1 enduf + sha224WithRSAEncryption eqOID + uf 3 KEYTYPE_RSA id-sha224 enduf + sha256WithRSAEncryption eqOID + uf 4 KEYTYPE_RSA id-sha256 enduf + sha384WithRSAEncryption eqOID + uf 5 KEYTYPE_RSA id-sha384 enduf + sha512WithRSAEncryption eqOID + uf 6 KEYTYPE_RSA id-sha512 enduf + + ecdsa-with-SHA1 eqOID + uf 2 KEYTYPE_EC id-sha1 enduf + ecdsa-with-SHA224 eqOID + uf 3 KEYTYPE_EC id-sha224 enduf + ecdsa-with-SHA256 eqOID + uf 4 KEYTYPE_EC id-sha256 enduf + ecdsa-with-SHA384 eqOID + uf 5 KEYTYPE_EC id-sha384 enduf + ecdsa-with-SHA512 eqOID + uf 6 KEYTYPE_EC id-sha512 enduf + ERR_X509_UNSUPPORTED fail + endchoice + addr-cert_sig_hash_oid set16 + addr-cert_signer_key_type set8 + + \ Compute the TBS hash into tbs_hash. + compute-tbs-hash + dup ifnot ERR_X509_UNSUPPORTED fail then + addr-cert_sig_hash_len set8 + else + ERR_X509_UNSUPPORTED fail + then + \ We ignore the parameters, whether they are present or not, + \ because we got all the information from the OID. + skip-close-elt + + \ signature value + read-bits-open + dup CX 0 8191 { BR_X509_BUFSIZE_SIG } > if + ERR_X509_LIMIT_EXCEEDED fail + then + dup addr-cert_sig_len set16 + addr-cert_sig read-blob + + \ Close the outer SEQUENCE. + close-elt + + \ Close the advertised total certificate length. This checks that + \ there is no trailing garbage after the certificate. + close-elt + + \ Flag the certificate as fully processed. + 0 addr-cert_length set32 + + \ Check whether the issuer for the current certificate is known + \ as a trusted CA; in which case, verify the signature. + check-trust-anchor-CA ; + +: main + \ Unless restricted by a Key Usage extension, all usages are + \ deemed allowed. + 0x30 addr-key_usages set8 + -1 decode-certificate + co + begin + 0 decode-certificate co + again + ;