atproto pds in zig pds.zat.dev
pds atproto
24

Configure Feed

Select the types of activity you want to include in your feed.

wire webauthn dependency

zzstoatzz (May 27, 2026, 12:54 AM -0500) bfa0ae48 85e57d8a

+56
+5
build.zig
··· 13 13 .target = target, 14 14 .optimize = optimize, 15 15 }); 16 + const webauthn = b.dependency("webauthn", .{ 17 + .target = target, 18 + .optimize = optimize, 19 + }); 16 20 17 21 const mod = b.addModule("zds", .{ 18 22 .root_source_file = b.path("src/root.zig"), ··· 22 26 .{ .name = "build_options", .module = buildOptions(b, version) }, 23 27 .{ .name = "zat", .module = zat.module("zat") }, 24 28 .{ .name = "zqlite", .module = zqlite.module("zqlite") }, 29 + .{ .name = "webauthn", .module = webauthn.module("webauthn") }, 25 30 }, 26 31 }); 27 32
+4
build.zig.zon
··· 12 12 .url = "git+https://github.com/karlseguin/zqlite.zig?ref=master#05a88d6758753e1c63fdd45b211dde2057094b0c", 13 13 .hash = "zqlite-0.0.1-RWLaYz6bmAAT7E_jxopXf-j5Ea8VQldnxsd6TU8sa0Bb", 14 14 }, 15 + .webauthn = .{ 16 + .url = "git+https://tangled.org/zzstoatzz.io/webauthn?ref=main#252f7f33ba63bfb21911edecb0be4773f6432883", 17 + .hash = "webauthn-0.0.1--JitMhxtAACEz8AIen39HWsjUPDMx1ync0TA99tpU2q5", 18 + }, 15 19 }, 16 20 .paths = .{ 17 21 "build.zig",
+46
src/internal/passkeys.zig
··· 1 + const std = @import("std"); 2 + const webauthn = @import("webauthn"); 3 + 4 + pub const CredentialKey = struct { 5 + bytes: []const u8, 6 + 7 + pub fn validate(self: CredentialKey) !void { 8 + _ = try webauthn.cose.parseEc2PublicKey(self.bytes); 9 + } 10 + }; 11 + 12 + pub fn buildAssertionMessage(allocator: std.mem.Allocator, authenticator_data: []const u8, client_data_json: []const u8) ![]u8 { 13 + var client_hash: [32]u8 = undefined; 14 + std.crypto.hash.sha2.Sha256.hash(client_data_json, &client_hash, .{}); 15 + 16 + const out = try allocator.alloc(u8, authenticator_data.len + client_hash.len); 17 + @memcpy(out[0..authenticator_data.len], authenticator_data); 18 + @memcpy(out[authenticator_data.len..], &client_hash); 19 + return out; 20 + } 21 + 22 + pub fn verifyAssertionSignature(credential_public_key: []const u8, signature_der: []const u8, authenticator_data: []const u8, client_data_json: []const u8, allocator: std.mem.Allocator) !void { 23 + const message = try buildAssertionMessage(allocator, authenticator_data, client_data_json); 24 + defer allocator.free(message); 25 + try webauthn.crypto.verifyWebAuthnEs256(credential_public_key, signature_der, message); 26 + } 27 + 28 + test "validates webauthn credential key through tangled dependency" { 29 + const key = try webauthn.base64url.decodeAlloc(std.testing.allocator, "pQECAyYgASFYIDNDxl6djmZTEhKfw1B5jiSdcFUsTKuyPpks-4jTpA5aIlggF5oAEvUgwjYE6o0sPzL6G27d72m3lM2-yPAMOajmYoE"); 30 + defer std.testing.allocator.free(key); 31 + try (CredentialKey{ .bytes = key }).validate(); 32 + } 33 + 34 + test "verifies real webauthn assertion signature through zds adapter" { 35 + const allocator = std.testing.allocator; 36 + const key = try webauthn.base64url.decodeAlloc(allocator, "pQECAyYgASFYIDNDxl6djmZTEhKfw1B5jiSdcFUsTKuyPpks-4jTpA5aIlggF5oAEvUgwjYE6o0sPzL6G27d72m3lM2-yPAMOajmYoE"); 37 + defer allocator.free(key); 38 + const auth_data = try webauthn.base64url.decodeAlloc(allocator, "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MdAAAAAA"); 39 + defer allocator.free(auth_data); 40 + const client_data_json = try webauthn.base64url.decodeAlloc(allocator, "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoibGgwR1c2OEZKZW03NWxBNV9sRTZKTmU4dlo2ODdsdmhaQmtrY0RzUVB5byIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCIsImNyb3NzT3JpZ2luIjpmYWxzZX0"); 41 + defer allocator.free(client_data_json); 42 + const signature = try webauthn.base64url.decodeAlloc(allocator, "MEYCIQDQ-pXZQT9yjPsXT_m47W-iTFAIRgBVOCBhwl6kU--0RwIhAKcJJhxipw6tsIR0ULRgvQAhTaeIXk_V29wKOqbfP1oL"); 43 + defer allocator.free(signature); 44 + 45 + try verifyAssertionSignature(key, signature, auth_data, client_data_json, allocator); 46 + }
+1
src/root.zig
··· 31 31 32 32 pub const internal = struct { 33 33 pub const cli = @import("internal/cli.zig"); 34 + pub const passkeys = @import("internal/passkeys.zig"); 34 35 pub const sharded_locks = @import("internal/sharded_locks.zig"); 35 36 }; 36 37