Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / tools / nettle-hash.c
blob5710216e99dd53545bf3f79be654ff5c22250907
1 /* nettle-hash.c
3 * General hashing tool. */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2011 Niels Möller
8 *
9 * The nettle library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or (at your
12 * option) any later version.
14 * The nettle library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the nettle library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02111-1301, USA.
25 #if HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
34 #include "nettle-meta.h"
35 #include "base16.h"
37 #include "getopt.h"
38 #include "misc.h"
40 #define BUFSIZE 16384
42 static void
43 list_algorithms (void)
45 unsigned i;
46 const struct nettle_hash *alg;
47 printf ("%10s digestsize (internal block size), in units of octets\n", "name");
49 for (i = 0; (alg = nettle_hashes[i]); i++)
50 printf ("%10s %d (%d)\n",
51 alg->name, alg->digest_size, alg->block_size);
54 static const struct nettle_hash *
55 find_algorithm (const char *name)
57 const struct nettle_hash *alg;
58 unsigned i;
60 for (i = 0; (alg = nettle_hashes[i]); i++)
61 if (!strcmp(name, alg->name))
62 return alg;
64 return NULL;
67 /* Also in examples/io.c */
68 static int
69 hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
71 for (;;)
73 char buffer[BUFSIZE];
74 size_t res = fread(buffer, 1, sizeof(buffer), f);
75 if (ferror(f))
76 return 0;
78 hash->update(ctx, res, buffer);
79 if (feof(f))
80 return 1;
84 static int
85 digest_file(const struct nettle_hash *alg,
86 unsigned digest_length, int raw,
87 FILE *f)
89 void *ctx;
90 uint8_t *digest;
91 ctx = xalloc(alg->context_size);
93 alg->init(ctx);
95 if (!hash_file (alg, ctx, f))
97 free (ctx);
98 return 0;
101 digest = xalloc(digest_length);
102 alg->digest(ctx, digest_length, digest);
103 free(ctx);
105 if (raw)
106 fwrite (digest, digest_length, 1, stdout);
108 else
110 unsigned i;
111 char *hex = xalloc(BASE16_ENCODE_LENGTH(8) + 1);
112 for (i = 0; i + 8 < digest_length; i += 8)
114 base16_encode_update(hex, 8, digest + i);
115 hex[BASE16_ENCODE_LENGTH(8)] = 0;
116 printf("%s ", hex);
118 base16_encode_update(hex, digest_length - i, digest + i);
119 hex[BASE16_ENCODE_LENGTH(digest_length - i)] = 0;
120 printf("%s %s\n", hex, alg->name);
121 free(hex);
124 free(digest);
126 return 1;
129 /* FIXME: Be more compatible with md5sum and sha1sum. Options -c
130 (check), -b (binary), -t (text), and output format with hex hash
131 sum, optional star (meaning binary mode), and file name. */
133 main (int argc, char **argv)
135 const char *alg_name = NULL;
136 const struct nettle_hash *alg;
137 unsigned length = 0;
138 int raw = 0;
139 int c;
141 enum { OPT_HELP = 0x300, OPT_RAW, OPT_LIST };
142 static const struct option options[] =
144 /* Name, args, flag, val */
145 { "help", no_argument, NULL, OPT_HELP },
146 { "version", no_argument, NULL, 'V' },
147 { "algorithm", required_argument, NULL, 'a' },
148 { "length", required_argument, NULL, 'l' },
149 { "list", no_argument, NULL, OPT_LIST },
150 { "raw", no_argument, NULL, OPT_RAW },
152 { NULL, 0, NULL, 0 }
155 while ( (c = getopt_long(argc, argv, "Va:l:", options, NULL)) != -1)
156 switch (c)
158 default:
159 abort();
160 case OPT_HELP:
161 printf("nettle-hash -a ALGORITHM [OPTIONS] [FILE ...]\n"
162 "Options:\n"
163 " --help Show this help.\n"
164 " -V, --version Show version information.\n"
165 " --list List supported hash algorithms.\n"
166 " -a, --algorithm=ALG Hash algorithm to use.\n"
167 " -l, --length=LENGTH Desired digest length (octets)\n"
168 " --raw Raw binary output.\n");
169 return EXIT_SUCCESS;
170 case 'V':
171 printf("nettle-hash (" PACKAGE_STRING ")\n");
172 return EXIT_SUCCESS;
173 case 'a':
174 alg_name = optarg;
175 break;
176 case 'l':
178 int arg;
179 arg = atoi (optarg);
180 if (arg <= 0)
181 die ("Invalid length argument: `%s'\n", optarg);
182 length = arg;
184 break;
185 case OPT_RAW:
186 raw = 1;
187 break;
188 case OPT_LIST:
189 list_algorithms();
190 return EXIT_SUCCESS;
193 if (!alg_name)
194 die("Algorithm argument (-a option) is mandatory.\n"
195 "See nettle-hash --help for further information.\n");
197 alg = find_algorithm (alg_name);
198 if (!alg)
199 die("Hash algorithm `%s' not supported or .\n"
200 "Use nettle-hash --list to list available algorithms.\n",
201 alg_name);
203 if (length == 0)
204 length = alg->digest_size;
205 else if (length > alg->digest_size)
206 die ("Length argument %d too large for selected algorithm.\n",
207 length);
209 argv += optind;
210 argc -= optind;
212 if (argc == 0)
213 digest_file (alg, length, raw, stdin);
214 else
216 int i;
217 for (i = 0; i < argc; i++)
219 FILE *f = fopen (argv[i], "rb");
220 if (!f)
221 die ("Cannot open `%s': %s\n", argv[i], STRERROR(errno));
222 printf("%s: ", argv[i]);
223 if (!digest_file (alg, length, raw, f))
224 die("Reading `%s' failed: %s\n", argv[i], STRERROR(errno));
225 fclose(f);
228 if (fflush(stdout) != 0 )
229 die("Write failed: %s\n", STRERROR(errno));
231 return EXIT_SUCCESS;