aboutsummaryrefslogtreecommitdiffstats
path: root/src/znk.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/znk.zig')
-rw-r--r--src/znk.zig93
1 files changed, 75 insertions, 18 deletions
diff --git a/src/znk.zig b/src/znk.zig
index ab36c96..fe66cb5 100644
--- a/src/znk.zig
+++ b/src/znk.zig
@@ -162,7 +162,7 @@ pub fn cmdGen(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !voi
162 162
163 try PrefixKeyGenerator.init(arena, ty.?, capitalized_prefix).generate(); 163 try PrefixKeyGenerator.init(arena, ty.?, capitalized_prefix).generate();
164 } else { 164 } else {
165 var kp = nkeys.SeedKeyPair.init(ty.?) catch |e| fatal("could not generate key pair: {e}", .{e}); 165 var kp = nkeys.SeedKeyPair.generate(ty.?) catch |e| fatal("could not generate key pair: {e}", .{e});
166 defer kp.wipe(); 166 defer kp.wipe();
167 try stdout.writeAll(&kp.seed); 167 try stdout.writeAll(&kp.seed);
168 try stdout.writeAll("\n"); 168 try stdout.writeAll("\n");
@@ -396,7 +396,7 @@ const PrefixKeyGenerator = struct {
396 while (true) { 396 while (true) {
397 if (self.done.load(.SeqCst)) return; 397 if (self.done.load(.SeqCst)) return;
398 398
399 var kp = nkeys.SeedKeyPair.init(self.ty) catch |e| fatal("could not generate key pair: {e}", .{e}); 399 var kp = nkeys.SeedKeyPair.generate(self.ty) catch |e| fatal("could not generate key pair: {e}", .{e});
400 defer kp.wipe(); 400 defer kp.wipe();
401 var public_key = kp.publicKey() catch |e| fatal("could not generate public key: {e}", .{e}); 401 var public_key = kp.publicKey() catch |e| fatal("could not generate public key: {e}", .{e});
402 if (!mem.startsWith(u8, public_key[1..], self.prefix)) continue; 402 if (!mem.startsWith(u8, public_key[1..], self.prefix)) continue;
@@ -425,22 +425,6 @@ const PrefixKeyGenerator = struct {
425 }; 425 };
426}; 426};
427 427
428pub fn readKeyFile(allocator: *Allocator, file: fs.File) nkeys.Key {
429 var bytes = file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch fatal("could not read key file", .{});
430
431 var iterator = mem.split(bytes, "\n");
432 while (iterator.next()) |line| {
433 if (nkeys.isValidEncoding(line) and line.len == nkeys.text_seed_len) {
434 var k = nkeys.fromText(line) catch continue;
435 defer k.wipe();
436 allocator.free(bytes);
437 return k;
438 }
439 }
440
441 fatal("could not find a valid key", .{});
442}
443
444fn two(slice: []const bool) bool { 428fn two(slice: []const bool) bool {
445 var one = false; 429 var one = false;
446 for (slice) |x| if (x and one) { 430 for (slice) |x| if (x and one) {
@@ -457,6 +441,79 @@ fn toUpper(allocator: *Allocator, slice: []const u8) ![]u8 {
457 return result; 441 return result;
458} 442}
459 443
444pub const Nkey = union(enum) {
445 seed_key_pair: nkeys.SeedKeyPair,
446 public_key: nkeys.PublicKey,
447
448 const Self = @This();
449
450 pub fn publicKey(self: *const Self) !nkeys.text_public {
451 return switch (self.*) {
452 .seed_key_pair => |*kp| try kp.publicKey(),
453 .public_key => |*pk| try pk.publicKey(),
454 };
455 }
456
457 pub fn intoPublicKey(self: *const Self) !nkeys.PublicKey {
458 return switch (self.*) {
459 .seed_key_pair => |*kp| try kp.intoPublicKey(),
460 .public_key => |pk| pk,
461 };
462 }
463
464 pub fn verify(
465 self: *const Self,
466 msg: []const u8,
467 sig: [std.crypto.sign.Ed25519.signature_length]u8,
468 ) !void {
469 return switch (self.*) {
470 .seed_key_pair => |*kp| try kp.verify(msg, sig),
471 .public_key => |*pk| try pk.verify(msg, sig),
472 };
473 }
474
475 pub fn wipe(self: *Self) void {
476 return switch (self.*) {
477 .seed_key_pair => |*kp| kp.wipe(),
478 .public_key => |*pk| pk.wipe(),
479 };
480 }
481
482 pub fn fromText(text: []const u8) !Self {
483 if (!nkeys.isValidEncoding(text)) return error.InvalidEncoding;
484 switch (text[0]) {
485 'S' => {
486 // It's a seed.
487 if (text.len != nkeys.text_seed_len) return error.InvalidSeed;
488 return Self{ .seed_key_pair = try nkeys.SeedKeyPair.fromTextSeed(text[0..nkeys.text_seed_len]) };
489 },
490 'P' => return error.InvalidEncoding, // unsupported for now
491 else => {
492 if (text.len != nkeys.text_public_len) return error.InvalidEncoding;
493 return Self{ .public_key = try nkeys.PublicKey.fromTextPublicKey(text[0..nkeys.text_public_len]) };
494 },
495 }
496 }
497};
498
499pub fn readKeyFile(allocator: *Allocator, file: fs.File) Nkey {
500 var bytes = file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch fatal("could not read key file", .{});
501
502 var iterator = mem.split(bytes, "\n");
503 while (iterator.next()) |line| {
504 if (nkeys.isValidEncoding(line) and line.len == nkeys.text_seed_len) {
505 var k = Nkey.fromText(line) catch continue;
506 defer k.wipe();
507 allocator.free(bytes);
508 return k;
509 }
510 }
511
512 fatal("could not find a valid key", .{});
513}
514
460test { 515test {
461 testing.refAllDecls(@This()); 516 testing.refAllDecls(@This());
517 testing.refAllDecls(Nkey);
518 testing.refAllDecls(PrefixKeyGenerator);
462} 519}