#include <string.h>

#include <nettle/base64.h>

#include "ssh.h"

bool
sigsum_ssh_parse_public_key (struct sigsum_pubkey *key, const char *s, const char **err)
{
#define FAIL(error_msg) do {			\
    if (err) *err = error_msg;			\
    return false;				\
  } while (0)

  s += strspn (s, " \t");

  if (strncmp (s, "ssh-ed25519", 11) != 0)
    FAIL ("invalid key, expected ssh-ed25519");

  s+= 11;
  size_t sep_len = strspn (s, " \t");
  if (!sep_len)
    FAIL ("invalid key, expected ssh-ed25519");
  s += sep_len;

  size_t b64_size = strcspn (s, " \t\n");
  if (b64_size != 68)
    FAIL ("invalid key, unexpected base64 blob size");

  uint8_t blob[BASE64_DECODE_LENGTH(68)];
  size_t blob_size = sizeof(blob);
  struct base64_decode_ctx ctx;
  base64_decode_init (&ctx);
  if (!(base64_decode_update (&ctx, &blob_size, blob, b64_size, s)
	&& base64_decode_final (&ctx)))
    FAIL ("invalid key, invalid base64");

  static const uint8_t prefix[] = {
    0, 0, 0, 11, 's', 's', 'h', '-', 'e', 'd', '2', '5', '5', '1', '9',
    0, 0, 0, 32
  };
  if (blob_size != sizeof (prefix) + SIGSUM_PUBKEY_SIZE)
    FAIL ("invalid key, unexpected blob size");

  if (memcmp (blob, prefix, sizeof (prefix)) != 0)
    FAIL ("invalid key, not an ed25519 blob");

  memcpy (key->k, blob + sizeof (prefix), sizeof (key->k));
  return true;
}
