From bd8558304df4d9f0369b4b9d465afba9e5d0b56f Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sun, 26 Apr 2020 01:43:33 +0900 Subject: [PATCH] planet apv verify command [changelog skip] --- Libplanet.Tools/Apv.cs | 116 ++++++++++++++++++++++++++++++++++++----- Libplanet.Tools/Key.cs | 4 +- 2 files changed, 105 insertions(+), 15 deletions(-) diff --git a/Libplanet.Tools/Apv.cs b/Libplanet.Tools/Apv.cs index a176655442b..b2b49581272 100644 --- a/Libplanet.Tools/Apv.cs +++ b/Libplanet.Tools/Apv.cs @@ -2,10 +2,12 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using Bencodex; using Bencodex.Types; using Cocona; using Libplanet.Crypto; +using Libplanet.KeyStore; using Libplanet.Net; namespace Libplanet.Tools @@ -99,31 +101,102 @@ public void Sign( Console.WriteLine(v.Token); } - [Command(Description = "Parse and analyze a given app protocol version token.")] - public void Analyze( + [Command(Description = "Verify a given app protocol version token's signature.")] + public void Verify( [Argument( Name = "APV-TOKEN", - Description = "An app protocol version token to analyze. " + + Description = "An app protocol version token to verify. " + "Read from the standard input if omitted." )] - string? token = null + string? token = null, + [Option( + 'p', + ValueName = "PUBLIC-KEY", + Description = "Public key(s) to be used for verification. " + + "Can be applied multiple times." + )] + string[]? publicKey = null, + [Option( + 'K', + Description = "Do not use any keys in the key store, " + + "but only -p/--public-key options." + )] + bool noKeyStore = false ) { - if (token is null) - { - token = Console.ReadLine(); - } + AppProtocolVersion v = ParseAppProtocolVersionToken(token); - AppProtocolVersion v; - try + if (publicKey is string[] pubKeyHexes) { - v = AppProtocolVersion.FromToken(token.Trim()); + foreach (string pubKeyHex in pubKeyHexes) + { + string opt = $"-p/--public-key=\"{pubKeyHex}\""; + PublicKey pubKey; + try + { + pubKey = new PublicKey(ByteUtil.ParseHex(pubKeyHex)); + } + catch (Exception e) + { + throw Utils.Error($"The {opt} is not a valid public key. {e.Message}"); + } + + if (v.Verify(pubKey)) + { + Console.Error.WriteLine( + "The signature successfully was verified using the {0}.", + opt + ); + return; + } + + Console.Error.WriteLine( + "The signature was failed to verify using the {0}.", + opt + ); + } } - catch (FormatException e) + + if (!noKeyStore) { - throw Utils.Error("Not a valid app protocol version token. " + e); + Key keyInstance = new Key(); + IEnumerable> ppks = keyInstance.KeyStore.List() + .Where(pair => pair.Item2.Address.Equals(v.Signer)); + foreach (Tuple pair in ppks) + { + pair.Deconstruct(out Guid keyId, out ProtectedPrivateKey ppk); + PublicKey pubKey = keyInstance.UnprotectKey(keyId).PublicKey; + if (v.Verify(pubKey)) + { + Console.Error.WriteLine( + "The signature successfully was verified using the key {0}.", + keyId + ); + return; + } + + Console.Error.WriteLine( + "The signature was failed to verify using the key {0}.", + keyId + ); + } } + throw Utils.Error("Failed to verify."); + } + + [Command(Description = "Parse and analyze a given app protocol version token.")] + public void Analyze( + [Argument( + Name = "APV-TOKEN", + Description = "An app protocol version token to analyze. " + + "Read from the standard input if omitted." + )] + string? token = null + ) + { + AppProtocolVersion v = ParseAppProtocolVersionToken(token); + var data = new List<(string, string)> { ("version", v.Version.ToString(CultureInfo.InvariantCulture)), @@ -192,5 +265,22 @@ void TreeIntoTable(IValue tree, List<(string, string)> table, string key) Utils.PrintTable(("Field", "Value"), data); } + + private AppProtocolVersion ParseAppProtocolVersionToken(string? token) + { + if (token is null) + { + token = Console.ReadLine(); + } + + try + { + return AppProtocolVersion.FromToken(token.Trim()); + } + catch (FormatException e) + { + throw Utils.Error($"Not a valid app protocol version token. {e.Message}"); + } + } } } diff --git a/Libplanet.Tools/Key.cs b/Libplanet.Tools/Key.cs index 8898b5c83bf..c369ac501ec 100644 --- a/Libplanet.Tools/Key.cs +++ b/Libplanet.Tools/Key.cs @@ -175,8 +175,6 @@ public void Generate( public PrivateKey UnprotectKey(Guid keyId, string? passphrase = null) { - passphrase ??= ConsolePasswordReader.Read("Passphrase: "); - ProtectedPrivateKey ppk; try { @@ -187,6 +185,8 @@ public PrivateKey UnprotectKey(Guid keyId, string? passphrase = null) throw Utils.Error($"No such key ID: {keyId}"); } + passphrase ??= ConsolePasswordReader.Read($"Passphrase (of {keyId}): "); + try { return ppk.Unprotect(passphrase);