supercop

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

verify.c (3727B)


      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_verify(int argc, const char **argv) {
     10   const char *keyFile         = NULL;
     11   const char *message         = NULL;
     12   const char *messageFile     = NULL;
     13   const char *verifySignature = NULL;
     14   struct KeyPair *kp;
     15   FILE *fmessage;
     16   FILE *fsignature;
     17   int isValid;
     18 
     19   static const char *const usages[] = {
     20     "supercop verify -k keyfile -s signature [-m message | -M message-file]",
     21     NULL,
     22   };
     23   struct argparse_option options[] = {
     24     OPT_HELP(),
     25     OPT_STRING('k', "key-file", &keyFile, "Select key file to use for the operation", NULL, 0, 0),
     26     OPT_STRING('m', "message", &message, "Message to verify (defaults to stdin)", NULL, 0, 0),
     27     OPT_STRING('M', "message-file", &messageFile, "Message file to verify (defaults to stdin)", NULL, 0, 0),
     28     OPT_STRING('s', "signature", &verifySignature, "Signature to verify", NULL, 0, 0),
     29     OPT_END(),
     30   };
     31 
     32   struct argparse argparse;
     33   argparse_init(&argparse, options, usages, ARGPARSE_STOP_AT_NON_OPTION);
     34   argparse_describe(&argparse, "\nVerify a message signature", NULL);
     35   argparse_parse(&argparse, argc, argv);
     36 
     37   if (!keyFile) {
     38     fprintf(stderr, "Missing required argument: key-file\n\n");
     39     argparse_usage(&argparse);
     40     return 1;
     41   }
     42 
     43   if (!verifySignature) {
     44     fprintf(stderr, "Missing required argument: signature\n\n");
     45     argparse_usage(&argparse);
     46     return 1;
     47   }
     48 
     49   fmessage   = supercop_open_message(message, messageFile);
     50   fsignature = supercop_parse_signature(verifySignature);
     51 
     52   long message_len = fremaining(fmessage);
     53   const unsigned char *msg = calloc(1, message_len);
     54   fread((void *)msg, 1, message_len, fmessage);
     55 
     56   long signature_len = fremaining(fsignature);
     57   const unsigned char *sig = calloc(1, signature_len);
     58   fread((void *)sig, 1, signature_len, fsignature);
     59   if (signature_len != 64) {
     60     fprintf(stderr, "Invalid signature!!\n");
     61     free((void *)sig);
     62     free((void *)msg);
     63     fclose(fsignature);
     64     return 1;
     65   }
     66 
     67   kp = readKeyFile(keyFile);
     68   if (!kp || !kp->public_key) {
     69     fprintf(stderr, "Could not decode key file: unknown or invalid format\n");
     70     free((void *)sig);
     71     free((void *)msg);
     72     fclose(fsignature);
     73     if (kp) keypair_free(kp);
     74     return 1;
     75   }
     76   isValid = ed25519_verify(sig, msg, message_len, kp->public_key);
     77 
     78   free((void *)sig);
     79   free((void *)msg);
     80   fclose(fsignature);
     81   keypair_free(kp);
     82 
     83   if (isValid) {
     84     fprintf(stdout, "OK\n");
     85     return 0;
     86   } else {
     87     fprintf(stdout, "FAIL\n");
     88     return 1;
     89   }
     90 }
     91 
     92 void __attribute__((constructor)) cmd_verify_setup(void) {
     93   struct cmd_struct *cmd = calloc(1, sizeof(struct cmd_struct));
     94   if (!cmd) {
     95     fprintf(stderr, "Failed to allocate memory for verify command\n");
     96     return;
     97   }
     98   cmd->next                        = commands;
     99   cmd->fn                          = cmd_verify;
    100   static const char *verify_names[] = {"verify", NULL};
    101   cmd->name                        = verify_names;
    102   cmd->display                     = "verify";
    103   cmd->description                 = "Verify a message signature";
    104   cmd->help_text =
    105       "supercop verify - Verify a message signature\n"
    106       "\n"
    107       "Usage:\n"
    108       "  supercop verify -k keyfile -s signature [-m message | -M message-file]\n"
    109       "\n"
    110       "Options:\n"
    111       "  -k, --key-file <path>       Select key file to use for the operation\n"
    112       "  -m, --message <message>     Message to verify (defaults to stdin)\n"
    113       "  -M, --message-file <path>   Message file to verify (defaults to stdin)\n"
    114       "  -s, --signature <hex>       Signature to verify the message against\n";
    115   commands = cmd;
    116 }