diff options
author | Rutger Broekhoff | 2021-05-24 22:59:24 +0200 |
---|---|---|
committer | Rutger Broekhoff | 2021-05-24 22:59:24 +0200 |
commit | 5a760ca15a3e9894b3409c690afcd8b6cd7e4ece (patch) | |
tree | add6d13a1f9146fb9e085c9faa1008614a501dd2 /src | |
parent | f3232a9022b67db164b901272f4a8e47f46a74b3 (diff) | |
download | zig-nkeys-5a760ca15a3e9894b3409c690afcd8b6cd7e4ece.tar.gz zig-nkeys-5a760ca15a3e9894b3409c690afcd8b6cd7e4ece.zip |
Support private keys in znk
Diffstat (limited to 'src')
-rw-r--r-- | src/znk.zig | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/src/znk.zig b/src/znk.zig index 7cb16c6..89fc82c 100644 --- a/src/znk.zig +++ b/src/znk.zig | |||
@@ -231,16 +231,11 @@ pub fn cmdSign(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !vo | |||
231 | const content = file.?.readToEndAlloc(arena, std.math.maxInt(usize)) catch { | 231 | const content = file.?.readToEndAlloc(arena, std.math.maxInt(usize)) catch { |
232 | fatal("could not read file to generate signature for", .{}); | 232 | fatal("could not read file to generate signature for", .{}); |
233 | }; | 233 | }; |
234 | var kp = switch (readKeyFile(arena, key.?) orelse fatal("could not find a valid key", .{})) { | 234 | var nkey = readKeyFile(arena, key.?) orelse fatal("could not find a valid key", .{}); |
235 | .seed_key_pair => |kp| kp, | 235 | if (nkey == .public_key) fatal("key was provided but is not a seed or private key", .{}); |
236 | else => |*k| { | 236 | defer nkey.wipe(); |
237 | k.wipe(); | ||
238 | fatal("key was provided but is not a seed", .{}); | ||
239 | }, | ||
240 | }; | ||
241 | defer kp.wipe(); | ||
242 | 237 | ||
243 | const sig = kp.sign(content) catch fatal("could not generate signature", .{}); | 238 | const sig = nkey.sign(content) catch fatal("could not generate signature", .{}); |
244 | var encoded_sig = try arena.alloc(u8, std.base64.standard.Encoder.calcSize(sig.len)); | 239 | var encoded_sig = try arena.alloc(u8, std.base64.standard.Encoder.calcSize(sig.len)); |
245 | _ = std.base64.standard.Encoder.encode(encoded_sig, &sig); | 240 | _ = std.base64.standard.Encoder.encode(encoded_sig, &sig); |
246 | try stdout.writeAll(encoded_sig); | 241 | try stdout.writeAll(encoded_sig); |
@@ -427,23 +422,18 @@ fn toUpper(allocator: *Allocator, slice: []const u8) ![]u8 { | |||
427 | } | 422 | } |
428 | 423 | ||
429 | pub const Nkey = union(enum) { | 424 | pub const Nkey = union(enum) { |
430 | seed_key_pair: nkeys.SeedKeyPair, | ||
431 | public_key: nkeys.PublicKey, | ||
432 | |||
433 | const Self = @This(); | 425 | const Self = @This(); |
434 | 426 | ||
435 | pub fn publicKey(self: *const Self) nkeys.text_public { | 427 | seed_key_pair: nkeys.SeedKeyPair, |
436 | return switch (self.*) { | 428 | public_key: nkeys.PublicKey, |
437 | .seed_key_pair => |*kp| kp.asTextPublicKey(), | 429 | private_key: nkeys.PrivateKey, |
438 | .public_key => |*pk| pk.asTextPublicKey(), | ||
439 | }; | ||
440 | } | ||
441 | 430 | ||
442 | pub fn intoPublicKey(self: *const Self) nkeys.PublicKey { | 431 | pub fn wipe(self: *Self) void { |
443 | return switch (self.*) { | 432 | switch (self.*) { |
444 | .seed_key_pair => |*kp| kp.asPublicKey(), | 433 | .seed_key_pair => |*kp| kp.wipe(), |
445 | .public_key => |pk| pk, | 434 | .public_key => |*pk| pk.wipe(), |
446 | }; | 435 | .private_key => |*pk| pk.wipe(), |
436 | } | ||
447 | } | 437 | } |
448 | 438 | ||
449 | pub fn verify( | 439 | pub fn verify( |
@@ -454,13 +444,18 @@ pub const Nkey = union(enum) { | |||
454 | return switch (self.*) { | 444 | return switch (self.*) { |
455 | .seed_key_pair => |*kp| try kp.verify(msg, sig), | 445 | .seed_key_pair => |*kp| try kp.verify(msg, sig), |
456 | .public_key => |*pk| try pk.verify(msg, sig), | 446 | .public_key => |*pk| try pk.verify(msg, sig), |
447 | .private_key => |*pk| try pk.verify(msg, sig), | ||
457 | }; | 448 | }; |
458 | } | 449 | } |
459 | 450 | ||
460 | pub fn wipe(self: *Self) void { | 451 | pub fn sign( |
452 | self: *const Self, | ||
453 | msg: []const u8, | ||
454 | ) ![std.crypto.sign.Ed25519.signature_length]u8 { | ||
461 | return switch (self.*) { | 455 | return switch (self.*) { |
462 | .seed_key_pair => |*kp| kp.wipe(), | 456 | .seed_key_pair => |*kp| try kp.sign(msg), |
463 | .public_key => |*pk| pk.wipe(), | 457 | .private_key => |*pk| try pk.sign(msg), |
458 | .public_key => return error.CantSign, | ||
464 | }; | 459 | }; |
465 | } | 460 | } |
466 | 461 | ||
@@ -472,8 +467,13 @@ pub const Nkey = union(enum) { | |||
472 | if (text.len != nkeys.text_seed_len) return error.InvalidSeed; | 467 | if (text.len != nkeys.text_seed_len) return error.InvalidSeed; |
473 | return Self{ .seed_key_pair = try nkeys.SeedKeyPair.fromTextSeed(text[0..nkeys.text_seed_len]) }; | 468 | return Self{ .seed_key_pair = try nkeys.SeedKeyPair.fromTextSeed(text[0..nkeys.text_seed_len]) }; |
474 | }, | 469 | }, |
475 | 'P' => return error.InvalidEncoding, // unsupported for now | 470 | 'P' => { |
471 | // It's a private key. | ||
472 | if (text.len != nkeys.text_private_len) return error.InvalidPrivateKey; | ||
473 | return Self{ .private_key = try nkeys.PrivateKey.fromTextPrivateKey(text[0..nkeys.text_private_len]) }; | ||
474 | }, | ||
476 | else => { | 475 | else => { |
476 | // It should be a public key. | ||
477 | if (text.len != nkeys.text_public_len) return error.InvalidEncoding; | 477 | if (text.len != nkeys.text_public_len) return error.InvalidEncoding; |
478 | return Self{ .public_key = try nkeys.PublicKey.fromTextPublicKey(text[0..nkeys.text_public_len]) }; | 478 | return Self{ .public_key = try nkeys.PublicKey.fromTextPublicKey(text[0..nkeys.text_public_len]) }; |
479 | }, | 479 | }, |