supercop

Basic CLI for supercop
git clone git://git.finwo.net/app/supercop
Log | Files | Refs | README | LICENSE

generate.c (2895B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include "cli/command.h"
      6 #include "cli/common.h"
      7 #include "cofyc/argparse.h"
      8 #include "orlp/ed25519.h"
      9 
     10 static int cmd_generate(int argc, const char **argv) {
     11   const char *keyFile = NULL;
     12   const char *format  = "0x00";
     13   FILE *fout = stdout;
     14   struct Format *fmt;
     15   struct KeyPair out;
     16   int result;
     17 
     18   static const char *const usages[] = {
     19     "supercop generate [options]",
     20     NULL,
     21   };
     22   struct argparse_option options[] = {
     23     OPT_HELP(),
     24     OPT_STRING('k', "key-file", &keyFile, "Key file to write (defaults to stdout)", NULL, 0, 0),
     25     OPT_STRING('f', "format", &format, "Key format to write (0x00, asc, hdr)", NULL, 0, 0),
     26     OPT_END(),
     27   };
     28 
     29   struct argparse argparse;
     30   argparse_init(&argparse, options, usages, ARGPARSE_STOP_AT_NON_OPTION);
     31   argparse_describe(&argparse, "\nGenerate a new ed25519 key", NULL);
     32   argparse_parse(&argparse, argc, argv);
     33 
     34   if (keyFile) {
     35     fout = fopen(keyFile, "w+");
     36     if (!fout) {
     37       fprintf(stderr, "Could not open output file\n");
     38       return 1;
     39     }
     40   }
     41 
     42   unsigned char seed[32];
     43   unsigned char public_key[32];
     44   unsigned char private_key[64];
     45 
     46   if (ed25519_create_seed(seed)) {
     47     fprintf(stderr, "Error while generating seed\n");
     48     if (keyFile) fclose(fout);
     49     return 1;
     50   }
     51 
     52   ed25519_create_keypair(public_key, private_key, seed);
     53   out.public_key  = public_key;
     54   out.private_key = private_key;
     55 
     56   // Encode in the requested format (default keeps historical behavior)
     57   fmt = supercop_find_format(format);
     58   if (!fmt) {
     59     fprintf(stderr, "Unknown format: %s\n", format);
     60     if (keyFile) fclose(fout);
     61     return 1;
     62   }
     63   size_t encoded_length;
     64   char *encoded = fmt->encode(&out, &encoded_length);
     65   if (!encoded) {
     66     fprintf(stderr, "Error while encoding key\n");
     67     if (keyFile) fclose(fout);
     68     return 1;
     69   }
     70   fwrite(encoded, 1, encoded_length, fout);
     71   free(encoded);
     72 
     73   result = 0;
     74   if (keyFile) {
     75     fclose(fout);
     76   }
     77 
     78   return result;
     79 }
     80 
     81 void __attribute__((constructor)) cmd_generate_setup(void) {
     82   struct cmd_struct *cmd = calloc(1, sizeof(struct cmd_struct));
     83   if (!cmd) {
     84     fprintf(stderr, "Failed to allocate memory for generate command\n");
     85     return;
     86   }
     87   cmd->next                          = commands;
     88   cmd->fn                            = cmd_generate;
     89   static const char *generate_names[] = {"generate", NULL};
     90   cmd->name                          = generate_names;
     91   cmd->display                       = "generate";
     92   cmd->description                   = "Generate new key";
     93   cmd->help_text =
     94       "supercop generate - Generate new key\n"
     95       "\n"
     96       "Usage:\n"
     97       "  supercop generate [options]\n"
     98       "\n"
     99       "Options:\n"
    100       "  -k, --key-file <path>  Key file to write (defaults to stdout)\n"
    101       "  -f, --format <name>    Key format to write: 0x00, asc, hdr (default 0x00)\n";
    102   commands = cmd;
    103 }