Download & Extend

Make HMAC authentication use interoperable formats (Proper HMAC hash and json instead of php serialize).

Project:Acquia Network Connector
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:postponed

Issue Summary

In order to make our web services more flexible, here are a few updates to our acquia_connector for more compliant and flexible authentication.

AttachmentSize
connector_new_hmac.diff3.08 KB

Comments

#1

basically looks good - however, we will probably postpone committing until we release version 6.x-1.2 of this project.

#2

Just a FYI, this is the hmac implementation I wanted to introduce in Drupal 6. It correctly deals with short and long keys and has been tested with the MD5 examples from RCF2202. If the "HASH Message Digest Framework" functions are available, the work is handed to them.

<?php
/**
* HMAC implementation according to RFC 2104.
*
* The HASH Message Digest Framework (PHP 5.1.2+ or PECL) functions will be
* used when available, the slower PHP implementation otherwise.
*
* @param $value
*   The value to create a HMAC for.
* @param $key
*   The secret key to sign the hash with. It needs to be at least L bytes long,
*   where L is byte-length of the hash output (16 for MD5, 20 for SHA1).
* @param $raw_output
*   If the optional raw_output is set to TRUE, then the hash digest is
*   returned in raw binary format. Defaults to FALSE.
* @param $hash
*   Optional hash function to use, default is md5.
* @param $block_size
*   Byte length of the internal blocks the hash function iterates on.
*
* @return The HMAC hash of value.
*/
function drupal_hmac($value, $key, $raw_output = FALSE, $hash = 'md5', $block_size = 64) {
  if (
function_exists('hash_hmac')) {
    return
hash_hmac($hash, $value, $key, $raw_output);
  }

 
$opad = str_repeat(chr(0x5c), $block_size);
 
$ipad = str_repeat(chr(0x36), $block_size);

  if (
strlen($key) > $block_size) {
   
$key = $hash($key, TRUE);
  }

if (
strlen($key) < $block_size) {
   
$key = str_pad($key, $block_size, "\0", STR_PAD_RIGHT);
  }

 
$ipad = $ipad ^ $key;
 
$opad = $opad ^ $key;

  return
$hash($opad . $hash($ipad . $value, TRUE), $raw_output);
}
?>

#3

@Heine - since hash_hmac assume the 64 block size, I think your suggested implementation is flawed.

I guess you could say ours is flawed by not handling a key > 64 bytes, but we know our keys are not that long.

#4

Status:active» needs work

Actually, since we know we are on php5, we can omit the pack() command by passing the last arg to sha1

#5

Also, we might as well make our function really compliant with http://www.faqs.org/rfcs/rfc2104.html

" The key for HMAC can be of any length (keys longer than B bytes are first hashed using H)."

#6

If hash_hmac assumes a 64 block size, it is flawed. According to hash_algos, the Hash Messaging Digest Framework supports a SHA512 hash, which has a block size of 128 bytes.

According to the source, hash.c uses ops->block_size, which for SHA512 is 128 bytes according to hash_sha.c:

const php_hash_ops php_hash_sha512_ops = {
  (php_hash_init_func_t) PHP_SHA512Init,
  (php_hash_update_func_t) PHP_SHA512Update,
  (php_hash_final_func_t) PHP_SHA512Final,
  64,   // digest size
  128, // block size
  sizeof(PHP_SHA512_CTX) // context size
};

#7

@Heine - ah, you are right, but then you still might have a mismatch between the requested blok size and the actual block size.

I don't think there is a lot of value to trying to much such a generic function with extra overhead - just mac hmac_md5() and hmac_sha1() functions (for example).

#8

That's right, you need to pass the correct $block_size for sha512, but I just wanted to give you guys a headstart on an RFC2104 compliant implementation. Mutilate as necessary :)

#9

@Heine - our implmentation matches with hash_hmac() one and the in python 2.4, so I think we're ok (barring key length issues).

#10

Status:needs work» postponed

So, unless we want to have 2 alternate hmac algorithms in the module, I'm not sure we should proceed any further with this until we are at 7.x, which requires php 5.2

#11

We really need to do something for Drupal 7, since use of sha1 is deprecated.

#12

If we do something like this, we should probably consider the proposed Oauth2 HMAC spec: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-02

nobody click here