Association.php

Go to the documentation of this file.
00001 <?php
00002 
00020 require_once 'Auth/OpenID/CryptUtil.php';
00021 
00025 require_once 'Auth/OpenID/KVForm.php';
00026 
00030 require_once 'Auth/OpenID/HMAC.php';
00031 
00044 class Auth_OpenID_Association {
00045 
00051     var $SIG_LENGTH = 20;
00052 
00058     var $assoc_keys = array(
00059                             'version',
00060                             'handle',
00061                             'secret',
00062                             'issued',
00063                             'lifetime',
00064                             'assoc_type'
00065                             );
00066 
00067     var $_macs = array(
00068                        'HMAC-SHA1' => 'Auth_OpenID_HMACSHA1',
00069                        'HMAC-SHA256' => 'Auth_OpenID_HMACSHA256'
00070                        );
00071 
00097     function fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
00098     {
00099         $issued = time();
00100         $lifetime = $expires_in;
00101         return new Auth_OpenID_Association($handle, $secret,
00102                                            $issued, $lifetime, $assoc_type);
00103     }
00104 
00131     function Auth_OpenID_Association(
00132         $handle, $secret, $issued, $lifetime, $assoc_type)
00133     {
00134         if (!in_array($assoc_type,
00135                       Auth_OpenID_getSupportedAssociationTypes())) {
00136             $fmt = 'Unsupported association type (%s)';
00137             trigger_error(sprintf($fmt, $assoc_type), E_USER_ERROR);
00138         }
00139 
00140         $this->handle = $handle;
00141         $this->secret = $secret;
00142         $this->issued = $issued;
00143         $this->lifetime = $lifetime;
00144         $this->assoc_type = $assoc_type;
00145     }
00146 
00154     function getExpiresIn($now = null)
00155     {
00156         if ($now == null) {
00157             $now = time();
00158         }
00159 
00160         return max(0, $this->issued + $this->lifetime - $now);
00161     }
00162 
00170     function equal($other)
00171     {
00172         return ((gettype($this) == gettype($other))
00173                 && ($this->handle == $other->handle)
00174                 && ($this->secret == $other->secret)
00175                 && ($this->issued == $other->issued)
00176                 && ($this->lifetime == $other->lifetime)
00177                 && ($this->assoc_type == $other->assoc_type));
00178     }
00179 
00186     function serialize()
00187     {
00188         $data = array(
00189                      'version' => '2',
00190                      'handle' => $this->handle,
00191                      'secret' => base64_encode($this->secret),
00192                      'issued' => strval(intval($this->issued)),
00193                      'lifetime' => strval(intval($this->lifetime)),
00194                      'assoc_type' => $this->assoc_type
00195                      );
00196 
00197         assert(array_keys($data) == $this->assoc_keys);
00198 
00199         return Auth_OpenID_KVForm::fromArray($data, $strict = true);
00200     }
00201 
00209     function deserialize($class_name, $assoc_s)
00210     {
00211         $pairs = Auth_OpenID_KVForm::toArray($assoc_s, $strict = true);
00212         $keys = array();
00213         $values = array();
00214         foreach ($pairs as $key => $value) {
00215             if (is_array($value)) {
00216                 list($key, $value) = $value;
00217             }
00218             $keys[] = $key;
00219             $values[] = $value;
00220         }
00221 
00222         $class_vars = get_class_vars($class_name);
00223         $class_assoc_keys = $class_vars['assoc_keys'];
00224 
00225         sort($keys);
00226         sort($class_assoc_keys);
00227 
00228         if ($keys != $class_assoc_keys) {
00229             trigger_error('Unexpected key values: ' . var_export($keys, true),
00230                           E_USER_WARNING);
00231             return null;
00232         }
00233 
00234         $version = $pairs['version'];
00235         $handle = $pairs['handle'];
00236         $secret = $pairs['secret'];
00237         $issued = $pairs['issued'];
00238         $lifetime = $pairs['lifetime'];
00239         $assoc_type = $pairs['assoc_type'];
00240 
00241         if ($version != '2') {
00242             trigger_error('Unknown version: ' . $version, E_USER_WARNING);
00243             return null;
00244         }
00245 
00246         $issued = intval($issued);
00247         $lifetime = intval($lifetime);
00248         $secret = base64_decode($secret);
00249 
00250         return new $class_name(
00251             $handle, $secret, $issued, $lifetime, $assoc_type);
00252     }
00253 
00263     function sign($pairs)
00264     {
00265         $kv = Auth_OpenID_KVForm::fromArray($pairs);
00266 
00267         /* Invalid association types should be caught at constructor */
00268         $callback = $this->_macs[$this->assoc_type];
00269 
00270         return call_user_func_array($callback, array($this->secret, $kv));
00271     }
00272 
00283     function signMessage($message)
00284     {
00285         if ($message->hasKey(Auth_OpenID_OPENID_NS, 'sig') ||
00286             $message->hasKey(Auth_OpenID_OPENID_NS, 'signed')) {
00287             // Already has a sig
00288             return null;
00289         }
00290 
00291         $extant_handle = $message->getArg(Auth_OpenID_OPENID_NS,
00292                                           'assoc_handle');
00293 
00294         if ($extant_handle && ($extant_handle != $this->handle)) {
00295             // raise ValueError("Message has a different association handle")
00296             return null;
00297         }
00298 
00299         $signed_message = $message;
00300         $signed_message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle',
00301                                 $this->handle);
00302 
00303         $message_keys = array_keys($signed_message->toPostArgs());
00304         $signed_list = array();
00305         $signed_prefix = 'openid.';
00306 
00307         foreach ($message_keys as $k) {
00308             if (strpos($k, $signed_prefix) === 0) {
00309                 $signed_list[] = substr($k, strlen($signed_prefix));
00310             }
00311         }
00312 
00313         $signed_list[] = 'signed';
00314         sort($signed_list);
00315 
00316         $signed_message->setArg(Auth_OpenID_OPENID_NS, 'signed',
00317                                 implode(',', $signed_list));
00318         $sig = $this->getMessageSignature($signed_message);
00319         $signed_message->setArg(Auth_OpenID_OPENID_NS, 'sig', $sig);
00320         return $signed_message;
00321     }
00322 
00330     function _makePairs(&$message)
00331     {
00332         $signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
00333         if (!$signed || Auth_OpenID::isFailure($signed)) {
00334             // raise ValueError('Message has no signed list: %s' % (message,))
00335             return null;
00336         }
00337 
00338         $signed_list = explode(',', $signed);
00339         $pairs = array();
00340         $data = $message->toPostArgs();
00341         foreach ($signed_list as $field) {
00342             $pairs[] = array($field, Auth_OpenID::arrayGet($data,
00343                                                            'openid.' .
00344                                                            $field, ''));
00345         }
00346         return $pairs;
00347     }
00348 
00355     function getMessageSignature(&$message)
00356     {
00357         $pairs = $this->_makePairs($message);
00358         return base64_encode($this->sign($pairs));
00359     }
00360 
00367     function checkMessageSignature(&$message)
00368     {
00369         $sig = $message->getArg(Auth_OpenID_OPENID_NS,
00370                                 'sig');
00371 
00372         if (!$sig || Auth_OpenID::isFailure($sig)) {
00373             return false;
00374         }
00375 
00376         $calculated_sig = $this->getMessageSignature($message);
00377         return $calculated_sig == $sig;
00378     }
00379 }
00380 
00381 function Auth_OpenID_getSecretSize($assoc_type)
00382 {
00383     if ($assoc_type == 'HMAC-SHA1') {
00384         return 20;
00385     } else if ($assoc_type == 'HMAC-SHA256') {
00386         return 32;
00387     } else {
00388         return null;
00389     }
00390 }
00391 
00392 function Auth_OpenID_getAllAssociationTypes()
00393 {
00394     return array('HMAC-SHA1', 'HMAC-SHA256');
00395 }
00396 
00397 function Auth_OpenID_getSupportedAssociationTypes()
00398 {
00399     $a = array('HMAC-SHA1');
00400 
00401     if (Auth_OpenID_HMACSHA256_SUPPORTED) {
00402         $a[] = 'HMAC-SHA256';
00403     }
00404 
00405     return $a;
00406 }
00407 
00408 function Auth_OpenID_getSessionTypes($assoc_type)
00409 {
00410     $assoc_to_session = array(
00411        'HMAC-SHA1' => array('DH-SHA1', 'no-encryption'));
00412 
00413     if (Auth_OpenID_HMACSHA256_SUPPORTED) {
00414         $assoc_to_session['HMAC-SHA256'] =
00415             array('DH-SHA256', 'no-encryption');
00416     }
00417 
00418     return Auth_OpenID::arrayGet($assoc_to_session, $assoc_type, array());
00419 }
00420 
00421 function Auth_OpenID_checkSessionType($assoc_type, $session_type)
00422 {
00423     if (!in_array($session_type,
00424                   Auth_OpenID_getSessionTypes($assoc_type))) {
00425         return false;
00426     }
00427 
00428     return true;
00429 }
00430 
00431 function Auth_OpenID_getDefaultAssociationOrder()
00432 {
00433     $order = array();
00434 
00435     if (!Auth_OpenID_noMathSupport()) {
00436         $order[] = array('HMAC-SHA1', 'DH-SHA1');
00437 
00438         if (Auth_OpenID_HMACSHA256_SUPPORTED) {
00439             $order[] = array('HMAC-SHA256', 'DH-SHA256');
00440         }
00441     }
00442 
00443     $order[] = array('HMAC-SHA1', 'no-encryption');
00444 
00445     if (Auth_OpenID_HMACSHA256_SUPPORTED) {
00446         $order[] = array('HMAC-SHA256', 'no-encryption');
00447     }
00448 
00449     return $order;
00450 }
00451 
00452 function Auth_OpenID_getOnlyEncryptedOrder()
00453 {
00454     $result = array();
00455 
00456     foreach (Auth_OpenID_getDefaultAssociationOrder() as $pair) {
00457         list($assoc, $session) = $pair;
00458 
00459         if ($session != 'no-encryption') {
00460             if (Auth_OpenID_HMACSHA256_SUPPORTED &&
00461                 ($assoc == 'HMAC-SHA256')) {
00462                 $result[] = $pair;
00463             } else if ($assoc != 'HMAC-SHA256') {
00464                 $result[] = $pair;
00465             }
00466         }
00467     }
00468 
00469     return $result;
00470 }
00471 
00472 function &Auth_OpenID_getDefaultNegotiator()
00473 {
00474     $x = new Auth_OpenID_SessionNegotiator(
00475                  Auth_OpenID_getDefaultAssociationOrder());
00476     return $x;
00477 }
00478 
00479 function &Auth_OpenID_getEncryptedNegotiator()
00480 {
00481     $x = new Auth_OpenID_SessionNegotiator(
00482                  Auth_OpenID_getOnlyEncryptedOrder());
00483     return $x;
00484 }
00485 
00527 class Auth_OpenID_SessionNegotiator {
00528     function Auth_OpenID_SessionNegotiator($allowed_types)
00529     {
00530         $this->allowed_types = array();
00531         $this->setAllowedTypes($allowed_types);
00532     }
00533 
00540     function setAllowedTypes($allowed_types)
00541     {
00542         foreach ($allowed_types as $pair) {
00543             list($assoc_type, $session_type) = $pair;
00544             if (!Auth_OpenID_checkSessionType($assoc_type, $session_type)) {
00545                 return false;
00546             }
00547         }
00548 
00549         $this->allowed_types = $allowed_types;
00550         return true;
00551     }
00552 
00560     function addAllowedType($assoc_type, $session_type = null)
00561     {
00562         if ($this->allowed_types === null) {
00563             $this->allowed_types = array();
00564         }
00565 
00566         if ($session_type === null) {
00567             $available = Auth_OpenID_getSessionTypes($assoc_type);
00568 
00569             if (!$available) {
00570                 return false;
00571             }
00572 
00573             foreach ($available as $session_type) {
00574                 $this->addAllowedType($assoc_type, $session_type);
00575             }
00576         } else {
00577             if (Auth_OpenID_checkSessionType($assoc_type, $session_type)) {
00578                 $this->allowed_types[] = array($assoc_type, $session_type);
00579             } else {
00580                 return false;
00581             }
00582         }
00583 
00584         return true;
00585     }
00586 
00587     // Is this combination of association type and session type allowed?
00588     function isAllowed($assoc_type, $session_type)
00589     {
00590         $assoc_good = in_array(array($assoc_type, $session_type),
00591                                $this->allowed_types);
00592 
00593         $matches = in_array($session_type,
00594                             Auth_OpenID_getSessionTypes($assoc_type));
00595 
00596         return ($assoc_good && $matches);
00597     }
00598 
00603     function getAllowedType()
00604     {
00605         if (!$this->allowed_types) {
00606             return array(null, null);
00607         }
00608 
00609         return $this->allowed_types[0];
00610     }
00611 }
00612 
00613 ?>

Generated on Thu Feb 19 15:02:21 2009 for OXID eShop CE by  doxygen 1.5.5