1 Commits

Author SHA1 Message Date
spencer f2a98bc782 refactor(ssh.odin): removed offset from parser logic. 2026-06-30 17:11:11 -04:00
3 changed files with 48 additions and 65 deletions
+2 -4
View File
@@ -16,11 +16,9 @@
8. Add tests for untested commands. 8. Add tests for untested commands.
9. Update `read_wire_string` to use a slice. 9. Consider getting rid of color global.
10. Consider getting rid of color global. 10. `write_flags_table` should never return false.
11. `write_flags_table` should never return false.
## Double-check AI output ## Double-check AI output
+40 -55
View File
@@ -35,18 +35,18 @@ parse_ssh_public_key :: proc(pub_path: string) -> (pub: [32]u8, ok: bool) {
return return
} }
offset := 0 buf := decoded
key_type, type_ok := read_wire_string(decoded, &offset) key_type, type_ok := read_wire_string(&buf)
if !type_ok || key_type != SSH_ED25519 { if !type_ok || string(key_type) != SSH_ED25519 {
return return
} }
pk_data, pk_ok := read_wire_string(decoded, &offset) pk_data, pk_ok := read_wire_string(&buf)
if !pk_ok || len(pk_data) != 32 { if !pk_ok || len(pk_data) != 32 {
return return
} }
mem.copy_non_overlapping(&pub[0], raw_data(pk_data), 32) mem.copy_non_overlapping(&pub[0], &pk_data[0], 32)
ok = true ok = true
return return
@@ -91,81 +91,63 @@ parse_ssh_private_key :: proc(priv_path: string) -> (kp: Ed25519Keypair, ok: boo
return return
} }
offset := len(magic) buf := decoded[len(magic):]
ciphername, cipher_ok := read_wire_string(decoded, &offset) ciphername, cipher_ok := read_wire_string(&buf)
if !cipher_ok || ciphername != "none" { if !cipher_ok || string(ciphername) != "none" {
return return
} }
kdfname, kdf_ok := read_wire_string(decoded, &offset) kdfname, kdf_ok := read_wire_string(&buf)
if !kdf_ok || kdfname != "none" { if !kdf_ok || string(kdfname) != "none" {
return return
} }
_, opts_ok := read_wire_string(decoded, &offset) _, opts_ok := read_wire_string(&buf)
if !opts_ok { if !opts_ok {
return return
} }
if offset + 4 > len(decoded) { num_keys, nkeys_ok := read_wire_u32(&buf)
if !nkeys_ok || num_keys != 1 {
return return
} }
num_keys := endian.get_u32(decoded[offset:offset + 4], .Big) or_return _, pub_blob_ok := read_wire_string(&buf)
offset += 4
if num_keys != 1 {
return
}
_, pub_blob_ok := read_wire_string(decoded, &offset)
if !pub_blob_ok { if !pub_blob_ok {
return return
} }
priv_blob, priv_blob_ok := read_wire_string(decoded, &offset) priv_blob, priv_blob_ok := read_wire_string(&buf)
if !priv_blob_ok { if !priv_blob_ok {
return return
} }
inner_offset := 0 inner := priv_blob
if inner_offset + 8 > len(priv_blob) {
check1, c1_ok := read_wire_u32(&inner)
check2, c2_ok := read_wire_u32(&inner)
if !c1_ok || !c2_ok || check1 != check2 {
return return
} }
check1 := endian.get_u32( priv_type, type_ok := read_wire_string(&inner)
transmute([]u8)(priv_blob)[inner_offset:inner_offset + 4], if !type_ok || string(priv_type) != SSH_ED25519 {
.Big,
) or_return
inner_offset += 4
check2 := endian.get_u32(
transmute([]u8)(priv_blob)[inner_offset:inner_offset + 4],
.Big,
) or_return
inner_offset += 4
if check1 != check2 {
return return
} }
priv_type, type_ok := read_wire_string(transmute([]u8)priv_blob, &inner_offset) pub_wire, pub_ok := read_wire_string(&inner)
if !type_ok || priv_type != SSH_ED25519 {
return
}
pub_wire, pub_ok := read_wire_string(transmute([]u8)priv_blob, &inner_offset)
if !pub_ok || len(pub_wire) != 32 { if !pub_ok || len(pub_wire) != 32 {
return return
} }
mem.copy_non_overlapping(&kp.Public[0], raw_data(pub_wire), 32) mem.copy_non_overlapping(&kp.Public[0], &pub_wire[0], 32)
priv_wire, priv_ok := read_wire_string(transmute([]u8)priv_blob, &inner_offset) priv_wire, priv_ok := read_wire_string(&inner)
if !priv_ok || len(priv_wire) != 64 { if !priv_ok || len(priv_wire) != 64 {
return return
} }
mem.copy_non_overlapping(&kp.Private[0], raw_data(priv_wire), 32) mem.copy_non_overlapping(&kp.Private[0], &priv_wire[0], 32)
ok = true ok = true
return return
@@ -182,19 +164,22 @@ is_ed25519_key :: proc(
return ok, nil return ok, nil
} }
read_wire_string :: proc(data: []u8, offset: ^int) -> (s: string, ok: bool) { read_wire_string :: proc(data: ^[]u8) -> (s: []u8, ok: bool) {
if offset^ + 4 > len(data) { if len(data^) < 4 do return
return length := endian.get_u32(data^[:4], .Big) or_return
} data^ = data^[4:]
length := endian.get_u32(data[offset^:offset^ + 4], .Big) or_return
offset^ += 4
if offset^ + int(length) > len(data) { if len(data^) < int(length) do return
return s = data^[:int(length)]
} data^ = data^[int(length):]
ok = true
return
}
s = string(data[offset^:offset^ + int(length)]) read_wire_u32 :: proc(data: ^[]u8) -> (v: u32, ok: bool) {
offset^ += int(length) if len(data^) < 4 do return
v = endian.get_u32(data^[:4], .Big) or_return
data^ = data^[4:]
ok = true ok = true
return return
} }
+6 -6
View File
@@ -52,15 +52,15 @@ test_private_key_pub_matches_public_key :: proc(t: ^testing.T) {
@(test) @(test)
test_read_wire_string :: proc(t: ^testing.T) { test_read_wire_string :: proc(t: ^testing.T) {
data := []u8{0, 0, 0, 5, u8('h'), u8('e'), u8('l'), u8('l'), u8('o'), 0, 0, 0, 0} data := []u8{0, 0, 0, 5, u8('h'), u8('e'), u8('l'), u8('l'), u8('o'), 0, 0, 0, 0}
offset := 0
s, ok := read_wire_string(data, &offset) buf := data
s, ok := read_wire_string(&buf)
testing.expect(t, ok, "expected read_wire_string to succeed") testing.expect(t, ok, "expected read_wire_string to succeed")
testing.expect_value(t, s, "hello") testing.expect_value(t, string(s), "hello")
testing.expect_value(t, offset, 9) testing.expect_value(t, len(data) - len(buf), 9)
s2, ok2 := read_wire_string(data, &offset) s2, ok2 := read_wire_string(&buf)
testing.expect(t, ok2, "expected second read to succeed") testing.expect(t, ok2, "expected second read to succeed")
testing.expect_value(t, s2, "") testing.expect_value(t, len(s2), 0)
} }