diff options
Diffstat (limited to 'example/verifysig/src/main.c')
-rw-r--r-- | example/verifysig/src/main.c | 373 |
1 files changed, 228 insertions, 145 deletions
diff --git a/example/verifysig/src/main.c b/example/verifysig/src/main.c index 6e91829..951f923 100644 --- a/example/verifysig/src/main.c +++ b/example/verifysig/src/main.c @@ -23,56 +23,51 @@ #include <stdlib.h> #include <string.h> +#include <dropt.h> #include "epid/common/errors.h" #include "epid/common/types.h" +#include "epid/common/file_parser.h" #include "epid/verifier/api.h" +#include "epid/verifier/1.1/api.h" -#include "util/argutil.h" #include "util/buffutil.h" #include "util/convutil.h" #include "util/envutil.h" #include "src/verifysig.h" +#include "src/verifysig11.h" // Defaults -#define PROGRAM_NAME ("verifysig") -#define PUBKEYFILE_DEFAULT ("pubkey.bin") +#define PROGRAM_NAME "verifysig" +#define PUBKEYFILE_DEFAULT "pubkey.bin" #define PRIVRL_DEFAULT NULL #define SIGRL_DEFAULT NULL -#define GRPRL_DEFAULT ("grprl.bin") +#define GRPRL_DEFAULT "grprl.bin" #define VERIFIERRL_DEFAULT NULL -#define SIG_DEFAULT ("sig.dat") -#define CACERT_DEFAULT ("cacert.bin") -#define HASHALG_DEFAULT ("SHA-512") +#define SIG_DEFAULT "sig.dat" +#define CACERT_DEFAULT "cacert.bin" +#define HASHALG_DEFAULT "SHA-512" +#define UNPARSED_HASHALG (kInvalidHashAlg) #define VPRECMPI_DEFAULT NULL #define VPRECMPO_DEFAULT NULL -/// Print usage message -void PrintUsage() { - log_fmt( - "Usage: %s [OPTION]...\n" - "Verify signature was created by group member in good standing\n" - "\n" - "Options:\n" - "\n" - "--sig=FILE load signature from FILE (default: %s)\n" - "--msg=MESSAGE MESSAGE that was signed (default: empty)\n" - "--bsn=BASENAME BASENAME used in signature (default: random)\n" - "--privrl=FILE load private key revocation list from FILE\n" - "--sigrl=FILE load signature based revocation list from FILE\n" - "--grprl=FILE load group revocation list from FILE\n" - " (default: %s)\n" - "--verifierrl=FILE load verifier revocation list from FILE\n" - "--gpubkey=FILE load group public key from FILE (default: %s)\n" - "--vprecmpi=FILE load pre-computed verifier data from FILE\n" - "--vprecmpo=FILE write pre-computed verifier data to FILE\n" - "--hashalg=NAME SHA-256 | SHA-384 | SHA-512 (default: %s)\n" - "--capubkey=FILE load IoT Issuing CA public key from FILE\n" - " (default: %s)\n" - "-h,--help display this help and exit\n" - "-v,--verbose print status messages to stdout\n" - "\n", - PROGRAM_NAME, SIG_DEFAULT, GRPRL_DEFAULT, PUBKEYFILE_DEFAULT, - HASHALG_DEFAULT, CACERT_DEFAULT); +/// parses string to a hashalg type +static dropt_error HandleHashalg(dropt_context* context, + const char* option_argument, + void* handler_data) { + dropt_error err = dropt_error_none; + HashAlg* hashalg = handler_data; + (void)context; + if (option_argument == NULL) { + *hashalg = UNPARSED_HASHALG; + } else if (option_argument[0] == '\0') { + err = dropt_error_insufficient_arguments; + } else if (StringToHashAlg(option_argument, hashalg)) { + err = dropt_error_none; + } else { + /* Reject the value as being inappropriate for this handler. */ + err = dropt_error_mismatch; + } + return err; } /// Main entrypoint @@ -81,56 +76,54 @@ int main(int argc, char* argv[]) { int ret_value = EXIT_SUCCESS; // intermediate return value for EPID functions EpidStatus result = kEpidErr; - // Temp option pointer - char const* opt_str = 0; // User Settings // Signature file name parameter - char const* sig_file = SIG_DEFAULT; + static char* sig_file = SIG_DEFAULT; // Message string parameter - char const* msg_str = NULL; + static char* msg_str = NULL; size_t msg_size = 0; // Basename string parameter - char const* basename_str = NULL; + static char* basename_str = NULL; size_t basename_size = 0; // PrivRl file name parameter - char const* privrl_file = PRIVRL_DEFAULT; + static char* privrl_file = NULL; // SigRl file name parameter - char const* sigrl_file = SIGRL_DEFAULT; + static char* sigrl_file = NULL; // GrpRl file name parameter - char const* grprl_file = GRPRL_DEFAULT; + static char* grprl_file = NULL; // VerRl file name parameter - char const* verrl_file = VERIFIERRL_DEFAULT; + static char* verrl_file = NULL; // Group public key file name parameter - char const* pubkey_file = PUBKEYFILE_DEFAULT; + static char* pubkey_file = NULL; // Verifier pre-computed settings input file name parameter - char const* vprecmpi_file = VPRECMPI_DEFAULT; + static char* vprecmpi_file = NULL; // Verifier pre-computed settings output file name parameter - char const* vprecmpo_file = VPRECMPO_DEFAULT; - - // Hash algorithm name parameter - char const* hashalg_str = HASHALG_DEFAULT; + static char* vprecmpo_file = NULL; // CA certificate file name parameter - char const* cacert_file_name = CACERT_DEFAULT; + static char* cacert_file_name = NULL; // Verbose flag parameter - bool verbose = false; + static bool verbose = false; + + // help flag parameter + static bool show_help = false; // Buffers and computed values // Signature buffer - EpidSignature* sig = NULL; + void* sig = NULL; size_t sig_size = 0; // PrivRl buffer @@ -154,90 +147,131 @@ int main(int argc, char* argv[]) { size_t signed_pubkey_size = 0; // Verifier pre-computed settings - VerifierPrecomp verifier_precmp = {0}; + void* verifier_precmp = NULL; + size_t verifier_precmp_size = 0; + size_t vprecmpi_file_size = 0; // Flag that Verifier pre-computed settings input is valid bool use_precmp_in; - // Hash algorithm - HashAlg hashalg; - // CA certificate EpidCaCertificate cacert = {0}; + // Hash algorithm + static HashAlg hashalg = UNPARSED_HASHALG; + + dropt_option options[] = { + {'\0', "sig", "load signature from FILE (default: " SIG_DEFAULT ")", + "FILE", dropt_handle_string, &sig_file}, + {'\0', "msg", "MESSAGE that was signed (default: empty)", "MESSAGE", + dropt_handle_string, &msg_str}, + {'\0', "bsn", "BASENAME used in signature (default: random)", "BASENAME", + dropt_handle_string, &basename_str}, + {'\0', "privrl", "load private key revocation list from FILE", "FILE", + dropt_handle_string, &privrl_file}, + {'\0', "sigrl", "load signature based revocation list from FILE", "FILE", + dropt_handle_string, &sigrl_file}, + {'\0', "grprl", + "load group revocation list from FILE\n (default: " GRPRL_DEFAULT ")", + "FILE", dropt_handle_string, &grprl_file}, + {'\0', "verifierrl", "load verifier revocation list from FILE", "FILE", + dropt_handle_string, &verrl_file}, + {'\0', "gpubkey", + "load group public key from FILE (default: " PUBKEYFILE_DEFAULT ")", + "FILE", dropt_handle_string, &pubkey_file}, + {'\0', "vprecmpi", "load pre-computed verifier data from FILE", "FILE", + dropt_handle_string, &vprecmpi_file}, + {'\0', "vprecmpo", "write pre-computed verifier data to FILE", "FILE", + dropt_handle_string, &vprecmpo_file}, + {'\0', "capubkey", + "load IoT Issuing CA public key from FILE\n (default: " CACERT_DEFAULT + ")", + "FILE", dropt_handle_string, &cacert_file_name}, + {'\0', "hashalg", + "use specified hash algorithm for 2.0 groups " + "(default: " HASHALG_DEFAULT ")", + "{SHA-256 | SHA-384 | SHA-512}", HandleHashalg, &hashalg}, + {'h', "help", "display this help and exit", NULL, dropt_handle_bool, + &show_help, dropt_attr_halt}, + {'v', "verbose", "print status messages to stdout", NULL, + dropt_handle_bool, &verbose}, + + {0} /* Required sentinel value. */ + }; + + dropt_context* dropt_ctx = NULL; // set program name for logging set_prog_name(PROGRAM_NAME); do { + EpidVersion epid_version = kNumEpidVersions; // Read command line args - if (argc < 1) { - PrintUsage(); + dropt_ctx = dropt_new_context(options); + if (!dropt_ctx) { ret_value = EXIT_FAILURE; break; + } else if (argc > 0) { + /* Parse the arguments from argv. + * + * argv[1] is always safe to access since argv[argc] is guaranteed + * to be NULL and since we've established that argc > 0. + */ + char** rest = dropt_parse(dropt_ctx, -1, &argv[1]); + if (dropt_get_error(dropt_ctx) != dropt_error_none) { + log_error(dropt_get_error_message(dropt_ctx)); + if (dropt_error_invalid_option == dropt_get_error(dropt_ctx)) { + fprintf(stderr, "Try '%s --help' for more information.\n", + PROGRAM_NAME); + } + ret_value = EXIT_FAILURE; + break; + } else if (show_help) { + log_fmt( + "Usage: %s [OPTION]...\n" + "Verify signature was created by group member in good standing\n" + "\n" + "Options:\n", + PROGRAM_NAME); + dropt_print_help(stdout, dropt_ctx, NULL); + ret_value = EXIT_SUCCESS; + break; + } else if (*rest) { + // we have unparsed (positional) arguments + log_error("invalid argument: %s", *rest); + fprintf(stderr, "Try '%s --help' for more information.\n", + PROGRAM_NAME); + ret_value = EXIT_FAILURE; + break; + } else { + if (verbose) { + verbose = ToggleVerbosity(); + } + if (!sig_file) sig_file = SIG_DEFAULT; + if (!grprl_file) grprl_file = GRPRL_DEFAULT; + if (!pubkey_file) pubkey_file = PUBKEYFILE_DEFAULT; + if (!cacert_file_name) cacert_file_name = CACERT_DEFAULT; + if (msg_str) msg_size = strlen(msg_str); + if (basename_str) basename_size = strlen(basename_str); + + if (verbose) { + log_msg("\nOption values:"); + log_msg(" sig_file : %s", sig_file); + log_msg(" msg_str : %s", msg_str); + log_msg(" basename_str : %s", basename_str); + log_msg(" privrl_file : %s", privrl_file); + log_msg(" sigrl_file : %s", sigrl_file); + log_msg(" grprl_file : %s", grprl_file); + log_msg(" verrl_file : %s", verrl_file); + log_msg(" vprecmpi_file : %s", vprecmpi_file); + log_msg(" vprecmpo_file : %s", vprecmpo_file); + log_msg(" hashalg : %s", (UNPARSED_HASHALG == hashalg) + ? "(default)" + : HashAlgToString(hashalg)); + log_msg(" cacert_file_name : %s", cacert_file_name); + log_msg(""); + } + } } - - if (CmdOptionExists(argc, argv, "--help") || - CmdOptionExists(argc, argv, "-h")) { - PrintUsage(); - ret_value = EXIT_SUCCESS; - break; - } - - if (CmdOptionExists(argc, argv, "--verbose") || - CmdOptionExists(argc, argv, "-v")) { - verbose = ToggleVerbosity(); - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--sig"))) { - sig_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--msg"))) { - msg_str = opt_str; - msg_size = strlen(msg_str); - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--bsn"))) { - basename_str = opt_str; - basename_size = strlen(basename_str); - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--privrl"))) { - privrl_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--sigrl"))) { - sigrl_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--grprl"))) { - grprl_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--verifierrl"))) { - verrl_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--gpubkey"))) { - pubkey_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--vprecmpi"))) { - vprecmpi_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--vprecmpo"))) { - vprecmpo_file = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--hashalg"))) { - hashalg_str = opt_str; - } - - if (0 != (opt_str = GetCmdOption(argc, argv, "--capubkey"))) { - cacert_file_name = opt_str; - } - // convert command line args to usable formats // Signature @@ -302,40 +336,72 @@ int main(int argc, char* argv[]) { break; } + // Detect EPID version + result = EpidParseFileHeader(signed_pubkey, signed_pubkey_size, + &epid_version, NULL); + if (kEpidNoErr != result || kNumEpidVersions <= epid_version) { + log_error("EPID version can not be detected"); + ret_value = EXIT_FAILURE; + break; + } + + // Configure hashalg based on group + if (kEpid1x == epid_version) { + if (!(kSha256 == hashalg || UNPARSED_HASHALG == hashalg)) { + log_error( + "unsupported hash algorithm: %s only supported for 2.0 groups", + HashAlgToString(hashalg)); + ret_value = EXIT_FAILURE; + break; + } + } else { + if (UNPARSED_HASHALG == hashalg) { + hashalg = kSha512; + } + } + // Load Verifier pre-computed settings + if (kEpid1x == epid_version) { + verifier_precmp_size = sizeof(Epid11VerifierPrecomp); + } else if (kEpid2x == epid_version) { + verifier_precmp_size = sizeof(VerifierPrecomp); + } else { + log_error("EPID version %s is not supported", + EpidVersionToString(epid_version)); + ret_value = EXIT_FAILURE; + break; + } + verifier_precmp = AllocBuffer(verifier_precmp_size); use_precmp_in = false; if (vprecmpi_file) { - if (sizeof(verifier_precmp) != GetFileSize(vprecmpi_file)) { - log_error("incorrect input precomp size"); + vprecmpi_file_size = GetFileSize(vprecmpi_file); + if (verifier_precmp_size != vprecmpi_file_size) { + if (kEpid2x == epid_version && + vprecmpi_file_size == verifier_precmp_size - sizeof(GroupId)) { + log_error( + "incorrect input precomp size: precomp format may have changed, " + "try regenerating it"); + } else { + log_error("incorrect input precomp size"); + } ret_value = EXIT_FAILURE; break; } use_precmp_in = true; - if (0 != - ReadLoud(vprecmpi_file, &verifier_precmp, sizeof(verifier_precmp))) { + if (0 != ReadLoud(vprecmpi_file, verifier_precmp, verifier_precmp_size)) { ret_value = EXIT_FAILURE; break; } } - // Hash algorithm - if (!StringToHashAlg(hashalg_str, &hashalg)) { - ret_value = EXIT_FAILURE; - break; - } - - if (hashalg != kSha256 && hashalg != kSha384 && hashalg != kSha512) { - log_error("unsupported hash algorithm %s", HashAlgToString(hashalg)); - ret_value = EXIT_FAILURE; - break; - } - // Report Settings if (verbose) { log_msg("=============================================="); log_msg("Verifying Message:"); log_msg(""); + log_msg(" [in] EPID version: %s", EpidVersionToString(epid_version)); + log_msg(""); log_msg(" [in] Signature Len: %d", (int)sig_size); log_msg(" [in] Signature: "); PrintBuffer(sig, sig_size); @@ -371,18 +437,32 @@ int main(int argc, char* argv[]) { if (use_precmp_in) { log_msg(""); log_msg(" [in] Verifier PreComp: "); - PrintBuffer(&verifier_precmp, sizeof(verifier_precmp)); + PrintBuffer(verifier_precmp, verifier_precmp_size); } log_msg("=============================================="); } // Verify - result = Verify( - sig, sig_size, msg_str, msg_size, basename_str, basename_size, - signed_priv_rl, signed_priv_rl_size, signed_sig_rl, signed_sig_rl_size, - signed_grp_rl, signed_grp_rl_size, ver_rl, ver_rl_size, signed_pubkey, - signed_pubkey_size, &cacert, hashalg, &verifier_precmp, use_precmp_in); - + if (kEpid2x == epid_version) { + result = + Verify(sig, sig_size, msg_str, msg_size, basename_str, basename_size, + signed_priv_rl, signed_priv_rl_size, signed_sig_rl, + signed_sig_rl_size, signed_grp_rl, signed_grp_rl_size, ver_rl, + ver_rl_size, signed_pubkey, signed_pubkey_size, &cacert, + hashalg, (VerifierPrecomp*)verifier_precmp, use_precmp_in); + } else if (kEpid1x == epid_version) { + result = Verify11(sig, sig_size, msg_str, msg_size, basename_str, + basename_size, signed_priv_rl, signed_priv_rl_size, + signed_sig_rl, signed_sig_rl_size, signed_grp_rl, + signed_grp_rl_size, signed_pubkey, signed_pubkey_size, + &cacert, (Epid11VerifierPrecomp*)verifier_precmp, + use_precmp_in); + } else { + log_error("EPID version %s is not supported", + EpidVersionToString(epid_version)); + ret_value = EXIT_FAILURE; + break; + } // Report Result if (kEpidNoErr == result) { log_msg("signature verified successfully"); @@ -396,7 +476,7 @@ int main(int argc, char* argv[]) { // Store Verifier pre-computed settings if (vprecmpo_file) { if (0 != - WriteLoud(&verifier_precmp, sizeof(verifier_precmp), vprecmpo_file)) { + WriteLoud(verifier_precmp, verifier_precmp_size, vprecmpo_file)) { ret_value = EXIT_FAILURE; break; } @@ -413,6 +493,9 @@ int main(int argc, char* argv[]) { if (signed_grp_rl) free(signed_grp_rl); if (ver_rl) free(ver_rl); if (signed_pubkey) free(signed_pubkey); + if (verifier_precmp) free(verifier_precmp); + + dropt_free_context(dropt_ctx); return ret_value; } |