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
↓ 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  
↓ 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];
↓ 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);
↓ 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
↓ 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   */
↓ 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