? openid_provider.patch
Index: openid_provider.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/openid_provider/openid_provider.inc,v
retrieving revision 1.1
diff -u -p -r1.1 openid_provider.inc
--- openid_provider.inc	13 Apr 2008 11:53:04 -0000	1.1
+++ openid_provider.inc	28 Apr 2008 11:02:17 -0000
@@ -28,19 +28,23 @@ function openid_provider_association_res
     'assoc_type' => $assoc_type,
     'expires_in' => $expires_in
   );
-
-  $secret = _openid_get_bytes(20);
+  
   if ($session_type == '' || $session_type == 'no-encryption') {
     if ($assoc_type == 'HMAC-SHA1') {
+      $secret = _openid_get_bytes(20);
       $mac_key = _openid_hmac($secret, $response['assoc_handle']);
       $response['mac_key'] = $mac_key;
     }
     elseif ($assoc_type == 'HMAC-SHA256') {
-      // TODO: Not yet supported
+      $secret = _openid_get_bytes(32);
+      $mac_key = hash_hmac('sha256', $response['assoc_handle'], $secret, true);
+      $response['mac_key'] = $mac_key;      
     }
   }
   elseif ($session_type == 'DH-SHA1' || $session_type == 'DH-SHA256') {
-    $dh_assoc = openid_provider_dh_assoc($request, $secret);
+    $algo = ($session_type == 'DH-SHA1') ? 'sha1' : 'sha256';
+    $secret = ($algo == 'sha1') ? _openid_get_bytes(20) : _openid_get_bytes(32);
+    $dh_assoc = openid_provider_dh_assoc($request, $secret, $algo);
     $mac_key = base64_encode($secret);
     $response['dh_server_public'] = $dh_assoc['dh_server_public'];
     $response['enc_mac_key'] = $dh_assoc['enc_mac_key'];
@@ -51,13 +55,7 @@ function openid_provider_association_res
   db_query("INSERT INTO {openid_provider_association} (assoc_handle, assoc_type, session_type, mac_key, created, expires_in) VALUES ('%s', '%s', '%s', '%s', %d, %d)",
            $assoc_handle, $assoc_type, $session_type, $mac_key, time(), $expires_in);
 
-  
-  if ($assoc_type == 'HMAC-SHA256' || $session_type == 'DH-SHA256') {
-    $message = _openid_create_message(openid_provider_association_error());
-  }
-  else {
-    $message = _openid_create_message($response);
-  }
+  $message = _openid_create_message($response);
 
   drupal_set_header('HTTP/1.1 200 OK');
   drupal_set_header("Content-Type: text/plain");
@@ -160,7 +158,7 @@ function openid_provider_authentication_
 
 
 
-function openid_provider_dh_assoc($request, $secret) {
+function openid_provider_dh_assoc($request, $secret, $algo = 'sha1') {
   if (empty($request['openid.dh_consumer_public'])) {
     return FALSE;
   }
@@ -185,7 +183,10 @@ function openid_provider_dh_assoc($reque
   
   $cpub = _openid_dh_base64_to_long($request['openid.dh_consumer_public']);
   $shared = bcpowmod($cpub, $private, $mod);
-  $mac_key = _openid_dh_xorsecret($shared, $secret);
+  
+  $mac_key = _openid_provider_dh_xorsecret($shared, $secret, $algo);
+  
+  
   $enc_mac_key = base64_encode($mac_key);
   $spub64 = _openid_dh_long_to_base64($public);
   return array(
@@ -194,6 +195,25 @@ function openid_provider_dh_assoc($reque
     );
 }
 
+/**
+ * Is copy of _opend_dh_xorsecret() but uses PHP5 hash() function. Should be merged back into openid client
+ * for D7.
+ *
+ * @param long $shared
+ * @param unknown_type $secret
+ * @param unknown_type $algo
+ * @return unknown
+ */
+function _openid_provider_dh_xorsecret($shared, $secret, $algo = 'sha1') {
+  $dh_shared_str = _openid_dh_long_to_binary($shared);
+  $sha1_dh_shared = hash($algo, $dh_shared_str, true);
+  $xsecret = "";
+  for ($i = 0; $i < strlen($secret); $i++) {
+    $xsecret .= chr(ord($secret[$i]) ^ ord($sha1_dh_shared[$i]));
+  }
+  return $xsecret;
+}
+
 // 9.2.2.2. Verifying Directly with the Identity Provider
 // 9.2.2.2.2. Response Parameters
 // Request is: Exact copies of all fields from the authentication response
@@ -305,6 +325,31 @@ function _openid_provider_sign($response
                                     $response['openid.assoc_handle']));
   
   // Generate signature for this message
-  $response['openid.sig'] = _openid_signature($assoc, $response, $signed_keys);
+  $response['openid.sig'] = _openid_provider_signature($assoc, $response, $signed_keys);
   return $response;
 }
+
+/**
+ * Is copy from openid client but uses PHP5 only hash_hmac() function.
+ *
+ * @param unknown_type $association
+ * @param unknown_type $message_array
+ * @param unknown_type $keys_to_sign
+ * @param unknown_type $algo
+ * @return unknown
+ */
+function _openid_provider_signature($association, $message_array, $keys_to_sign) {
+  $signature = '';
+  $sign_data = array();
+
+  foreach ($keys_to_sign as $key) {
+    if (isset($message_array['openid.'. $key])) {
+      $sign_data[$key] = $message_array['openid.'. $key];
+    }
+  }
+
+  $message = _openid_create_message($sign_data);
+  $secret = base64_decode($association->mac_key);
+  $signature = hash_hmac($association->session_type == 'DH-SHA256' ? 'sha256' : 'sha1', $message, $secret, true);
+  return base64_encode($signature);
+}
