| ... | ... | @@ -46,7 +46,6 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 46 | 46 | // Only possible to happen if the private key is all zeroes. |
| 47 | 47 | error.IdentityElement => return error.InsufficientEntropy, |
| 48 | 48 | }; |
| 49 | | _ = secp256r1_kp; |
| 50 | 49 | |
| 51 | 50 | const extensions_payload = |
| 52 | 51 | tls.extension(.supported_versions, [_]u8{ |
| ... | ... | @@ -70,11 +69,14 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 70 | 69 | .rsa_pkcs1_sha1, |
| 71 | 70 | .ecdsa_sha1, |
| 72 | 71 | })) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{ |
| 73 | | //.secp256r1, |
| 72 | .secp256r1, |
| 74 | 73 | .x25519, |
| 75 | 74 | })) ++ tls.extension( |
| 76 | 75 | .key_share, |
| 77 | | array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++ array(1, x25519_kp.public_key)), |
| 76 | array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++ |
| 77 | array(1, x25519_kp.public_key) ++ |
| 78 | int2(@enumToInt(tls.NamedGroup.secp256r1)) ++ |
| 79 | array(1, secp256r1_kp.public_key.toUncompressedSec1())), |
| 78 | 80 | ) ++ |
| 79 | 81 | int2(@enumToInt(tls.ExtensionType.server_name)) ++ |
| 80 | 82 | int2(host_len + 5) ++ // byte length of this extension payload |
| ... | ... | @@ -182,7 +184,8 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 182 | 184 | i += 2; |
| 183 | 185 | if (i + extensions_size != frag.len) return error.TlsBadLength; |
| 184 | 186 | var supported_version: u16 = 0; |
| 185 | | var opt_x25519_server_pub_key: ?*[32]u8 = null; |
| 187 | var shared_key: [32]u8 = undefined; |
| 188 | var have_shared_key = false; |
| 186 | 189 | while (i < frag.len) { |
| 187 | 190 | const et = mem.readIntBig(u16, frag[i..][0..2]); |
| 188 | 191 | i += 2; |
| ... | ... | @@ -196,15 +199,34 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 196 | 199 | supported_version = mem.readIntBig(u16, frag[i..][0..2]); |
| 197 | 200 | }, |
| 198 | 201 | @enumToInt(tls.ExtensionType.key_share) => { |
| 199 | | if (opt_x25519_server_pub_key != null) return error.TlsIllegalParameter; |
| 202 | if (have_shared_key) return error.TlsIllegalParameter; |
| 203 | have_shared_key = true; |
| 200 | 204 | const named_group = mem.readIntBig(u16, frag[i..][0..2]); |
| 201 | 205 | i += 2; |
| 206 | const key_size = mem.readIntBig(u16, frag[i..][0..2]); |
| 207 | i += 2; |
| 208 | |
| 202 | 209 | switch (named_group) { |
| 203 | 210 | @enumToInt(tls.NamedGroup.x25519) => { |
| 204 | | const key_size = mem.readIntBig(u16, frag[i..][0..2]); |
| 205 | | i += 2; |
| 206 | 211 | if (key_size != 32) return error.TlsBadLength; |
| 207 | | opt_x25519_server_pub_key = frag[i..][0..32]; |
| 212 | const server_pub_key = frag[i..][0..32]; |
| 213 | |
| 214 | shared_key = crypto.dh.X25519.scalarmult( |
| 215 | x25519_kp.secret_key, |
| 216 | server_pub_key.*, |
| 217 | ) catch return error.TlsDecryptFailure; |
| 218 | }, |
| 219 | @enumToInt(tls.NamedGroup.secp256r1) => { |
| 220 | const server_pub_key = frag[i..][0..key_size]; |
| 221 | |
| 222 | const PublicKey = crypto.sign.ecdsa.EcdsaP256Sha256.PublicKey; |
| 223 | const pk = PublicKey.fromSec1(server_pub_key) catch { |
| 224 | return error.TlsDecryptFailure; |
| 225 | }; |
| 226 | const mul = pk.p.mulPublic(secp256r1_kp.secret_key.bytes, .Big) catch { |
| 227 | return error.TlsDecryptFailure; |
| 228 | }; |
| 229 | shared_key = mul.affineCoordinates().x.toBytes(.Big); |
| 208 | 230 | }, |
| 209 | 231 | else => { |
| 210 | 232 | std.debug.print("named group: {x}\n", .{named_group}); |
| ... | ... | @@ -218,8 +240,7 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 218 | 240 | } |
| 219 | 241 | i = next_i; |
| 220 | 242 | } |
| 221 | | const x25519_server_pub_key = opt_x25519_server_pub_key orelse |
| 222 | | return error.TlsIllegalParameter; |
| 243 | if (!have_shared_key) return error.TlsIllegalParameter; |
| 223 | 244 | const tls_version = if (supported_version == 0) legacy_version else supported_version; |
| 224 | 245 | switch (tls_version) { |
| 225 | 246 | @enumToInt(tls.ProtocolVersion.tls_1_2) => { |
| ... | ... | @@ -231,11 +252,6 @@ pub fn init(stream: net.Stream, host: []const u8) !Client { |
| 231 | 252 | else => return error.TlsIllegalParameter, |
| 232 | 253 | } |
| 233 | 254 | |
| 234 | | const shared_key = crypto.dh.X25519.scalarmult( |
| 235 | | x25519_kp.secret_key, |
| 236 | | x25519_server_pub_key.*, |
| 237 | | ) catch return error.TlsDecryptFailure; |
| 238 | | |
| 239 | 255 | switch (cipher_suite_tag) { |
| 240 | 256 | inline .AES_128_GCM_SHA256, |
| 241 | 257 | .AES_256_GCM_SHA384, |