authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-18 16:17:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 16:57:15-07:00
log41f4461cdabb50e45c0f956d4a1380d2008cd127
tree89778d75b5c0263f4e25686b6249d2270208984e
parentf6c3a86f0f570a2feb721e443efea3319d19d098

std.crypto.tls.Client: verify the server's Finished message


2 files changed, 11 insertions(+), 2 deletions(-)

lib/std/crypto/tls.zig+1
...@@ -237,6 +237,7 @@ pub fn CipherParamsT(comptime AeadType: type, comptime HashType: type) type {...@@ -237,6 +237,7 @@ pub fn CipherParamsT(comptime AeadType: type, comptime HashType: type) type {
237 client_handshake_iv: [AEAD.nonce_length]u8,237 client_handshake_iv: [AEAD.nonce_length]u8,
238 server_handshake_iv: [AEAD.nonce_length]u8,238 server_handshake_iv: [AEAD.nonce_length]u8,
239 transcript_hash: Hash,239 transcript_hash: Hash,
240 finished_digest: [Hash.digest_length]u8,
240 };241 };
241}242}
242243
lib/std/crypto/tls/Client.zig+10-2
...@@ -257,6 +257,7 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -257,6 +257,7 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
257 .client_handshake_iv = undefined,257 .client_handshake_iv = undefined,
258 .server_handshake_iv = undefined,258 .server_handshake_iv = undefined,
259 .transcript_hash = P.Hash.init(.{}),259 .transcript_hash = P.Hash.init(.{}),
260 .finished_digest = undefined,
260 });261 });
261 const p = &@field(cipher_params, @tagName(tag));262 const p = &@field(cipher_params, @tagName(tag));
262 p.transcript_hash.update(client_hello_bytes1); // Client Hello part 1263 p.transcript_hash.update(client_hello_bytes1); // Client Hello part 1
...@@ -391,6 +392,11 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -391,6 +392,11 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
391 },392 },
392 @enumToInt(HandshakeType.certificate_verify) => {393 @enumToInt(HandshakeType.certificate_verify) => {
393 std.debug.print("the certificate came with a fancy signature\n", .{});394 std.debug.print("the certificate came with a fancy signature\n", .{});
395 switch (cipher_params) {
396 inline else => |*p| {
397 p.finished_digest = p.transcript_hash.peek();
398 },
399 }
394 },400 },
395 @enumToInt(HandshakeType.finished) => {401 @enumToInt(HandshakeType.finished) => {
396 // This message is to trick buggy proxies into behaving correctly.402 // This message is to trick buggy proxies into behaving correctly.
...@@ -403,7 +409,10 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -403,7 +409,10 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
403 const app_cipher = switch (cipher_params) {409 const app_cipher = switch (cipher_params) {
404 inline else => |*p, tag| c: {410 inline else => |*p, tag| c: {
405 const P = @TypeOf(p.*);411 const P = @TypeOf(p.*);
406 // TODO verify the server's data412 const expected_server_verify_data = tls.hmac(P.Hmac, &p.finished_digest, p.server_finished_key);
413 const actual_server_verify_data = cleartext[ct_i..][0..handshake_len];
414 if (!mem.eql(u8, &expected_server_verify_data, actual_server_verify_data))
415 return error.TlsDecryptError;
407 const handshake_hash = p.transcript_hash.finalResult();416 const handshake_hash = p.transcript_hash.finalResult();
408 const verify_data = tls.hmac(P.Hmac, &handshake_hash, p.client_finished_key);417 const verify_data = tls.hmac(P.Hmac, &handshake_hash, p.client_finished_key);
409 const out_cleartext = [_]u8{418 const out_cleartext = [_]u8{
...@@ -454,7 +463,6 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -454,7 +463,6 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
454 };463 };
455 },464 },
456 else => {465 else => {
457 std.debug.print("handshake type: {d}\n", .{cleartext[0]});
458 return error.TlsUnexpectedMessage;466 return error.TlsUnexpectedMessage;
459 },467 },
460 }468 }