Serenity Operating System
1/*
2 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
3 * Copyright (c) 2022, Michiel Visser <opensource@webmichiel.nl>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/Debug.h>
9#include <AK/Endian.h>
10#include <AK/Random.h>
11
12#include <LibCore/Timer.h>
13#include <LibCrypto/ASN1/DER.h>
14#include <LibCrypto/Curves/EllipticCurve.h>
15#include <LibCrypto/Curves/SECP256r1.h>
16#include <LibCrypto/Curves/X25519.h>
17#include <LibCrypto/Curves/X448.h>
18#include <LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h>
19#include <LibCrypto/PK/Code/EMSA_PSS.h>
20#include <LibTLS/TLSv12.h>
21
22namespace TLS {
23
24ssize_t TLSv12::handle_server_hello(ReadonlyBytes buffer, WritePacketStage& write_packets)
25{
26 write_packets = WritePacketStage::Initial;
27 if (m_context.connection_status != ConnectionStatus::Disconnected && m_context.connection_status != ConnectionStatus::Renegotiating) {
28 dbgln("unexpected hello message");
29 return (i8)Error::UnexpectedMessage;
30 }
31 ssize_t res = 0;
32 size_t min_hello_size = 41;
33
34 if (min_hello_size > buffer.size()) {
35 dbgln("need more data");
36 return (i8)Error::NeedMoreData;
37 }
38 size_t following_bytes = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2];
39 res += 3;
40 if (buffer.size() - res < following_bytes) {
41 dbgln("not enough data after header: {} < {}", buffer.size() - res, following_bytes);
42 return (i8)Error::NeedMoreData;
43 }
44
45 if (buffer.size() - res < 2) {
46 dbgln("not enough data for version");
47 return (i8)Error::NeedMoreData;
48 }
49 auto version = static_cast<Version>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))));
50
51 res += 2;
52 if (!supports_version(version))
53 return (i8)Error::NotSafe;
54
55 memcpy(m_context.remote_random, buffer.offset_pointer(res), sizeof(m_context.remote_random));
56 res += sizeof(m_context.remote_random);
57
58 u8 session_length = buffer[res++];
59 if (buffer.size() - res < session_length) {
60 dbgln("not enough data for session id");
61 return (i8)Error::NeedMoreData;
62 }
63
64 if (session_length && session_length <= 32) {
65 memcpy(m_context.session_id, buffer.offset_pointer(res), session_length);
66 m_context.session_id_size = session_length;
67 if constexpr (TLS_DEBUG) {
68 dbgln("Remote session ID:");
69 print_buffer(ReadonlyBytes { m_context.session_id, session_length });
70 }
71 } else {
72 m_context.session_id_size = 0;
73 }
74 res += session_length;
75
76 if (buffer.size() - res < 2) {
77 dbgln("not enough data for cipher suite listing");
78 return (i8)Error::NeedMoreData;
79 }
80 auto cipher = static_cast<CipherSuite>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res))));
81 res += 2;
82 if (!supports_cipher(cipher)) {
83 m_context.cipher = CipherSuite::Invalid;
84 dbgln("No supported cipher could be agreed upon");
85 return (i8)Error::NoCommonCipher;
86 }
87 m_context.cipher = cipher;
88 dbgln_if(TLS_DEBUG, "Cipher: {}", (u16)cipher);
89
90 // Simplification: We only support handshake hash functions via HMAC
91 m_context.handshake_hash.initialize(hmac_hash());
92
93 // Compression method
94 if (buffer.size() - res < 1)
95 return (i8)Error::NeedMoreData;
96 u8 compression = buffer[res++];
97 if (compression != 0)
98 return (i8)Error::CompressionNotSupported;
99
100 if (m_context.connection_status != ConnectionStatus::Renegotiating)
101 m_context.connection_status = ConnectionStatus::Negotiating;
102 if (m_context.is_server) {
103 dbgln("unsupported: server mode");
104 write_packets = WritePacketStage::ServerHandshake;
105 }
106
107 // Presence of extensions is determined by availability of bytes after compression_method
108 if (buffer.size() - res >= 2) {
109 auto extensions_bytes_total = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
110 dbgln_if(TLS_DEBUG, "Extensions bytes total: {}", extensions_bytes_total);
111 }
112
113 while (buffer.size() - res >= 4) {
114 auto extension_type = (HandshakeExtension)AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
115 res += 2;
116 u16 extension_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
117 res += 2;
118
119 dbgln_if(TLS_DEBUG, "Extension {} with length {}", (u16)extension_type, extension_length);
120
121 if (buffer.size() - res < extension_length)
122 return (i8)Error::NeedMoreData;
123
124 if (extension_type == HandshakeExtension::ServerName) {
125 // RFC6066 section 3: SNI extension_data can be empty in the server hello
126 if (extension_length > 0) {
127 // ServerNameList total size
128 if (buffer.size() - res < 2)
129 return (i8)Error::NeedMoreData;
130 auto sni_name_list_bytes = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
131 dbgln_if(TLS_DEBUG, "SNI: expecting ServerNameList of {} bytes", sni_name_list_bytes);
132
133 // Exactly one ServerName should be present
134 if (buffer.size() - res < 3)
135 return (i8)Error::NeedMoreData;
136 auto sni_name_type = (NameType)(*(u8 const*)buffer.offset_pointer(res++));
137 auto sni_name_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res += 2)));
138
139 if (sni_name_type != NameType::HostName)
140 return (i8)Error::NotUnderstood;
141
142 if (sizeof(sni_name_type) + sizeof(sni_name_length) + sni_name_length != sni_name_list_bytes)
143 return (i8)Error::BrokenPacket;
144
145 // Read out the host_name
146 if (buffer.size() - res < sni_name_length)
147 return (i8)Error::NeedMoreData;
148 m_context.extensions.SNI = DeprecatedString { (char const*)buffer.offset_pointer(res), sni_name_length };
149 res += sni_name_length;
150 dbgln("SNI host_name: {}", m_context.extensions.SNI);
151 }
152 } else if (extension_type == HandshakeExtension::ApplicationLayerProtocolNegotiation && m_context.alpn.size()) {
153 if (buffer.size() - res > 2) {
154 auto alpn_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(res)));
155 if (alpn_length && alpn_length <= extension_length - 2) {
156 u8 const* alpn = buffer.offset_pointer(res + 2);
157 size_t alpn_position = 0;
158 while (alpn_position < alpn_length) {
159 u8 alpn_size = alpn[alpn_position++];
160 if (alpn_size + alpn_position >= extension_length)
161 break;
162 DeprecatedString alpn_str { (char const*)alpn + alpn_position, alpn_length };
163 if (alpn_size && m_context.alpn.contains_slow(alpn_str)) {
164 m_context.negotiated_alpn = alpn_str;
165 dbgln("negotiated alpn: {}", alpn_str);
166 break;
167 }
168 alpn_position += alpn_length;
169 if (!m_context.is_server) // server hello must contain one ALPN
170 break;
171 }
172 }
173 }
174 res += extension_length;
175 } else if (extension_type == HandshakeExtension::SignatureAlgorithms) {
176 dbgln("supported signatures: ");
177 print_buffer(buffer.slice(res, extension_length));
178 res += extension_length;
179 // FIXME: what are we supposed to do here?
180 } else if (extension_type == HandshakeExtension::ECPointFormats) {
181 // RFC8422 section 5.2: A server that selects an ECC cipher suite in response to a ClientHello message
182 // including a Supported Point Formats Extension appends this extension (along with others) to its
183 // ServerHello message, enumerating the point formats it can parse. The Supported Point Formats Extension,
184 // when used, MUST contain the value 0 (uncompressed) as one of the items in the list of point formats.
185 //
186 // The current implementation only supports uncompressed points, and the server is required to support
187 // uncompressed points. Therefore, this extension can be safely ignored as it should always inform us
188 // that the server supports uncompressed points.
189 res += extension_length;
190 } else {
191 dbgln("Encountered unknown extension {} with length {}", (u16)extension_type, extension_length);
192 res += extension_length;
193 }
194 }
195
196 return res;
197}
198
199ssize_t TLSv12::handle_server_hello_done(ReadonlyBytes buffer)
200{
201 if (buffer.size() < 3)
202 return (i8)Error::NeedMoreData;
203
204 size_t size = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2];
205
206 if (buffer.size() - 3 < size)
207 return (i8)Error::NeedMoreData;
208
209 return size + 3;
210}
211
212ByteBuffer TLSv12::build_server_key_exchange()
213{
214 dbgln("FIXME: build_server_key_exchange");
215 return {};
216}
217
218ssize_t TLSv12::handle_server_key_exchange(ReadonlyBytes buffer)
219{
220 switch (get_key_exchange_algorithm(m_context.cipher)) {
221 case KeyExchangeAlgorithm::RSA:
222 case KeyExchangeAlgorithm::DH_DSS:
223 case KeyExchangeAlgorithm::DH_RSA:
224 // RFC 5246 section 7.4.3. Server Key Exchange Message
225 // It is not legal to send the server key exchange message for RSA, DH_DSS, DH_RSA
226 dbgln("Server key exchange received for RSA, DH_DSS or DH_RSA is not legal");
227 return (i8)Error::UnexpectedMessage;
228 case KeyExchangeAlgorithm::DHE_DSS:
229 dbgln("Server key exchange for DHE_DSS is not implemented");
230 TODO();
231 break;
232 case KeyExchangeAlgorithm::DHE_RSA:
233 return handle_dhe_rsa_server_key_exchange(buffer);
234 case KeyExchangeAlgorithm::DH_anon:
235 dbgln("Server key exchange for DH_anon is not implemented");
236 TODO();
237 break;
238 case KeyExchangeAlgorithm::ECDHE_RSA:
239 return handle_ecdhe_rsa_server_key_exchange(buffer);
240 case KeyExchangeAlgorithm::ECDH_ECDSA:
241 case KeyExchangeAlgorithm::ECDH_RSA:
242 case KeyExchangeAlgorithm::ECDHE_ECDSA:
243 case KeyExchangeAlgorithm::ECDH_anon:
244 dbgln("Server key exchange for ECDHE algorithms is not implemented");
245 TODO();
246 break;
247 default:
248 dbgln("Unknown server key exchange algorithm");
249 VERIFY_NOT_REACHED();
250 break;
251 }
252 return 0;
253}
254
255ssize_t TLSv12::handle_dhe_rsa_server_key_exchange(ReadonlyBytes buffer)
256{
257 auto dh_p_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(3)));
258 auto dh_p = buffer.slice(5, dh_p_length);
259 auto p_result = ByteBuffer::copy(dh_p);
260 if (p_result.is_error()) {
261 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
262 return (i8)Error::OutOfMemory;
263 }
264 m_context.server_diffie_hellman_params.p = p_result.release_value();
265
266 auto dh_g_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(5 + dh_p_length)));
267 auto dh_g = buffer.slice(7 + dh_p_length, dh_g_length);
268 auto g_result = ByteBuffer::copy(dh_g);
269 if (g_result.is_error()) {
270 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
271 return (i8)Error::OutOfMemory;
272 }
273 m_context.server_diffie_hellman_params.g = g_result.release_value();
274
275 auto dh_Ys_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(7 + dh_p_length + dh_g_length)));
276 auto dh_Ys = buffer.slice(9 + dh_p_length + dh_g_length, dh_Ys_length);
277 auto Ys_result = ByteBuffer::copy(dh_Ys);
278 if (Ys_result.is_error()) {
279 dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
280 return (i8)Error::OutOfMemory;
281 }
282 m_context.server_diffie_hellman_params.Ys = Ys_result.release_value();
283
284 if constexpr (TLS_DEBUG) {
285 dbgln("dh_p: {:hex-dump}", dh_p);
286 dbgln("dh_g: {:hex-dump}", dh_g);
287 dbgln("dh_Ys: {:hex-dump}", dh_Ys);
288 }
289
290 auto server_key_info = buffer.slice(3, 6 + dh_p_length + dh_g_length + dh_Ys_length);
291 auto signature = buffer.slice(9 + dh_p_length + dh_g_length + dh_Ys_length);
292 return verify_rsa_server_key_exchange(server_key_info, signature);
293}
294
295ssize_t TLSv12::handle_ecdhe_rsa_server_key_exchange(ReadonlyBytes buffer)
296{
297 if (buffer.size() < 7)
298 return (i8)Error::NeedMoreData;
299
300 auto curve_type = buffer[3];
301 if (curve_type != (u8)ECCurveType::NamedCurve)
302 return (i8)Error::NotUnderstood;
303
304 auto curve = static_cast<NamedCurve>(AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(4))));
305 if (!m_context.options.elliptic_curves.contains_slow(curve))
306 return (i8)Error::NotUnderstood;
307
308 switch ((NamedCurve)curve) {
309 case NamedCurve::x25519:
310 m_context.server_key_exchange_curve = make<Crypto::Curves::X25519>();
311 break;
312 case NamedCurve::x448:
313 m_context.server_key_exchange_curve = make<Crypto::Curves::X448>();
314 break;
315 case NamedCurve::secp256r1:
316 m_context.server_key_exchange_curve = make<Crypto::Curves::SECP256r1>();
317 break;
318 default:
319 return (i8)Error::NotUnderstood;
320 }
321
322 auto server_public_key_length = buffer[6];
323 if (server_public_key_length != m_context.server_key_exchange_curve->key_size())
324 return (i8)Error::NotUnderstood;
325
326 if (buffer.size() < 7u + server_public_key_length)
327 return (i8)Error::NeedMoreData;
328
329 auto server_public_key = buffer.slice(7, server_public_key_length);
330 auto server_public_key_copy_result = ByteBuffer::copy(server_public_key);
331 if (server_public_key_copy_result.is_error()) {
332 dbgln("ecdhe_rsa_server_key_exchange failed: Not enough memory");
333 return (i8)Error::OutOfMemory;
334 }
335 m_context.server_diffie_hellman_params.p = server_public_key_copy_result.release_value();
336
337 if constexpr (TLS_DEBUG) {
338 dbgln("ECDHE server public key: {:hex-dump}", server_public_key);
339 }
340
341 auto server_key_info = buffer.slice(3, 4 + server_public_key_length);
342 auto signature = buffer.slice(7 + server_public_key_length);
343 return verify_rsa_server_key_exchange(server_key_info, signature);
344}
345
346ssize_t TLSv12::verify_rsa_server_key_exchange(ReadonlyBytes server_key_info_buffer, ReadonlyBytes signature_buffer)
347{
348 auto signature_hash = signature_buffer[0];
349 auto signature_algorithm = signature_buffer[1];
350 if (signature_algorithm != (u8)SignatureAlgorithm::RSA) {
351 dbgln("verify_rsa_server_key_exchange failed: Signature algorithm is not RSA, instead {}", signature_algorithm);
352 return (i8)Error::NotUnderstood;
353 }
354
355 auto signature_length = AK::convert_between_host_and_network_endian(ByteReader::load16(signature_buffer.offset_pointer(2)));
356 auto signature = signature_buffer.slice(4, signature_length);
357
358 if (m_context.certificates.is_empty()) {
359 dbgln("verify_rsa_server_key_exchange failed: Attempting to verify signature without certificates");
360 return (i8)Error::NotSafe;
361 }
362 // RFC5246 section 7.4.2: The sender's certificate MUST come first in the list.
363 auto certificate_public_key = m_context.certificates.first().public_key;
364 Crypto::PK::RSAPrivateKey dummy_private_key;
365 auto rsa = Crypto::PK::RSA(certificate_public_key, dummy_private_key);
366
367 auto signature_verify_buffer_result = ByteBuffer::create_uninitialized(signature_length);
368 if (signature_verify_buffer_result.is_error()) {
369 dbgln("verify_rsa_server_key_exchange failed: Not enough memory");
370 return (i8)Error::OutOfMemory;
371 }
372 auto signature_verify_buffer = signature_verify_buffer_result.release_value();
373 auto signature_verify_bytes = signature_verify_buffer.bytes();
374 rsa.verify(signature, signature_verify_bytes);
375
376 auto message_result = ByteBuffer::create_uninitialized(64 + server_key_info_buffer.size());
377 if (message_result.is_error()) {
378 dbgln("verify_rsa_server_key_exchange failed: Not enough memory");
379 return (i8)Error::OutOfMemory;
380 }
381 auto message = message_result.release_value();
382 message.overwrite(0, m_context.local_random, 32);
383 message.overwrite(32, m_context.remote_random, 32);
384 message.overwrite(64, server_key_info_buffer.data(), server_key_info_buffer.size());
385
386 Crypto::Hash::HashKind hash_kind;
387 switch ((HashAlgorithm)signature_hash) {
388 case HashAlgorithm::SHA1:
389 hash_kind = Crypto::Hash::HashKind::SHA1;
390 break;
391 case HashAlgorithm::SHA256:
392 hash_kind = Crypto::Hash::HashKind::SHA256;
393 break;
394 case HashAlgorithm::SHA384:
395 hash_kind = Crypto::Hash::HashKind::SHA384;
396 break;
397 case HashAlgorithm::SHA512:
398 hash_kind = Crypto::Hash::HashKind::SHA512;
399 break;
400 default:
401 dbgln("verify_rsa_server_key_exchange failed: Hash algorithm is not SHA1/256/384/512, instead {}", signature_hash);
402 return (i8)Error::NotUnderstood;
403 }
404
405 auto pkcs1 = Crypto::PK::EMSA_PKCS1_V1_5<Crypto::Hash::Manager>(hash_kind);
406 auto verification = pkcs1.verify(message, signature_verify_bytes, signature_length * 8);
407
408 if (verification == Crypto::VerificationConsistency::Inconsistent) {
409 dbgln("verify_rsa_server_key_exchange failed: Verification of signature inconsistent");
410 return (i8)Error::NotSafe;
411 }
412
413 return 0;
414}
415}