/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Verified boot key utility
 */

#include <getopt.h>
#include <inttypes.h>  /* For PRIu64 */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cryptolib.h"
#include "futility.h"
#include "host_common.h"
#include "util_misc.h"
#include "vboot_common.h"


/* Command line options */
enum {
  OPT_INKEY = 1000,
  OPT_KEY_VERSION,
  OPT_ALGORITHM,
  OPT_MODE_PACK,
  OPT_MODE_UNPACK,
  OPT_COPYTO,
};

static struct option long_opts[] = {
  {"key", 1, 0,                       OPT_INKEY                   },
  {"version", 1, 0,                   OPT_KEY_VERSION             },
  {"algorithm", 1, 0,                 OPT_ALGORITHM               },
  {"pack", 1, 0,                      OPT_MODE_PACK               },
  {"unpack", 1, 0,                    OPT_MODE_UNPACK             },
  {"copyto", 1, 0,                    OPT_COPYTO                  },
  {NULL, 0, 0, 0}
};


/* Print help and return error */
static int PrintHelp(char *progname) {
  int i;

  fprintf(stderr,
          "This program wraps RSA keys with verified boot headers\n");
  fprintf(stderr,
          "\n"
          "Usage:  %s --pack <outfile> [PARAMETERS]\n"
          "\n"
          "  Required parameters:\n"
          "    --key <infile>              RSA key file (.keyb or .pem)\n"
          "    --version <number>          Key version number "
          "(required for .keyb,\n"
	  "                                  ignored for .pem)\n"
          "    --algorithm <number>        "
	  "Signing algorithm to use with key:\n",
          progname);

  for (i = 0; i < kNumAlgorithms; i++) {
    fprintf(stderr,
            "                                  %d = (%s)\n",
            i, algo_strings[i]);
  }

  fprintf(stderr,
          "\nOR\n\n"
          "Usage:  %s --unpack <infile>\n"
          "\n"
          "  Optional parameters:\n"
          "    --copyto <file>             "
          "Write a copy of the key to this file.\n"
          "\n",
          progname);

  return 1;
}

/* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
                uint64_t version) {
  VbPublicKey* pubkey;
  VbPrivateKey* privkey;

  if (!infile || !outfile) {
    fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
    return 1;
  }

  if ((pubkey = PublicKeyReadKeyb(infile, algorithm, version))) {
    if (0 != PublicKeyWrite(outfile, pubkey)) {
      fprintf(stderr, "vbutil_key: Error writing key.\n");
      return 1;
    }
    free(pubkey);
    return 0;
  }

  if ((privkey = PrivateKeyReadPem(infile, algorithm))) {
    if (0 != PrivateKeyWrite(outfile, privkey)) {
      fprintf(stderr, "vbutil_key: Error writing key.\n");
      return 1;
    }
    free(privkey);
    return 0;
  }

  VbExError("Unable to parse either .keyb or .pem from %s\n", infile);
  return 1;
}


/* Unpack a .vbpubk or .vbprivk */
static int Unpack(const char *infile, const char *outfile) {
  VbPublicKey* pubkey;
  VbPrivateKey* privkey;

  if (!infile) {
    fprintf(stderr, "Need file to unpack\n");
    return 1;
  }

  if ((pubkey = PublicKeyRead(infile))) {
    printf("Public Key file:   %s\n", infile);
    printf("Algorithm:         %" PRIu64 " %s\n", pubkey->algorithm,
           (pubkey->algorithm < kNumAlgorithms ?
            algo_strings[pubkey->algorithm] : "(invalid)"));
    printf("Key Version:       %" PRIu64 "\n", pubkey->key_version);
    printf("Key sha1sum:       ");
    PrintPubKeySha1Sum(pubkey);
    printf("\n");
    if (outfile) {
      if (0 != PublicKeyWrite(outfile, pubkey)) {
        fprintf(stderr, "vbutil_key: Error writing key copy.\n");
        free(pubkey);
        return 1;
      }
    }
    free(pubkey);
    return 0;
  }

  if ((privkey = PrivateKeyRead(infile))) {
    printf("Private Key file:  %s\n", infile);
    printf("Algorithm:         %" PRIu64 " %s\n", privkey->algorithm,
           (privkey->algorithm < kNumAlgorithms ?
            algo_strings[privkey->algorithm] : "(invalid)"));
    if (outfile) {
      if (0 != PrivateKeyWrite(outfile, privkey)) {
        fprintf(stderr, "vbutil_key: Error writing key copy.\n");
        free(privkey);
        return 1;
      }
    }
    free(privkey);
    return 0;
  }

  VbExError("Unable to parse either .vbpubk or vbprivk from %s\n", infile);
  return 1;
}


int do_vbutil_key(int argc, char* argv[]) {

  char *infile = NULL;
  char *outfile = NULL;
  int mode = 0;
  int parse_error = 0;
  uint64_t version = 1;
  uint64_t algorithm = kNumAlgorithms;
  char* e;
  int i;

  char *progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
    switch (i) {
      case '?':
        /* Unhandled option */
        VbExError("Unknown option\n");
        parse_error = 1;
        break;

      case OPT_INKEY:
        infile = optarg;
        break;

      case OPT_KEY_VERSION:
        version = strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          VbExError("Invalid --version\n");
          parse_error = 1;
        }
        break;

      case OPT_ALGORITHM:
        algorithm = strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          VbExError("Invalid --algorithm\n");
          parse_error = 1;
        }
        break;

      case OPT_MODE_PACK:
        mode = i;
        outfile = optarg;
        break;

      case OPT_MODE_UNPACK:
        mode = i;
        infile = optarg;
        break;

      case OPT_COPYTO:
        outfile = optarg;
        break;
    }
  }

  if (parse_error)
    return PrintHelp(progname);

  switch(mode) {
    case OPT_MODE_PACK:
      return Pack(infile, outfile, algorithm, version);
    case OPT_MODE_UNPACK:
      return Unpack(infile, outfile);
    default:
      printf("Must specify a mode.\n");
      return PrintHelp(progname);
  }
}

DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key,
		      "Wraps RSA keys with vboot headers");
