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

* tools/Makefile.in (TARGETS): Added nettle-hash, and related

build rules.
(SOURCES): Added nettle-hash.c.

* tools/nettle-hash.c: New file.

Rev: nettle/tools/Makefile.in:1.5
Rev: nettle/tools/nettle-hash.c:1.1
parent 8a9d1fa9
......@@ -18,7 +18,7 @@ PRE_CPPFLAGS = -I.. -I$(top_srcdir)
PRE_LDFLAGS = -L..
HOGWEED_TARGETS = pkcs1-conv$(EXEEXT)
TARGETS = sexp-conv$(EXEEXT) nettle-lfib-stream$(EXEEXT) \
TARGETS = sexp-conv$(EXEEXT) nettle-hash$(EXEEXT) nettle-lfib-stream$(EXEEXT) \
@IF_HOGWEED@ $(HOGWEED_TARGETS)
all: $(TARGETS)
......@@ -26,8 +26,9 @@ all: $(TARGETS)
sexp_conv_SOURCES = sexp-conv.c input.c output.c parse.c \
getopt.c getopt1.c misc.c
pkcs1_conv_SOURCES = pkcs1-conv.c getopt.c getopt1.c misc.c
nettle_hash_SOURCES = nettle-hash.c getopt.c getopt1.c misc.c
SOURCES = $(sexp_conv_SOURCES) nettle-lfib-stream.c pkcs1-conv.c
SOURCES = $(sexp_conv_SOURCES) nettle-hash.c nettle-lfib-stream.c pkcs1-conv.c
DISTFILES = $(SOURCES) Makefile.in getopt.h input.h misc.h output.h parse.h
......@@ -42,6 +43,12 @@ pkcs1_conv_OBJS = $(pkcs1_conv_SOURCES:.c=.$(OBJEXT))
pkcs1-conv$(EXEEXT): $(pkcs1_conv_OBJS) ../libnettle.a ../libhogweed.a
$(LINK) $(pkcs1_conv_OBJS) -lhogweed -lnettle $(LIBS) -o $@
# FIXME: Avoid linking with gmp
nettle_hash_OBJS = $(nettle_hash_SOURCES:.c=.$(OBJEXT))
nettle-hash$(EXEEXT): $(nettle_hash_OBJS) ../libnettle.a
$(LINK) $(nettle_hash_OBJS) -lnettle $(LIBS) -o $@
.c.$(OBJEXT):
$(COMPILE) -c $< && $(DEP_PROCESS)
......
/* nettle-hash.c
*
* General hashing tool. */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2011 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nettle-meta.h"
#include "base16.h"
#include "getopt.h"
#include "misc.h"
#define BUFSIZE 16384
static void
list_algorithms (void)
{
unsigned i;
const struct nettle_hash *alg;
printf ("%10s digestsize (internal block size), in units of octest\n", "name");
for (i = 0; (alg = nettle_hashes[i]); i++)
printf ("%10s %d (%d)\n",
alg->name, alg->digest_size, alg->block_size);
};
static const struct nettle_hash *
find_algorithm (const char *name)
{
size_t length = strlen (name);
const struct nettle_hash *alg;
const struct nettle_hash *found = NULL;
unsigned i;
for (i = 0; (alg = nettle_hashes[i]); i++)
{
if (!strncmp(name, alg->name, length))
{
/* Luckily, no valid algorithm name is a prefix of any
other, so we don't need to handle exact matches
specially. */
if (found)
die("Hash algorithm `%s' is ambiguous (%s or %s or ...?).\n"
"Use nettle-hash --list to list all available algorithms.\n",
name, alg->name, found->name);
found = alg;
}
}
if (!found)
die("Hash algorithm `%s' is not supported.\n"
"Use nettle-hash --list to list all available algorithms.\n",
name);
return found;
}
/* Also in examples/io.c */
static int
hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
{
for (;;)
{
char buffer[BUFSIZE];
size_t res = fread(buffer, 1, sizeof(buffer), f);
if (ferror(f))
return 0;
hash->update(ctx, res, buffer);
if (feof(f))
return 1;
}
}
static int
digest_file(const struct nettle_hash *alg,
unsigned digest_length, int raw,
FILE *f)
{
void *ctx;
uint8_t *digest;
ctx = xalloc(alg->context_size);
alg->init(ctx);
if (!hash_file (alg, ctx, f))
{
free (ctx);
return 0;
}
digest = xalloc(digest_length);
alg->digest(ctx, digest_length, digest);
free(ctx);
if (raw)
fwrite (digest, digest_length, 1, stdout);
else
{
unsigned i;
char *hex = xalloc(BASE16_ENCODE_LENGTH(8) + 1);
for (i = 0; i + 8 < digest_length; i += 8)
{
base16_encode_update(hex, 8, digest + i);
hex[BASE16_ENCODE_LENGTH(8)] = 0;
printf("%s ", hex);
}
base16_encode_update(hex, digest_length - i, digest + i);
hex[BASE16_ENCODE_LENGTH(digest_length - i)] = 0;
printf("%s %s\n", hex, alg->name);
free(hex);
}
free(digest);
return 1;
}
int
main (int argc, char **argv)
{
const char *alg_name = NULL;
const struct nettle_hash *alg;
unsigned length = 0;
int raw = 0;
int c;
enum { OPT_HELP = 0x300, OPT_RAW, OPT_LIST };
static const struct option options[] =
{
/* Name, args, flag, val */
{ "help", no_argument, NULL, OPT_HELP },
{ "version", no_argument, NULL, 'V' },
{ "algorithm", required_argument, NULL, 'a' },
{ "length", required_argument, NULL, 'l' },
{ "list", no_argument, NULL, OPT_LIST },
{ "raw", no_argument, NULL, OPT_RAW },
{ NULL, 0, NULL, 0 }
};
while ( (c = getopt_long(argc, argv, "Va:l:", options, NULL)) != -1)
switch (c)
{
default:
abort();
case OPT_HELP:
printf("nettle-hash -a ALGORITHM [OPTIONS] [FILE ...]\n"
"Options:\n"
" --help Show this help.\n"
" -V, --version Show version information.\n"
" --list List supported hash algorithms.\n"
" -a, --algorithm=ALG Hash algorithm to use.\n"
" -l, --length=LENGTH Desired digest length (octets)\n"
" --raw Raw binary output.\n");
return EXIT_SUCCESS;
case 'V':
printf("nettle-hash (" PACKAGE_STRING ")\n");
return EXIT_SUCCESS;
case 'a':
alg_name = optarg;
break;
case 'l':
{
int arg;
arg = atoi (optarg);
if (arg <= 0)
die ("Invalid length argument: `%s'\n", optarg);
length = arg;
}
break;
case OPT_RAW:
raw = 1;
break;
case OPT_LIST:
list_algorithms();
return EXIT_SUCCESS;
}
if (!alg_name)
die("Algorithm argument (-a option) is mandatory.\n"
"See nettle-hash --help for further information.\n");
alg = find_algorithm (alg_name);
if (!alg)
die("Hash algorithm `%s' not supported or .\n"
"Use nettle-hash --list to list available algorithms.\n",
alg_name);
if (length == 0)
length = alg->digest_size;
else if (length > alg->digest_size)
die ("Length argument %d too large for selected algorithm.\n",
length);
argv += optind;
argc -= optind;
if (argc == 0)
digest_file (alg, length, raw, stdin);
else
{
int i;
for (i = 0; i < argc; i++)
{
FILE *f = fopen (argv[i], "rb");
if (!f)
die ("Cannot open `%s': %s\n", argv[i], STRERROR(errno));
printf("%s: ", argv[i]);
if (!digest_file (alg, length, raw, f))
die("Reading `%s' failed: %s\n", argv[i], STRERROR(errno));
fclose(f);
}
}
if (fflush(stdout) != 0 )
die("Write failed: %s\n", STRERROR(errno));
return EXIT_SUCCESS;
}
Markdown is supported
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