]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/bin/tools/isc-hmac-fixup.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / bin / tools / isc-hmac-fixup.c
1 /*
2  * Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id: isc-hmac-fixup.c,v 1.4 2010/03/10 02:17:52 marka Exp $ */
18
19 #include <config.h>
20
21 #include <isc/base64.h>
22 #include <isc/buffer.h>
23 #include <isc/md5.h>
24 #include <isc/region.h>
25 #include <isc/result.h>
26 #include <isc/sha1.h>
27 #include <isc/sha2.h>
28 #include <isc/stdio.h>
29 #include <isc/string.h>
30
31 #define HMAC_LEN        64
32
33 int
34 main(int argc, char **argv)  {
35         isc_buffer_t buf;
36         unsigned char key[1024];
37         char secret[1024];
38         char base64[(1024*4)/3];
39         isc_region_t r;
40         isc_result_t result;
41
42         if (argc != 3) {
43                 fprintf(stderr, "Usage:\t%s algorithm secret\n", argv[0]);
44                 fprintf(stderr, "\talgorithm: (MD5 | SHA1 | SHA224 | "
45                                 "SHA256 | SHA384 | SHA512)\n");
46                 return (1);
47         }
48
49         isc_buffer_init(&buf, secret, sizeof(secret));
50         result = isc_base64_decodestring(argv[2], &buf);
51         if (result != ISC_R_SUCCESS) {
52                 fprintf(stderr, "error: %s\n", isc_result_totext(result));
53                 return (1);
54         }
55         isc__buffer_usedregion(&buf, &r);
56
57         if (!strcasecmp(argv[1], "md5") ||
58             !strcasecmp(argv[1], "hmac-md5")) {
59                 if (r.length > HMAC_LEN) {
60                         isc_md5_t md5ctx;
61                         isc_md5_init(&md5ctx);
62                         isc_md5_update(&md5ctx, r.base, r.length);
63                         isc_md5_final(&md5ctx, key);
64
65                         r.base = key;
66                         r.length = ISC_MD5_DIGESTLENGTH;
67                 }
68         } else if (!strcasecmp(argv[1], "sha1") ||
69                    !strcasecmp(argv[1], "hmac-sha1")) {
70                 if (r.length > ISC_SHA1_DIGESTLENGTH) {
71                         isc_sha1_t sha1ctx;
72                         isc_sha1_init(&sha1ctx);
73                         isc_sha1_update(&sha1ctx, r.base, r.length);
74                         isc_sha1_final(&sha1ctx, key);
75
76                         r.base = key;
77                         r.length = ISC_SHA1_DIGESTLENGTH;
78                 }
79         } else if (!strcasecmp(argv[1], "sha224") ||
80                    !strcasecmp(argv[1], "hmac-sha224")) {
81                 if (r.length > ISC_SHA224_DIGESTLENGTH) {
82                         isc_sha224_t sha224ctx;
83                         isc_sha224_init(&sha224ctx);
84                         isc_sha224_update(&sha224ctx, r.base, r.length);
85                         isc_sha224_final(key, &sha224ctx);
86
87                         r.base = key;
88                         r.length = ISC_SHA224_DIGESTLENGTH;
89                 }
90         } else if (!strcasecmp(argv[1], "sha256") ||
91                    !strcasecmp(argv[1], "hmac-sha256")) {
92                 if (r.length > ISC_SHA256_DIGESTLENGTH) {
93                         isc_sha256_t sha256ctx;
94                         isc_sha256_init(&sha256ctx);
95                         isc_sha256_update(&sha256ctx, r.base, r.length);
96                         isc_sha256_final(key, &sha256ctx);
97
98                         r.base = key;
99                         r.length = ISC_SHA256_DIGESTLENGTH;
100                 }
101         } else if (!strcasecmp(argv[1], "sha384") ||
102                    !strcasecmp(argv[1], "hmac-sha384")) {
103                 if (r.length > ISC_SHA384_DIGESTLENGTH) {
104                         isc_sha384_t sha384ctx;
105                         isc_sha384_init(&sha384ctx);
106                         isc_sha384_update(&sha384ctx, r.base, r.length);
107                         isc_sha384_final(key, &sha384ctx);
108
109                         r.base = key;
110                         r.length = ISC_SHA384_DIGESTLENGTH;
111                 }
112         } else if (!strcasecmp(argv[1], "sha512") ||
113                    !strcasecmp(argv[1], "hmac-sha512")) {
114                 if (r.length > ISC_SHA512_DIGESTLENGTH) {
115                         isc_sha512_t sha512ctx;
116                         isc_sha512_init(&sha512ctx);
117                         isc_sha512_update(&sha512ctx, r.base, r.length);
118                         isc_sha512_final(key, &sha512ctx);
119
120                         r.base = key;
121                         r.length = ISC_SHA512_DIGESTLENGTH;
122                 }
123         } else {
124                 fprintf(stderr, "unknown hmac/digest algorithm: %s\n", argv[1]);
125                 return (1);
126         }
127
128         isc_buffer_init(&buf, base64, sizeof(base64));
129         result = isc_base64_totext(&r, 0, "", &buf);
130         if (result != ISC_R_SUCCESS) {
131                 fprintf(stderr, "error: %s\n", isc_result_totext(result));
132                 return (1);
133         }
134         fprintf(stdout, "%.*s\n", (int)isc_buffer_usedlength(&buf), base64);
135         return (0);
136 }