1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:27:45 +00:00

LibTLS: Use RSA key exchange based on the cipher

After this, we aren't hardcoding RSA in everything we do anymore!
This commit is contained in:
DexesTTP 2021-05-19 00:12:09 +02:00 committed by Andreas Kling
parent 9bb823a6ab
commit 68f6796e72
3 changed files with 60 additions and 7 deletions

View file

@ -109,7 +109,7 @@ bool TLSv12::expand_key()
return true;
}
bool TLSv12::compute_master_secret(size_t length)
bool TLSv12::compute_master_secret_from_pre_master_secret(size_t length)
{
if (m_context.premaster_key.size() == 0 || length < 48) {
dbgln("there's no way I can make a master secret like this");
@ -168,7 +168,7 @@ Optional<size_t> TLSv12::verify_chain_and_get_matching_certificate(const StringV
return {};
}
void TLSv12::build_random(PacketBuilder& builder)
void TLSv12::build_rsa_pre_master_secret(PacketBuilder& builder)
{
u8 random_bytes[48];
size_t bytes = 48;
@ -215,7 +215,7 @@ void TLSv12::build_random(PacketBuilder& builder)
print_buffer(outbuf);
}
if (!compute_master_secret(bytes)) {
if (!compute_master_secret_from_pre_master_secret(bytes)) {
dbgln("oh noes we could not derive a master key :(");
return;
}
@ -282,7 +282,28 @@ ByteBuffer TLSv12::build_client_key_exchange()
{
PacketBuilder builder { MessageType::Handshake, m_context.options.version };
builder.append((u8)HandshakeType::ClientKeyExchange);
build_random(builder);
switch (get_signature_algorithm(m_context.cipher)) {
case SignatureAlgorithm::Anonymous:
dbgln("Client key exchange for Anonymous signature is not implemented");
TODO();
break;
case SignatureAlgorithm::RSA:
build_rsa_pre_master_secret(builder);
break;
case SignatureAlgorithm::DSA:
dbgln("Client key exchange for DSA signature is not implemented");
TODO();
break;
case SignatureAlgorithm::ECDSA:
dbgln("Client key exchange for ECDSA signature is not implemented");
TODO();
break;
default:
dbgln("Unknonwn client key exchange signature algorithm");
VERIFY_NOT_REACHED();
break;
}
m_context.connection_status = ConnectionStatus::KeyExchange;

View file

@ -201,7 +201,26 @@ ByteBuffer TLSv12::build_server_key_exchange()
ssize_t TLSv12::handle_server_key_exchange(ReadonlyBytes)
{
dbgln("FIXME: parse_server_key_exchange");
switch (get_signature_algorithm(m_context.cipher)) {
case SignatureAlgorithm::Anonymous:
dbgln("Client key exchange for Anonymous signature is not implemented");
TODO();
break;
case SignatureAlgorithm::RSA:
case SignatureAlgorithm::DSA:
// RFC 5246 section 7.4.3. Server Key Exchange Message
// It is not legal to send the server key exchange message for RSA, DH_DSS, DH_RSA
dbgln("Server key exchange received for RSA or DSA is not legal");
return (i8)Error::UnexpectedMessage;
case SignatureAlgorithm::ECDSA:
dbgln("Client key exchange for ECDSA signature is not implemented");
TODO();
break;
default:
dbgln("Unknonwn client key exchange signature algorithm");
VERIFY_NOT_REACHED();
break;
}
return 0;
}

View file

@ -179,6 +179,19 @@ enum ClientVerificationStaus {
C(true, CipherSuite::RSA_WITH_AES_128_GCM_SHA256, SignatureAlgorithm::RSA, CipherAlgorithm::AES_128_GCM, Crypto::Hash::SHA256, 8, true) \
C(false, CipherSuite::RSA_WITH_AES_256_GCM_SHA384, SignatureAlgorithm::RSA, CipherAlgorithm::AES_256_GCM, Crypto::Hash::SHA384, 8, true)
constexpr SignatureAlgorithm get_signature_algorithm(CipherSuite suite)
{
switch (suite) {
#define C(is_supported, suite, signature, cipher, hash, iv_size, is_aead) \
case suite: \
return signature;
ENUMERATE_CIPHERS(C)
#undef C
default:
return SignatureAlgorithm::Anonymous;
}
}
constexpr CipherAlgorithm get_cipher_algorithm(CipherSuite suite)
{
switch (suite) {
@ -389,7 +402,7 @@ private:
ByteBuffer build_alert(bool critical, u8 code);
ByteBuffer build_change_cipher_spec();
ByteBuffer build_verify_request();
void build_random(PacketBuilder&);
void build_rsa_pre_master_secret(PacketBuilder&);
bool flush();
void write_into_socket();
@ -465,7 +478,7 @@ private:
bool expand_key();
bool compute_master_secret(size_t length);
bool compute_master_secret_from_pre_master_secret(size_t length);
Optional<size_t> verify_chain_and_get_matching_certificate(const StringView& host) const;