diff options
Diffstat (limited to 'Libraries/LibTLS')
-rw-r--r-- | Libraries/LibTLS/TLSv12.cpp | 489 | ||||
-rw-r--r-- | Libraries/LibTLS/TLSv12.h | 93 |
2 files changed, 312 insertions, 270 deletions
diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index 07eb74b362..f05a9865e7 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -60,137 +60,121 @@ namespace TLS { // "for now" q&d implementation of ASN1 namespace { - static bool _asn1_is_field_present(const u32* fields, const u32* prefix) - { - size_t i = 0; - while (prefix[i]) { - if (fields[i] != prefix[i]) - return false; - ++i; - } - return true; +static bool _asn1_is_field_present(const u32* fields, const u32* prefix) +{ + size_t i = 0; + while (prefix[i]) { + if (fields[i] != prefix[i]) + return false; + ++i; } + return true; +} - static bool _asn1_is_oid(const u8* oid, const u8* compare, size_t length = 3) - { - size_t i = 0; - while (oid[i] && i < length) { - if (oid[i] != compare[i]) - return false; - ++i; - } - return true; +static bool _asn1_is_oid(const u8* oid, const u8* compare, size_t length = 3) +{ + size_t i = 0; + while (oid[i] && i < length) { + if (oid[i] != compare[i]) + return false; + ++i; } + return true; +} - static void _set_algorithm(u32&, const u8* value, size_t length) - { - if (length != 9) { - dbg() << "unsupported algorithm " << value; - } - - dbg() << "FIXME: Set algorithm"; +static void _set_algorithm(u32&, const u8* value, size_t length) +{ + if (length != 9) { + dbg() << "unsupported algorithm " << value; } - static size_t _get_asn1_length(const u8* buffer, size_t length, size_t& octets) - { - octets = 0; - if (length < 1) - return 0; + dbg() << "FIXME: Set algorithm"; +} - u8 size = buffer[0]; - if (size & 0x80) { - octets = size & 0x7f; - if (octets > length - 1) { - return 0; - } - auto reference_octets = octets; - if (octets > 4) - reference_octets = 4; - size_t long_size = 0, coeff = 1; - for (auto i = reference_octets; i > 0; --i) { - long_size += buffer[i] * coeff; - coeff *= 0x100; - } - ++octets; - return long_size; +static size_t _get_asn1_length(const u8* buffer, size_t length, size_t& octets) +{ + octets = 0; + if (length < 1) + return 0; + + u8 size = buffer[0]; + if (size & 0x80) { + octets = size & 0x7f; + if (octets > length - 1) { + return 0; + } + auto reference_octets = octets; + if (octets > 4) + reference_octets = 4; + size_t long_size = 0, coeff = 1; + for (auto i = reference_octets; i > 0; --i) { + long_size += buffer[i] * coeff; + coeff *= 0x100; } ++octets; - return size; + return long_size; } + ++octets; + return size; +} - static ssize_t _parse_asn1(Context& context, Certificate& cert, const u8* buffer, size_t size, int level, u32* fields, u8* has_key, int client_cert, u8* root_oid, OIDChain* chain) - { - OIDChain local_chain; - local_chain.root = chain; - size_t position = 0; - - // parse DER...again - size_t index = 0; - u8 oid[16] { 0 }; - - local_chain.oid = oid; - if (has_key) - *has_key = 0; - - u8 local_has_key = 0; - const u8* cert_data = nullptr; - size_t cert_length = 0; - while (position < size) { - size_t start_position = position; - if (size - position < 2) { - dbg() << "not enough data for certificate size"; - return (i8)Error::NeedMoreData; - } - u8 first = buffer[position++]; - u8 type = first & 0x1f; - u8 constructed = first & 0x20; - size_t octets = 0; - u32 temp; - index++; +static ssize_t _parse_asn1(Context& context, Certificate& cert, const u8* buffer, size_t size, int level, u32* fields, u8* has_key, int client_cert, u8* root_oid, OIDChain* chain) +{ + OIDChain local_chain; + local_chain.root = chain; + size_t position = 0; - if (level <= 0xff) - fields[level - 1] = index; + // parse DER...again + size_t index = 0; + u8 oid[16] { 0 }; + + local_chain.oid = oid; + if (has_key) + *has_key = 0; + + u8 local_has_key = 0; + const u8* cert_data = nullptr; + size_t cert_length = 0; + while (position < size) { + size_t start_position = position; + if (size - position < 2) { + dbg() << "not enough data for certificate size"; + return (i8)Error::NeedMoreData; + } + u8 first = buffer[position++]; + u8 type = first & 0x1f; + u8 constructed = first & 0x20; + size_t octets = 0; + u32 temp; + index++; - size_t length = _get_asn1_length((const u8*)&buffer[position], size - position, octets); + if (level <= 0xff) + fields[level - 1] = index; - if (octets > 4 || octets > size - position) { - dbg() << "could not read the certificate"; - return position; - } + size_t length = _get_asn1_length((const u8*)&buffer[position], size - position, octets); - position += octets; - if (size - position < length) { - dbg() << "not enough data for sequence"; - return (i8)Error::NeedMoreData; - } + if (octets > 4 || octets > size - position) { + dbg() << "could not read the certificate"; + return position; + } - if (length && constructed) { - switch (type) { - case 0x03: - break; - case 0x10: - if (level == 2 && index == 1) { - cert_length = length + position - start_position; - cert_data = buffer + start_position; - } - // public key data - if (!cert.version && _asn1_is_field_present(fields, Constants::priv_der_id)) { - temp = length + position - start_position; - if (cert.der.size() < temp) { - cert.der.grow(temp); - } else { - cert.der.trim(temp); - } - cert.der.overwrite(0, buffer + start_position, temp); - } - break; + position += octets; + if (size - position < length) { + dbg() << "not enough data for sequence"; + return (i8)Error::NeedMoreData; + } - default: - break; + if (length && constructed) { + switch (type) { + case 0x03: + break; + case 0x10: + if (level == 2 && index == 1) { + cert_length = length + position - start_position; + cert_data = buffer + start_position; } - local_has_key = false; - _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); - if ((local_has_key && (!context.is_server || client_cert)) || (client_cert || _asn1_is_field_present(fields, Constants::pk_id))) { + // public key data + if (!cert.version && _asn1_is_field_present(fields, Constants::priv_der_id)) { temp = length + position - start_position; if (cert.der.size() < temp) { cert.der.grow(temp); @@ -199,134 +183,150 @@ namespace { } cert.der.overwrite(0, buffer + start_position, temp); } - } else { - switch (type) { - case 0x00: - return position; - break; - case 0x01: - temp = buffer[position]; - break; - case 0x02: - if (_asn1_is_field_present(fields, Constants::pk_id)) { - if (has_key) - *has_key = true; - - if (index == 1) - cert.public_key.set( - Crypto::UnsignedBigInteger::import_data(buffer + position, length), - cert.public_key.public_exponent()); - else if (index == 2) - cert.public_key.set( - cert.public_key.modulus(), - Crypto::UnsignedBigInteger::import_data(buffer + position, length)); - } else if (_asn1_is_field_present(fields, Constants::serial_id)) { - cert.serial_number = Crypto::UnsignedBigInteger::import_data(buffer + position, length); - } - if (_asn1_is_field_present(fields, Constants::version_id)) { - if (length == 1) - cert.version = buffer[position]; - } - // print_buffer(ByteBuffer::wrap(buffer + position, length)); - break; - case 0x03: - if (_asn1_is_field_present(fields, Constants::pk_id)) { - if (has_key) - *has_key = true; + break; + + default: + break; + } + local_has_key = false; + _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); + if ((local_has_key && (!context.is_server || client_cert)) || (client_cert || _asn1_is_field_present(fields, Constants::pk_id))) { + temp = length + position - start_position; + if (cert.der.size() < temp) { + cert.der.grow(temp); + } else { + cert.der.trim(temp); + } + cert.der.overwrite(0, buffer + start_position, temp); + } + } else { + switch (type) { + case 0x00: + return position; + break; + case 0x01: + temp = buffer[position]; + break; + case 0x02: + if (_asn1_is_field_present(fields, Constants::pk_id)) { + if (has_key) + *has_key = true; + + if (index == 1) + cert.public_key.set( + Crypto::UnsignedBigInteger::import_data(buffer + position, length), + cert.public_key.public_exponent()); + else if (index == 2) + cert.public_key.set( + cert.public_key.modulus(), + Crypto::UnsignedBigInteger::import_data(buffer + position, length)); + } else if (_asn1_is_field_present(fields, Constants::serial_id)) { + cert.serial_number = Crypto::UnsignedBigInteger::import_data(buffer + position, length); + } + if (_asn1_is_field_present(fields, Constants::version_id)) { + if (length == 1) + cert.version = buffer[position]; + } + // print_buffer(ByteBuffer::wrap(buffer + position, length)); + break; + case 0x03: + if (_asn1_is_field_present(fields, Constants::pk_id)) { + if (has_key) + *has_key = true; + } + if (_asn1_is_field_present(fields, Constants::sign_id)) { + auto* value = buffer + position; + auto len = length; + if (!value[0] && len % 2) { + ++value; + --len; } - if (_asn1_is_field_present(fields, Constants::sign_id)) { - auto* value = buffer + position; - auto len = length; - if (!value[0] && len % 2) { - ++value; - --len; - } - cert.sign_key = ByteBuffer::copy(value, len); + cert.sign_key = ByteBuffer::copy(value, len); + } else { + if (buffer[position] == 0 && length > 256) { + _parse_asn1(context, cert, buffer + position + 1, length - 1, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); } else { - if (buffer[position] == 0 && length > 256) { - _parse_asn1(context, cert, buffer + position + 1, length - 1, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); - } else { - _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); - } - } - break; - case 0x04: - _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); - break; - case 0x05: - break; - case 0x06: - if (_asn1_is_field_present(fields, Constants::pk_id)) { - _set_algorithm(cert.key_algorithm, buffer + position, length); - } - if (_asn1_is_field_present(fields, Constants::algorithm_id)) { - _set_algorithm(cert.algorithm, buffer + position, length); + _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); } + } + break; + case 0x04: + _parse_asn1(context, cert, buffer + position, length, level + 1, fields, &local_has_key, client_cert, root_oid, &local_chain); + break; + case 0x05: + break; + case 0x06: + if (_asn1_is_field_present(fields, Constants::pk_id)) { + _set_algorithm(cert.key_algorithm, buffer + position, length); + } + if (_asn1_is_field_present(fields, Constants::algorithm_id)) { + _set_algorithm(cert.algorithm, buffer + position, length); + } - if (length < 16) - memcpy(oid, buffer + position, length); - else - memcpy(oid, buffer + position, 16); - if (root_oid) - memcpy(root_oid, oid, 16); - break; - case 0x09: - break; - case 0x17: - case 0x018: - // time - // ignore - break; - case 0x013: - case 0x0c: - case 0x14: - case 0x15: - case 0x16: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - // printable string and such - if (_asn1_is_field_present(fields, Constants::issurer_id)) { - if (_asn1_is_oid(oid, Constants::country_oid)) { - cert.issuer_country = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::state_oid)) { - cert.issuer_state = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::location_oid)) { - cert.issuer_location = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::entity_oid)) { - cert.issuer_entity = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::subject_oid)) { - cert.issuer_subject = String { (const char*)buffer + position, length }; - } - } else if (_asn1_is_field_present(fields, Constants::owner_id)) { - if (_asn1_is_oid(oid, Constants::country_oid)) { - cert.country = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::state_oid)) { - cert.state = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::location_oid)) { - cert.location = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::entity_oid)) { - cert.entity = String { (const char*)buffer + position, length }; - } else if (_asn1_is_oid(oid, Constants::subject_oid)) { - cert.subject = String { (const char*)buffer + position, length }; - } + if (length < 16) + memcpy(oid, buffer + position, length); + else + memcpy(oid, buffer + position, 16); + if (root_oid) + memcpy(root_oid, oid, 16); + break; + case 0x09: + break; + case 0x17: + case 0x018: + // time + // ignore + break; + case 0x013: + case 0x0c: + case 0x14: + case 0x15: + case 0x16: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + // printable string and such + if (_asn1_is_field_present(fields, Constants::issurer_id)) { + if (_asn1_is_oid(oid, Constants::country_oid)) { + cert.issuer_country = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::state_oid)) { + cert.issuer_state = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::location_oid)) { + cert.issuer_location = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::entity_oid)) { + cert.issuer_entity = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::subject_oid)) { + cert.issuer_subject = String { (const char*)buffer + position, length }; + } + } else if (_asn1_is_field_present(fields, Constants::owner_id)) { + if (_asn1_is_oid(oid, Constants::country_oid)) { + cert.country = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::state_oid)) { + cert.state = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::location_oid)) { + cert.location = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::entity_oid)) { + cert.entity = String { (const char*)buffer + position, length }; + } else if (_asn1_is_oid(oid, Constants::subject_oid)) { + cert.subject = String { (const char*)buffer + position, length }; } - break; - default: - // dbg() << "unused field " << type; - break; } + break; + default: + // dbg() << "unused field " << type; + break; } - position += length; - } - if (level == 2 && cert.sign_key.size() && cert_length && cert_data) { - dbg() << "FIXME: Cert.fingerprint"; } - return position; + position += length; + } + if (level == 2 && cert.sign_key.size() && cert_length && cert_data) { + dbg() << "FIXME: Cert.fingerprint"; } + return position; +} } Optional<Certificate> TLSv12::parse_asn1(const ByteBuffer& buffer, bool) @@ -520,7 +520,7 @@ bool TLSv12::expand_key() auto key_size = key_length(); auto mac_size = mac_length(); - auto iv_size = 16; + auto iv_size = iv_length(); pseudorandom_function( key_buffer, @@ -769,9 +769,10 @@ void TLSv12::update_packet(ByteBuffer& packet) auto buffer = ByteBuffer::create_zeroed(length); size_t buffer_position = 0; u16 aligned_length = length + block_size - length % block_size; + auto iv_size = iv_length(); - // we need enough space for a header, 16 bytes of IV and whatever the packet contains - auto ct = ByteBuffer::create_zeroed(aligned_length + header_size + 16); + // we need enough space for a header, iv_length bytes of IV and whatever the packet contains + auto ct = ByteBuffer::create_zeroed(aligned_length + header_size + iv_size); // copy the header over ct.overwrite(0, packet.data(), header_size - 2); @@ -798,18 +799,15 @@ void TLSv12::update_packet(ByteBuffer& packet) // throws a wrench into our plans buffer.trim(buffer_position); - // make a random seed IV for this message - u8 record_iv[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - // arc4random_buf(record_iv, 16); - - auto iv = ByteBuffer::wrap(record_iv, 16); + // FIXME: REALLY Should be filled with random bytes + auto iv = ByteBuffer::create_zeroed(iv_size); // write it into the ciphertext portion of the message - ct.overwrite(header_size, record_iv, 16); + ct.overwrite(header_size, iv.data(), iv.size()); ct.trim(length + block_size - length % block_size + header_size + block_size - padding); // get a block to encrypt into - auto view = ct.slice_view(header_size + 16, length + block_size - length % block_size + block_size - padding - 16); + auto view = ct.slice_view(header_size + iv_size, length + block_size - length % block_size + block_size - padding - iv_size); // encrypt the message m_aes_local->encrypt(buffer, view, iv); @@ -1346,11 +1344,12 @@ ssize_t TLSv12::handle_message(const ByteBuffer& buffer) #endif ASSERT(m_aes_remote); + auto iv_size = iv_length(); - auto decrypted = m_aes_remote->create_aligned_buffer(length - 16); - auto iv = buffer.slice_view(header_size, 16); + auto decrypted = m_aes_remote->create_aligned_buffer(length - iv_size); + auto iv = buffer.slice_view(header_size, iv_size); - m_aes_remote->decrypt(buffer.slice_view(header_size + 16, length - 16), decrypted, iv); + m_aes_remote->decrypt(buffer.slice_view(header_size + iv_size, length - iv_size), decrypted, iv); length = decrypted.size(); diff --git a/Libraries/LibTLS/TLSv12.h b/Libraries/LibTLS/TLSv12.h index b70ca56fea..315fb7babb 100644 --- a/Libraries/LibTLS/TLSv12.h +++ b/Libraries/LibTLS/TLSv12.h @@ -92,8 +92,11 @@ enum class CipherSuite { RSA_WITH_AES_128_CBC_SHA = 0x002F, RSA_WITH_AES_256_CBC_SHA = 0x0035, - RSA_WITH_AES_128_CBC_SHA256 = 0x003C, // we support this - RSA_WITH_AES_256_CBC_SHA256 = 0x003D, //<- this is our guy + + // We support these + RSA_WITH_AES_128_CBC_SHA256 = 0x003C, + RSA_WITH_AES_256_CBC_SHA256 = 0x003D, + // TODO RSA_WITH_AES_128_GCM_SHA256 = 0x009C, RSA_WITH_AES_256_GCM_SHA384 = 0x009D, }; @@ -360,8 +363,48 @@ private: void pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret, const u8* label, size_t label_length, const ByteBuffer& seed, const ByteBuffer& seed_b); - size_t key_length() const { return m_aes_local ? m_aes_local->cipher().key().length() : 16; } // FIXME: generalize - size_t mac_length() const { return Crypto::Authentication::HMAC<Crypto::Hash::SHA256>::DigestSize; } // FIXME: generalize + size_t key_length() const + { + switch (m_context.cipher) { + case CipherSuite::AES_128_CCM_8_SHA256: + case CipherSuite::AES_128_CCM_SHA256: + case CipherSuite::AES_128_GCM_SHA256: + case CipherSuite::Invalid: + case CipherSuite::RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite::RSA_WITH_AES_128_CBC_SHA: + case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: + default: + return 128 / 8; + case CipherSuite::AES_256_GCM_SHA384: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: + return 256 / 8; + } + } + size_t mac_length() const + { + return Crypto::Authentication::HMAC<Crypto::Hash::SHA256>::DigestSize; + } // FIXME: generalize + size_t iv_length() const + { + switch (m_context.cipher) { + case CipherSuite::AES_128_CCM_8_SHA256: + case CipherSuite::AES_128_CCM_SHA256: + case CipherSuite::Invalid: + case CipherSuite::RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite::RSA_WITH_AES_128_CBC_SHA: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA: + default: + return 16; + case CipherSuite::AES_128_GCM_SHA256: + case CipherSuite::AES_256_GCM_SHA384: + case CipherSuite::RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: + return 12; + } + } bool expand_key(); @@ -375,27 +418,27 @@ private: }; namespace Constants { - constexpr static const u32 version_id[] { 1, 1, 1, 0 }; - constexpr static const u32 pk_id[] { 1, 1, 7, 0 }; - constexpr static const u32 serial_id[] { 1, 1, 2, 1, 0 }; - constexpr static const u32 issurer_id[] { 1, 1, 4, 0 }; - constexpr static const u32 owner_id[] { 1, 1, 6, 0 }; - constexpr static const u32 validity_id[] { 1, 1, 5, 0 }; - constexpr static const u32 algorithm_id[] { 1, 1, 3, 0 }; - constexpr static const u32 sign_id[] { 1, 3, 2, 1, 0 }; - constexpr static const u32 priv_id[] { 1, 4, 0 }; - constexpr static const u32 priv_der_id[] { 1, 3, 1, 0 }; - constexpr static const u32 ecc_priv_id[] { 1, 2, 0 }; - - constexpr static const u8 country_oid[] { 0x55, 0x04, 0x06, 0x00 }; - constexpr static const u8 state_oid[] { 0x55, 0x04, 0x08, 0x00 }; - constexpr static const u8 location_oid[] { 0x55, 0x04, 0x07, 0x00 }; - constexpr static const u8 entity_oid[] { 0x55, 0x04, 0x0A, 0x00 }; - constexpr static const u8 subject_oid[] { 0x55, 0x04, 0x03, 0x00 }; - constexpr static const u8 san_oid[] { 0x55, 0x1D, 0x11, 0x00 }; - constexpr static const u8 ocsp_oid[] { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x00 }; - - constexpr static const u8 TLS_RSA_SIGN_SHA256_OID[] { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x00 }; +constexpr static const u32 version_id[] { 1, 1, 1, 0 }; +constexpr static const u32 pk_id[] { 1, 1, 7, 0 }; +constexpr static const u32 serial_id[] { 1, 1, 2, 1, 0 }; +constexpr static const u32 issurer_id[] { 1, 1, 4, 0 }; +constexpr static const u32 owner_id[] { 1, 1, 6, 0 }; +constexpr static const u32 validity_id[] { 1, 1, 5, 0 }; +constexpr static const u32 algorithm_id[] { 1, 1, 3, 0 }; +constexpr static const u32 sign_id[] { 1, 3, 2, 1, 0 }; +constexpr static const u32 priv_id[] { 1, 4, 0 }; +constexpr static const u32 priv_der_id[] { 1, 3, 1, 0 }; +constexpr static const u32 ecc_priv_id[] { 1, 2, 0 }; + +constexpr static const u8 country_oid[] { 0x55, 0x04, 0x06, 0x00 }; +constexpr static const u8 state_oid[] { 0x55, 0x04, 0x08, 0x00 }; +constexpr static const u8 location_oid[] { 0x55, 0x04, 0x07, 0x00 }; +constexpr static const u8 entity_oid[] { 0x55, 0x04, 0x0A, 0x00 }; +constexpr static const u8 subject_oid[] { 0x55, 0x04, 0x03, 0x00 }; +constexpr static const u8 san_oid[] { 0x55, 0x1D, 0x11, 0x00 }; +constexpr static const u8 ocsp_oid[] { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x00 }; + +constexpr static const u8 TLS_RSA_SIGN_SHA256_OID[] { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x00 }; } |