Commit 40b0e3ed authored by Niels Möller's avatar Niels Möller
Browse files

(parse_options): New function.

(main): By default, read and hash stdin, and compare with the hash
in the signature. New option --no-data to omit this check.

Rev: src/spki/tools/spki-check-signature.c:1.3
parent 0144844f
......@@ -23,50 +23,126 @@
#include "certificate.h"
#include "parse.h"
#include <stdarg.h>
#include "misc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
static void
die(const char *format, ...)
usage(void)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "spki-check-signature [ --no-data ] SIGNATURE\n");
exit(EXIT_FAILURE);
}
struct check_options
{
int with_data;
/* NOTE: We actually use that the argv string is writable. */
char *signature;
};
static void
usage(void)
parse_options(struct check_options *o,
int argc, char **argv)
{
fprintf(stderr, "spki-check-signature SIGNATURE\n");
exit(EXIT_FAILURE);
o->with_data = 1;
for (;;)
{
static const struct option options[] =
{
/* Name, args, flag, val */
{ "no-data", no_argument, NULL, 'n' },
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, '?' },
{ NULL, 0, NULL, 0 }
};
int c;
c = getopt_long(argc, argv, "V?", options, NULL);
switch (c)
{
default:
abort();
case -1:
if (optind == argc)
die("spki-check-signature: No signature given.\n");
o->signature = argv[optind++];
if (optind != argc)
die("spki-check-signature: Too many arguments.\n");
return;
case 'V':
die("spki-check-signature --version not implemented\n");
case 'n':
o->with_data = 0;
break;
case '?':
usage();
}
}
}
int
main(int argc, char **argv)
{
struct check_options o;
struct spki_acl_db db;
struct sexp_iterator sexp;
struct spki_iterator i;
struct spki_hash_value hash;
struct spki_principal *principal;
if (argc != 2)
usage();
parse_options(&o, argc, argv);
spki_acl_init(&db);
if (sexp_transport_iterator_first(&sexp, strlen(argv[1]), argv[1])
if (sexp_transport_iterator_first(&sexp, strlen(o.signature), o.signature)
&& spki_iterator_first_sexp(&i, &sexp)
&& spki_check_type(&i, SPKI_TYPE_SIGNATURE)
&& spki_parse_hash(&i, &hash)
&& spki_parse_principal(&db, &i, &principal))
{
if (o.with_data)
{
const struct nettle_hash *hash_algorithm;
uint8_t *digest;
switch (hash.type)
{
default:
die("Unsupported hash algorithm.");
case SPKI_TYPE_MD5:
hash_algorithm = &nettle_md5;
break;
case SPKI_TYPE_SHA1:
hash_algorithm = &nettle_sha1;
break;
}
if (hash.length != hash_algorithm->digest_size)
die("Incorrect hash (bad length)\n");
digest = hash_file(hash_algorithm, stdin);
if (!digest)
die("Reading stdin failed.\n");
if (memcmp(digest, hash.digest, hash_algorithm->digest_size))
die("Hash value doesn't match input.\n");
}
if (!spki_verify(NULL, &hash, principal, &i))
die("Bad signature\n");
if (!spki_parse_end(&i))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment