8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.lib / wanboot / hmac / hmac.c
blob320550cf9033ef9a6b9a0dca07ee583c4d2d392a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <libintl.h>
33 #include <locale.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <wanbootutil.h>
37 #include <sys/wanboot_impl.h>
39 /* Return codes */
40 #define HMAC_SUCCESS 0
41 #define HMAC_NOKEY 1
42 #define HMAC_ERROR 2
44 /* Private buffer length */
45 #define HMAC_BUF_LEN 1024
48 * This routine is used to compute a hash digest for the file represented
49 * by the file descirptor, 'fd'. The key, 'hmac_key', and key type, 'ka',
50 * will be provided by the caller. The resulting hash digest will be
51 * written to stdout.
53 * Returns:
54 * HMAC_SUCCESS or HMAC_ERROR.
56 static int
57 hash_gen(int in_fd, const wbku_key_attr_t *ka, const uint8_t *hmac_key)
59 SHA1_CTX ctx;
60 uint8_t buf[HMAC_BUF_LEN];
61 ssize_t i;
62 uint8_t digest[HMAC_DIGEST_LEN];
65 * Initialize the computation.
67 HMACInit(&ctx, hmac_key, ka->ka_len);
70 * Read the data to hash.
72 while ((i = read(in_fd, buf, HMAC_BUF_LEN)) > 0) {
73 HMACUpdate(&ctx, buf, i);
75 if (i < 0) {
76 wbku_printerr("Cannot read input_file");
77 return (HMAC_ERROR);
81 * Finalize the digest.
83 HMACFinal(&ctx, hmac_key, ka->ka_len, digest);
86 * Write the digest to stdout.
88 if (wbio_nwrite(STDOUT_FILENO, digest, sizeof (digest)) != 0) {
89 wbku_printerr("Cannot output digest");
90 return (HMAC_ERROR);
94 * Success.
96 return (HMAC_SUCCESS);
100 * Prints usage().
102 static void
103 usage(const char *cmd)
105 (void) fprintf(stderr,
106 gettext("Usage: %s [-i input_file] -k key_file\n"), cmd);
110 * This program is used to compute a hash digest for data read in from
111 * stdin or optionally, a file. The resulting hash digest will be written
112 * to stdout.
114 * Returns:
115 * HMAC_SUCCESS, HMAC_ERROR or HMAC_NOKEY.
118 main(int argc, char **argv)
120 uint8_t hmac_key[WANBOOT_HMAC_KEY_SIZE];
121 int c;
122 char *infile_name = NULL;
123 char *keyfile_name = NULL;
124 int in_fd = -1;
125 FILE *key_fp = NULL;
126 wbku_key_attr_t ka;
127 wbku_retcode_t wbkuret;
128 int ret = HMAC_ERROR;
131 * Do the necessary magic for localization support.
133 (void) setlocale(LC_ALL, "");
134 #if !defined(TEXT_DOMAIN)
135 #define TEXT_DOMAIN "SYS_TEST"
136 #endif
137 (void) textdomain(TEXT_DOMAIN);
140 * Initialize program name for use by wbku_printerr().
142 wbku_errinit(argv[0]);
145 * Should be at least three arguments.
147 if (argc < 3) {
148 usage(argv[0]);
149 return (HMAC_ERROR);
153 * Parse the options.
155 while ((c = getopt(argc, argv, "i:k:")) != EOF) {
156 switch (c) {
157 case 'i':
159 * Optional input file.
161 infile_name = optarg;
162 break;
163 case 'k':
165 * Path to key file.
167 keyfile_name = optarg;
168 break;
169 default:
170 usage(argv[0]);
171 return (HMAC_ERROR);
176 * A key file must be defined.
178 if (keyfile_name == NULL) {
179 wbku_printerr("Must specify the key_file\n");
180 return (HMAC_ERROR);
184 * If the user did not provide an input file for the data,
185 * then use stdin as the source.
187 if (infile_name == NULL) {
188 in_fd = STDIN_FILENO;
189 } else {
190 in_fd = open(infile_name, O_RDONLY);
191 if (in_fd < 0) {
192 wbku_printerr("Cannot open input_file");
193 return (HMAC_ERROR);
198 * Open the key file for reading.
200 if ((key_fp = fopen(keyfile_name, "r")) == NULL) {
201 wbku_printerr("Cannot open %s", keyfile_name);
202 goto out;
206 * Create a SHA1 key attribute structure. It's the only hash
207 * type we support.
209 wbkuret = wbku_str_to_keyattr(WBKU_KW_HMAC_SHA1, &ka, WBKU_HASH_KEY);
210 if (wbkuret != WBKU_SUCCESS) {
211 wbku_printerr("%s\n", wbku_retmsg(wbkuret));
212 goto out;
216 * Find the client key, if it exists.
218 wbkuret = wbku_find_key(key_fp, NULL, &ka, hmac_key, B_FALSE);
219 if (wbkuret != WBKU_SUCCESS) {
220 wbku_printerr("%s\n", wbku_retmsg(wbkuret));
221 ret = (wbkuret == WBKU_NOKEY) ? HMAC_NOKEY : HMAC_ERROR;
222 } else {
223 ret = hash_gen(in_fd, &ka, hmac_key);
225 out:
227 * Cleanup.
229 if (in_fd != -1) {
230 (void) close(in_fd);
232 if (key_fp != NULL) {
233 (void) fclose(key_fp);
236 return (ret);