diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-08-02 05:26:21 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-02 18:57:51 +0200 |
commit | 9d3ffa096ad1c618461953241cdf1c99624fa6a1 (patch) | |
tree | 1dd242f83609afc99e328c2da89785f947a8e94c /Libraries/LibTLS | |
parent | e54a5b7fb88f6f8a87674bb3bb95099872ba2676 (diff) | |
download | serenity-9d3ffa096ad1c618461953241cdf1c99624fa6a1.zip |
LibTLS: Add (basic) support for sending client certificates
Diffstat (limited to 'Libraries/LibTLS')
-rw-r--r-- | Libraries/LibTLS/ClientHandshake.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibTLS/Exchange.cpp | 53 |
2 files changed, 57 insertions, 4 deletions
diff --git a/Libraries/LibTLS/ClientHandshake.cpp b/Libraries/LibTLS/ClientHandshake.cpp index 28d27215dc..52389f0e0f 100644 --- a/Libraries/LibTLS/ClientHandshake.cpp +++ b/Libraries/LibTLS/ClientHandshake.cpp @@ -439,7 +439,9 @@ ssize_t TLSv12::handle_payload(const ByteBuffer& vbuffer) } else { // we do not support "certificate request" dbg() << "certificate request"; - ASSERT_NOT_REACHED(); + if (on_tls_certificate_request) + on_tls_certificate_request(*this); + m_context.client_verified = VerificationNeeded; } break; case ServerHelloDone: @@ -590,8 +592,10 @@ ssize_t TLSv12::handle_payload(const ByteBuffer& vbuffer) // nothing to write break; case WritePacketStage::ClientHandshake: - // Note: currently not used if (m_context.client_verified == VerificationNeeded) { +#ifdef TLS_DEBUG + dbg() << "> Client Certificate"; +#endif auto packet = build_certificate(); write_packet(packet); m_context.client_verified = Verified; diff --git a/Libraries/LibTLS/Exchange.cpp b/Libraries/LibTLS/Exchange.cpp index aeaa9c1cc4..9350977131 100644 --- a/Libraries/LibTLS/Exchange.cpp +++ b/Libraries/LibTLS/Exchange.cpp @@ -166,8 +166,57 @@ bool TLSv12::compute_master_secret(size_t length) ByteBuffer TLSv12::build_certificate() { - dbg() << "FIXME: build_certificate"; - return {}; + PacketBuilder builder { MessageType::Handshake, m_context.version }; + + Vector<const Certificate*> certificates; + Vector<Certificate>* local_certificates = nullptr; + + if (m_context.is_server) { + dbg() << "Unsupported: Server mode"; + ASSERT_NOT_REACHED(); + } else { + local_certificates = &m_context.client_certificates; + } + + constexpr size_t der_length_delta = 3; + constexpr size_t certificate_vector_header_size = 3; + + size_t total_certificate_size = 0; + + for (size_t i = 0; i < local_certificates->size(); ++i) { + auto& certificate = local_certificates->at(i); + if (!certificate.der.is_empty()) { + total_certificate_size += certificate.der.size() + der_length_delta; + + // FIXME: Check for and respond with only the requested certificate types. + if (true) { + certificates.append(&certificate); + } + } + } + + builder.append((u8)HandshakeType::CertificateMessage); + + if (!total_certificate_size) { +#ifdef TLS_DEBUG + dbg() << "No certificates, sending empty certificate message"; +#endif + builder.append_u24(certificate_vector_header_size); + builder.append_u24(total_certificate_size); + } else { + builder.append_u24(total_certificate_size + certificate_vector_header_size); // 3 bytes for header + builder.append_u24(total_certificate_size); + + for (auto& certificate : certificates) { + if (!certificate->der.is_empty()) { + builder.append_u24(certificate->der.size()); + builder.append(certificate->der); + } + } + } + auto packet = builder.build(); + update_packet(packet); + return packet; } ByteBuffer TLSv12::build_change_cipher_spec() |