1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:37:35 +00:00

LibTLS: Add (basic) support for sending client certificates

This commit is contained in:
AnotherTest 2020-08-02 05:26:21 +04:30 committed by Andreas Kling
parent e54a5b7fb8
commit 9d3ffa096a
2 changed files with 57 additions and 4 deletions

View file

@ -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;

View file

@ -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()