aboutsummaryrefslogtreecommitdiff
path: root/example/verifysig/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'example/verifysig/src/main.c')
-rw-r--r--example/verifysig/src/main.c373
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;
}