| ... | @@ -5,18 +5,14 @@ const net = std.net; | ... | @@ -5,18 +5,14 @@ const net = std.net; |
| 5 | const mem = std.mem; | 5 | const mem = std.mem; |
| 6 | const crypto = std.crypto; | 6 | const crypto = std.crypto; |
| 7 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| | 8 | const Certificate = std.crypto.Certificate; |
| 8 | | 9 | |
| 9 | const ApplicationCipher = tls.ApplicationCipher; | | |
| 10 | const CipherSuite = tls.CipherSuite; | | |
| 11 | const ContentType = tls.ContentType; | | |
| 12 | const HandshakeCipher = tls.HandshakeCipher; | | |
| 13 | const max_ciphertext_len = tls.max_ciphertext_len; | 10 | const max_ciphertext_len = tls.max_ciphertext_len; |
| 14 | const hkdfExpandLabel = tls.hkdfExpandLabel; | 11 | const hkdfExpandLabel = tls.hkdfExpandLabel; |
| 15 | const int2 = tls.int2; | 12 | const int2 = tls.int2; |
| 16 | const int3 = tls.int3; | 13 | const int3 = tls.int3; |
| 17 | const array = tls.array; | 14 | const array = tls.array; |
| 18 | const enum_array = tls.enum_array; | 15 | const enum_array = tls.enum_array; |
| 19 | const Certificate = crypto.Certificate; | | |
| 20 | | 16 | |
| 21 | read_seq: u64, | 17 | read_seq: u64, |
| 22 | write_seq: u64, | 18 | write_seq: u64, |
| ... | @@ -27,7 +23,7 @@ partially_read_len: u15, | ... | @@ -27,7 +23,7 @@ partially_read_len: u15, |
| 27 | /// re-decrypt bytes from `partially_read_buffer` when the buffer supplied by | 23 | /// re-decrypt bytes from `partially_read_buffer` when the buffer supplied by |
| 28 | /// the read() API user is not large enough. | 24 | /// the read() API user is not large enough. |
| 29 | partial_cleartext_index: u15, | 25 | partial_cleartext_index: u15, |
| 30 | application_cipher: ApplicationCipher, | 26 | application_cipher: tls.ApplicationCipher, |
| 31 | eof: bool, | 27 | eof: bool, |
| 32 | /// The size is enough to contain exactly one TLSCiphertext record. | 28 | /// The size is enough to contain exactly one TLSCiphertext record. |
| 33 | /// Contains encrypted bytes. | 29 | /// Contains encrypted bytes. |
| ... | @@ -101,7 +97,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -101,7 +97,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 101 | client_hello; | 97 | client_hello; |
| 102 | | 98 | |
| 103 | const plaintext_header = [_]u8{ | 99 | const plaintext_header = [_]u8{ |
| 104 | @enumToInt(ContentType.handshake), | 100 | @enumToInt(tls.ContentType.handshake), |
| 105 | 0x03, 0x01, // legacy_record_version | 101 | 0x03, 0x01, // legacy_record_version |
| 106 | } ++ int2(@intCast(u16, out_handshake.len + host_len)) ++ out_handshake; | 102 | } ++ int2(@intCast(u16, out_handshake.len + host_len)) ++ out_handshake; |
| 107 | | 103 | |
| ... | @@ -121,7 +117,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -121,7 +117,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 121 | | 117 | |
| 122 | const client_hello_bytes1 = plaintext_header[5..]; | 118 | const client_hello_bytes1 = plaintext_header[5..]; |
| 123 | | 119 | |
| 124 | var handshake_cipher: HandshakeCipher = undefined; | 120 | var handshake_cipher: tls.HandshakeCipher = undefined; |
| 125 | | 121 | |
| 126 | var handshake_buf: [8000]u8 = undefined; | 122 | var handshake_buf: [8000]u8 = undefined; |
| 127 | var len: usize = 0; | 123 | var len: usize = 0; |
| ... | @@ -129,7 +125,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -129,7 +125,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 129 | const plaintext = handshake_buf[0..5]; | 125 | const plaintext = handshake_buf[0..5]; |
| 130 | len = try stream.readAtLeast(&handshake_buf, plaintext.len); | 126 | len = try stream.readAtLeast(&handshake_buf, plaintext.len); |
| 131 | if (len < plaintext.len) return error.EndOfStream; | 127 | if (len < plaintext.len) return error.EndOfStream; |
| 132 | const ct = @intToEnum(ContentType, plaintext[0]); | 128 | const ct = @intToEnum(tls.ContentType, plaintext[0]); |
| 133 | const frag_len = mem.readIntBig(u16, plaintext[3..][0..2]); | 129 | const frag_len = mem.readIntBig(u16, plaintext[3..][0..2]); |
| 134 | const end = plaintext.len + frag_len; | 130 | const end = plaintext.len + frag_len; |
| 135 | if (end > handshake_buf.len) return error.TlsRecordOverflow; | 131 | if (end > handshake_buf.len) return error.TlsRecordOverflow; |
| ... | @@ -169,7 +165,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -169,7 +165,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 169 | i += 32; | 165 | i += 32; |
| 170 | const cipher_suite_int = mem.readIntBig(u16, frag[i..][0..2]); | 166 | const cipher_suite_int = mem.readIntBig(u16, frag[i..][0..2]); |
| 171 | i += 2; | 167 | i += 2; |
| 172 | const cipher_suite_tag = @intToEnum(CipherSuite, cipher_suite_int); | 168 | const cipher_suite_tag = @intToEnum(tls.CipherSuite, cipher_suite_int); |
| 173 | const legacy_compression_method = frag[i]; | 169 | const legacy_compression_method = frag[i]; |
| 174 | i += 1; | 170 | i += 1; |
| 175 | _ = legacy_compression_method; | 171 | _ = legacy_compression_method; |
| ... | @@ -247,8 +243,8 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -247,8 +243,8 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 247 | .AEGIS_256_SHA384, | 243 | .AEGIS_256_SHA384, |
| 248 | .AEGIS_128L_SHA256, | 244 | .AEGIS_128L_SHA256, |
| 249 | => |tag| { | 245 | => |tag| { |
| 250 | const P = std.meta.TagPayloadByName(HandshakeCipher, @tagName(tag)); | 246 | const P = std.meta.TagPayloadByName(tls.HandshakeCipher, @tagName(tag)); |
| 251 | handshake_cipher = @unionInit(HandshakeCipher, @tagName(tag), .{ | 247 | handshake_cipher = @unionInit(tls.HandshakeCipher, @tagName(tag), .{ |
| 252 | .handshake_secret = undefined, | 248 | .handshake_secret = undefined, |
| 253 | .master_secret = undefined, | 249 | .master_secret = undefined, |
| 254 | .client_handshake_key = undefined, | 250 | .client_handshake_key = undefined, |
| ... | @@ -338,7 +334,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -338,7 +334,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 338 | len += try stream.readAtLeast(handshake_buf[len..], end_hdr - len); | 334 | len += try stream.readAtLeast(handshake_buf[len..], end_hdr - len); |
| 339 | if (end_hdr > len) return error.EndOfStream; | 335 | if (end_hdr > len) return error.EndOfStream; |
| 340 | } | 336 | } |
| 341 | const ct = @intToEnum(ContentType, handshake_buf[i]); | 337 | const ct = @intToEnum(tls.ContentType, handshake_buf[i]); |
| 342 | i += 1; | 338 | i += 1; |
| 343 | const legacy_version = mem.readIntBig(u16, handshake_buf[i..][0..2]); | 339 | const legacy_version = mem.readIntBig(u16, handshake_buf[i..][0..2]); |
| 344 | i += 2; | 340 | i += 2; |
| ... | @@ -380,7 +376,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -380,7 +376,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 380 | }, | 376 | }, |
| 381 | }; | 377 | }; |
| 382 | | 378 | |
| 383 | const inner_ct = @intToEnum(ContentType, cleartext[cleartext.len - 1]); | 379 | const inner_ct = @intToEnum(tls.ContentType, cleartext[cleartext.len - 1]); |
| 384 | switch (inner_ct) { | 380 | switch (inner_ct) { |
| 385 | .handshake => { | 381 | .handshake => { |
| 386 | var ct_i: usize = 0; | 382 | var ct_i: usize = 0; |
| ... | @@ -546,7 +542,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -546,7 +542,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 546 | if (handshake_state != .finished) return error.TlsUnexpectedMessage; | 542 | if (handshake_state != .finished) return error.TlsUnexpectedMessage; |
| 547 | // This message is to trick buggy proxies into behaving correctly. | 543 | // This message is to trick buggy proxies into behaving correctly. |
| 548 | const client_change_cipher_spec_msg = [_]u8{ | 544 | const client_change_cipher_spec_msg = [_]u8{ |
| 549 | @enumToInt(ContentType.change_cipher_spec), | 545 | @enumToInt(tls.ContentType.change_cipher_spec), |
| 550 | 0x03, 0x03, // legacy protocol version | 546 | 0x03, 0x03, // legacy protocol version |
| 551 | 0x00, 0x01, // length | 547 | 0x00, 0x01, // length |
| 552 | 0x01, | 548 | 0x01, |
| ... | @@ -564,12 +560,12 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -564,12 +560,12 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 564 | const out_cleartext = [_]u8{ | 560 | const out_cleartext = [_]u8{ |
| 565 | @enumToInt(tls.HandshakeType.finished), | 561 | @enumToInt(tls.HandshakeType.finished), |
| 566 | 0, 0, verify_data.len, // length | 562 | 0, 0, verify_data.len, // length |
| 567 | } ++ verify_data ++ [1]u8{@enumToInt(ContentType.handshake)}; | 563 | } ++ verify_data ++ [1]u8{@enumToInt(tls.ContentType.handshake)}; |
| 568 | | 564 | |
| 569 | const wrapped_len = out_cleartext.len + P.AEAD.tag_length; | 565 | const wrapped_len = out_cleartext.len + P.AEAD.tag_length; |
| 570 | | 566 | |
| 571 | var finished_msg = [_]u8{ | 567 | var finished_msg = [_]u8{ |
| 572 | @enumToInt(ContentType.application_data), | 568 | @enumToInt(tls.ContentType.application_data), |
| 573 | 0x03, 0x03, // legacy protocol version | 569 | 0x03, 0x03, // legacy protocol version |
| 574 | 0, wrapped_len, // byte length of encrypted record | 570 | 0, wrapped_len, // byte length of encrypted record |
| 575 | } ++ @as([wrapped_len]u8, undefined); | 571 | } ++ @as([wrapped_len]u8, undefined); |
| ... | @@ -590,7 +586,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) | ... | @@ -590,7 +586,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8) |
| 590 | // std.fmt.fmtSliceHexLower(&client_secret), | 586 | // std.fmt.fmtSliceHexLower(&client_secret), |
| 591 | // std.fmt.fmtSliceHexLower(&server_secret), | 587 | // std.fmt.fmtSliceHexLower(&server_secret), |
| 592 | //}); | 588 | //}); |
| 593 | break :c @unionInit(ApplicationCipher, @tagName(tag), .{ | 589 | break :c @unionInit(tls.ApplicationCipher, @tagName(tag), .{ |
| 594 | .client_secret = client_secret, | 590 | .client_secret = client_secret, |
| 595 | .server_secret = server_secret, | 591 | .server_secret = server_secret, |
| 596 | .client_key = hkdfExpandLabel(P.Hkdf, client_secret, "key", "", P.AEAD.key_length), | 592 | .client_key = hkdfExpandLabel(P.Hkdf, client_secret, "key", "", P.AEAD.key_length), |
| ... | @@ -661,7 +657,7 @@ pub fn write(c: *Client, stream: net.Stream, bytes: []const u8) !usize { | ... | @@ -661,7 +657,7 @@ pub fn write(c: *Client, stream: net.Stream, bytes: []const u8) !usize { |
| 661 | if (encrypted_content_len == 0) break :l overhead_len; | 657 | if (encrypted_content_len == 0) break :l overhead_len; |
| 662 | | 658 | |
| 663 | mem.copy(u8, &cleartext_buf, bytes[bytes_i..][0..encrypted_content_len]); | 659 | mem.copy(u8, &cleartext_buf, bytes[bytes_i..][0..encrypted_content_len]); |
| 664 | cleartext_buf[encrypted_content_len] = @enumToInt(ContentType.application_data); | 660 | cleartext_buf[encrypted_content_len] = @enumToInt(tls.ContentType.application_data); |
| 665 | bytes_i += encrypted_content_len; | 661 | bytes_i += encrypted_content_len; |
| 666 | const ciphertext_len = encrypted_content_len + 1; | 662 | const ciphertext_len = encrypted_content_len + 1; |
| 667 | const cleartext = cleartext_buf[0..ciphertext_len]; | 663 | const cleartext = cleartext_buf[0..ciphertext_len]; |
| ... | @@ -669,7 +665,7 @@ pub fn write(c: *Client, stream: net.Stream, bytes: []const u8) !usize { | ... | @@ -669,7 +665,7 @@ pub fn write(c: *Client, stream: net.Stream, bytes: []const u8) !usize { |
| 669 | const record_start = ciphertext_end; | 665 | const record_start = ciphertext_end; |
| 670 | const ad = ciphertext_buf[ciphertext_end..][0..5]; | 666 | const ad = ciphertext_buf[ciphertext_end..][0..5]; |
| 671 | ad.* = | 667 | ad.* = |
| 672 | [_]u8{@enumToInt(ContentType.application_data)} ++ | 668 | [_]u8{@enumToInt(tls.ContentType.application_data)} ++ |
| 673 | int2(@enumToInt(tls.ProtocolVersion.tls_1_2)) ++ | 669 | int2(@enumToInt(tls.ProtocolVersion.tls_1_2)) ++ |
| 674 | int2(ciphertext_len + P.AEAD.tag_length); | 670 | int2(ciphertext_len + P.AEAD.tag_length); |
| 675 | ciphertext_end += ad.len; | 671 | ciphertext_end += ad.len; |
| ... | @@ -818,7 +814,7 @@ pub fn readAdvanced(c: *Client, stream: net.Stream, buffer: []u8) !usize { | ... | @@ -818,7 +814,7 @@ pub fn readAdvanced(c: *Client, stream: net.Stream, buffer: []u8) !usize { |
| 818 | return finishRead(c, frag, in, out); | 814 | return finishRead(c, frag, in, out); |
| 819 | } | 815 | } |
| 820 | const record_start = in; | 816 | const record_start = in; |
| 821 | const ct = @intToEnum(ContentType, frag[in]); | 817 | const ct = @intToEnum(tls.ContentType, frag[in]); |
| 822 | in += 1; | 818 | in += 1; |
| 823 | const legacy_version = mem.readIntBig(u16, frag[in..][0..2]); | 819 | const legacy_version = mem.readIntBig(u16, frag[in..][0..2]); |
| 824 | in += 2; | 820 | in += 2; |
| ... | @@ -861,7 +857,7 @@ pub fn readAdvanced(c: *Client, stream: net.Stream, buffer: []u8) !usize { | ... | @@ -861,7 +857,7 @@ pub fn readAdvanced(c: *Client, stream: net.Stream, buffer: []u8) !usize { |
| 861 | }, | 857 | }, |
| 862 | }; | 858 | }; |
| 863 | | 859 | |
| 864 | const inner_ct = @intToEnum(ContentType, cleartext[cleartext.len - 1]); | 860 | const inner_ct = @intToEnum(tls.ContentType, cleartext[cleartext.len - 1]); |
| 865 | switch (inner_ct) { | 861 | switch (inner_ct) { |
| 866 | .alert => { | 862 | .alert => { |
| 867 | c.read_seq += 1; | 863 | c.read_seq += 1; |