diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-04-25 05:07:24 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-02 12:24:10 +0200 |
commit | bb46e5f608cee772896ae4ac8ae69318e9edab1a (patch) | |
tree | facb54846664faff33507b5f834fdeeb48974e22 /Libraries/LibTLS | |
parent | 43a49f5fff72b519bdc3a87f0df610bcd9f405bf (diff) | |
download | serenity-bb46e5f608cee772896ae4ac8ae69318e9edab1a.zip |
LibTLS: Switch to Hash::Manager for hashing and add SHA1
Now we can talk to google.com
Diffstat (limited to 'Libraries/LibTLS')
-rw-r--r-- | Libraries/LibTLS/TLSv12.cpp | 47 | ||||
-rw-r--r-- | Libraries/LibTLS/TLSv12.h | 45 |
2 files changed, 54 insertions, 38 deletions
diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index f05a9865e7..0aceeb21ee 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -389,9 +389,11 @@ ByteBuffer TLSv12::build_hello() } // Ciphers - builder.append((u16)(2 * sizeof(u16))); + builder.append((u16)(4 * sizeof(u16))); builder.append((u16)CipherSuite::RSA_WITH_AES_128_CBC_SHA256); builder.append((u16)CipherSuite::RSA_WITH_AES_256_CBC_SHA256); + builder.append((u16)CipherSuite::RSA_WITH_AES_128_CBC_SHA); + builder.append((u16)CipherSuite::RSA_WITH_AES_256_CBC_SHA); // we don't like compression builder.append((u8)1); @@ -460,8 +462,8 @@ ByteBuffer TLSv12::build_finished() auto outbuffer = ByteBuffer::wrap(out, out_size); auto dummy = ByteBuffer::create_zeroed(0); - auto digest = m_context.handshake_hash.hash.peek(); - auto hashbuf = ByteBuffer::wrap(digest.data, m_context.handshake_hash.hash.DigestSize); + auto digest = m_context.handshake_hash.digest(); + auto hashbuf = ByteBuffer::wrap(digest.immutable_data(), m_context.handshake_hash.digest_size()); pseudorandom_function(outbuffer, m_context.master_key, (const u8*)"client finished", 15, hashbuf, dummy); builder.append(outbuffer); @@ -554,9 +556,9 @@ bool TLSv12::expand_key() dbg() << "server iv"; print_buffer(server_iv, iv_size); dbg() << "client mac key"; - print_buffer(m_context.crypto.local_mac, 32); + print_buffer(m_context.crypto.local_mac, mac_size); dbg() << "server mac key"; - print_buffer(m_context.crypto.remote_mac, 32); + print_buffer(m_context.crypto.remote_mac, mac_size); #endif memcpy(m_context.crypto.local_iv, client_iv, iv_size); @@ -577,6 +579,11 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret, return; } + // RFC 5246: "In this section, we define one PRF, based on HMAC. This PRF with the + // SHA-256 hash function is used for all cipher suites defined in this + // document and in TLS documents published prior to this document when + // TLS 1.2 is negotiated." + // Apparently this PRF _always_ uses SHA256 Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(secret); auto l_seed_size = label_length + seed.size() + seed_b.size(); @@ -586,11 +593,13 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret, label_seed_buffer.overwrite(label_length, seed.data(), seed.size()); label_seed_buffer.overwrite(label_length + seed.size(), seed_b.data(), seed_b.size()); - u8 digest[hmac.DigestSize]; + auto digest_size = hmac.digest_size(); - auto digest_0 = ByteBuffer::wrap(digest, hmac.DigestSize); + u8 digest[digest_size]; - digest_0.overwrite(0, hmac.process(label_seed_buffer).data, hmac.DigestSize); + auto digest_0 = ByteBuffer::wrap(digest, digest_size); + + digest_0.overwrite(0, hmac.process(label_seed_buffer).immutable_data(), digest_size); size_t index = 0; while (index < output.size()) { @@ -598,12 +607,12 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret, hmac.update(label_seed_buffer); auto digest_1 = hmac.digest(); - auto copy_size = min(hmac.DigestSize, output.size() - index); + auto copy_size = min(digest_size, output.size() - index); - output.overwrite(index, digest_1.data, copy_size); + output.overwrite(index, digest_1.immutable_data(), copy_size); index += copy_size; - digest_0.overwrite(0, hmac.process(digest_0).data, hmac.DigestSize); + digest_0.overwrite(0, hmac.process(digest_0).immutable_data(), digest_size); } } @@ -888,6 +897,9 @@ ssize_t TLSv12::handle_hello(const ByteBuffer& buffer, size_t& write_packets) m_context.cipher = cipher; dbg() << "Cipher: " << (u16)cipher; + // The handshake hash function is _always_ SHA256 + m_context.handshake_hash.initialize(Crypto::Hash::HashKind::SHA256); + if (buffer.size() - res < 1) { dbg() << "not enough data for compression spec"; return (i8)Error::NeedMoreData; @@ -1115,7 +1127,7 @@ ssize_t TLSv12::handle_verify(const ByteBuffer&) void TLSv12::update_hash(const ByteBuffer& message) { - m_context.handshake_hash.hash.update(message); + m_context.handshake_hash.update(message); } bool TLSv12::connect(const String& hostname, int port) @@ -1476,7 +1488,8 @@ ByteBuffer TLSv12::hmac_message(const ByteBuffer& buf, const Optional<ByteBuffer if (buf2.has_value() && buf2.value().size()) { hmac.update(buf2.value()); } - auto mac = ByteBuffer::copy(hmac.digest().data, hmac.DigestSize); + auto digest = hmac.digest(); + auto mac = ByteBuffer::copy(digest.immutable_data(), digest.data_length()); #ifdef TLS_DEBUG dbg() << "HMAC of the block for sequence number " << m_context.local_sequence_number; print_buffer(mac); @@ -1484,12 +1497,16 @@ ByteBuffer TLSv12::hmac_message(const ByteBuffer& buf, const Optional<ByteBuffer return mac; }; switch (mac_length) { + case Crypto::Hash::SHA1::DigestSize: { + Crypto::Authentication::HMAC<Crypto::Hash::SHA1> hmac(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, mac_length)); + return digest(hmac); + } case Crypto::Hash::SHA256::DigestSize: { - Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, 32)); + Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, mac_length)); return digest(hmac); } case Crypto::Hash::SHA512::DigestSize: { - Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, 32)); + Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, mac_length)); return digest(hmac); } default: diff --git a/Libraries/LibTLS/TLSv12.h b/Libraries/LibTLS/TLSv12.h index 315fb7babb..83ca59aaf4 100644 --- a/Libraries/LibTLS/TLSv12.h +++ b/Libraries/LibTLS/TLSv12.h @@ -34,7 +34,7 @@ #include <LibCrypto/Authentication/HMAC.h> #include <LibCrypto/BigInt/UnsignedBigInteger.h> #include <LibCrypto/Cipher/AES.h> -#include <LibCrypto/Hash/SHA2.h> +#include <LibCrypto/Hash/HashManager.h> #include <LibCrypto/PK/RSA.h> #include <LibTLS/TLSPacketBuilder.h> @@ -42,8 +42,6 @@ namespace TLS { class Socket; -using HashFunction = Crypto::Hash::SHA256; - enum class KeyExchangeAlgorithms { DHE_DSS, DHE_RSA, @@ -66,16 +64,6 @@ enum class ClientCertificateType { ECDSA_FixedECDH = 66 }; -enum class HashAlgorithm { - None = 0, - MD5 = 1, - SHA1 = 2, - SHA224 = 3, - SHA256 = 4, - SHA384 = 5, - SHA512 = 6 -}; - enum class SignatureAlgorithm { Anonymous = 0, RSA = 1, @@ -90,10 +78,9 @@ enum class CipherSuite { AES_128_CCM_SHA256 = 0x1304, AES_128_CCM_8_SHA256 = 0x1305, + // We support these RSA_WITH_AES_128_CBC_SHA = 0x002F, RSA_WITH_AES_256_CBC_SHA = 0x0035, - - // We support these RSA_WITH_AES_128_CBC_SHA256 = 0x003C, RSA_WITH_AES_256_CBC_SHA256 = 0x003D, // TODO @@ -187,10 +174,6 @@ struct Certificate { ByteBuffer data; }; -struct Hash { - Crypto::Hash::SHA256 hash; -}; - struct Context { String to_string() const; bool verify() const; @@ -220,7 +203,7 @@ struct Context { u8 remote_iv[16]; } crypto; - Hash handshake_hash; + Crypto::Hash::Manager handshake_hash; ByteBuffer message_buffer; u64 remote_sequence_number { 0 }; @@ -299,7 +282,7 @@ public: bool cipher_supported(CipherSuite suite) const { - return suite == CipherSuite::RSA_WITH_AES_128_CBC_SHA256 || suite == CipherSuite::RSA_WITH_AES_256_CBC_SHA256; + return suite == CipherSuite::RSA_WITH_AES_128_CBC_SHA256 || suite == CipherSuite::RSA_WITH_AES_256_CBC_SHA256 || suite == CipherSuite::RSA_WITH_AES_128_CBC_SHA || suite == CipherSuite::RSA_WITH_AES_256_CBC_SHA; } bool version_supported(Version v) const @@ -384,8 +367,24 @@ private: } size_t mac_length() const { - return Crypto::Authentication::HMAC<Crypto::Hash::SHA256>::DigestSize; - } // FIXME: generalize + switch (m_context.cipher) { + case CipherSuite::RSA_WITH_AES_128_CBC_SHA: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA: + return Crypto::Hash::SHA1::digest_size(); + case CipherSuite::AES_256_GCM_SHA384: + case CipherSuite::RSA_WITH_AES_256_GCM_SHA384: + return Crypto::Hash::SHA512::digest_size(); + 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_GCM_SHA256: + case CipherSuite::RSA_WITH_AES_256_CBC_SHA256: + default: + return Crypto::Hash::SHA256::digest_size(); + } + } size_t iv_length() const { switch (m_context.cipher) { |