diff options
-rw-r--r-- | src/nkeys.zig | 54 | ||||
-rw-r--r-- | src/znk.zig | 8 |
2 files changed, 34 insertions, 28 deletions
diff --git a/src/nkeys.zig b/src/nkeys.zig index aac326c..b66865d 100644 --- a/src/nkeys.zig +++ b/src/nkeys.zig | |||
@@ -95,7 +95,7 @@ pub const SeedKeyPair = struct { | |||
95 | Ed25519.verify(sig, msg, self.kp.public_key) catch return error.InvalidSignature; | 95 | Ed25519.verify(sig, msg, self.kp.public_key) catch return error.InvalidSignature; |
96 | } | 96 | } |
97 | 97 | ||
98 | pub fn asTextSeed(self: *const Self) text_seed { | 98 | pub fn textSeed(self: *const Self) text_seed { |
99 | const full_prefix = &[_]u8{ | 99 | const full_prefix = &[_]u8{ |
100 | @enumToInt(KeyTypePrefixByte.seed) | (@enumToInt(self.prefix) >> 5), | 100 | @enumToInt(KeyTypePrefixByte.seed) | (@enumToInt(self.prefix) >> 5), |
101 | (@enumToInt(self.prefix) & 0b00011111) << 3, | 101 | (@enumToInt(self.prefix) & 0b00011111) << 3, |
@@ -104,22 +104,22 @@ pub const SeedKeyPair = struct { | |||
104 | return encode(full_prefix.len, seed.len, full_prefix, seed); | 104 | return encode(full_prefix.len, seed.len, full_prefix, seed); |
105 | } | 105 | } |
106 | 106 | ||
107 | pub fn asTextPrivateKey(self: *const Self) text_private { | 107 | pub fn textPrivateKey(self: *const Self) text_private { |
108 | return encode(1, self.kp.secret_key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, &self.kp.secret_key); | 108 | return encode(1, self.kp.secret_key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, &self.kp.secret_key); |
109 | } | 109 | } |
110 | 110 | ||
111 | pub fn asTextPublicKey(self: *const Self) text_public { | 111 | pub fn textPublicKey(self: *const Self) text_public { |
112 | return encode(1, self.kp.public_key.len, &[_]u8{@enumToInt(self.prefix)}, &self.kp.public_key); | 112 | return encode(1, self.kp.public_key.len, &[_]u8{@enumToInt(self.prefix)}, &self.kp.public_key); |
113 | } | 113 | } |
114 | 114 | ||
115 | pub fn asPublicKey(self: *const Self) PublicKey { | 115 | pub fn intoPublicKey(self: *const Self) PublicKey { |
116 | return PublicKey{ | 116 | return PublicKey{ |
117 | .prefix = self.prefix, | 117 | .prefix = self.prefix, |
118 | .key = self.kp.public_key, | 118 | .key = self.kp.public_key, |
119 | }; | 119 | }; |
120 | } | 120 | } |
121 | 121 | ||
122 | pub fn asPrivateKey(self: *const Self) PrivateKey { | 122 | pub fn intoPrivateKey(self: *const Self) PrivateKey { |
123 | return PrivateKey{ .kp = self.kp }; | 123 | return PrivateKey{ .kp = self.kp }; |
124 | } | 124 | } |
125 | 125 | ||
@@ -153,7 +153,14 @@ pub const PublicKey = struct { | |||
153 | }; | 153 | }; |
154 | } | 154 | } |
155 | 155 | ||
156 | pub fn asTextPublicKey(self: *const Self) text_public { | 156 | pub fn fromRawPublicKey( |
157 | prefix: PublicPrefixByte, | ||
158 | raw_key: *const [Ed25519.public_length]u8, | ||
159 | ) Self { | ||
160 | return Self{ .prefix = prefix, .key = raw_key.* }; | ||
161 | } | ||
162 | |||
163 | pub fn textPublicKey(self: *const Self) text_public { | ||
157 | return encode(1, self.key.len, &[_]u8{@enumToInt(self.prefix)}, &self.key); | 164 | return encode(1, self.key.len, &[_]u8{@enumToInt(self.prefix)}, &self.key); |
158 | } | 165 | } |
159 | 166 | ||
@@ -184,21 +191,25 @@ pub const PrivateKey = struct { | |||
184 | return PrivateKey{ .kp = Ed25519.KeyPair.fromSecretKey(decoded.data) }; | 191 | return PrivateKey{ .kp = Ed25519.KeyPair.fromSecretKey(decoded.data) }; |
185 | } | 192 | } |
186 | 193 | ||
187 | pub fn asSeedKeyPair(self: *const Self, prefix: PublicPrefixByte) SeedKeyPair { | 194 | pub fn fromRawPrivateKey(raw_key: *const [Ed25519.secret_length]u8) Self { |
195 | return Self{ .kp = Ed25519.KeyPair.fromSecretKey(raw_key.*) }; | ||
196 | } | ||
197 | |||
198 | pub fn intoSeedKeyPair(self: *const Self, prefix: PublicPrefixByte) SeedKeyPair { | ||
188 | return SeedKeyPair{ | 199 | return SeedKeyPair{ |
189 | .prefix = prefix, | 200 | .prefix = prefix, |
190 | .kp = self.kp, | 201 | .kp = self.kp, |
191 | }; | 202 | }; |
192 | } | 203 | } |
193 | 204 | ||
194 | pub fn asPublicKey(self: *const Self, prefix: PublicPrefixByte) PublicKey { | 205 | pub fn intoPublicKey(self: *const Self, prefix: PublicPrefixByte) PublicKey { |
195 | return PublicKey{ | 206 | return PublicKey{ |
196 | .prefix = prefix, | 207 | .prefix = prefix, |
197 | .key = self.kp.public_key, | 208 | .key = self.kp.public_key, |
198 | }; | 209 | }; |
199 | } | 210 | } |
200 | 211 | ||
201 | pub fn asTextPrivateKey(self: *const Self) text_private { | 212 | pub fn textPrivateKey(self: *const Self) text_private { |
202 | return encode(1, self.kp.secret_key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, &self.kp.secret_key); | 213 | return encode(1, self.kp.secret_key.len, &[_]u8{@enumToInt(KeyTypePrefixByte.private)}, &self.kp.secret_key); |
203 | } | 214 | } |
204 | 215 | ||
@@ -409,7 +420,7 @@ pub fn parseDecoratedNkey(contents: []const u8) NoNkeySeedFoundError!SeedKeyPair | |||
409 | 420 | ||
410 | pub fn parseDecoratedUserNkey(contents: []const u8) (NoNkeySeedFoundError || NoNkeyUserSeedFoundError)!SeedKeyPair { | 421 | pub fn parseDecoratedUserNkey(contents: []const u8) (NoNkeySeedFoundError || NoNkeyUserSeedFoundError)!SeedKeyPair { |
411 | var key = try parseDecoratedNkey(contents); | 422 | var key = try parseDecoratedNkey(contents); |
412 | if (!mem.startsWith(u8, &key.asTextSeed(), "SU")) return error.NoNkeyUserSeedFound; | 423 | if (!mem.startsWith(u8, &key.textSeed(), "SU")) return error.NoNkeyUserSeedFound; |
413 | defer key.wipe(); | 424 | defer key.wipe(); |
414 | return key; | 425 | return key; |
415 | } | 426 | } |
@@ -425,32 +436,27 @@ test { | |||
425 | var key_pair = try SeedKeyPair.generate(PublicPrefixByte.server); | 436 | var key_pair = try SeedKeyPair.generate(PublicPrefixByte.server); |
426 | defer key_pair.wipe(); | 437 | defer key_pair.wipe(); |
427 | 438 | ||
428 | var decoded_seed = try SeedKeyPair.fromTextSeed(&key_pair.asTextSeed()); | 439 | var decoded_seed = try SeedKeyPair.fromTextSeed(&key_pair.textSeed()); |
429 | defer decoded_seed.wipe(); | 440 | defer decoded_seed.wipe(); |
430 | try testing.expect(isValidEncoding(&decoded_seed.asTextSeed())); | 441 | try testing.expect(isValidEncoding(&decoded_seed.textSeed())); |
431 | 442 | ||
432 | var pub_key_str_a = key_pair.asTextPublicKey(); | 443 | var pub_key_str_a = key_pair.textPublicKey(); |
433 | defer wipeBytes(&pub_key_str_a); | 444 | defer wipeBytes(&pub_key_str_a); |
434 | var priv_key_str = key_pair.asTextPrivateKey(); | 445 | var priv_key_str = key_pair.textPrivateKey(); |
435 | defer wipeBytes(&priv_key_str); | 446 | defer wipeBytes(&priv_key_str); |
436 | try testing.expect(pub_key_str_a.len != 0); | 447 | try testing.expect(pub_key_str_a.len != 0); |
437 | try testing.expect(priv_key_str.len != 0); | 448 | try testing.expect(priv_key_str.len != 0); |
438 | try testing.expect(isValidEncoding(&pub_key_str_a)); | 449 | try testing.expect(isValidEncoding(&pub_key_str_a)); |
439 | try testing.expect(isValidEncoding(&priv_key_str)); | 450 | try testing.expect(isValidEncoding(&priv_key_str)); |
440 | 451 | ||
441 | var pub_key = key_pair.asPublicKey(); | 452 | var pub_key = key_pair.intoPublicKey(); |
442 | defer pub_key.wipe(); | 453 | defer pub_key.wipe(); |
443 | var pub_key_str_b = pub_key.asTextPublicKey(); | 454 | var pub_key_str_b = pub_key.textPublicKey(); |
444 | defer wipeBytes(&pub_key_str_b); | 455 | defer wipeBytes(&pub_key_str_b); |
445 | try testing.expectEqualSlices(u8, &pub_key_str_a, &pub_key_str_b); | 456 | try testing.expectEqualSlices(u8, &pub_key_str_a, &pub_key_str_b); |
446 | } | 457 | } |
447 | 458 | ||
448 | test "encode" { | 459 | // TODO(rutgerbrf): test decode (+bad), seed, account, user, operator, cluster, isValid*, from*, fromRaw*, wipe |
449 | var raw_key: [32]u8 = undefined; | ||
450 | crypto.random.bytes(&raw_key); | ||
451 | |||
452 | // encode( | ||
453 | } | ||
454 | 460 | ||
455 | test "parse decorated JWT (bad)" { | 461 | test "parse decorated JWT (bad)" { |
456 | try testing.expectEqualStrings("foo", parseDecoratedJwt("foo")); | 462 | try testing.expectEqualStrings("foo", parseDecoratedJwt("foo")); |
@@ -480,10 +486,10 @@ test "parse decorated seed and JWT" { | |||
480 | const seed = "SUAGIEYODKBBTUMOB666Z5KA4FCWAZV7HWSGRHOD7MK6UM5IYLWLACH7DQ"; | 486 | const seed = "SUAGIEYODKBBTUMOB666Z5KA4FCWAZV7HWSGRHOD7MK6UM5IYLWLACH7DQ"; |
481 | 487 | ||
482 | var got_kp = try parseDecoratedUserNkey(creds); | 488 | var got_kp = try parseDecoratedUserNkey(creds); |
483 | try testing.expectEqualStrings(seed, &got_kp.asTextSeed()); | 489 | try testing.expectEqualStrings(seed, &got_kp.textSeed()); |
484 | 490 | ||
485 | got_kp = try parseDecoratedNkey(creds); | 491 | got_kp = try parseDecoratedNkey(creds); |
486 | try testing.expectEqualStrings(seed, &got_kp.asTextSeed()); | 492 | try testing.expectEqualStrings(seed, &got_kp.textSeed()); |
487 | 493 | ||
488 | var got_jwt = parseDecoratedJwt(creds); | 494 | var got_jwt = parseDecoratedJwt(creds); |
489 | try testing.expectEqualStrings(jwt, got_jwt); | 495 | try testing.expectEqualStrings(jwt, got_jwt); |
diff --git a/src/znk.zig b/src/znk.zig index 89fc82c..7837cc8 100644 --- a/src/znk.zig +++ b/src/znk.zig | |||
@@ -149,10 +149,10 @@ pub fn cmdGen(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !voi | |||
149 | } else { | 149 | } else { |
150 | var kp = try nkeys.SeedKeyPair.generate(ty.?); | 150 | var kp = try nkeys.SeedKeyPair.generate(ty.?); |
151 | defer kp.wipe(); | 151 | defer kp.wipe(); |
152 | try stdout.writeAll(&kp.asTextSeed()); | 152 | try stdout.writeAll(&kp.textSeed()); |
153 | try stdout.writeAll("\n"); | 153 | try stdout.writeAll("\n"); |
154 | 154 | ||
155 | var public_key = kp.asTextPublicKey(); | 155 | var public_key = kp.textPublicKey(); |
156 | if (pub_out) { | 156 | if (pub_out) { |
157 | try stdout.writeAll(&public_key); | 157 | try stdout.writeAll(&public_key); |
158 | try stdout.writeAll("\n"); | 158 | try stdout.writeAll("\n"); |
@@ -378,12 +378,12 @@ const PrefixKeyGenerator = struct { | |||
378 | 378 | ||
379 | var kp = try nkeys.SeedKeyPair.generate(self.ty); | 379 | var kp = try nkeys.SeedKeyPair.generate(self.ty); |
380 | defer kp.wipe(); | 380 | defer kp.wipe(); |
381 | var public_key = kp.asTextPublicKey(); | 381 | var public_key = kp.textPublicKey(); |
382 | if (!mem.startsWith(u8, public_key[1..], self.prefix)) continue; | 382 | if (!mem.startsWith(u8, public_key[1..], self.prefix)) continue; |
383 | 383 | ||
384 | if (self.done.xchg(true, .SeqCst)) return; // another thread is already done | 384 | if (self.done.xchg(true, .SeqCst)) return; // another thread is already done |
385 | 385 | ||
386 | info("{s}", .{kp.asTextSeed()}); | 386 | info("{s}", .{kp.textSeed()}); |
387 | info("{s}", .{public_key}); | 387 | info("{s}", .{public_key}); |
388 | 388 | ||
389 | return; | 389 | return; |