#include <string.h>

#include "ssh.h"
#include "ascii.h"

#include "test-utils.h"

static void
test_valid (void)
{
  static const struct {
    const char *in;
    const char *exp_hex;
  } valid[] = {
    { "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym",
      "314cb82ac8b5fe90cf18bf190afa4759b80779709f991f736f044d5e13bcbca6" },
    { "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym\n",
      "314cb82ac8b5fe90cf18bf190afa4759b80779709f991f736f044d5e13bcbca6" },
    { " ssh-ed25519\tAAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym\n",
      "314cb82ac8b5fe90cf18bf190afa4759b80779709f991f736f044d5e13bcbca6" },
    { " ssh-ed25519\tAAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym comment\n",
      "314cb82ac8b5fe90cf18bf190afa4759b80779709f991f736f044d5e13bcbca6" },
  };

  for (size_t i = 0; i < sizeof (valid) / sizeof (valid[0]); i++)
    {
      struct sigsum_pubkey key, exp;
      const char *err;

      if (!sigsum_ssh_parse_public_key (&key, valid[i].in, &err))
	die ("sigsum_ssh_parse_public_key: failed on test case %zu: %s", i, err);

      if (!_sigsum_decode_hex_key (&exp, valid[i].exp_hex))
	die ("_sigsum_decode_hex_key: failed on test case %zu: %s", i, err);

      if (memcmp (key.k, exp.k, sizeof (key.k)))
	{
	  dump_hex (stderr, sizeof (key.k), key.k);
	  die ("sigsum_ssh_parse_public_key: unexpected output");
	}
    }
}

static void
test_invalid (void)
{
  static const struct {
    const char *in;
    const char *exp_err;
  } invalid[] = {
    { "\fssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym",
      "expected ssh-ed25519" },
    { "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym\f",
      "unexpected base64 blob size" },
    { "ssh-ed25519-sk AAAAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym",
      "expected ssh-ed25519" },
    { "ssh-ed25519 A.AAC3NzaC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym",
      "invalid base64" },
    { "ssh-ed25519 AAAAC3NzbC1lZDI1NTE5AAAAIDFMuCrItf6Qzxi/GQr6R1m4B3lwn5kfc28ETV4TvLym",
      "not an ed25519 blob" },
  };
  for (size_t i = 0; i < sizeof (invalid) / sizeof (invalid[0]); i++)
    {
      struct sigsum_pubkey key;
      const char *err;
      if (sigsum_ssh_parse_public_key (&key, invalid[i].in, &err))
	die ("sigsum_ssh_parse_public_key: test case %zu: accepted invalid key", i);
      if (!strstr (err, invalid[i].exp_err))
	die ("sigsum_ssh_parse_public_key: test case %zu: unexpected error: %s", i, err);
    }
}

int
main (void)
{
  test_valid();
  test_invalid();

  return 0;
}
