supercop

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

sign.c (2981B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #include "cli/command.h"
      5 #include "cli/common.h"
      6 #include "cofyc/argparse.h"
      7 #include "orlp/ed25519.h"
      8 
      9 static int cmd_sign(int argc, const char **argv) {
     10   const char *keyFile     = NULL;
     11   const char *message     = NULL;
     12   const char *messageFile = NULL;
     13   struct KeyPair *kp;
     14   FILE *fmessage;
     15   int i, result;
     16 
     17   static const char *const usages[] = {
     18     "supercop sign -k keyfile [-m message | -M message-file]",
     19     NULL,
     20   };
     21   struct argparse_option options[] = {
     22     OPT_HELP(),
     23     OPT_STRING('k', "key-file", &keyFile, "Select key file to use for the operation", NULL, 0, 0),
     24     OPT_STRING('m', "message", &message, "Message to sign (defaults to stdin)", NULL, 0, 0),
     25     OPT_STRING('M', "message-file", &messageFile, "Message file to sign (defaults to stdin)", 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, "\nSign a message", NULL);
     32   argparse_parse(&argparse, argc, argv);
     33 
     34   if (!keyFile) {
     35     fprintf(stderr, "Missing required argument: key-file\n\n");
     36     argparse_usage(&argparse);
     37     return 1;
     38   }
     39 
     40   fmessage = supercop_open_message(message, messageFile);
     41   kp = readKeyFile(keyFile);
     42   if (!kp || !kp->public_key) {
     43     fprintf(stderr, "Could not decode key file: unknown or invalid format\n");
     44     if (kp) keypair_free(kp);
     45     return 1;
     46   }
     47   if (!kp->private_key) {
     48     fprintf(stderr, "Key file contains no private key: signing requires a full key\n");
     49     keypair_free(kp);
     50     return 1;
     51   }
     52 
     53   long message_len = fremaining(fmessage);
     54   const unsigned char *msg = calloc(1, message_len);
     55   fread((void *)msg, 1, message_len, fmessage);
     56 
     57   unsigned char *signature = calloc(1, 64);
     58   ed25519_sign(signature, msg, message_len, kp->public_key, kp->private_key);
     59 
     60   for(i=0;i<64;i++) fprintf(stdout, "%02x", signature[i]);
     61   fprintf(stdout, "\n");
     62 
     63   free(signature);
     64   free((void *)msg);
     65   keypair_free(kp);
     66   result = 0;
     67   return result;
     68 }
     69 
     70 void __attribute__((constructor)) cmd_sign_setup(void) {
     71   struct cmd_struct *cmd = calloc(1, sizeof(struct cmd_struct));
     72   if (!cmd) {
     73     fprintf(stderr, "Failed to allocate memory for sign command\n");
     74     return;
     75   }
     76   cmd->next                      = commands;
     77   cmd->fn                        = cmd_sign;
     78   static const char *sign_names[] = {"sign", NULL};
     79   cmd->name                      = sign_names;
     80   cmd->display                   = "sign";
     81   cmd->description               = "Sign a message";
     82   cmd->help_text =
     83       "supercop sign - Sign a message\n"
     84       "\n"
     85       "Usage:\n"
     86       "  supercop sign -k keyfile [-m message | -M message-file]\n"
     87       "\n"
     88       "Options:\n"
     89       "  -k, --key-file <path>       Select key file to use for the operation\n"
     90       "  -m, --message <message>     Message to sign (defaults to stdin)\n"
     91       "  -M, --message-file <path>   Message file to sign (defaults to stdin)\n";
     92   commands = cmd;
     93 }