Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libresolv2/common/dst/hmac_link.c
+++ new/usr/src/lib/libresolv2/common/dst/hmac_link.c
1 1 /*
2 - * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2 + * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 3 * Use is subject to license terms.
4 4 */
5 5
6 -#pragma ident "%Z%%M% %I% %E% SMI"
7 6
8 7 #ifdef HMAC_MD5
9 8 #ifndef LINT
10 -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/hmac_link.c,v 1.9 2001/05/29 05:48:10 marka Exp $";
9 +static const char rcsid[] = "$Header: /proj/cvs/prod/libbind/dst/hmac_link.c,v 1.8 2007/09/24 17:18:25 each Exp $";
11 10 #endif
12 11 /*
13 12 * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
14 13 *
15 14 * Permission to use, copy modify, and distribute this software for any
16 15 * purpose with or without fee is hereby granted, provided that the above
17 16 * copyright notice and this permission notice appear in all copies.
18 17 *
19 18 * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
20 19 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
21 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
22 21 * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
23 22 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
24 23 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
25 24 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
26 25 * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
27 26 */
28 27
29 -/*
28 +/*%
30 29 * This file contains an implementation of the HMAC-MD5 algorithm.
31 30 */
32 31 #include "port_before.h"
33 32
34 33 #include <stdio.h>
35 34 #include <unistd.h>
36 35 #include <stdlib.h>
37 36 #include <string.h>
38 37 #include <memory.h>
39 38 #include <sys/param.h>
40 39 #include <sys/time.h>
41 40 #include <netinet/in.h>
42 41 #include <arpa/nameser.h>
43 42 #include <resolv.h>
44 43
45 44 #include "dst_internal.h"
45 +
46 46 #ifdef USE_MD5
47 -#ifndef SUNW_LIBMD5
48 -# include "md5.h"
49 -#else
50 -#include <sys/md5.h>
51 -#endif
47 +# ifndef HAVE_MD5
48 +# include "md5.h"
49 +# else
50 +# ifdef SOLARIS2
51 +# include <sys/md5.h>
52 +# endif
53 +# endif
52 54 # ifndef _MD5_H_
53 -# define _MD5_H_ 1 /* make sure we do not include rsaref md5.h file */
55 +# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */
54 56 # endif
55 57 #endif
56 58
57 59 #include "port_after.h"
58 60
59 61
60 62 #define HMAC_LEN 64
61 63 #define HMAC_IPAD 0x36
62 64 #define HMAC_OPAD 0x5c
63 65 #define MD5_LEN 16
64 66
65 67
66 68 typedef struct hmackey {
67 69 u_char hk_ipad[64], hk_opad[64];
68 70 } HMAC_Key;
69 71
70 72
71 73 /**************************************************************************
72 74 * dst_hmac_md5_sign
73 75 * Call HMAC signing functions to sign a block of data.
74 76 * There are three steps to signing, INIT (initialize structures),
75 77 * UPDATE (hash (more) data), FINAL (generate a signature). This
76 78 * routine performs one or more of these steps.
77 79 * Parameters
78 80 * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
79 81 * priv_key key to use for signing.
80 82 * context the context to be used in this digest
81 83 * data data to be signed.
82 84 * len length in bytes of data.
83 85 * signature location to store signature.
84 86 * sig_len size of the signature location
85 87 * returns
86 88 * N Success on SIG_MODE_FINAL = returns signature length in bytes
87 89 * 0 Success on SIG_MODE_INIT and UPDATE
88 90 * <0 Failure
89 91 */
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
90 92
91 93 static int
92 94 dst_hmac_md5_sign(const int mode, DST_KEY *d_key, void **context,
93 95 const u_char *data, const int len,
94 96 u_char *signature, const int sig_len)
95 97 {
96 98 HMAC_Key *key;
97 99 int sign_len = 0;
98 100 MD5_CTX *ctx = NULL;
99 101
102 + if (d_key == NULL || d_key->dk_KEY_struct == NULL)
103 + return (-1);
104 +
100 105 if (mode & SIG_MODE_INIT)
101 106 ctx = (MD5_CTX *) malloc(sizeof(*ctx));
102 107 else if (context)
103 108 ctx = (MD5_CTX *) *context;
104 109 if (ctx == NULL)
105 110 return (-1);
106 111
107 - if (d_key == NULL || d_key->dk_KEY_struct == NULL)
108 - return (-1);
109 112 key = (HMAC_Key *) d_key->dk_KEY_struct;
110 113
111 114 if (mode & SIG_MODE_INIT) {
112 115 MD5Init(ctx);
113 116 MD5Update(ctx, key->hk_ipad, HMAC_LEN);
114 117 }
115 118
116 119 if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
117 120 MD5Update(ctx, data, len);
118 121
119 122 if (mode & SIG_MODE_FINAL) {
120 123 if (signature == NULL || sig_len < MD5_LEN)
121 124 return (SIGN_FINAL_FAILURE);
122 125 MD5Final(signature, ctx);
123 126
124 127 /* perform outer MD5 */
125 128 MD5Init(ctx);
126 129 MD5Update(ctx, key->hk_opad, HMAC_LEN);
127 130 MD5Update(ctx, signature, MD5_LEN);
128 131 MD5Final(signature, ctx);
129 132 sign_len = MD5_LEN;
130 133 SAFE_FREE(ctx);
131 134 }
132 135 else {
133 136 if (context == NULL)
134 137 return (-1);
135 138 *context = (void *) ctx;
136 139 }
137 140 return (sign_len);
138 141 }
139 142
140 143
141 144 /**************************************************************************
142 145 * dst_hmac_md5_verify()
143 146 * Calls HMAC verification routines. There are three steps to
144 147 * verification, INIT (initialize structures), UPDATE (hash (more) data),
145 148 * FINAL (generate a signature). This routine performs one or more of
146 149 * these steps.
147 150 * Parameters
148 151 * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
149 152 * dkey key to use for verify.
150 153 * data data signed.
151 154 * len length in bytes of data.
152 155 * signature signature.
153 156 * sig_len length in bytes of signature.
154 157 * returns
155 158 * 0 Success
156 159 * <0 Failure
|
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
157 160 */
158 161
159 162 static int
160 163 dst_hmac_md5_verify(const int mode, DST_KEY *d_key, void **context,
161 164 const u_char *data, const int len,
162 165 const u_char *signature, const int sig_len)
163 166 {
164 167 HMAC_Key *key;
165 168 MD5_CTX *ctx = NULL;
166 169
170 + if (d_key == NULL || d_key->dk_KEY_struct == NULL)
171 + return (-1);
172 +
167 173 if (mode & SIG_MODE_INIT)
168 174 ctx = (MD5_CTX *) malloc(sizeof(*ctx));
169 175 else if (context)
170 176 ctx = (MD5_CTX *) *context;
171 177 if (ctx == NULL)
172 178 return (-1);
173 179
174 - if (d_key == NULL || d_key->dk_KEY_struct == NULL)
175 - return (-1);
176 -
177 180 key = (HMAC_Key *) d_key->dk_KEY_struct;
178 181 if (mode & SIG_MODE_INIT) {
179 182 MD5Init(ctx);
180 183 MD5Update(ctx, key->hk_ipad, HMAC_LEN);
181 184 }
182 185 if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
183 186 MD5Update(ctx, data, len);
184 187
185 188 if (mode & SIG_MODE_FINAL) {
186 189 u_char digest[MD5_LEN];
187 190 if (signature == NULL || key == NULL || sig_len != MD5_LEN)
188 191 return (VERIFY_FINAL_FAILURE);
189 192 MD5Final(digest, ctx);
190 193
191 194 /* perform outer MD5 */
192 195 MD5Init(ctx);
193 196 MD5Update(ctx, key->hk_opad, HMAC_LEN);
194 197 MD5Update(ctx, digest, MD5_LEN);
195 198 MD5Final(digest, ctx);
196 199
197 200 SAFE_FREE(ctx);
198 201 if (memcmp(digest, signature, MD5_LEN) != 0)
199 202 return (VERIFY_FINAL_FAILURE);
200 203 }
201 204 else {
202 205 if (context == NULL)
203 206 return (-1);
204 207 *context = (void *) ctx;
205 208 }
206 209 return (0);
207 210 }
208 211
209 212
210 213 /**************************************************************************
211 214 * dst_buffer_to_hmac_md5
212 215 * Converts key from raw data to an HMAC Key
213 216 * This function gets in a pointer to the data
214 217 * Parameters
215 218 * hkey the HMAC key to be filled in
216 219 * key the key in raw format
217 220 * keylen the length of the key
218 221 * Return
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
219 222 * 0 Success
220 223 * <0 Failure
221 224 */
222 225 static int
223 226 dst_buffer_to_hmac_md5(DST_KEY *dkey, const u_char *key, const int keylen)
224 227 {
225 228 int i;
226 229 HMAC_Key *hkey = NULL;
227 230 MD5_CTX ctx;
228 231 int local_keylen = keylen;
232 + u_char tk[MD5_LEN];
229 233
230 234 if (dkey == NULL || key == NULL || keylen < 0)
231 235 return (-1);
232 236
233 237 if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
234 238 return (-2);
235 239
236 240 memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
237 241 memset(hkey->hk_opad, 0, sizeof(hkey->hk_opad));
238 242
239 243 /* if key is longer than HMAC_LEN bytes reset it to key=MD5(key) */
240 244 if (keylen > HMAC_LEN) {
241 - u_char tk[MD5_LEN];
242 245 MD5Init(&ctx);
243 246 MD5Update(&ctx, key, keylen);
244 247 MD5Final(tk, &ctx);
245 248 memset((void *) &ctx, 0, sizeof(ctx));
246 249 key = tk;
247 250 local_keylen = MD5_LEN;
248 251 }
249 252 /* start out by storing key in pads */
250 253 memcpy(hkey->hk_ipad, key, local_keylen);
251 254 memcpy(hkey->hk_opad, key, local_keylen);
252 255
253 256 /* XOR key with hk_ipad and opad values */
254 257 for (i = 0; i < HMAC_LEN; i++) {
255 258 hkey->hk_ipad[i] ^= HMAC_IPAD;
256 259 hkey->hk_opad[i] ^= HMAC_OPAD;
257 260 }
258 261 dkey->dk_key_size = local_keylen;
259 262 dkey->dk_KEY_struct = (void *) hkey;
260 263 return (1);
261 264 }
262 265
263 266
264 267 /**************************************************************************
265 268 * dst_hmac_md5_key_to_file_format
266 269 * Encodes an HMAC Key into the portable file format.
267 270 * Parameters
268 271 * hkey HMAC KEY structure
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
269 272 * buff output buffer
270 273 * buff_len size of output buffer
271 274 * Return
272 275 * 0 Failure - null input hkey
273 276 * -1 Failure - not enough space in output area
274 277 * N Success - Length of data returned in buff
275 278 */
276 279
277 280 static int
278 281 dst_hmac_md5_key_to_file_format(const DST_KEY *dkey, char *buff,
279 - const int buff_len)
282 + const int buff_len)
280 283 {
281 284 char *bp;
282 - int len, b_len, i, key_len;
285 + int len, i, key_len;
283 286 u_char key[HMAC_LEN];
284 287 HMAC_Key *hkey;
285 288
286 289 if (dkey == NULL || dkey->dk_KEY_struct == NULL)
287 290 return (0);
288 - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str))
289 - return (-1); /* no OR not enough space in output area */
290 -
291 + /*
292 + * Using snprintf() would be so much simpler here.
293 + */
294 + if (buff == NULL ||
295 + buff_len <= (int)(strlen(key_file_fmt_str) +
296 + strlen(KEY_FILE_FORMAT) + 4))
297 + return (-1); /*%< no OR not enough space in output area */
291 298 hkey = (HMAC_Key *) dkey->dk_KEY_struct;
292 - memset(buff, 0, buff_len); /* just in case */
299 + memset(buff, 0, buff_len); /*%< just in case */
293 300 /* write file header */
294 301 sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_HMAC_MD5, "HMAC");
295 302
296 - bp = (char *) strchr(buff, '\0');
297 - b_len = buff_len - (bp - buff);
303 + bp = buff + strlen(buff);
298 304
299 305 memset(key, 0, HMAC_LEN);
300 306 for (i = 0; i < HMAC_LEN; i++)
301 307 key[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
302 308 for (i = HMAC_LEN - 1; i >= 0; i--)
303 309 if (key[i] != 0)
304 310 break;
305 311 key_len = i + 1;
306 312
313 + if (buff_len - (bp - buff) < 6)
314 + return (-1);
307 315 strcat(bp, "Key: ");
308 316 bp += strlen("Key: ");
309 - b_len = buff_len - (bp - buff);
310 317
311 - len = b64_ntop(key, key_len, bp, b_len);
318 + len = b64_ntop(key, key_len, bp, buff_len - (bp - buff));
312 319 if (len < 0)
313 320 return (-1);
314 321 bp += len;
322 + if (buff_len - (bp - buff) < 2)
323 + return (-1);
315 324 *(bp++) = '\n';
316 325 *bp = '\0';
317 - b_len = buff_len - (bp - buff);
318 326
319 - return (buff_len - b_len);
327 + return (bp - buff);
320 328 }
321 329
322 330
323 331 /**************************************************************************
324 332 * dst_hmac_md5_key_from_file_format
325 333 * Converts contents of a key file into an HMAC key.
326 334 * Parameters
327 335 * hkey structure to put key into
328 336 * buff buffer containing the encoded key
329 337 * buff_len the length of the buffer
330 338 * Return
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
331 339 * n >= 0 Foot print of the key converted
332 340 * n < 0 Error in conversion
333 341 */
334 342
335 343 static int
336 344 dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff,
337 345 const int buff_len)
338 346 {
339 347 const char *p = buff, *eol;
340 348 u_char key[HMAC_LEN+1]; /* b64_pton needs more than 64 bytes do decode
341 - * it should probably be fixed rather than doing
342 - * this
343 - */
349 + * it should probably be fixed rather than doing
350 + * this
351 + */
344 352 u_char *tmp;
345 353 int key_len, len;
346 354
347 355 if (dkey == NULL)
348 356 return (-2);
349 357 if (buff == NULL || buff_len < 0)
350 358 return (-1);
351 359
352 360 memset(key, 0, sizeof(key));
353 361
354 362 if (!dst_s_verify_str(&p, "Key: "))
355 363 return (-3);
356 364
357 365 eol = strchr(p, '\n');
358 366 if (eol == NULL)
359 367 return (-4);
360 368 len = eol - p;
361 369 tmp = malloc(len + 2);
370 + if (tmp == NULL)
371 + return (-5);
362 372 memcpy(tmp, p, len);
363 373 *(tmp + len) = 0x0;
364 - key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /* see above */
374 + key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /*%< see above */
365 375 SAFE_FREE2(tmp, len + 2);
366 376
367 377 if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) {
368 378 return (-6);
369 379 }
370 380 return (0);
371 381 }
372 382
373 -/*
383 +/*%
374 384 * dst_hmac_md5_to_dns_key()
375 385 * function to extract hmac key from DST_KEY structure
376 386 * intput:
377 387 * in_key: HMAC-MD5 key
378 388 * output:
379 389 * out_str: buffer to write ot
380 390 * out_len: size of output buffer
381 391 * returns:
382 392 * number of bytes written to output buffer
383 393 */
384 394 static int
385 395 dst_hmac_md5_to_dns_key(const DST_KEY *in_key, u_char *out_str,
386 396 const int out_len)
387 397 {
388 398
389 399 HMAC_Key *hkey;
390 400 int i;
391 401
392 402 if (in_key == NULL || in_key->dk_KEY_struct == NULL ||
393 403 out_len <= in_key->dk_key_size || out_str == NULL)
394 404 return (-1);
395 405
396 406 hkey = (HMAC_Key *) in_key->dk_KEY_struct;
397 407 for (i = 0; i < in_key->dk_key_size; i++)
398 408 out_str[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
399 409 return (i);
400 410 }
401 411
402 412 /**************************************************************************
403 413 * dst_hmac_md5_compare_keys
404 414 * Compare two keys for equality.
405 415 * Return
406 416 * 0 The keys are equal
407 417 * NON-ZERO The keys are not equal
408 418 */
409 419
410 420 static int
411 421 dst_hmac_md5_compare_keys(const DST_KEY *key1, const DST_KEY *key2)
412 422 {
413 423 HMAC_Key *hkey1 = (HMAC_Key *) key1->dk_KEY_struct;
414 424 HMAC_Key *hkey2 = (HMAC_Key *) key2->dk_KEY_struct;
415 425 return memcmp(hkey1->hk_ipad, hkey2->hk_ipad, HMAC_LEN);
416 426 }
417 427
418 428 /**************************************************************************
419 429 * dst_hmac_md5_free_key_structure
420 430 * Frees all (none) dynamically allocated structures in hkey
421 431 */
422 432
423 433 static void *
424 434 dst_hmac_md5_free_key_structure(void *key)
425 435 {
426 436 HMAC_Key *hkey = key;
427 437 SAFE_FREE(hkey);
428 438 return (NULL);
429 439 }
430 440
431 441
|
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
432 442 /***************************************************************************
433 443 * dst_hmac_md5_generate_key
434 444 * Creates a HMAC key of size size with a maximum size of 63 bytes
435 445 * generating a HMAC key larger than 63 bytes makes no sense as that key
436 446 * is digested before use.
437 447 */
438 448
439 449 static int
440 450 dst_hmac_md5_generate_key(DST_KEY *key, const int nothing)
441 451 {
442 - u_char *buff;
443 - int i, n, size;
444 -
445 - i = nothing;
446 -
447 - if (key == NULL || key->dk_alg != KEY_HMAC_MD5)
448 - return (0);
449 - size = (key->dk_key_size + 7) / 8; /* convert to bytes */
450 - if (size <= 0)
451 - return(0);
452 -
453 - i = size > 64 ? 64 : size;
454 - buff = malloc(i+8);
455 -
456 - n = dst_random(DST_RAND_SEMI, i, buff);
457 - n += dst_random(DST_RAND_KEY, i, buff);
458 - if (n <= i) { /* failed getting anything */
459 - SAFE_FREE2(buff, i);
460 - return (-1);
461 - }
462 - n = dst_buffer_to_hmac_md5(key, buff, i);
463 - SAFE_FREE2(buff, i);
464 - if (n <= 0)
465 - return (n);
466 - return (1);
452 + (void)key;
453 + (void)nothing;
454 + return (-1);
467 455 }
468 456
469 -/*
457 +/*%
470 458 * dst_hmac_md5_init() Function to answer set up function pointers for HMAC
471 459 * related functions
472 460 */
473 461 int
474 -#ifdef ORIGINAL_ISC_CODE
475 462 dst_hmac_md5_init()
476 -#else
477 -dst_md5_hmac_init()
478 -#endif
479 463 {
480 464 if (dst_t_func[KEY_HMAC_MD5] != NULL)
481 465 return (1);
482 466 dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
483 467 if (dst_t_func[KEY_HMAC_MD5] == NULL)
484 468 return (0);
485 469 memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
486 470 dst_t_func[KEY_HMAC_MD5]->sign = dst_hmac_md5_sign;
487 471 dst_t_func[KEY_HMAC_MD5]->verify = dst_hmac_md5_verify;
488 472 dst_t_func[KEY_HMAC_MD5]->compare = dst_hmac_md5_compare_keys;
489 473 dst_t_func[KEY_HMAC_MD5]->generate = dst_hmac_md5_generate_key;
490 474 dst_t_func[KEY_HMAC_MD5]->destroy = dst_hmac_md5_free_key_structure;
491 475 dst_t_func[KEY_HMAC_MD5]->to_dns_key = dst_hmac_md5_to_dns_key;
492 476 dst_t_func[KEY_HMAC_MD5]->from_dns_key = dst_buffer_to_hmac_md5;
493 477 dst_t_func[KEY_HMAC_MD5]->to_file_fmt = dst_hmac_md5_key_to_file_format;
494 478 dst_t_func[KEY_HMAC_MD5]->from_file_fmt = dst_hmac_md5_key_from_file_format;
495 479 return (1);
496 480 }
497 481
498 482 #else
483 +#define dst_hmac_md5_init __dst_hmac_md5_init
484 +
499 485 int
500 486 dst_hmac_md5_init(){
501 487 return (0);
502 488 }
503 489 #endif
504 490
505 -
506 -
507 -
508 -
509 -
510 -
491 +/*! \file */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX