Example #1
0
        public void Sign(
            [Argument(Name = "KEY-ID", Description = "A private key to use for signing.")]
            Guid keyId,
            [Argument(Name = "VERSION", Description = "A version number to sign.")]
            int version,
            [Option(
                 'p',
                 ValueName = "PASSPHRASE",
                 Description = "Take passphrase through this option instead of prompt."
                 )]
            string?passphrase = null,
            [Option(
                 'E',
                 ValueName = "FILE",
                 Description = "Bencodex file to use for extra data.  " +
                               "For standard input, use a hyphen (`-').  " +
                               "For an actual file named a hyphen, prepend `./', i.e., `./-'."
                 )]
            string?extraFile = null,
            [Option(
                 'e',
                 ValueName = "KEY=VALUE",
                 Description = "Set a value to a key on extra Bencodex dictionary.  " +
                               "Can be applied multiple times (e.g., `-e foo=1 -e bar=baz').  " +
                               "This option implies the extra data to be a Bencodex dictionary, " +
                               "hence cannot be used together with -E/--extra-file option."
                 )]
            string[]?extra = null
            )
        {
            PrivateKey key        = new KeyCommand().UnprotectKey(keyId, passphrase);
            IValue?    extraValue = null;

            if (extraFile is string path)
            {
                if (extra is string[] e && e.Length > 0)
                {
                    throw Utils.Error(
                              "-E/--extra-file and -e/--extra cannot be used together at a time."
                              );
                }

                var codec = new Codec();
                if (path == "-")
                {
                    // Stream for stdin does not support .Seek()
                    using MemoryStream buffer = new MemoryStream();
                    using (Stream stream = Console.OpenStandardInput())
                    {
                        stream.CopyTo(buffer);
                    }

                    buffer.Seek(0, SeekOrigin.Begin);
                    extraValue = codec.Decode(buffer);
                }
                else
                {
                    using Stream stream = File.Open(path, FileMode.Open, FileAccess.Read);
                    extraValue          = codec.Decode(stream);
                }
            }
            else if (extra is string[] e && e.Length > 0)
            {
                var dict = Bencodex.Types.Dictionary.Empty;
                foreach (string pair in e)
                {
                    int sepPos = pair.IndexOf('=');
                    if (sepPos < 0)
                    {
                        throw Utils.Error(
                                  "-e/--extra must be a pair of KEY=VALUE, but no equal (=) separator: " +
                                  $"`{pair}'."
                                  );
                    }

                    string key_  = pair.Substring(0, sepPos);
                    string value = pair.Substring(sepPos + 1);
                    dict = dict.SetItem(key_, value);
                }

                extraValue = dict;
            }

            AppProtocolVersion v = AppProtocolVersion.Sign(key, version, extraValue);

            Console.WriteLine(v.Token);
        }
Example #2
0
        public void Verify(
            [Argument(
                 Name = "APV-TOKEN",
                 Description = "An app protocol version token to verify.  " +
                               "Read from the standard input if omitted."
                 )]
            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
            )
        {
            AppProtocolVersion v = ParseAppProtocolVersionToken(token);

            if (publicKey is string[] pubKeyHexes)
            {
                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
                        );
                }
            }

            if (!noKeyStore)
            {
                KeyCommand keyInstance = new KeyCommand();
                IEnumerable <Tuple <Guid, ProtectedPrivateKey> > ppks = keyInstance.KeyStore.List()
                                                                        .Where(pair => pair.Item2.Address.Equals(v.Signer));
                foreach (Tuple <Guid, ProtectedPrivateKey> 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.");
        }