Skip to content

Commit

Permalink
Auth.handle function simplyfied. HtapHid.handle function now returns …
Browse files Browse the repository at this point in the history
…a struct.
  • Loading branch information
r4gus committed Jan 3, 2024
1 parent 405bb43 commit 710c584
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 61 deletions.
31 changes: 16 additions & 15 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,22 @@ pub fn build(b: *std.build.Builder) !void {
// C bindings
// ------------------------------------------------

const c_bindings = b.addStaticLibrary(.{
.name = "keylib",
.root_source_file = .{ .path = "bindings/c/src/keylib.zig" },
.target = target,
.optimize = optimize,
});
c_bindings.addModule("keylib", keylib_module);
c_bindings.linkLibC();
c_bindings.installHeadersDirectoryOptions(.{
.source_dir = std.Build.LazyPath{ .path = "bindings/c/include" },
.install_dir = .header,
.install_subdir = "keylib",
.exclude_extensions = &.{".c"},
});
b.installArtifact(c_bindings);
// TODO: doesn't make much sense right now to provide C bindings
//const c_bindings = b.addStaticLibrary(.{
// .name = "keylib",
// .root_source_file = .{ .path = "bindings/c/src/keylib.zig" },
// .target = target,
// .optimize = optimize,
//});
//c_bindings.addModule("keylib", keylib_module);
//c_bindings.linkLibC();
//c_bindings.installHeadersDirectoryOptions(.{
// .source_dir = std.Build.LazyPath{ .path = "bindings/c/include" },
// .install_dir = .header,
// .install_subdir = "keylib",
// .exclude_extensions = &.{".c"},
//});
//b.installArtifact(c_bindings);

const uhid = b.addStaticLibrary(.{
.name = "uhid",
Expand Down
23 changes: 16 additions & 7 deletions lib/ctap/auth/Authenticator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,22 @@ pub const Auth = struct {
}
}

pub fn handle(self: *@This(), request: []const u8) Response {
pub fn handle(
self: *@This(),
out: *[fido.ctap.transports.ctaphid.authenticator.MAX_DATA_SIZE]u8,
request: []const u8,
) []const u8 {
// Buffer for the response message
var res = std.ArrayList(u8).init(self.allocator);
defer res.deinit();
var response = res.writer();
response.writeByte(0x00) catch unreachable;

// Decode the command of the given message
if (request.len < 1) return Response{ .err = @intFromEnum(StatusCodes.ctap1_err_invalid_length) };
if (request.len < 1) {
out[0] = @intFromEnum(StatusCodes.ctap1_err_invalid_length);
return out[0..1];
}
const cmd = request[0];

// Updates (and possibly invalidates) an existing pinUvAuth token. This has to
Expand All @@ -270,18 +278,19 @@ pub const Auth = struct {
);

if (status != .ctap1_err_success) {
res.deinit();
return Response{ .err = @intFromEnum(status) };
out[0] = @intFromEnum(status);
return out[0..1];
}

break;
}
} else {
res.deinit();
return Response{ .err = @intFromEnum(StatusCodes.ctap2_err_not_allowed) };
out[0] = @intFromEnum(StatusCodes.ctap2_err_not_allowed);
return out[0..1];
}

return Response{ .ok = res.toOwnedSlice() catch unreachable };
std.mem.copy(u8, out[0..res.items.len], res.items);
return out[0..res.items.len];
}

/// Given a set of credential parameters, select the first algorithm that is also supported by the authenticator.
Expand Down
79 changes: 40 additions & 39 deletions lib/ctap/transports/ctaphid/authenticator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,28 @@ pub const InitResponse = packed struct {
// message Handler
//--------------------------------------------------------------------+

pub const MAX_DATA_SIZE = 7609;

pub const CtapHidMsg = struct {
cmd: Cmd,
cid: Cid,
_data: [MAX_DATA_SIZE]u8,
data: []const u8,

pub fn new(cmd: Cmd, cid: Cid, data: []const u8) @This() {
var self: @This() = undefined;
self.cmd = cmd;
self.cid = cid;
@memcpy(self._data[0..data.len], data);
self.data = self._data[0..data.len];
return self;
}

pub fn iterator(self: *const @This()) CtapHidMessageIterator {
return resp.iterator(self.cid, self.cmd, self.data);
}
};

pub const CtapHid = struct {
// Authenticator is currently busy handling a request with the given
// Cid. `null` means not busy.
Expand All @@ -148,13 +170,15 @@ pub const CtapHid = struct {
// All clients (CIDs) share the same buffer, i.e. only one request
// can be handled at a time. This buffer is also used for some of
// the response data.
data: [7609]u8 = undefined,
data: [MAX_DATA_SIZE]u8 = undefined,

channels: std.ArrayList(Cid),

/// CSPRNG
random: std.rand.Random,

milliTimestamp: *const fn () i64 = std.time.milliTimestamp,

const timeout: u64 = 250; // 250 milli second timeout

pub fn init(a: std.mem.Allocator, random: std.rand.Random) @This() {
Expand Down Expand Up @@ -193,9 +217,9 @@ pub const CtapHid = struct {
return false;
}

pub fn handle(self: *@This(), packet: []const u8, auth: anytype) ?CtapHidMessageIterator {
pub fn handle(self: *@This(), packet: []const u8) ?CtapHidMsg {
//std.log.err("{s}", .{std.fmt.fmtSliceHexLower(packet)});
if (self.begin != null and (auth.milliTimestamp() - self.begin.?) > CtapHid.timeout) {
if (self.begin != null and (self.milliTimestamp() - self.begin.?) > CtapHid.timeout) {
// the previous transaction has timed out -> reset
self.reset();
}
Expand All @@ -209,7 +233,7 @@ pub const CtapHid = struct {
}

self.busy = misc.sliceToInt(Cid, packet[0..4]);
self.begin = auth.milliTimestamp();
self.begin = self.milliTimestamp();

if (!isBroadcast(self.busy.?) and !self.isValidChannel(self.busy.?)) {
return self.@"error"(ErrorCodes.invalid_channel);
Expand Down Expand Up @@ -265,35 +289,10 @@ pub const CtapHid = struct {
// execute the command
switch (self.cmd.?) {
.msg => {
var response = resp.CtapHidMessageIterator.new(self.busy.?, self.cmd.?);

if (self.data[1] == 3) {
return resp.iterator(self.busy.?, self.cmd.?, "CTAP2/U2F_V2\x90\x00");
} else {
return resp.iterator(self.busy.?, self.cmd.?, "\x69\x86");
}

return response;
return CtapHidMsg.new(self.cmd.?, self.busy.?, self.data[0..self.bcnt]);
},
.cbor => {
var response = resp.CtapHidMessageIterator.new(self.busy.?, self.cmd.?);

var _data = auth.handle(self.data[0..self.bcnt]);
switch (_data) {
.ok => |d| {
response.data = d;
response.allocator = auth.allocator;
},
.err => |e| {
// `data` is freed within handle()
var d = auth.allocator.alloc(u8, 1) catch unreachable;
d[0] = e;
response.data = d;
response.allocator = auth.allocator;
},
}

return response;
return CtapHidMsg.new(self.cmd.?, self.busy.?, self.data[0..self.bcnt]);
},
.init => {
if (isBroadcast(self.busy.?)) {
Expand All @@ -313,19 +312,16 @@ pub const CtapHid = struct {
false,
);
ir.serialize(self.data[0..InitResponse.SIZE]);
var response = resp.iterator(self.busy.?, self.cmd.?, self.data[0..InitResponse.SIZE]);
return response;
return CtapHidMsg.new(self.cmd.?, self.busy.?, self.data[0..InitResponse.SIZE]);
} else {
// The device then responds with the CID of the channel it received
// the INIT on, using that channel.
misc.intToSlice(self.data[0..], self.busy.?);
var response = resp.iterator(self.busy.?, self.cmd.?, self.data[0..4]);
return response;
return CtapHidMsg.new(self.cmd.?, self.busy.?, self.data[0..4]);
}
},
.ping => {
var response = resp.iterator(self.busy.?, self.cmd.?, self.data[0..self.bcnt]);
return response;
return CtapHidMsg.new(self.cmd.?, self.busy.?, self.data[0..self.bcnt]);
},
.cancel => {
return null;
Expand All @@ -349,7 +345,7 @@ pub const CtapHid = struct {
s.seq = null;
}

fn @"error"(self: *@This(), e: ErrorCodes) CtapHidMessageIterator {
fn @"error"(self: *@This(), e: ErrorCodes) CtapHidMsg {
const es = switch (e) {
.invalid_cmd => "\x01",
.invalid_par => "\x02",
Expand All @@ -362,7 +358,12 @@ pub const CtapHid = struct {
else => "\x7f",
};

const response = resp.iterator(if (self.busy) |c| c else 0xffffffff, Cmd.err, es);
const response = CtapHidMsg.new(
Cmd.err,
if (self.busy) |c| c else 0xffffffff,
es,
);

self.reset();
return response;
}
Expand Down

0 comments on commit 710c584

Please sign in to comment.