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 }