1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 18:25:06 +00:00

LibTLS: Switch to Hash::Manager for hashing and add SHA1

Now we can talk to google.com
This commit is contained in:
AnotherTest 2020-04-25 05:07:24 +04:30 committed by Andreas Kling
parent 43a49f5fff
commit bb46e5f608
6 changed files with 157 additions and 95 deletions

View file

@ -27,6 +27,7 @@
#pragma once #pragma once
#include <AK/Optional.h> #include <AK/Optional.h>
#include <AK/OwnPtr.h>
#include <LibCrypto/Hash/HashFunction.h> #include <LibCrypto/Hash/HashFunction.h>
#include <LibCrypto/Hash/MD5.h> #include <LibCrypto/Hash/MD5.h>
#include <LibCrypto/Hash/SHA1.h> #include <LibCrypto/Hash/SHA1.h>
@ -124,7 +125,7 @@ public:
Manager(const Manager& other) // NOT a copy constructor! Manager(const Manager& other) // NOT a copy constructor!
{ {
m_pre_init_buffer = ByteBuffer::create_zeroed(0); // will not be used m_pre_init_buffer = ByteBuffer::create_zeroed(0); // will not be used
initialise(other.m_kind); initialize(other.m_kind);
} }
Manager(HashKind kind) Manager(HashKind kind)
@ -135,6 +136,10 @@ public:
~Manager() ~Manager()
{ {
m_sha1 = nullptr;
m_sha256 = nullptr;
m_sha512 = nullptr;
m_md5 = nullptr;
} }
virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); }; virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
@ -143,13 +148,13 @@ public:
{ {
switch (m_kind) { switch (m_kind) {
case HashKind::MD5: case HashKind::MD5:
return md5.value().digest_size(); return m_md5->digest_size();
case HashKind::SHA1: case HashKind::SHA1:
return sha1.value().digest_size(); return m_sha1->digest_size();
case HashKind::SHA256: case HashKind::SHA256:
return sha256.value().digest_size(); return m_sha256->digest_size();
case HashKind::SHA512: case HashKind::SHA512:
return sha512.value().digest_size(); return m_sha512->digest_size();
default: default:
case HashKind::None: case HashKind::None:
return 0; return 0;
@ -180,16 +185,16 @@ public:
m_kind = kind; m_kind = kind;
switch (kind) { switch (kind) {
case HashKind::MD5: case HashKind::MD5:
md5 = MD5 {}; m_md5 = make<MD5>();
break; break;
case HashKind::SHA1: case HashKind::SHA1:
sha1 = SHA1 {}; m_sha1 = make<SHA1>();
break; break;
case HashKind::SHA256: case HashKind::SHA256:
sha256 = SHA256 {}; m_sha256 = make<SHA256>();
break; break;
case HashKind::SHA512: case HashKind::SHA512:
sha512 = SHA512 {}; m_sha512 = make<SHA512>();
break; break;
default: default:
case HashKind::None: case HashKind::None:
@ -199,46 +204,48 @@ public:
virtual void update(const u8* data, size_t length) override virtual void update(const u8* data, size_t length) override
{ {
auto size = m_pre_init_buffer.size();
switch (m_kind) { switch (m_kind) {
case HashKind::MD5: case HashKind::MD5:
if (m_pre_init_buffer.size()) if (size)
md5.value().update(m_pre_init_buffer); m_md5->update(m_pre_init_buffer);
md5.value().update(data, length); m_md5->update(data, length);
break; break;
case HashKind::SHA1: case HashKind::SHA1:
if (m_pre_init_buffer.size()) if (size)
sha1.value().update(m_pre_init_buffer); m_sha1->update(m_pre_init_buffer);
sha1.value().update(data, length); m_sha1->update(data, length);
break; break;
case HashKind::SHA256: case HashKind::SHA256:
if (m_pre_init_buffer.size()) if (size)
sha256.value().update(m_pre_init_buffer); m_sha256->update(m_pre_init_buffer);
sha256.value().update(data, length); m_sha256->update(data, length);
break; break;
case HashKind::SHA512: case HashKind::SHA512:
if (m_pre_init_buffer.size()) if (size)
sha512.value().update(m_pre_init_buffer); m_sha512->update(m_pre_init_buffer);
sha512.value().update(data, length); m_sha512->update(data, length);
break; break;
default: default:
case HashKind::None: case HashKind::None:
m_pre_init_buffer.append(data, length); m_pre_init_buffer.append(data, length);
return; return;
} }
m_pre_init_buffer.clear(); if (size)
m_pre_init_buffer.clear();
} }
virtual DigestType peek() override virtual DigestType peek() override
{ {
switch (m_kind) { switch (m_kind) {
case HashKind::MD5: case HashKind::MD5:
return { md5.value().peek() }; return { m_md5->peek() };
case HashKind::SHA1: case HashKind::SHA1:
return { sha1.value().peek() }; return { m_sha1->peek() };
case HashKind::SHA256: case HashKind::SHA256:
return { sha256.value().peek() }; return { m_sha256->peek() };
case HashKind::SHA512: case HashKind::SHA512:
return { sha512.value().peek() }; return { m_sha512->peek() };
default: default:
case HashKind::None: case HashKind::None:
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -255,18 +262,19 @@ public:
virtual void reset() override virtual void reset() override
{ {
m_pre_init_buffer.clear();
switch (m_kind) { switch (m_kind) {
case HashKind::MD5: case HashKind::MD5:
md5.value().reset(); m_md5->reset();
break; break;
case HashKind::SHA1: case HashKind::SHA1:
sha1.value().reset(); m_sha1->reset();
break; break;
case HashKind::SHA256: case HashKind::SHA256:
sha256.value().reset(); m_sha256->reset();
break; break;
case HashKind::SHA512: case HashKind::SHA512:
sha512.value().reset(); m_sha512->reset();
break; break;
default: default:
case HashKind::None: case HashKind::None:
@ -278,13 +286,13 @@ public:
{ {
switch (m_kind) { switch (m_kind) {
case HashKind::MD5: case HashKind::MD5:
return md5.value().class_name(); return m_md5->class_name();
case HashKind::SHA1: case HashKind::SHA1:
return sha1.value().class_name(); return m_sha1->class_name();
case HashKind::SHA256: case HashKind::SHA256:
return sha256.value().class_name(); return m_sha256->class_name();
case HashKind::SHA512: case HashKind::SHA512:
return sha512.value().class_name(); return m_sha512->class_name();
default: default:
case HashKind::None: case HashKind::None:
return "UninitializedHashManager"; return "UninitializedHashManager";
@ -297,10 +305,10 @@ public:
} }
private: private:
Optional<SHA1> sha1; OwnPtr<SHA1> m_sha1;
Optional<SHA256> sha256; OwnPtr<SHA256> m_sha256;
Optional<SHA512> sha512; OwnPtr<SHA512> m_sha512;
Optional<MD5> md5; OwnPtr<MD5> m_md5;
HashKind m_kind { HashKind::None }; HashKind m_kind { HashKind::None };
ByteBuffer m_pre_init_buffer; ByteBuffer m_pre_init_buffer;
}; };

View file

@ -85,6 +85,8 @@ public:
}; };
inline virtual void reset() override inline virtual void reset() override
{ {
m_data_length = 0;
m_bit_length = 0;
for (auto i = 0; i < 5; ++i) for (auto i = 0; i < 5; ++i)
m_state[i] = SHA1Constants::InitializationHashes[i]; m_state[i] = SHA1Constants::InitializationHashes[i];
} }

View file

@ -162,13 +162,11 @@ void HttpsJob::on_socket_connected()
return finish_up(); return finish_up();
return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
dbg() << "Read payload, " << payload.size() << " bytes";
m_received_buffers.append(payload); m_received_buffers.append(payload);
m_received_size += payload.size(); m_received_size += payload.size();
auto content_length_header = m_headers.get("Content-Length"); auto content_length_header = m_headers.get("Content-Length");
if (content_length_header.has_value()) { if (content_length_header.has_value()) {
dbg() << "content length is " << content_length_header.value() << ", we have " << m_received_size;
bool ok; bool ok;
if (m_received_size >= content_length_header.value().to_uint(ok) && ok) if (m_received_size >= content_length_header.value().to_uint(ok) && ok)
finish_up(); finish_up();

View file

@ -389,9 +389,11 @@ ByteBuffer TLSv12::build_hello()
} }
// Ciphers // 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_128_CBC_SHA256);
builder.append((u16)CipherSuite::RSA_WITH_AES_256_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 // we don't like compression
builder.append((u8)1); builder.append((u8)1);
@ -460,8 +462,8 @@ ByteBuffer TLSv12::build_finished()
auto outbuffer = ByteBuffer::wrap(out, out_size); auto outbuffer = ByteBuffer::wrap(out, out_size);
auto dummy = ByteBuffer::create_zeroed(0); auto dummy = ByteBuffer::create_zeroed(0);
auto digest = m_context.handshake_hash.hash.peek(); auto digest = m_context.handshake_hash.digest();
auto hashbuf = ByteBuffer::wrap(digest.data, m_context.handshake_hash.hash.DigestSize); 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); pseudorandom_function(outbuffer, m_context.master_key, (const u8*)"client finished", 15, hashbuf, dummy);
builder.append(outbuffer); builder.append(outbuffer);
@ -554,9 +556,9 @@ bool TLSv12::expand_key()
dbg() << "server iv"; dbg() << "server iv";
print_buffer(server_iv, iv_size); print_buffer(server_iv, iv_size);
dbg() << "client mac key"; 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"; dbg() << "server mac key";
print_buffer(m_context.crypto.remote_mac, 32); print_buffer(m_context.crypto.remote_mac, mac_size);
#endif #endif
memcpy(m_context.crypto.local_iv, client_iv, iv_size); memcpy(m_context.crypto.local_iv, client_iv, iv_size);
@ -577,6 +579,11 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret,
return; 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); Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(secret);
auto l_seed_size = label_length + seed.size() + seed_b.size(); 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.data(), seed.size());
label_seed_buffer.overwrite(label_length + seed.size(), seed_b.data(), seed_b.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; size_t index = 0;
while (index < output.size()) { while (index < output.size()) {
@ -598,12 +607,12 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, const ByteBuffer& secret,
hmac.update(label_seed_buffer); hmac.update(label_seed_buffer);
auto digest_1 = hmac.digest(); 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; 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; m_context.cipher = cipher;
dbg() << "Cipher: " << (u16)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) { if (buffer.size() - res < 1) {
dbg() << "not enough data for compression spec"; dbg() << "not enough data for compression spec";
return (i8)Error::NeedMoreData; return (i8)Error::NeedMoreData;
@ -1115,7 +1127,7 @@ ssize_t TLSv12::handle_verify(const ByteBuffer&)
void TLSv12::update_hash(const ByteBuffer& message) 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) 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()) { if (buf2.has_value() && buf2.value().size()) {
hmac.update(buf2.value()); 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 #ifdef TLS_DEBUG
dbg() << "HMAC of the block for sequence number " << m_context.local_sequence_number; dbg() << "HMAC of the block for sequence number " << m_context.local_sequence_number;
print_buffer(mac); print_buffer(mac);
@ -1484,12 +1497,16 @@ ByteBuffer TLSv12::hmac_message(const ByteBuffer& buf, const Optional<ByteBuffer
return mac; return mac;
}; };
switch (mac_length) { 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: { 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); return digest(hmac);
} }
case Crypto::Hash::SHA512::DigestSize: { 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); return digest(hmac);
} }
default: default:

View file

@ -34,7 +34,7 @@
#include <LibCrypto/Authentication/HMAC.h> #include <LibCrypto/Authentication/HMAC.h>
#include <LibCrypto/BigInt/UnsignedBigInteger.h> #include <LibCrypto/BigInt/UnsignedBigInteger.h>
#include <LibCrypto/Cipher/AES.h> #include <LibCrypto/Cipher/AES.h>
#include <LibCrypto/Hash/SHA2.h> #include <LibCrypto/Hash/HashManager.h>
#include <LibCrypto/PK/RSA.h> #include <LibCrypto/PK/RSA.h>
#include <LibTLS/TLSPacketBuilder.h> #include <LibTLS/TLSPacketBuilder.h>
@ -42,8 +42,6 @@ namespace TLS {
class Socket; class Socket;
using HashFunction = Crypto::Hash::SHA256;
enum class KeyExchangeAlgorithms { enum class KeyExchangeAlgorithms {
DHE_DSS, DHE_DSS,
DHE_RSA, DHE_RSA,
@ -66,16 +64,6 @@ enum class ClientCertificateType {
ECDSA_FixedECDH = 66 ECDSA_FixedECDH = 66
}; };
enum class HashAlgorithm {
None = 0,
MD5 = 1,
SHA1 = 2,
SHA224 = 3,
SHA256 = 4,
SHA384 = 5,
SHA512 = 6
};
enum class SignatureAlgorithm { enum class SignatureAlgorithm {
Anonymous = 0, Anonymous = 0,
RSA = 1, RSA = 1,
@ -90,10 +78,9 @@ enum class CipherSuite {
AES_128_CCM_SHA256 = 0x1304, AES_128_CCM_SHA256 = 0x1304,
AES_128_CCM_8_SHA256 = 0x1305, AES_128_CCM_8_SHA256 = 0x1305,
// We support these
RSA_WITH_AES_128_CBC_SHA = 0x002F, RSA_WITH_AES_128_CBC_SHA = 0x002F,
RSA_WITH_AES_256_CBC_SHA = 0x0035, RSA_WITH_AES_256_CBC_SHA = 0x0035,
// We support these
RSA_WITH_AES_128_CBC_SHA256 = 0x003C, RSA_WITH_AES_128_CBC_SHA256 = 0x003C,
RSA_WITH_AES_256_CBC_SHA256 = 0x003D, RSA_WITH_AES_256_CBC_SHA256 = 0x003D,
// TODO // TODO
@ -187,10 +174,6 @@ struct Certificate {
ByteBuffer data; ByteBuffer data;
}; };
struct Hash {
Crypto::Hash::SHA256 hash;
};
struct Context { struct Context {
String to_string() const; String to_string() const;
bool verify() const; bool verify() const;
@ -220,7 +203,7 @@ struct Context {
u8 remote_iv[16]; u8 remote_iv[16];
} crypto; } crypto;
Hash handshake_hash; Crypto::Hash::Manager handshake_hash;
ByteBuffer message_buffer; ByteBuffer message_buffer;
u64 remote_sequence_number { 0 }; u64 remote_sequence_number { 0 };
@ -299,7 +282,7 @@ public:
bool cipher_supported(CipherSuite suite) const 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 bool version_supported(Version v) const
@ -384,8 +367,24 @@ private:
} }
size_t mac_length() const size_t mac_length() const
{ {
return Crypto::Authentication::HMAC<Crypto::Hash::SHA256>::DigestSize; switch (m_context.cipher) {
} // FIXME: generalize 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 size_t iv_length() const
{ {
switch (m_context.cipher) { switch (m_context.cipher) {

View file

@ -138,9 +138,9 @@ void hmac_md5(const char* message, size_t len)
Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac(secret_key); Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac(secret_key);
auto mac = hmac.process((const u8*)message, len); auto mac = hmac.process((const u8*)message, len);
if (binary) if (binary)
printf("%.*s", (int)hmac.DigestSize, mac.data); printf("%.*s", (int)hmac.digest_size(), mac.data);
else else
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} }
void sha1(const char* message, size_t len) void sha1(const char* message, size_t len)
@ -166,9 +166,9 @@ void hmac_sha256(const char* message, size_t len)
Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(secret_key); Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(secret_key);
auto mac = hmac.process((const u8*)message, len); auto mac = hmac.process((const u8*)message, len);
if (binary) if (binary)
printf("%.*s", (int)hmac.DigestSize, mac.data); printf("%.*s", (int)hmac.digest_size(), mac.data);
else else
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} }
void sha512(const char* message, size_t len) void sha512(const char* message, size_t len)
@ -185,9 +185,9 @@ void hmac_sha512(const char* message, size_t len)
Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac(secret_key); Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac(secret_key);
auto mac = hmac.process((const u8*)message, len); auto mac = hmac.process((const u8*)message, len);
if (binary) if (binary)
printf("%.*s", (int)hmac.DigestSize, mac.data); printf("%.*s", (int)hmac.digest_size(), mac.data);
else else
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} }
auto main(int argc, char** argv) -> int auto main(int argc, char** argv) -> int
@ -676,9 +676,9 @@ void hmac_md5_test_process()
0x3b, 0x5b, 0xde, 0x30, 0x3a, 0x54, 0x7b, 0xbb, 0x09, 0xfe, 0x78, 0x89, 0xbc, 0x9f, 0x22, 0xa3 0x3b, 0x5b, 0xde, 0x30, 0x3a, 0x54, 0x7b, 0xbb, 0x09, 0xfe, 0x78, 0x89, 0xbc, 0x9f, 0x22, 0xa3
}; };
auto mac = hmac.process("Some bogus data"); auto mac = hmac.process("Some bogus data");
if (memcmp(result, mac.data, hmac.DigestSize) != 0) { if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
FAIL(Invalid mac); FAIL(Invalid mac);
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} else } else
PASS; PASS;
} }
@ -689,7 +689,7 @@ void hmac_md5_test_process()
auto mac_0 = hmac.process("Some bogus data"); auto mac_0 = hmac.process("Some bogus data");
auto mac_1 = hmac.process("Some bogus data"); auto mac_1 = hmac.process("Some bogus data");
if (memcmp(mac_0.data, mac_1.data, hmac.DigestSize) != 0) { if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
FAIL(Cannot reuse); FAIL(Cannot reuse);
} else } else
PASS; PASS;
@ -728,6 +728,44 @@ void sha1_test_hash()
} else } else
PASS; PASS;
} }
{
I_TEST((SHA256 Hashing | Long String));
u8 result[] {
0x12, 0x15, 0x1f, 0xb1, 0x04, 0x44, 0x93, 0xcc, 0xed, 0x54, 0xa6, 0xb8, 0x7e, 0x93, 0x37, 0x7b, 0xb2, 0x13, 0x39, 0xdb
};
auto digest = Crypto::Hash::SHA1::hash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
if (memcmp(result, digest.data, Crypto::Hash::SHA1::digest_size()) != 0) {
FAIL(Invalid hash);
print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
} else
PASS;
}
{
I_TEST((SHA256 Hashing | Successive Updates));
u8 result[] {
0xd6, 0x6e, 0xce, 0xd1, 0xf4, 0x08, 0xc6, 0xd8, 0x35, 0xab, 0xf0, 0xc9, 0x05, 0x26, 0xa4, 0xb2, 0xb8, 0xa3, 0x7c, 0xd3
};
auto hasher = Crypto::Hash::SHA1 {};
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaaaaaaaa");
hasher.update("aaaaaaaaa");
auto digest = hasher.digest();
if (memcmp(result, digest.data, Crypto::Hash::SHA1::digest_size()) != 0) {
FAIL(Invalid hash);
print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
} else
PASS;
}
} }
int sha256_tests() int sha256_tests()
@ -795,9 +833,9 @@ void hmac_sha256_test_process()
0x1a, 0xf2, 0x20, 0x62, 0xde, 0x3b, 0x84, 0x65, 0xc1, 0x25, 0x23, 0x99, 0x76, 0x15, 0x1b, 0xec, 0x15, 0x21, 0x82, 0x1f, 0x23, 0xca, 0x11, 0x66, 0xdd, 0x8c, 0x6e, 0xf1, 0x81, 0x3b, 0x7f, 0x1b 0x1a, 0xf2, 0x20, 0x62, 0xde, 0x3b, 0x84, 0x65, 0xc1, 0x25, 0x23, 0x99, 0x76, 0x15, 0x1b, 0xec, 0x15, 0x21, 0x82, 0x1f, 0x23, 0xca, 0x11, 0x66, 0xdd, 0x8c, 0x6e, 0xf1, 0x81, 0x3b, 0x7f, 0x1b
}; };
auto mac = hmac.process("Some bogus data"); auto mac = hmac.process("Some bogus data");
if (memcmp(result, mac.data, hmac.DigestSize) != 0) { if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
FAIL(Invalid mac); FAIL(Invalid mac);
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} else } else
PASS; PASS;
} }
@ -808,7 +846,7 @@ void hmac_sha256_test_process()
auto mac_0 = hmac.process("Some bogus data"); auto mac_0 = hmac.process("Some bogus data");
auto mac_1 = hmac.process("Some bogus data"); auto mac_1 = hmac.process("Some bogus data");
if (memcmp(mac_0.data, mac_1.data, hmac.DigestSize) != 0) { if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
FAIL(Cannot reuse); FAIL(Cannot reuse);
} else } else
PASS; PASS;
@ -880,9 +918,9 @@ void hmac_sha512_test_process()
0xeb, 0xa8, 0x34, 0x11, 0xfd, 0x5b, 0x46, 0x5b, 0xef, 0xbb, 0x67, 0x5e, 0x7d, 0xc2, 0x7c, 0x2c, 0x6b, 0xe1, 0xcf, 0xe6, 0xc7, 0xe4, 0x7d, 0xeb, 0xca, 0x97, 0xb7, 0x4c, 0xd3, 0x4d, 0x6f, 0x08, 0x9f, 0x0d, 0x3a, 0xf1, 0xcb, 0x00, 0x79, 0x78, 0x2f, 0x05, 0x8e, 0xeb, 0x94, 0x48, 0x0d, 0x50, 0x64, 0x3b, 0xca, 0x70, 0xe2, 0x69, 0x38, 0x4f, 0xe4, 0xb0, 0x49, 0x0f, 0xc5, 0x4c, 0x7a, 0xa7 0xeb, 0xa8, 0x34, 0x11, 0xfd, 0x5b, 0x46, 0x5b, 0xef, 0xbb, 0x67, 0x5e, 0x7d, 0xc2, 0x7c, 0x2c, 0x6b, 0xe1, 0xcf, 0xe6, 0xc7, 0xe4, 0x7d, 0xeb, 0xca, 0x97, 0xb7, 0x4c, 0xd3, 0x4d, 0x6f, 0x08, 0x9f, 0x0d, 0x3a, 0xf1, 0xcb, 0x00, 0x79, 0x78, 0x2f, 0x05, 0x8e, 0xeb, 0x94, 0x48, 0x0d, 0x50, 0x64, 0x3b, 0xca, 0x70, 0xe2, 0x69, 0x38, 0x4f, 0xe4, 0xb0, 0x49, 0x0f, 0xc5, 0x4c, 0x7a, 0xa7
}; };
auto mac = hmac.process("Some bogus data"); auto mac = hmac.process("Some bogus data");
if (memcmp(result, mac.data, hmac.DigestSize) != 0) { if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
FAIL(Invalid mac); FAIL(Invalid mac);
print_buffer(ByteBuffer::wrap(mac.data, hmac.DigestSize), -1); print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
} else } else
PASS; PASS;
} }
@ -893,7 +931,7 @@ void hmac_sha512_test_process()
auto mac_0 = hmac.process("Some bogus data"); auto mac_0 = hmac.process("Some bogus data");
auto mac_1 = hmac.process("Some bogus data"); auto mac_1 = hmac.process("Some bogus data");
if (memcmp(mac_0.data, mac_1.data, hmac.DigestSize) != 0) { if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
FAIL(Cannot reuse); FAIL(Cannot reuse);
} else } else
PASS; PASS;
@ -1053,7 +1091,7 @@ void tls_test_client_hello()
if (sent_request) if (sent_request)
return; return;
sent_request = true; sent_request = true;
if (!tls.write("GET /SerenityOS/serenity HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n"_b)) { if (!tls.write("GET / HTTP/1.1\r\nHost: google.com\r\nConnection: close\r\n\r\n"_b)) {
FAIL(write() failed); FAIL(write() failed);
loop.quit(0); loop.quit(0);
} }
@ -1084,7 +1122,7 @@ void tls_test_client_hello()
FAIL(Connection failure); FAIL(Connection failure);
loop.quit(1); loop.quit(1);
}; };
if (!tls->connect("github.com", 443)) { if (!tls->connect("192.168.1.2", 8443)) {
FAIL(connect() failed); FAIL(connect() failed);
return; return;
} }