ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Association.php
Go to the documentation of this file.
1<?php
2
20require_once 'Auth/OpenID/CryptUtil.php';
21
25require_once 'Auth/OpenID/KVForm.php';
26
30require_once 'Auth/OpenID/HMAC.php';
31
45
51 var $SIG_LENGTH = 20;
52
58 var $assoc_keys = array(
59 'version',
60 'handle',
61 'secret',
62 'issued',
63 'lifetime',
64 'assoc_type'
65 );
66
67 var $_macs = array(
68 'HMAC-SHA1' => 'Auth_OpenID_HMACSHA1',
69 'HMAC-SHA256' => 'Auth_OpenID_HMACSHA256'
70 );
71
97 static function fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
98 {
99 $issued = time();
100 $lifetime = $expires_in;
101 return new Auth_OpenID_Association($handle, $secret,
102 $issued, $lifetime, $assoc_type);
103 }
104
132 $handle, $secret, $issued, $lifetime, $assoc_type)
133 {
134 if (!in_array($assoc_type,
136 $fmt = 'Unsupported association type (%s)';
137 trigger_error(sprintf($fmt, $assoc_type), E_USER_ERROR);
138 }
139
140 $this->handle = $handle;
141 $this->secret = $secret;
142 $this->issued = $issued;
143 $this->lifetime = $lifetime;
144 $this->assoc_type = $assoc_type;
145 }
146
154 function getExpiresIn($now = null)
155 {
156 if ($now == null) {
157 $now = time();
158 }
159
160 return max(0, $this->issued + $this->lifetime - $now);
161 }
162
170 function equal($other)
171 {
172 return ((gettype($this) == gettype($other))
173 && ($this->handle == $other->handle)
174 && ($this->secret == $other->secret)
175 && ($this->issued == $other->issued)
176 && ($this->lifetime == $other->lifetime)
177 && ($this->assoc_type == $other->assoc_type));
178 }
179
186 function serialize()
187 {
188 $data = array(
189 'version' => '2',
190 'handle' => $this->handle,
191 'secret' => base64_encode($this->secret),
192 'issued' => strval(intval($this->issued)),
193 'lifetime' => strval(intval($this->lifetime)),
194 'assoc_type' => $this->assoc_type
195 );
196
197 assert(array_keys($data) == $this->assoc_keys);
198
199 return Auth_OpenID_KVForm::fromArray($data, $strict = true);
200 }
201
209 static function deserialize($class_name, $assoc_s)
210 {
211 $pairs = Auth_OpenID_KVForm::toArray($assoc_s, $strict = true);
212 $keys = array();
213 $values = array();
214 foreach ($pairs as $key => $value) {
215 if (is_array($value)) {
216 list($key, $value) = $value;
217 }
218 $keys[] = $key;
219 $values[] = $value;
220 }
221
222 $class_vars = get_class_vars($class_name);
223 $class_assoc_keys = $class_vars['assoc_keys'];
224
225 sort($keys);
226 sort($class_assoc_keys);
227
228 if ($keys != $class_assoc_keys) {
229 trigger_error('Unexpected key values: ' . var_export($keys, true),
230 E_USER_WARNING);
231 return null;
232 }
233
234 $version = $pairs['version'];
235 $handle = $pairs['handle'];
236 $secret = $pairs['secret'];
237 $issued = $pairs['issued'];
238 $lifetime = $pairs['lifetime'];
239 $assoc_type = $pairs['assoc_type'];
240
241 if ($version != '2') {
242 trigger_error('Unknown version: ' . $version, E_USER_WARNING);
243 return null;
244 }
245
246 $issued = intval($issued);
247 $lifetime = intval($lifetime);
248 $secret = base64_decode($secret);
249
250 return new $class_name(
251 $handle, $secret, $issued, $lifetime, $assoc_type);
252 }
253
263 function sign($pairs)
264 {
265 $kv = Auth_OpenID_KVForm::fromArray($pairs);
266
267 /* Invalid association types should be caught at constructor */
268 $callback = $this->_macs[$this->assoc_type];
269
270 return call_user_func_array($callback, array($this->secret, $kv));
271 }
272
283 function signMessage($message)
284 {
285 if ($message->hasKey(Auth_OpenID_OPENID_NS, 'sig') ||
286 $message->hasKey(Auth_OpenID_OPENID_NS, 'signed')) {
287 // Already has a sig
288 return null;
289 }
290
291 $extant_handle = $message->getArg(Auth_OpenID_OPENID_NS,
292 'assoc_handle');
293
294 if ($extant_handle && ($extant_handle != $this->handle)) {
295 // raise ValueError("Message has a different association handle")
296 return null;
297 }
298
299 $signed_message = $message;
300 $signed_message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle',
301 $this->handle);
302
303 $message_keys = array_keys($signed_message->toPostArgs());
304 $signed_list = array();
305 $signed_prefix = 'openid.';
306
307 foreach ($message_keys as $k) {
308 if (strpos($k, $signed_prefix) === 0) {
309 $signed_list[] = substr($k, strlen($signed_prefix));
310 }
311 }
312
313 $signed_list[] = 'signed';
314 sort($signed_list);
315
316 $signed_message->setArg(Auth_OpenID_OPENID_NS, 'signed',
317 implode(',', $signed_list));
318 $sig = $this->getMessageSignature($signed_message);
319 $signed_message->setArg(Auth_OpenID_OPENID_NS, 'sig', $sig);
320 return $signed_message;
321 }
322
330 function _makePairs($message)
331 {
332 $signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
333 if (!$signed || Auth_OpenID::isFailure($signed)) {
334 // raise ValueError('Message has no signed list: %s' % (message,))
335 return null;
336 }
337
338 $signed_list = explode(',', $signed);
339 $pairs = array();
340 $data = $message->toPostArgs();
341 foreach ($signed_list as $field) {
342 $pairs[] = array($field, Auth_OpenID::arrayGet($data,
343 'openid.' .
344 $field, ''));
345 }
346 return $pairs;
347 }
348
355 function getMessageSignature($message)
356 {
357 $pairs = $this->_makePairs($message);
358 return base64_encode($this->sign($pairs));
359 }
360
367 function checkMessageSignature($message)
368 {
369 $sig = $message->getArg(Auth_OpenID_OPENID_NS,
370 'sig');
371
372 if (!$sig || Auth_OpenID::isFailure($sig)) {
373 return false;
374 }
375
376 $calculated_sig = $this->getMessageSignature($message);
377 return $calculated_sig == $sig;
378 }
379}
380
381function Auth_OpenID_getSecretSize($assoc_type)
382{
383 if ($assoc_type == 'HMAC-SHA1') {
384 return 20;
385 } else if ($assoc_type == 'HMAC-SHA256') {
386 return 32;
387 } else {
388 return null;
389 }
390}
391
393{
394 return array('HMAC-SHA1', 'HMAC-SHA256');
395}
396
398{
399 $a = array('HMAC-SHA1');
400
401 if (Auth_OpenID_HMACSHA256_SUPPORTED) {
402 $a[] = 'HMAC-SHA256';
403 }
404
405 return $a;
406}
407
408function Auth_OpenID_getSessionTypes($assoc_type)
409{
410 $assoc_to_session = array(
411 'HMAC-SHA1' => array('DH-SHA1', 'no-encryption'));
412
413 if (Auth_OpenID_HMACSHA256_SUPPORTED) {
414 $assoc_to_session['HMAC-SHA256'] =
415 array('DH-SHA256', 'no-encryption');
416 }
417
418 return Auth_OpenID::arrayGet($assoc_to_session, $assoc_type, array());
419}
420
421function Auth_OpenID_checkSessionType($assoc_type, $session_type)
422{
423 if (!in_array($session_type,
424 Auth_OpenID_getSessionTypes($assoc_type))) {
425 return false;
426 }
427
428 return true;
429}
430
432{
433 $order = array();
434
436 $order[] = array('HMAC-SHA1', 'DH-SHA1');
437
438 if (Auth_OpenID_HMACSHA256_SUPPORTED) {
439 $order[] = array('HMAC-SHA256', 'DH-SHA256');
440 }
441 }
442
443 $order[] = array('HMAC-SHA1', 'no-encryption');
444
445 if (Auth_OpenID_HMACSHA256_SUPPORTED) {
446 $order[] = array('HMAC-SHA256', 'no-encryption');
447 }
448
449 return $order;
450}
451
453{
454 $result = array();
455
456 foreach (Auth_OpenID_getDefaultAssociationOrder() as $pair) {
457 list($assoc, $session) = $pair;
458
459 if ($session != 'no-encryption') {
460 if (Auth_OpenID_HMACSHA256_SUPPORTED &&
461 ($assoc == 'HMAC-SHA256')) {
462 $result[] = $pair;
463 } else if ($assoc != 'HMAC-SHA256') {
464 $result[] = $pair;
465 }
466 }
467 }
468
469 return $result;
470}
471
473{
476}
477
479{
482}
483
526 function Auth_OpenID_SessionNegotiator($allowed_types)
527 {
528 $this->allowed_types = array();
529 $this->setAllowedTypes($allowed_types);
530 }
531
538 function setAllowedTypes($allowed_types)
539 {
540 foreach ($allowed_types as $pair) {
541 list($assoc_type, $session_type) = $pair;
542 if (!Auth_OpenID_checkSessionType($assoc_type, $session_type)) {
543 return false;
544 }
545 }
546
547 $this->allowed_types = $allowed_types;
548 return true;
549 }
550
558 function addAllowedType($assoc_type, $session_type = null)
559 {
560 if ($this->allowed_types === null) {
561 $this->allowed_types = array();
562 }
563
564 if ($session_type === null) {
565 $available = Auth_OpenID_getSessionTypes($assoc_type);
566
567 if (!$available) {
568 return false;
569 }
570
571 foreach ($available as $session_type) {
572 $this->addAllowedType($assoc_type, $session_type);
573 }
574 } else {
575 if (Auth_OpenID_checkSessionType($assoc_type, $session_type)) {
576 $this->allowed_types[] = array($assoc_type, $session_type);
577 } else {
578 return false;
579 }
580 }
581
582 return true;
583 }
584
585 // Is this combination of association type and session type allowed?
586 function isAllowed($assoc_type, $session_type)
587 {
588 $assoc_good = in_array(array($assoc_type, $session_type),
589 $this->allowed_types);
590
591 $matches = in_array($session_type,
592 Auth_OpenID_getSessionTypes($assoc_type));
593
594 return ($assoc_good && $matches);
595 }
596
601 function getAllowedType()
602 {
603 if (!$this->allowed_types) {
604 return array(null, null);
605 }
606
607 return $this->allowed_types[0];
608 }
609}
610
Auth_OpenID_getSupportedAssociationTypes()
Auth_OpenID_getSessionTypes($assoc_type)
Auth_OpenID_getOnlyEncryptedOrder()
Auth_OpenID_getSecretSize($assoc_type)
Auth_OpenID_getAllAssociationTypes()
Auth_OpenID_getEncryptedNegotiator()
Auth_OpenID_getDefaultNegotiator()
Auth_OpenID_checkSessionType($assoc_type, $session_type)
Auth_OpenID_getDefaultAssociationOrder()
Auth_OpenID_noMathSupport()
Definition: BigMath.php:447
$result
const Auth_OpenID_OPENID_NS
Definition: Message.php:42
$SIG_LENGTH
This is a HMAC-SHA1 specific value.
Definition: Association.php:51
serialize()
Convert an association to KV form.
equal($other)
This checks to see if two Auth_OpenID_Association instances represent the same association.
static deserialize($class_name, $assoc_s)
Parse an association as stored by serialize().
_makePairs($message)
Given a Auth_OpenID_Message, return the key/value pairs to be signed according to the signed list in ...
Auth_OpenID_Association( $handle, $secret, $issued, $lifetime, $assoc_type)
This is the standard constructor for creating an association.
$assoc_keys
The ordering and name of keys as stored by serialize.
Definition: Association.php:58
signMessage($message)
Generate a signature for some fields in a dictionary.
getExpiresIn($now=null)
This returns the number of seconds this association is still valid for, or 0 if the association is no...
checkMessageSignature($message)
Confirm that the signature of these fields matches the signature contained in the data.
static fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
This is an alternate constructor (factory method) used by the OpenID consumer library to create assoc...
Definition: Association.php:97
sign($pairs)
Generate a signature for a sequence of (key, value) pairs.
getMessageSignature($message)
Given an Auth_OpenID_Message, return the signature for the signed list in the message.
static toArray($kvs, $strict=false)
Convert an OpenID colon/newline separated string into an associative array.
Definition: KVForm.php:29
static fromArray($values)
Convert an array into an OpenID colon/newline separated string.
Definition: KVForm.php:81
addAllowedType($assoc_type, $session_type=null)
Add an association type and session type to the allowed types list.
Auth_OpenID_SessionNegotiator($allowed_types)
isAllowed($assoc_type, $session_type)
getAllowedType()
Get a pair of assocation type and session type that are supported.
setAllowedTypes($allowed_types)
Set the allowed association types, checking to make sure each combination is valid.
static arrayGet($arr, $key, $fallback=null)
Convenience function for getting array values.
Definition: OpenID.php:242
static isFailure($thing)
Return true if $thing is an Auth_OpenID_FailureResponse object; false if not.
Definition: OpenID.php:118
$data