lib/quic/src/tls/engine/test.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const quic = @import("../../root.zig");
3 const tls = @import("../root.zig");
4
5 const limits = tls.Limits{ .max_message = 512 };
6 const storage_bytes: usize = 4_124;
7
8 const HarnessOptions = struct {
9 client_expected: ?tls.PublicKey = null,
10 server_expected_override: ?tls.PublicKey = null,
11 server_alpn: []const u8 = "tiny/1",
12 };
13
14 const Harness = struct {
15 client_bytes: [storage_bytes]u8 align(tls.Storage.storage_alignment),
16 server_bytes: [storage_bytes]u8 align(tls.Storage.storage_alignment),
17 client_storage: tls.Storage,
18 server_storage: tls.Storage,
19 client: tls.Engine,
20 server: tls.Engine,
21
22 fn init(self: *Harness, client_expected: ?tls.PublicKey) !void {
23 return self.initWith(.{ .client_expected = client_expected });
24 }
25
26 fn initWith(self: *Harness, options: HarnessOptions) !void {
27 const client_identity = try tls.Identity.fromSeed(@splat(0x11));
28 const server_identity = try tls.Identity.fromSeed(@splat(0x22));
29 const server_expected = options.server_expected_override orelse client_identity.public();
30 self.client_storage = try tls.Storage.init(&self.client_bytes, limits);
31 self.server_storage = try tls.Storage.init(&self.server_bytes, limits);
32 self.client = try tls.Engine.init(.{
33 .role = .client,
34 .identity = client_identity,
35 .expected_peer = options.client_expected,
36 .alpn = "tiny/1",
37 .transport_parameters = &.{ 0x01, 0x02 },
38 .server_name = "peer.test",
39 .random = tls.Random.testing(fixedRandom(0x33, 0x44)),
40 }, limits, &self.client_storage);
41 self.server = try tls.Engine.init(.{
42 .role = .server,
43 .identity = server_identity,
44 .expected_peer = server_expected,
45 .alpn = options.server_alpn,
46 .transport_parameters = &.{ 0x03, 0x04, 0x05 },
47 .server_name = "peer.test",
48 .random = tls.Random.testing(fixedRandom(0x55, 0x66)),
49 }, limits, &self.server_storage);
50 }
51
52 fn exchangeInitial(self: *Harness, wire: []u8) !void {
53 try transfer(&self.client, &self.server, .initial, wire);
54 try transfer(&self.server, &self.client, .initial, wire);
55 }
56
57 fn finish(self: *Harness, wire: []u8) !void {
58 try self.exchangeInitial(wire);
59 try transfer(&self.server, &self.client, .handshake, wire);
60 try transfer(&self.client, &self.server, .handshake, wire);
61 }
62
63 fn deinit(self: *Harness) void {
64 self.client.deinit();
65 self.server.deinit();
66 _ = self.client_storage.deinit();
67 _ = self.server_storage.deinit();
68 }
69 };
70
71 fn fixedRandom(hello: u8, key: u8) tls.FixedRandom {
72 return .{ .hello = @splat(hello), .key_exchange = @splat(key) };
73 }
74
75 fn transfer(sender: *tls.Engine, receiver: *tls.Engine, level: tls.Level, wire: []u8) !void {
76 const count = sender.emit(level, wire);
77 try std.testing.expect(count != 0);
78 try receiver.receive(level, wire[0..count]);
79 }
80
81 fn transferChunked(sender: *tls.Engine, receiver: *tls.Engine, level: tls.Level) !void {
82 var byte: [1]u8 = undefined;
83 for (0..2_048) |_| {
84 const count = sender.emit(level, &byte);
85 if (count == 0) return;
86 try std.testing.expectEqual(@as(usize, 1), count);
87 try receiver.receive(level, &byte);
88 }
89 return error.FlightTooLarge;
90 }
91
92 fn handshakeOffset(bytes: []const u8, wanted: std.crypto.tls.HandshakeType) !usize {
93 var offset: usize = 0;
94 for (0..8) |_| {
95 if (offset == bytes.len) return error.NotFound;
96 if (bytes.len - offset < 4) return error.Truncated;
97 const length = (@as(usize, bytes[offset + 1]) << 16) |
98 (@as(usize, bytes[offset + 2]) << 8) | bytes[offset + 3];
99 if (length > bytes.len - offset - 4) return error.Truncated;
100 if (bytes[offset] == @backingInt(wanted)) return offset;
101 offset += length + 4;
102 }
103 return error.NotFound;
104 }
105
106 fn clientExtensionOffset(bytes: []const u8, wanted: std.crypto.tls.ExtensionType) !usize {
107 const hello = try tls.message.decodeClientHello(bytes);
108 var iterator = hello.extensions.iterator();
109 for (0..tls.message.extension_count_max + 1) |_| {
110 const item = try iterator.next() orelse return error.NotFound;
111 if (@backingInt(item.kind) != @backingInt(wanted)) continue;
112 return @intFromPtr(item.data.ptr) - @intFromPtr(bytes.ptr) - 4;
113 }
114 unreachable;
115 }
116
117 test "RFC 8446 section 4 mutual raw-key loopback handshake" {
118 var harness: Harness = undefined;
119 try harness.init(null);
120 defer harness.deinit();
121 var wire: [2_048]u8 = undefined;
122 try harness.finish(&wire);
123 try std.testing.expectEqual(tls.Status.handshake_complete, harness.client.state());
124 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.server.state());
125 try std.testing.expectEqual(
126 std.crypto.tls.CipherSuite.AES_128_GCM_SHA256,
127 harness.client.cipherSuite().?,
128 );
129 try std.testing.expectEqual(harness.client.cipherSuite(), harness.server.cipherSuite());
130 try std.testing.expectEqual(
131 harness.client.secret(.one_rtt, .write),
132 harness.server.secret(.one_rtt, .read),
133 );
134 try std.testing.expectEqual(
135 harness.client.secret(.one_rtt, .read),
136 harness.server.secret(.one_rtt, .write),
137 );
138 try expectPeers(&harness);
139 harness.client.confirm();
140 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.client.state());
141 }
142
143 test "RFC 9001 sections 4.1 and 5.7 role status and secret sequence" {
144 var harness: Harness = undefined;
145 try harness.init(null);
146 defer harness.deinit();
147 var wire: [2_048]u8 = undefined;
148 try std.testing.expectEqual(tls.Status.handshaking, harness.client.state());
149 try std.testing.expectEqual(tls.Status.handshaking, harness.server.state());
150 try transfer(&harness.client, &harness.server, .initial, &wire);
151 try std.testing.expect(harness.server.secret(.one_rtt, .write) != null);
152 try std.testing.expectEqual(@as(?tls.Secret, null), harness.server.secret(.one_rtt, .read));
153 try std.testing.expect(std.mem.allEqual(u8, &harness.server.schedule.?.early, 0));
154 try std.testing.expect(std.mem.allEqual(u8, &harness.server.schedule.?.handshake, 0));
155 try std.testing.expect(std.mem.allEqual(u8, &harness.server.schedule.?.master, 0));
156 try transfer(&harness.server, &harness.client, .initial, &wire);
157 try std.testing.expectEqual(
158 harness.client.secret(.handshake, .write),
159 harness.server.secret(.handshake, .read),
160 );
161 try std.testing.expectEqual(
162 harness.client.secret(.handshake, .read),
163 harness.server.secret(.handshake, .write),
164 );
165 try transfer(&harness.server, &harness.client, .handshake, &wire);
166 try std.testing.expectEqual(tls.Status.handshaking, harness.client.state());
167 try std.testing.expectEqual(tls.Status.handshaking, harness.server.state());
168 try std.testing.expectEqual(@as(?tls.Secret, null), harness.server.secret(.one_rtt, .read));
169 try transfer(&harness.client, &harness.server, .handshake, &wire);
170 try std.testing.expectEqual(tls.Status.handshake_complete, harness.client.state());
171 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.server.state());
172 try std.testing.expectEqual(
173 harness.client.secret(.one_rtt, .write),
174 harness.server.secret(.one_rtt, .read),
175 );
176 try std.testing.expectEqual(@as(?tls.Secret, null), harness.server.secret(.handshake, .read));
177 try std.testing.expect(std.mem.allEqual(
178 u8,
179 &harness.server.schedule.?.client_handshake,
180 0,
181 ));
182 try std.testing.expect(std.mem.allEqual(
183 u8,
184 &harness.server.schedule.?.server_handshake,
185 0,
186 ));
187 harness.client.confirm();
188 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.client.state());
189 try std.testing.expectEqual(@as(?tls.Secret, null), harness.client.secret(.handshake, .write));
190 }
191
192 test "RFC 9000 section 13.3 emitted handshake bytes stay readable for a resent CRYPTO frame" {
193 var harness: Harness = undefined;
194 try harness.init(null);
195 defer harness.deinit();
196 var wire: [512]u8 = undefined;
197 try std.testing.expectEqual(@as(usize, 0), harness.client.emitted(.initial).len);
198 const head = harness.client.emit(.initial, wire[0..16]);
199 try std.testing.expectEqual(@as(usize, 16), head);
200 try std.testing.expectEqualSlices(u8, wire[0..head], harness.client.emitted(.initial));
201 const tail = harness.client.emit(.initial, wire[head..]);
202 try std.testing.expect(tail != 0);
203 const flight = harness.client.emitted(.initial);
204 try std.testing.expectEqualSlices(u8, wire[0 .. head + tail], flight);
205 try std.testing.expectEqual(@as(usize, 0), harness.client.emitted(.handshake).len);
206 try std.testing.expectEqual(@as(usize, 0), harness.client.emitted(.one_rtt).len);
207 }
208
209 test "RFC 8446 section 4 partial handshake messages remain buffered" {
210 var harness: Harness = undefined;
211 try harness.init(null);
212 defer harness.deinit();
213 try transferChunked(&harness.client, &harness.server, .initial);
214 try transferChunked(&harness.server, &harness.client, .initial);
215 try transferChunked(&harness.server, &harness.client, .handshake);
216 try transferChunked(&harness.client, &harness.server, .handshake);
217 try std.testing.expectEqual(tls.Status.handshake_complete, harness.client.state());
218 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.server.state());
219 }
220
221 test "RFC 9001 section 4.1.3 partial messages cannot cross encryption levels" {
222 var harness: Harness = undefined;
223 try harness.init(null);
224 defer harness.deinit();
225 var wire: [2_048]u8 = undefined;
226 const count = harness.client.emit(.initial, &wire);
227 wire[count] = @backingInt(std.crypto.tls.HandshakeType.certificate);
228 wire[count + 1] = 0;
229 try harness.server.receive(.initial, wire[0 .. count + 2]);
230 try std.testing.expectError(
231 error.TlsAlert,
232 harness.server.receive(.handshake, &.{0}),
233 );
234 try std.testing.expectEqual(tls.Alert.unexpected_message, harness.server.alert().?);
235 }
236
237 test "RFC 8446 section 4.1.3 ChaCha20 handshake confirms with matching secrets" {
238 var harness: Harness = undefined;
239 try harness.init(null);
240 defer harness.deinit();
241 var wire: [2_048]u8 = undefined;
242 const count = harness.client.emit(.initial, &wire);
243 const hello = try tls.message.decodeClientHello(wire[0..count]);
244 const offset = @intFromPtr(hello.cipher_suites.ptr) - @intFromPtr(wire[0..].ptr);
245 const chacha = @backingInt(std.crypto.tls.CipherSuite.CHACHA20_POLY1305_SHA256);
246 wire[offset] = @truncate(chacha >> 8);
247 wire[offset + 1] = @truncate(chacha);
248 wire[offset + 2] = @truncate(chacha >> 8);
249 wire[offset + 3] = @truncate(chacha);
250 harness.client.transcript = std.crypto.hash.sha2.Sha256.init(.{});
251 harness.client.transcript.update(wire[0..count]);
252 try harness.server.receive(.initial, wire[0..count]);
253 const response_count = harness.server.emit(.initial, &wire);
254 const response = try tls.message.decodeServerHello(wire[0..response_count]);
255 try std.testing.expectEqual(chacha, response.cipher_suite);
256 try std.testing.expectEqual(
257 std.crypto.tls.CipherSuite.CHACHA20_POLY1305_SHA256,
258 harness.server.cipherSuite().?,
259 );
260 try harness.client.receive(.initial, wire[0..response_count]);
261 try transfer(&harness.server, &harness.client, .handshake, &wire);
262 try transfer(&harness.client, &harness.server, .handshake, &wire);
263 harness.client.confirm();
264 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.client.state());
265 try std.testing.expectEqual(tls.Status.handshake_confirmed, harness.server.state());
266 try std.testing.expectEqual(harness.client.cipherSuite(), harness.server.cipherSuite());
267 try std.testing.expectEqual(
268 harness.client.secret(.one_rtt, .write),
269 harness.server.secret(.one_rtt, .read),
270 );
271 try std.testing.expectEqual(
272 harness.client.secret(.one_rtt, .read),
273 harness.server.secret(.one_rtt, .write),
274 );
275 }
276
277 test "RFC 8446 section 4.1.4 HelloRetryRequest aborts" {
278 var harness: Harness = undefined;
279 try harness.init(null);
280 defer harness.deinit();
281 var bytes: [128]u8 = undefined;
282 var output = quic.cursor.Write.init(&bytes);
283 try tls.message.profile.encodeServerHello(.{
284 .random = std.crypto.tls.hello_retry_request_sequence,
285 .key_share = @splat(0xa5),
286 .cipher_suite = .AES_128_GCM_SHA256,
287 }, &output);
288 try std.testing.expectError(
289 error.TlsAlert,
290 harness.client.receive(.initial, output.written()),
291 );
292 try std.testing.expectEqual(tls.Alert.handshake_failure, harness.client.alert().?);
293 }
294
295 test "RFC 8446 section 4.1.3 ServerHello downgrade sentinel aborts" {
296 var harness: Harness = undefined;
297 try harness.init(null);
298 defer harness.deinit();
299 var random: [32]u8 = @splat(0xa5);
300 @memcpy(random[24..], "DOWNGRD\x01");
301 var bytes: [128]u8 = undefined;
302 var output = quic.cursor.Write.init(&bytes);
303 try tls.message.profile.encodeServerHello(.{
304 .random = random,
305 .key_share = @splat(0x5a),
306 .cipher_suite = .AES_128_GCM_SHA256,
307 }, &output);
308 const hello = try tls.message.decodeServerHello(output.written());
309 const version = (try tls.message.findExtension(hello.extensions, .supported_versions)).?;
310 const version_offset = @intFromPtr(version.ptr) - @intFromPtr(bytes[0..].ptr);
311 bytes[version_offset + 1] = 0x03;
312 try std.testing.expectError(
313 error.TlsAlert,
314 harness.client.receive(.initial, output.written()),
315 );
316 try std.testing.expectEqual(tls.Alert.illegal_parameter, harness.client.alert().?);
317 }
318
319 test "RFC 8446 section 4.2.8.2 X25519 all-zero shared secret aborts" {
320 var harness: Harness = undefined;
321 try harness.init(null);
322 defer harness.deinit();
323 var bytes: [128]u8 = undefined;
324 var output = quic.cursor.Write.init(&bytes);
325 try tls.message.profile.encodeServerHello(.{
326 .random = @splat(0xa5),
327 .key_share = @splat(0),
328 .cipher_suite = .AES_128_GCM_SHA256,
329 }, &output);
330 try std.testing.expectError(
331 error.TlsAlert,
332 harness.client.receive(.initial, output.written()),
333 );
334 try std.testing.expectEqual(tls.Alert.illegal_parameter, harness.client.alert().?);
335 }
336
337 test "RFC 9001 section 6 KeyUpdate aborts with unexpected message" {
338 var harness: Harness = undefined;
339 try harness.init(null);
340 defer harness.deinit();
341 const bytes = [_]u8{ @backingInt(std.crypto.tls.HandshakeType.key_update), 0, 0, 1, 0 };
342 try std.testing.expectError(error.TlsAlert, harness.server.receive(.one_rtt, &bytes));
343 try std.testing.expectEqual(tls.Alert.unexpected_message, harness.server.alert().?);
344 }
345
346 const ticket_type = @backingInt(std.crypto.tls.HandshakeType.new_session_ticket);
347 const session_ticket = [_]u8{ ticket_type, 0, 0, 14, 0, 0, 0, 60, 1, 2, 3, 4, 0, 0, 1, 90, 0, 0 };
348
349 test "RFC 8446 section 4.6.1 client parses a NewSessionTicket" {
350 var harness: Harness = undefined;
351 try harness.init(null);
352 defer harness.deinit();
353 try harness.client.receive(.one_rtt, &session_ticket);
354 try std.testing.expectEqual(@as(?tls.Alert, null), harness.client.alert());
355 }
356
357 test "RFC 8446 section 4.6.1 empty ticket aborts with decode error" {
358 var harness: Harness = undefined;
359 try harness.init(null);
360 defer harness.deinit();
361 const bytes = [_]u8{ ticket_type, 0, 0, 13, 0, 0, 0, 60, 1, 2, 3, 4, 0, 0, 0, 0, 0 };
362 try std.testing.expectError(error.TlsAlert, harness.client.receive(.one_rtt, &bytes));
363 try std.testing.expectEqual(tls.Alert.decode_error, harness.client.alert().?);
364 }
365
366 test "RFC 8446 section 4.6.1 server rejects a NewSessionTicket" {
367 var harness: Harness = undefined;
368 try harness.init(null);
369 defer harness.deinit();
370 try std.testing.expectError(error.TlsAlert, harness.server.receive(.one_rtt, &session_ticket));
371 try std.testing.expectEqual(tls.Alert.unexpected_message, harness.server.alert().?);
372 }
373
374 test "RFC 8446 section 4.4.2.4 empty client Certificate aborts" {
375 var harness: Harness = undefined;
376 try harness.init(null);
377 defer harness.deinit();
378 var wire: [2_048]u8 = undefined;
379 try transfer(&harness.client, &harness.server, .initial, &wire);
380 var output = quic.cursor.Write.init(&wire);
381 try tls.message.encodeCertificate(.{
382 .request_context = &.{},
383 .entries = .{ .bytes = &.{} },
384 }, &output);
385 try std.testing.expectError(
386 error.TlsAlert,
387 harness.server.receive(.handshake, output.written()),
388 );
389 try std.testing.expectEqual(tls.Alert.certificate_required, harness.server.alert().?);
390 }
391
392 test "RFC 8446 section 4.4.2.4 empty server Certificate uses decode error" {
393 var harness: Harness = undefined;
394 try harness.init(null);
395 defer harness.deinit();
396 var wire: [2_048]u8 = undefined;
397 try harness.exchangeInitial(&wire);
398 const count = harness.server.emit(.handshake, &wire);
399 const certificate_offset = try handshakeOffset(wire[0..count], .certificate);
400 try harness.client.receive(.handshake, wire[0..certificate_offset]);
401 var empty: [16]u8 = undefined;
402 var output = quic.cursor.Write.init(&empty);
403 try tls.message.encodeCertificate(.{
404 .request_context = &.{},
405 .entries = .{ .bytes = &.{} },
406 }, &output);
407 try std.testing.expectError(
408 error.TlsAlert,
409 harness.client.receive(.handshake, output.written()),
410 );
411 try std.testing.expectEqual(tls.Alert.decode_error, harness.client.alert().?);
412 }
413
414 fn expectPeers(harness: *const Harness) !void {
415 const client_peer = harness.client.peer().?;
416 const server_peer = harness.server.peer().?;
417 try std.testing.expectEqual(harness.server.config.identity.public(), client_peer.public_key);
418 try std.testing.expectEqual(harness.client.config.identity.public(), server_peer.public_key);
419 try std.testing.expectEqualStrings("tiny/1", client_peer.alpn);
420 try std.testing.expectEqualStrings("tiny/1", server_peer.alpn);
421 try std.testing.expectEqualSlices(u8, &.{ 0x03, 0x04, 0x05 }, client_peer.transport_parameters);
422 try std.testing.expectEqualSlices(u8, &.{ 0x01, 0x02 }, server_peer.transport_parameters);
423 }
424
425 test "RFC 8446 section 4.4.2 wrong expected raw key aborts" {
426 var harness: Harness = undefined;
427 try harness.init(@splat(0xaa));
428 defer harness.deinit();
429 var wire: [2_048]u8 = undefined;
430 try harness.exchangeInitial(&wire);
431 const count = harness.server.emit(.handshake, &wire);
432 try std.testing.expectError(error.TlsAlert, harness.client.receive(.handshake, wire[0..count]));
433 try std.testing.expectEqual(tls.Alert.bad_certificate, harness.client.alert().?);
434 }
435
436 test "RFC 8446 section 4.4.2 wrong server-side expected raw key aborts" {
437 var harness: Harness = undefined;
438 try harness.initWith(.{ .server_expected_override = @splat(0xaa) });
439 defer harness.deinit();
440 var wire: [2_048]u8 = undefined;
441 try harness.exchangeInitial(&wire);
442 try transfer(&harness.server, &harness.client, .handshake, &wire);
443 const count = harness.client.emit(.handshake, &wire);
444 try std.testing.expectError(
445 error.TlsAlert,
446 harness.server.receive(.handshake, wire[0..count]),
447 );
448 try std.testing.expectEqual(tls.Alert.bad_certificate, harness.server.alert().?);
449 }
450
451 test "RFC 8446 section 4.4.3 modified CertificateVerify aborts" {
452 var harness: Harness = undefined;
453 try harness.init(null);
454 defer harness.deinit();
455 var wire: [2_048]u8 = undefined;
456 try harness.exchangeInitial(&wire);
457 const count = harness.server.emit(.handshake, &wire);
458 const offset = try handshakeOffset(wire[0..count], .certificate_verify);
459 wire[offset + 10] ^= 1;
460 try std.testing.expectError(error.TlsAlert, harness.client.receive(.handshake, wire[0..count]));
461 try std.testing.expectEqual(tls.Alert.decrypt_error, harness.client.alert().?);
462 }
463
464 test "RFC 8446 section 4.4.4 modified Finished aborts" {
465 var harness: Harness = undefined;
466 try harness.init(null);
467 defer harness.deinit();
468 var wire: [2_048]u8 = undefined;
469 try harness.exchangeInitial(&wire);
470 const count = harness.server.emit(.handshake, &wire);
471 const offset = try handshakeOffset(wire[0..count], .finished);
472 wire[offset + 4] ^= 1;
473 try std.testing.expectError(error.TlsAlert, harness.client.receive(.handshake, wire[0..count]));
474 try std.testing.expectEqual(tls.Alert.decrypt_error, harness.client.alert().?);
475 }
476
477 test "RFC 9001 section 8.1 missing ClientHello ALPN aborts" {
478 try expectMissingClientExtension(
479 .application_layer_protocol_negotiation,
480 .no_application_protocol,
481 );
482 }
483
484 test "RFC 9001 section 8.1 disjoint ClientHello ALPN aborts" {
485 var harness: Harness = undefined;
486 try harness.initWith(.{ .server_alpn = "other/1" });
487 defer harness.deinit();
488 var wire: [2_048]u8 = undefined;
489 const count = harness.client.emit(.initial, &wire);
490 try std.testing.expectError(
491 error.TlsAlert,
492 harness.server.receive(.initial, wire[0..count]),
493 );
494 try std.testing.expectEqual(tls.Alert.no_application_protocol, harness.server.alert().?);
495 }
496
497 test "RFC 9001 section 8.2 missing QUIC transport parameters aborts" {
498 try expectMissingClientExtension(.quic_transport_parameters, .missing_extension);
499 }
500
501 fn expectMissingClientExtension(
502 kind: std.crypto.tls.ExtensionType,
503 alert_value: tls.Alert,
504 ) !void {
505 var harness: Harness = undefined;
506 try harness.init(null);
507 defer harness.deinit();
508 var wire: [2_048]u8 = undefined;
509 const count = harness.client.emit(.initial, &wire);
510 const offset = try clientExtensionOffset(wire[0..count], kind);
511 wire[offset] = 0xaa;
512 wire[offset + 1] = 0xaa;
513 try std.testing.expectError(error.TlsAlert, harness.server.receive(.initial, wire[0..count]));
514 try std.testing.expectEqual(alert_value, harness.server.alert().?);
515 }
516
517 test "RFC 8446 section 7.1 Engine teardown erases secrets and storage" {
518 var harness: Harness = undefined;
519 try harness.init(null);
520 var wire: [2_048]u8 = undefined;
521 try harness.finish(&wire);
522 try std.testing.expect(!std.mem.allEqual(u8, std.mem.asBytes(&harness.client), 0));
523 harness.deinit();
524 try std.testing.expect(std.mem.allEqual(u8, std.mem.asBytes(&harness.client), 0));
525 try std.testing.expect(std.mem.allEqual(u8, std.mem.asBytes(&harness.server), 0));
526 try std.testing.expect(std.mem.allEqual(u8, &harness.client_bytes, 0));
527 try std.testing.expect(std.mem.allEqual(u8, &harness.server_bytes, 0));
528 }
529
530 test "RFC 8446 section 4 handshake message maximum and maximum plus one" {
531 const small_limits = tls.Limits{ .max_message = 256 };
532 const capacity = try tls.Capacity.derive(small_limits);
533 try std.testing.expectEqual(@as(usize, 2_076), capacity.storage_bytes);
534 var bytes: [2_076]u8 align(tls.Storage.storage_alignment) = undefined;
535 var owner = try tls.Storage.init(&bytes, small_limits);
536 const identity = try tls.Identity.fromSeed(@splat(0x77));
537 var engine = try tls.Engine.init(.{
538 .role = .client,
539 .identity = identity,
540 .expected_peer = null,
541 .alpn = "a",
542 .transport_parameters = &.{},
543 .server_name = null,
544 .random = tls.Random.testing(fixedRandom(0x88, 0x99)),
545 }, small_limits, &owner);
546 var message: [260]u8 = @splat(0);
547 message[0] = @backingInt(std.crypto.tls.HandshakeType.new_session_ticket);
548 message[2] = 1;
549 message[14] = 243;
550 try engine.receive(.one_rtt, &message);
551 var too_large = [_]u8{
552 @backingInt(std.crypto.tls.HandshakeType.new_session_ticket), 0, 1, 1,
553 };
554 try std.testing.expectError(error.MessageTooLarge, engine.receive(.one_rtt, &too_large));
555 engine.deinit();
556 _ = owner.deinit();
557 }