Serenity Operating System
at master 107 lines 3.3 kB view raw
1/* 2 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Debug.h> 8#include <AK/Endian.h> 9#include <AK/Random.h> 10 11#include <LibCore/Timer.h> 12#include <LibCrypto/ASN1/DER.h> 13#include <LibCrypto/PK/Code/EMSA_PSS.h> 14#include <LibTLS/TLSv12.h> 15 16namespace TLS { 17 18ssize_t TLSv12::handle_certificate(ReadonlyBytes buffer) 19{ 20 ssize_t res = 0; 21 22 if (buffer.size() < 3) { 23 dbgln_if(TLS_DEBUG, "not enough certificate header data"); 24 return (i8)Error::NeedMoreData; 25 } 26 27 u32 certificate_total_length = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2]; 28 29 dbgln_if(TLS_DEBUG, "total length: {}", certificate_total_length); 30 31 if (certificate_total_length <= 4) 32 return 3 * certificate_total_length; 33 34 res += 3; 35 36 if (certificate_total_length > buffer.size() - res) { 37 dbgln_if(TLS_DEBUG, "not enough data for claimed total cert length"); 38 return (i8)Error::NeedMoreData; 39 } 40 size_t size = certificate_total_length; 41 42 bool valid_certificate = false; 43 44 while (size > 0) { 45 if (buffer.size() - res < 3) { 46 dbgln_if(TLS_DEBUG, "not enough data for certificate length"); 47 return (i8)Error::NeedMoreData; 48 } 49 size_t certificate_size = buffer[res] * 0x10000 + buffer[res + 1] * 0x100 + buffer[res + 2]; 50 res += 3; 51 52 if (buffer.size() - res < certificate_size) { 53 dbgln_if(TLS_DEBUG, "not enough data for certificate body"); 54 return (i8)Error::NeedMoreData; 55 } 56 57 auto res_cert = res; 58 auto remaining = certificate_size; 59 60 do { 61 if (remaining <= 3) { 62 dbgln("Ran out of data"); 63 break; 64 } 65 if (buffer.size() < (size_t)res_cert + 3) { 66 dbgln("not enough data to read cert size ({} < {})", buffer.size(), res_cert + 3); 67 break; 68 } 69 size_t certificate_size_specific = buffer[res_cert] * 0x10000 + buffer[res_cert + 1] * 0x100 + buffer[res_cert + 2]; 70 res_cert += 3; 71 remaining -= 3; 72 73 if (certificate_size_specific > remaining) { 74 dbgln("invalid certificate size (expected {} but got {})", remaining, certificate_size_specific); 75 break; 76 } 77 remaining -= certificate_size_specific; 78 79 auto certificate = Certificate::parse_asn1(buffer.slice(res_cert, certificate_size_specific), false); 80 if (certificate.has_value()) { 81 m_context.certificates.append(certificate.value()); 82 valid_certificate = true; 83 } 84 res_cert += certificate_size_specific; 85 } while (remaining > 0); 86 if (remaining) { 87 dbgln("extraneous {} bytes left over after parsing certificates", remaining); 88 } 89 size -= certificate_size + 3; 90 res += certificate_size; 91 } 92 if (!valid_certificate) 93 return (i8)Error::UnsupportedCertificate; 94 95 if ((size_t)res != buffer.size()) 96 dbgln("some data left unread: {} bytes out of {}", res, buffer.size()); 97 98 return res; 99} 100 101ssize_t TLSv12::handle_certificate_verify(ReadonlyBytes) 102{ 103 dbgln("FIXME: parse_verify"); 104 return 0; 105} 106 107}