aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSem <sembrestels@riseup.net>2013-11-09 16:26:19 +0100
committerSem <sembrestels@riseup.net>2013-11-09 16:26:19 +0100
commit5cc7f96262509b2a5d43fa6fbb6cd083064385be (patch)
treec2de1ca30876063882cbbb0818d1d618cc6da4c4
parent2161e2335c9c650b8e44a56f6c9b0bd37546ae1f (diff)
parentb6c722ac63d250972fea066b30e58026d00ab3e2 (diff)
downloadelgg-5cc7f96262509b2a5d43fa6fbb6cd083064385be.tar.gz
elgg-5cc7f96262509b2a5d43fa6fbb6cd083064385be.tar.bz2
Add 'mod/openid_server/' from commit 'b6c722ac63d250972fea066b30e58026d00ab3e2'
git-subtree-dir: mod/openid_server git-subtree-mainline: 2161e2335c9c650b8e44a56f6c9b0bd37546ae1f git-subtree-split: b6c722ac63d250972fea066b30e58026d00ab3e2
-rw-r--r--mod/openid_server/Crypt/RSA.php524
-rw-r--r--mod/openid_server/Crypt/RSA/ErrorHandler.php234
-rw-r--r--mod/openid_server/Crypt/RSA/Key.php314
-rw-r--r--mod/openid_server/Crypt/RSA/KeyPair.php804
-rw-r--r--mod/openid_server/Crypt/RSA/Math/BCMath.php482
-rw-r--r--mod/openid_server/Crypt/RSA/Math/BigInt.php313
-rw-r--r--mod/openid_server/Crypt/RSA/Math/GMP.php361
-rw-r--r--mod/openid_server/Crypt/RSA/MathLoader.php135
-rwxr-xr-xmod/openid_server/actions/admin.php90
-rwxr-xr-xmod/openid_server/actions/autologin.php52
-rwxr-xr-xmod/openid_server/actions/autologout.php48
-rwxr-xr-xmod/openid_server/actions/trust.php93
-rw-r--r--mod/openid_server/languages/ca.php40
-rwxr-xr-xmod/openid_server/languages/en.php47
-rwxr-xr-xmod/openid_server/languages/es.php40
-rw-r--r--mod/openid_server/languages/gl.php40
-rw-r--r--mod/openid_server/languages/pt.php27
-rwxr-xr-xmod/openid_server/lib/actions.php173
-rwxr-xr-xmod/openid_server/lib/common.php164
-rwxr-xr-xmod/openid_server/lib/session.php140
-rwxr-xr-xmod/openid_server/manifest.xml20
-rwxr-xr-xmod/openid_server/openid_server_include.php340
-rwxr-xr-xmod/openid_server/server.php32
-rwxr-xr-xmod/openid_server/start.php65
-rwxr-xr-xmod/openid_server/views/default/forms/openid_server/trust.php34
-rwxr-xr-xmod/openid_server/views/default/openid_server/forms/admin.php154
-rwxr-xr-xmod/openid_server/views/default/openid_server/forms/autologin.php22
-rwxr-xr-xmod/openid_server/views/default/openid_server/forms/autologout.php24
-rwxr-xr-xmod/openid_server/views/default/openid_server/forms/trust.php35
-rwxr-xr-xmod/openid_server/views/default/openid_server/metatags.php6
-rw-r--r--mod/openid_server/views/xrds/openid_server/profile.php11
-rw-r--r--mod/openid_server/views/xrds/openid_server/service.php15
32 files changed, 4879 insertions, 0 deletions
diff --git a/mod/openid_server/Crypt/RSA.php b/mod/openid_server/Crypt/RSA.php
new file mode 100644
index 000000000..16dfa54d4
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA.php
@@ -0,0 +1,524 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version 1.2.0b
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * RSA error handling facilities
+ */
+require_once 'Crypt/RSA/ErrorHandler.php';
+
+/**
+ * loader for math wrappers
+ */
+require_once 'Crypt/RSA/MathLoader.php';
+
+/**
+ * helper class for mange single key
+ */
+require_once 'Crypt/RSA/Key.php';
+
+/**
+ * helper class for manage key pair
+ */
+require_once 'Crypt/RSA/KeyPair.php';
+
+/**
+ * Crypt_RSA class, derived from Crypt_RSA_ErrorHandler
+ *
+ * Provides the following functions:
+ * - setParams($params) - sets parameters of current object
+ * - encrypt($plain_data, $key = null) - encrypts data
+ * - decrypt($enc_data, $key = null) - decrypts data
+ * - createSign($doc, $private_key = null) - signs document by private key
+ * - validateSign($doc, $signature, $public_key = null) - validates signature of document
+ *
+ * Example usage:
+ * // creating an error handler
+ * $error_handler = create_function('$obj', 'echo "error: ", $obj->getMessage(), "\n"');
+ *
+ * // 1024-bit key pair generation
+ * $key_pair = new Crypt_RSA_KeyPair(1024);
+ *
+ * // check consistence of Crypt_RSA_KeyPair object
+ * $error_handler($key_pair);
+ *
+ * // creating Crypt_RSA object
+ * $rsa_obj = new Crypt_RSA;
+ *
+ * // check consistence of Crypt_RSA object
+ * $error_handler($rsa_obj);
+ *
+ * // set error handler on Crypt_RSA object ( see Crypt/RSA/ErrorHandler.php for details )
+ * $rsa_obj->setErrorHandler($error_handler);
+ *
+ * // encryption (usually using public key)
+ * $enc_data = $rsa_obj->encrypt($plain_data, $key_pair->getPublicKey());
+ *
+ * // decryption (usually using private key)
+ * $plain_data = $rsa_obj->decrypt($enc_data, $key_pair->getPrivateKey());
+ *
+ * // signing
+ * $signature = $rsa_obj->createSign($document, $key_pair->getPrivateKey());
+ *
+ * // signature checking
+ * $is_valid = $rsa_obj->validateSign($document, $signature, $key_pair->getPublicKey());
+ *
+ * // signing many documents by one private key
+ * $rsa_obj = new Crypt_RSA(array('private_key' => $key_pair->getPrivateKey()));
+ * // check consistence of Crypt_RSA object
+ * $error_handler($rsa_obj);
+ * // set error handler ( see Crypt/RSA/ErrorHandler.php for details )
+ * $rsa_obj->setErrorHandler($error_handler);
+ * // sign many documents
+ * $sign_1 = $rsa_obj->sign($doc_1);
+ * $sign_2 = $rsa_obj->sign($doc_2);
+ * //...
+ * $sign_n = $rsa_obj->sign($doc_n);
+ *
+ * // changing default hash function, which is used for sign
+ * // creating/validation
+ * $rsa_obj->setParams(array('hash_func' => 'md5'));
+ *
+ * // using factory() method instead of constructor (it returns PEAR_Error object on failure)
+ * $rsa_obj = &Crypt_RSA::factory();
+ * if (PEAR::isError($rsa_obj)) {
+ * echo "error: ", $rsa_obj->getMessage(), "\n";
+ * }
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_RSA extends Crypt_RSA_ErrorHandler
+{
+ /**
+ * Reference to math wrapper, which is used to
+ * manipulate large integers in RSA algorithm.
+ *
+ * @var object of Crypt_RSA_Math_* class
+ * @access private
+ */
+ var $_math_obj;
+
+ /**
+ * key for encryption, which is used by encrypt() method
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_enc_key;
+
+ /**
+ * key for decryption, which is used by decrypt() method
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_dec_key;
+
+ /**
+ * public key, which is used by validateSign() method
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_public_key;
+
+ /**
+ * private key, which is used by createSign() method
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_private_key;
+
+ /**
+ * name of hash function, which is used by validateSign()
+ * and createSign() methods. Default hash function is SHA-1
+ *
+ * @var string
+ * @access private
+ */
+ var $_hash_func = 'sha1';
+
+ /**
+ * Crypt_RSA constructor.
+ *
+ * @param array $params
+ * Optional associative array of parameters, such as:
+ * enc_key, dec_key, private_key, public_key, hash_func.
+ * See setParams() method for more detailed description of
+ * these parameters.
+ * @param string $wrapper_name
+ * Name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ * @param string $error_handler name of error handler function
+ *
+ * @access public
+ */
+ function Crypt_RSA($params = null, $wrapper_name = 'default', $error_handler = '')
+ {
+ // set error handler
+ $this->setErrorHandler($error_handler);
+ // try to load math wrapper
+ $obj = &Crypt_RSA_MathLoader::loadWrapper($wrapper_name);
+ if ($this->isError($obj)) {
+ // error during loading of math wrapper
+ // Crypt_RSA object is partially constructed.
+ $this->pushError($obj);
+ return;
+ }
+ $this->_math_obj = &$obj;
+
+ if (!is_null($params)) {
+ if (!$this->setParams($params)) {
+ // error in Crypt_RSA::setParams() function
+ return;
+ }
+ }
+ }
+
+ /**
+ * Crypt_RSA factory.
+ *
+ * @param array $params
+ * Optional associative array of parameters, such as:
+ * enc_key, dec_key, private_key, public_key, hash_func.
+ * See setParams() method for more detailed description of
+ * these parameters.
+ * @param string $wrapper_name
+ * Name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ * @param string $error_handler name of error handler function
+ *
+ * @return object new Crypt_RSA object on success or PEAR_Error object on failure
+ * @access public
+ */
+ function &factory($params = null, $wrapper_name = 'default', $error_handler = '')
+ {
+ $obj = &new Crypt_RSA($params, $wrapper_name, $error_handler);
+ if ($obj->isError()) {
+ // error during creating a new object. Retrurn PEAR_Error object
+ return $obj->getLastError();
+ }
+ // object created successfully. Return it
+ return $obj;
+ }
+
+ /**
+ * Accepts any combination of available parameters as associative array:
+ * enc_key - encryption key for encrypt() method
+ * dec_key - decryption key for decrypt() method
+ * public_key - key for validateSign() method
+ * private_key - key for createSign() method
+ * hash_func - name of hash function, which will be used to create and validate sign
+ *
+ * @param array $params
+ * associative array of permitted parameters (see above)
+ *
+ * @return bool true on success or false on error
+ * @access public
+ */
+ function setParams($params)
+ {
+ if (!is_array($params)) {
+ $this->pushError('parameters must be passed to function as associative array', CRYPT_RSA_ERROR_WRONG_PARAMS);
+ return false;
+ }
+
+ if (isset($params['enc_key'])) {
+ if (Crypt_RSA_Key::isValid($params['enc_key'])) {
+ $this->_enc_key = $params['enc_key'];
+ }
+ else {
+ $this->pushError('wrong encryption key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+ }
+ if (isset($params['dec_key'])) {
+ if (Crypt_RSA_Key::isValid($params['dec_key'])) {
+ $this->_dec_key = $params['dec_key'];
+ }
+ else {
+ $this->pushError('wrong decryption key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+ }
+ if (isset($params['private_key'])) {
+ if (Crypt_RSA_Key::isValid($params['private_key'])) {
+ if ($params['private_key']->getKeyType() != 'private') {
+ $this->pushError('private key must have "private" attribute', CRYPT_RSA_ERROR_WRONG_KEY_TYPE);
+ return false;
+ }
+ $this->_private_key = $params['private_key'];
+ }
+ else {
+ $this->pushError('wrong private key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+ }
+ if (isset($params['public_key'])) {
+ if (Crypt_RSA_Key::isValid($params['public_key'])) {
+ if ($params['public_key']->getKeyType() != 'public') {
+ $this->pushError('public key must have "public" attribute', CRYPT_RSA_ERROR_WRONG_KEY_TYPE);
+ return false;
+ }
+ $this->_public_key = $params['public_key'];
+ }
+ else {
+ $this->pushError('wrong public key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+ }
+ if (isset($params['hash_func'])) {
+ if (!function_exists($params['hash_func'])) {
+ $this->pushError('cannot find hash function with name [' . $params['hash_func'] . ']', CRYPT_RSA_ERROR_WRONG_HASH_FUNC);
+ return false;
+ }
+ $this->_hash_func = $params['hash_func'];
+ }
+ return true; // all ok
+ }
+
+ /**
+ * Ecnrypts $plain_data by the key $this->_enc_key or $key.
+ *
+ * @param string $plain_data data, which must be encrypted
+ * @param object $key encryption key (object of Crypt_RSA_Key class)
+ * @return mixed
+ * encrypted data as string on success or false on error
+ *
+ * @access public
+ */
+ function encrypt($plain_data, $key = null)
+ {
+ $enc_data = $this->encryptBinary($plain_data, $key);
+ if ($enc_data !== false) {
+ return base64_encode($enc_data);
+ }
+ // error during encripting data
+ return false;
+ }
+
+ /**
+ * Ecnrypts $plain_data by the key $this->_enc_key or $key.
+ *
+ * @param string $plain_data data, which must be encrypted
+ * @param object $key encryption key (object of Crypt_RSA_Key class)
+ * @return mixed
+ * encrypted data as binary string on success or false on error
+ *
+ * @access public
+ */
+ function encryptBinary($plain_data, $key = null)
+ {
+ if (is_null($key)) {
+ // use current encryption key
+ $key = $this->_enc_key;
+ }
+ else if (!Crypt_RSA_Key::isValid($key)) {
+ $this->pushError('invalid encryption key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+
+ // append tail \x01 to plain data. It needs for correctly decrypting of data
+ $plain_data .= "\x01";
+
+ $plain_data = $this->_math_obj->bin2int($plain_data);
+ $exp = $this->_math_obj->bin2int($key->getExponent());
+ $modulus = $this->_math_obj->bin2int($key->getModulus());
+
+ // divide plain data into chunks
+ $data_len = $this->_math_obj->bitLen($plain_data);
+ $chunk_len = $key->getKeyLength() - 1;
+ $block_len = (int) ceil($chunk_len / 8);
+ $curr_pos = 0;
+ $enc_data = '';
+ while ($curr_pos < $data_len) {
+ $tmp = $this->_math_obj->subint($plain_data, $curr_pos, $chunk_len);
+ $enc_data .= str_pad(
+ $this->_math_obj->int2bin($this->_math_obj->powmod($tmp, $exp, $modulus)),
+ $block_len,
+ "\0"
+ );
+ $curr_pos += $chunk_len;
+ }
+ return $enc_data;
+ }
+
+ /**
+ * Decrypts $enc_data by the key $this->_dec_key or $key.
+ *
+ * @param string $enc_data encrypted data as string
+ * @param object $key decryption key (object of RSA_Crypt_Key class)
+ * @return mixed
+ * decrypted data as string on success or false on error
+ *
+ * @access public
+ */
+ function decrypt($enc_data, $key = null)
+ {
+ $enc_data = base64_decode($enc_data);
+ return $this->decryptBinary($enc_data, $key);
+ }
+
+ /**
+ * Decrypts $enc_data by the key $this->_dec_key or $key.
+ *
+ * @param string $enc_data encrypted data as binary string
+ * @param object $key decryption key (object of RSA_Crypt_Key class)
+ * @return mixed
+ * decrypted data as string on success or false on error
+ *
+ * @access public
+ */
+ function decryptBinary($enc_data, $key = null)
+ {
+ if (is_null($key)) {
+ // use current decryption key
+ $key = $this->_dec_key;
+ }
+ else if (!Crypt_RSA_Key::isValid($key)) {
+ $this->pushError('invalid decryption key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+
+ $exp = $this->_math_obj->bin2int($key->getExponent());
+ $modulus = $this->_math_obj->bin2int($key->getModulus());
+
+ $data_len = strlen($enc_data);
+ $chunk_len = $key->getKeyLength() - 1;
+ $block_len = (int) ceil($chunk_len / 8);
+ $curr_pos = 0;
+ $bit_pos = 0;
+ $plain_data = $this->_math_obj->bin2int("\0");
+ while ($curr_pos < $data_len) {
+ $tmp = $this->_math_obj->bin2int(substr($enc_data, $curr_pos, $block_len));
+ $tmp = $this->_math_obj->powmod($tmp, $exp, $modulus);
+ $plain_data = $this->_math_obj->bitOr($plain_data, $tmp, $bit_pos);
+ $bit_pos += $chunk_len;
+ $curr_pos += $block_len;
+ }
+ $result = $this->_math_obj->int2bin($plain_data);
+
+ // delete tail, containing of \x01
+ $tail = ord($result{strlen($result) - 1});
+ if ($tail != 1) {
+ $this->pushError("Error tail of decrypted text = {$tail}. Expected 1", CRYPT_RSA_ERROR_WRONG_TAIL);
+ return false;
+ }
+ return substr($result, 0, -1);
+ }
+
+ /**
+ * Creates sign for document $document, using $this->_private_key or $private_key
+ * as private key and $this->_hash_func or $hash_func as hash function.
+ *
+ * @param string $document document, which must be signed
+ * @param object $private_key private key (object of Crypt_RSA_Key type)
+ * @param string $hash_func name of hash function, which will be used during signing
+ * @return mixed
+ * signature of $document as string on success or false on error
+ *
+ * @access public
+ */
+ function createSign($document, $private_key = null, $hash_func = null)
+ {
+ // check private key
+ if (is_null($private_key)) {
+ $private_key = $this->_private_key;
+ }
+ else if (!Crypt_RSA_Key::isValid($private_key)) {
+ $this->pushError('invalid private key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return false;
+ }
+ if ($private_key->getKeyType() != 'private') {
+ $this->pushError('signing key must be private', CRYPT_RSA_ERROR_NEED_PRV_KEY);
+ return false;
+ }
+
+ // check hash_func
+ if (is_null($hash_func)) {
+ $hash_func = $this->_hash_func;
+ }
+ if (!function_exists($hash_func)) {
+ $this->pushError("cannot find hash function with name [$hash_func]", CRYPT_RSA_ERROR_WRONG_HASH_FUNC);
+ return false;
+ }
+
+ return $this->encrypt($hash_func($document), $private_key);
+ }
+
+ /**
+ * Validates $signature for document $document with public key $this->_public_key
+ * or $public_key and hash function $this->_hash_func or $hash_func.
+ *
+ * @param string $document document, signature of which must be validated
+ * @param string $signature signature, which must be validated
+ * @param object $public_key public key (object of Crypt_RSA_Key class)
+ * @param string $hash_func hash function, which will be used during validating signature
+ * @return mixed
+ * true, if signature of document is valid
+ * false, if signature of document is invalid
+ * null on error
+ *
+ * @access public
+ */
+ function validateSign($document, $signature, $public_key = null, $hash_func = null)
+ {
+ // check public key
+ if (is_null($public_key)) {
+ $public_key = $this->_public_key;
+ }
+ else if (!Crypt_RSA_Key::isValid($public_key)) {
+ $this->pushError('invalid public key. It must be an object of Crypt_RSA_Key class', CRYPT_RSA_ERROR_WRONG_KEY);
+ return null;
+ }
+ if ($public_key->getKeyType() != 'public') {
+ $this->pushError('validating key must be public', CRYPT_RSA_ERROR_NEED_PUB_KEY);
+ return null;
+ }
+
+ // check hash_func
+ if (is_null($hash_func)) {
+ $hash_func = $this->_hash_func;
+ }
+ if (!function_exists($hash_func)) {
+ $this->pushError("cannot find hash function with name [$hash_func]", CRYPT_RSA_ERROR_WRONG_HASH_FUNC);
+ return null;
+ }
+
+ return $hash_func($document) == $this->decrypt($signature, $public_key);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/Crypt/RSA/ErrorHandler.php b/mod/openid_server/Crypt/RSA/ErrorHandler.php
new file mode 100644
index 000000000..8f39741e0
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/ErrorHandler.php
@@ -0,0 +1,234 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: ErrorHandler.php,v 1.4 2009/01/05 08:30:29 clockwerx Exp $
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * uses PEAR's error handling
+ */
+require_once 'PEAR.php';
+
+/**
+ * cannot load required extension for math wrapper
+ */
+define('CRYPT_RSA_ERROR_NO_EXT', 1);
+
+/**
+ * cannot load any math wrappers.
+ * Possible reasons:
+ * - there is no any wrappers (they must exist in Crypt/RSA/Math folder )
+ * - all available wrappers are incorrect (read docs/Crypt_RSA/docs/math_wrappers.txt )
+ * - cannot load any extension, required by available wrappers
+ */
+define('CRYPT_RSA_ERROR_NO_WRAPPERS', 2);
+
+/**
+ * cannot find file, containing requested math wrapper
+ */
+define('CRYPT_RSA_ERROR_NO_FILE', 3);
+
+/**
+ * cannot find math wrapper class in the math wrapper file
+ */
+define('CRYPT_RSA_ERROR_NO_CLASS', 4);
+
+/**
+ * invalid key type passed to function (it must be 'public' or 'private')
+ */
+define('CRYPT_RSA_ERROR_WRONG_KEY_TYPE', 5);
+
+/**
+ * key modulus must be greater than key exponent
+ */
+define('CRYPT_RSA_ERROR_EXP_GE_MOD', 6);
+
+/**
+ * missing $key_len parameter in Crypt_RSA_KeyPair::generate($key_len) function
+ */
+define('CRYPT_RSA_ERROR_MISSING_KEY_LEN', 7);
+
+/**
+ * wrong key object passed to function (it must be an object of Crypt_RSA_Key class)
+ */
+define('CRYPT_RSA_ERROR_WRONG_KEY', 8);
+
+/**
+ * wrong name of hash function passed to Crypt_RSA::setParams() function
+ */
+define('CRYPT_RSA_ERROR_WRONG_HASH_FUNC', 9);
+
+/**
+ * key, used for signing, must be private
+ */
+define('CRYPT_RSA_ERROR_NEED_PRV_KEY', 10);
+
+/**
+ * key, used for sign validating, must be public
+ */
+define('CRYPT_RSA_ERROR_NEED_PUB_KEY', 11);
+
+/**
+ * parameters must be passed to function as associative array
+ */
+define('CRYPT_RSA_ERROR_WRONG_PARAMS', 12);
+
+/**
+ * error tail of decrypted text. Maybe, wrong decryption key?
+ */
+define('CRYPT_RSA_ERROR_WRONG_TAIL', 13);
+
+/**
+ * Crypt_RSA_ErrorHandler class.
+ *
+ * This class is used as base for Crypt_RSA, Crypt_RSA_Key
+ * and Crypt_RSA_KeyPair classes.
+ *
+ * It provides following functions:
+ * - isError() - returns true, if list contains errors, else returns false
+ * - getErrorList() - returns error list
+ * - getLastError() - returns last error from error list or false, if list is empty
+ * - pushError($errstr) - pushes $errstr into the error list
+ * - setErrorHandler($new_error_handler) - sets error handler function
+ * - getErrorHandler() - returns name of error handler function
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @access public
+ */
+class Crypt_RSA_ErrorHandler
+{
+ /**
+ * array of error objects, pushed by $this->pushError()
+ *
+ * @var array
+ * @access private
+ */
+ var $_errors = array();
+
+ /**
+ * name of error handler - function, which calls on $this->pushError() call
+ *
+ * @var string
+ * @access private
+ */
+ var $_error_handler = '';
+
+ /**
+ * Returns true if list of errors is not empty, else returns false
+ *
+ * @param mixed $err Check if the object is an error
+ *
+ * @return bool true, if list of errors is not empty or $err is PEAR_Error object, else false
+ * @access public
+ */
+ function isError($err = null)
+ {
+ return is_null($err) ? (sizeof($this->_errors) > 0) : PEAR::isError($err);
+ }
+
+ /**
+ * Returns list of all errors, pushed to error list by $this->pushError()
+ *
+ * @return array list of errors (usually it contains objects of PEAR_Error class)
+ * @access public
+ */
+ function getErrorList()
+ {
+ return $this->_errors;
+ }
+
+ /**
+ * Returns last error from errors list or false, if list is empty
+ *
+ * @return mixed
+ * last error from errors list (usually it is PEAR_Error object)
+ * or false, if list is empty.
+ *
+ * @access public
+ */
+ function getLastError()
+ {
+ $len = sizeof($this->_errors);
+ return $len ? $this->_errors[$len - 1] : false;
+ }
+
+ /**
+ * pushes error object $error to the error list
+ *
+ * @param string $errstr error string
+ * @param int $errno error number
+ *
+ * @return bool true on success, false on error
+ * @access public
+ */
+ function pushError($errstr, $errno = 0)
+ {
+ $this->_errors[] = PEAR::raiseError($errstr, $errno);
+
+ if ($this->_error_handler != '') {
+ // call user defined error handler
+ $func = $this->_error_handler;
+ $func($this);
+ }
+ return true;
+ }
+
+ /**
+ * sets error handler to function with name $func_name.
+ * Function $func_name must accept one parameter - current
+ * object, which triggered error.
+ *
+ * @param string $func_name name of error handler function
+ *
+ * @return bool true on success, false on error
+ * @access public
+ */
+ function setErrorHandler($func_name = '')
+ {
+ if ($func_name == '') {
+ $this->_error_handler = '';
+ }
+ if (!function_exists($func_name)) {
+ return false;
+ }
+ $this->_error_handler = $func_name;
+ return true;
+ }
+
+ /**
+ * returns name of current error handler, or null if there is no error handler
+ *
+ * @return mixed error handler name as string or null, if there is no error handler
+ * @access public
+ */
+ function getErrorHandler()
+ {
+ return $this->_error_handler;
+ }
+}
+
+?>
diff --git a/mod/openid_server/Crypt/RSA/Key.php b/mod/openid_server/Crypt/RSA/Key.php
new file mode 100644
index 000000000..72a71e2d0
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/Key.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: Key.php,v 1.6 2009/01/05 08:30:29 clockwerx Exp $
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * RSA error handling facilities
+ */
+require_once 'Crypt/RSA/ErrorHandler.php';
+
+/**
+ * loader for RSA math wrappers
+ */
+require_once 'Crypt/RSA/MathLoader.php';
+
+/**
+ * Crypt_RSA_Key class, derived from Crypt_RSA_ErrorHandler
+ *
+ * Provides the following functions:
+ * - getKeyLength() - returns bit key length
+ * - getExponent() - returns key exponent as binary string
+ * - getModulus() - returns key modulus as binary string
+ * - getKeyType() - returns type of the key (public or private)
+ * - toString() - returns serialized key as string
+ * - fromString($key_str) - static function; returns key, unserialized from string
+ * - isValid($key) - static function for validating of $key
+ *
+ * Example usage:
+ * // create new 1024-bit key pair
+ * $key_pair = new Crypt_RSA_KeyPair(1024);
+ *
+ * // get public key (its class is Crypt_RSA_Key)
+ * $key = $key_pair->getPublicKey();
+ *
+ * // get key length
+ * $len = $key->getKeyLength();
+ *
+ * // get modulus as string
+ * $modulus = $key->getModulus();
+ *
+ * // get exponent as string
+ * $exponent = $key->getExponent();
+ *
+ * // get string represenation of key (use it instead of serialization of Crypt_RSA_Key object)
+ * $key_in_str = $key->toString();
+ *
+ * // restore key object from string using 'BigInt' math wrapper
+ * $key = Crypt_RSA_Key::fromString($key_in_str, 'BigInt');
+ *
+ * // error check
+ * if ($key->isError()) {
+ * echo "error while unserializing key object:\n";
+ * $erorr = $key->getLastError();
+ * echo $error->getMessage(), "\n";
+ * }
+ *
+ * // validate key
+ * if (Crypt_RSA_Key::isValid($key)) echo 'valid key';
+ * else echo 'invalid key';
+ *
+ * // using factory() method instead of constructor (it returns PEAR_Error object on failure)
+ * $rsa_obj = &Crypt_RSA_Key::factory($modulus, $exp, $key_type);
+ * if (PEAR::isError($rsa_obj)) {
+ * echo "error: ", $rsa_obj->getMessage(), "\n";
+ * }
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @access public
+ */
+class Crypt_RSA_Key extends Crypt_RSA_ErrorHandler
+{
+ /**
+ * Reference to math wrapper object, which is used to
+ * manipulate large integers in RSA algorithm.
+ *
+ * @var object of Crypt_RSA_Math_* class
+ * @access private
+ */
+ var $_math_obj;
+
+ /**
+ * shared modulus
+ *
+ * @var string
+ * @access private
+ */
+ var $_modulus;
+
+ /**
+ * exponent
+ *
+ * @var string
+ * @access private
+ */
+ var $_exp;
+
+ /**
+ * key type (private or public)
+ *
+ * @var string
+ * @access private
+ */
+ var $_key_type;
+
+ /**
+ * key length in bits
+ *
+ * @var int
+ * @access private
+ */
+ var $_key_len;
+
+ /**
+ * Crypt_RSA_Key constructor.
+ *
+ * You should pass in the name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ *
+ * @param string $modulus key modulus
+ * @param string $exp key exponent
+ * @param string $key_type type of the key (public or private)
+ * @param string $wrapper_name wrapper to use
+ * @param string $error_handler name of error handler function
+ *
+ * @access public
+ */
+ function Crypt_RSA_Key($modulus, $exp, $key_type, $wrapper_name = 'default', $error_handler = '')
+ {
+ // set error handler
+ $this->setErrorHandler($error_handler);
+ // try to load math wrapper $wrapper_name
+ $obj = &Crypt_RSA_MathLoader::loadWrapper($wrapper_name);
+ if ($this->isError($obj)) {
+ // error during loading of math wrapper
+ $this->pushError($obj); // push error object into error list
+ return;
+ }
+ $this->_math_obj = &$obj;
+
+ $this->_modulus = $modulus;
+ $this->_exp = $exp;
+
+ if (!in_array($key_type, array('private', 'public'))) {
+ $this->pushError('invalid key type. It must be private or public', CRYPT_RSA_ERROR_WRONG_KEY_TYPE);
+ return;
+ }
+ $this->_key_type = $key_type;
+
+ /* check length of modulus & exponent ( abs(modulus) > abs(exp) ) */
+ $mod_num = $this->_math_obj->bin2int($this->_modulus);
+ $exp_num = $this->_math_obj->bin2int($this->_exp);
+
+ if ($this->_math_obj->cmpAbs($mod_num, $exp_num) <= 0) {
+ $this->pushError('modulus must be greater than exponent', CRYPT_RSA_ERROR_EXP_GE_MOD);
+ return;
+ }
+ // determine key length
+ $this->_key_len = $this->_math_obj->bitLen($mod_num);
+ }
+
+ /**
+ * Crypt_RSA_Key factory.
+ *
+ * @param string $modulus key modulus
+ * @param string $exp key exponent
+ * @param string $key_type type of the key (public or private)
+ * @param string $wrapper_name wrapper to use
+ * @param string $error_handler name of error handler function
+ *
+ * @return object new Crypt_RSA_Key object on success or PEAR_Error object on failure
+ * @access public
+ */
+ function factory($modulus, $exp, $key_type, $wrapper_name = 'default', $error_handler = '')
+ {
+ $obj = new Crypt_RSA_Key($modulus, $exp, $key_type, $wrapper_name, $error_handler);
+ if ($obj->isError()) {
+ // error during creating a new object. Retrurn PEAR_Error object
+ return $obj->getLastError();
+ }
+ // object created successfully. Return it
+ return $obj;
+ }
+
+ /**
+ * Calculates bit length of the key
+ *
+ * @return int bit length of key
+ * @access public
+ */
+ function getKeyLength()
+ {
+ return $this->_key_len;
+ }
+
+ /**
+ * Returns modulus part of the key as binary string,
+ * which can be used to construct new Crypt_RSA_Key object.
+ *
+ * @return string modulus as binary string
+ * @access public
+ */
+ function getModulus()
+ {
+ return $this->_modulus;
+ }
+
+ /**
+ * Returns exponent part of the key as binary string,
+ * which can be used to construct new Crypt_RSA_Key object.
+ *
+ * @return string exponent as binary string
+ * @access public
+ */
+ function getExponent()
+ {
+ return $this->_exp;
+ }
+
+ /**
+ * Returns key type (public, private)
+ *
+ * @return string key type (public, private)
+ * @access public
+ */
+ function getKeyType()
+ {
+ return $this->_key_type;
+ }
+
+ /**
+ * Returns string representation of key
+ *
+ * @return string key, serialized to string
+ * @access public
+ */
+ function toString()
+ {
+ return base64_encode(
+ serialize(
+ array($this->_modulus, $this->_exp, $this->_key_type)
+ )
+ );
+ }
+
+ /**
+ * Returns Crypt_RSA_Key object, unserialized from
+ * string representation of key.
+ *
+ * optional parameter $wrapper_name - is the name of math wrapper,
+ * which will be used during unserialization of this object.
+ *
+ * This function can be called statically:
+ * $key = Crypt_RSA_Key::fromString($key_in_string, 'BigInt');
+ *
+ * @param string $key_str RSA key, serialized into string
+ * @param string $wrapper_name optional math wrapper name
+ *
+ * @return object key as Crypt_RSA_Key object
+ * @access public
+ * @static
+ */
+ function fromString($key_str, $wrapper_name = 'default')
+ {
+ list($modulus, $exponent, $key_type) = unserialize(base64_decode($key_str));
+ $obj = new Crypt_RSA_Key($modulus, $exponent, $key_type, $wrapper_name);
+ return $obj;
+ }
+
+ /**
+ * Validates key
+ * This function can be called statically:
+ * $is_valid = Crypt_RSA_Key::isValid($key)
+ *
+ * Returns true, if $key is valid Crypt_RSA key, else returns false
+ *
+ * @param object $key Crypt_RSA_Key object for validating
+ *
+ * @return bool true if $key is valid, else false
+ * @access public
+ */
+ function isValid($key)
+ {
+ return (is_object($key) && strtolower(get_class($key)) === strtolower(__CLASS__));
+ }
+}
+
+?>
diff --git a/mod/openid_server/Crypt/RSA/KeyPair.php b/mod/openid_server/Crypt/RSA/KeyPair.php
new file mode 100644
index 000000000..ecc0b7dc7
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/KeyPair.php
@@ -0,0 +1,804 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: KeyPair.php,v 1.7 2009/01/05 08:30:29 clockwerx Exp $
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * RSA error handling facilities
+ */
+require_once 'Crypt/RSA/ErrorHandler.php';
+
+/**
+ * loader for RSA math wrappers
+ */
+require_once 'Crypt/RSA/MathLoader.php';
+
+/**
+ * helper class for single key managing
+ */
+require_once 'Crypt/RSA/Key.php';
+
+/**
+ * Crypt_RSA_KeyPair class, derived from Crypt_RSA_ErrorHandler
+ *
+ * Provides the following functions:
+ * - generate($key) - generates new key pair
+ * - getPublicKey() - returns public key
+ * - getPrivateKey() - returns private key
+ * - getKeyLength() - returns bit key length
+ * - setRandomGenerator($func_name) - sets random generator to $func_name
+ * - fromPEMString($str) - retrieves keypair from PEM-encoded string
+ * - toPEMString() - stores keypair to PEM-encoded string
+ * - isEqual($keypair2) - compares current keypair to $keypair2
+ *
+ * Example usage:
+ * // create new 1024-bit key pair
+ * $key_pair = new Crypt_RSA_KeyPair(1024);
+ *
+ * // error check
+ * if ($key_pair->isError()) {
+ * echo "error while initializing Crypt_RSA_KeyPair object:\n";
+ * $erorr = $key_pair->getLastError();
+ * echo $error->getMessage(), "\n";
+ * }
+ *
+ * // get public key
+ * $public_key = $key_pair->getPublicKey();
+ *
+ * // get private key
+ * $private_key = $key_pair->getPrivateKey();
+ *
+ * // generate new 512-bit key pair
+ * $key_pair->generate(512);
+ *
+ * // error check
+ * if ($key_pair->isError()) {
+ * echo "error while generating key pair:\n";
+ * $erorr = $key_pair->getLastError();
+ * echo $error->getMessage(), "\n";
+ * }
+ *
+ * // get key pair length
+ * $length = $key_pair->getKeyLength();
+ *
+ * // set random generator to $func_name, where $func_name
+ * // consists name of random generator function. See comments
+ * // before setRandomGenerator() method for details
+ * $key_pair->setRandomGenerator($func_name);
+ *
+ * // error check
+ * if ($key_pair->isError()) {
+ * echo "error while changing random generator:\n";
+ * $erorr = $key_pair->getLastError();
+ * echo $error->getMessage(), "\n";
+ * }
+ *
+ * // using factory() method instead of constructor (it returns PEAR_Error object on failure)
+ * $rsa_obj = &Crypt_RSA_KeyPair::factory($key_len);
+ * if (PEAR::isError($rsa_obj)) {
+ * echo "error: ", $rsa_obj->getMessage(), "\n";
+ * }
+ *
+ * // read key pair from PEM-encoded string:
+ * $str = "-----BEGIN RSA PRIVATE KEY-----"
+ * . "MCsCAQACBHr5LDkCAwEAAQIEBc6jbQIDAOCfAgMAjCcCAk3pAgJMawIDAL41"
+ * . "-----END RSA PRIVATE KEY-----";
+ * $keypair = Crypt_RSA_KeyPair::fromPEMString($str);
+ *
+ * // read key pair from .pem file 'private.pem':
+ * $str = file_get_contents('private.pem');
+ * $keypair = Crypt_RSA_KeyPair::fromPEMString($str);
+ *
+ * // generate and write 1024-bit key pair to .pem file 'private_new.pem'
+ * $keypair = new Crypt_RSA_KeyPair(1024);
+ * $str = $keypair->toPEMString();
+ * file_put_contents('private_new.pem', $str);
+ *
+ * // compare $keypair1 to $keypair2
+ * if ($keypair1->isEqual($keypair2)) {
+ * echo "keypair1 = keypair2\n";
+ * }
+ * else {
+ * echo "keypair1 != keypair2\n";
+ * }
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @access public
+ */
+class Crypt_RSA_KeyPair extends Crypt_RSA_ErrorHandler
+{
+ /**
+ * Reference to math wrapper object, which is used to
+ * manipulate large integers in RSA algorithm.
+ *
+ * @var object of Crypt_RSA_Math_* class
+ * @access private
+ */
+ var $_math_obj;
+
+ /**
+ * length of each key in the key pair
+ *
+ * @var int
+ * @access private
+ */
+ var $_key_len;
+
+ /**
+ * public key
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_public_key;
+
+ /**
+ * private key
+ *
+ * @var object of Crypt_RSA_KEY class
+ * @access private
+ */
+ var $_private_key;
+
+ /**
+ * name of function, which is used as random generator
+ *
+ * @var string
+ * @access private
+ */
+ var $_random_generator;
+
+ /**
+ * RSA keypair attributes [version, n, e, d, p, q, dmp1, dmq1, iqmp] as associative array
+ *
+ * @var array
+ * @access private
+ */
+ var $_attrs;
+
+ /**
+ * Returns names of keypair attributes from $this->_attrs array
+ *
+ * @return array Array of keypair attributes names
+ * @access private
+ */
+ function _get_attr_names()
+ {
+ return array('version', 'n', 'e', 'd', 'p', 'q', 'dmp1', 'dmq1', 'iqmp');
+ }
+
+ /**
+ * Parses ASN.1 string [$str] starting form position [$pos].
+ * Returns tag and string value of parsed object.
+ *
+ * @param string $str
+ * @param int &$pos
+ * @param Crypt_RSA_ErrorHandler &$err_handler
+ *
+ * @return mixed Array('tag' => ..., 'str' => ...) on success, false on error
+ * @access private
+ */
+ function _ASN1Parse($str, &$pos, &$err_handler)
+ {
+ $max_pos = strlen($str);
+ if ($max_pos < 2) {
+ $err_handler->pushError("ASN.1 string too short");
+ return false;
+ }
+
+ // get ASN.1 tag value
+ $tag = ord($str[$pos++]) & 0x1f;
+ if ($tag == 0x1f) {
+ $tag = 0;
+ do {
+ $n = ord($str[$pos++]);
+ $tag <<= 7;
+ $tag |= $n & 0x7f;
+ } while (($n & 0x80) && $pos < $max_pos);
+ }
+ if ($pos >= $max_pos) {
+ $err_handler->pushError("ASN.1 string too short");
+ return false;
+ }
+
+ // get ASN.1 object length
+ $len = ord($str[$pos++]);
+ if ($len & 0x80) {
+ $n = $len & 0x1f;
+ $len = 0;
+ while ($n-- && $pos < $max_pos) {
+ $len <<= 8;
+ $len |= ord($str[$pos++]);
+ }
+ }
+ if ($pos >= $max_pos || $len > $max_pos - $pos) {
+ $err_handler->pushError("ASN.1 string too short");
+ return false;
+ }
+
+ // get string value of ASN.1 object
+ $str = substr($str, $pos, $len);
+
+ return array(
+ 'tag' => $tag,
+ 'str' => $str,
+ );
+ }
+
+ /**
+ * Parses ASN.1 sting [$str] starting from position [$pos].
+ * Returns string representation of number, which can be passed
+ * in bin2int() function of math wrapper.
+ *
+ * @param string $str
+ * @param int &$pos
+ * @param Crypt_RSA_ErrorHandler &$err_handler
+ *
+ * @return mixed string representation of parsed number on success, false on error
+ * @access private
+ */
+ function _ASN1ParseInt($str, &$pos, &$err_handler)
+ {
+ $tmp = Crypt_RSA_KeyPair::_ASN1Parse($str, $pos, $err_handler);
+ if ($err_handler->isError()) {
+ return false;
+ }
+ if ($tmp['tag'] != 0x02) {
+ $errstr = sprintf("wrong ASN tag value: 0x%02x. Expected 0x02 (INTEGER)", $tmp['tag']);
+ $err_handler->pushError($errstr);
+ return false;
+ }
+ $pos += strlen($tmp['str']);
+
+ return strrev($tmp['str']);
+ }
+
+ /**
+ * Constructs ASN.1 string from tag $tag and object $str
+ *
+ * @param string $str ASN.1 object string
+ * @param int $tag ASN.1 tag value
+ * @param bool $is_constructed
+ * @param bool $is_private
+ *
+ * @return ASN.1-encoded string
+ * @access private
+ */
+ function _ASN1Store($str, $tag, $is_constructed = false, $is_private = false)
+ {
+ $out = '';
+
+ // encode ASN.1 tag value
+ $tag_ext = ($is_constructed ? 0x20 : 0) | ($is_private ? 0xc0 : 0);
+ if ($tag < 0x1f) {
+ $out .= chr($tag | $tag_ext);
+ } else {
+ $out .= chr($tag_ext | 0x1f);
+ $tmp = chr($tag & 0x7f);
+ $tag >>= 7;
+ while ($tag) {
+ $tmp .= chr(($tag & 0x7f) | 0x80);
+ $tag >>= 7;
+ }
+ $out .= strrev($tmp);
+ }
+
+ // encode ASN.1 object length
+ $len = strlen($str);
+ if ($len < 0x7f) {
+ $out .= chr($len);
+ } else {
+ $tmp = '';
+ $n = 0;
+ while ($len) {
+ $tmp .= chr($len & 0xff);
+ $len >>= 8;
+ $n++;
+ }
+ $out .= chr($n | 0x80);
+ $out .= strrev($tmp);
+ }
+
+ return $out . $str;
+ }
+
+ /**
+ * Constructs ASN.1 string from binary representation of big integer
+ *
+ * @param string $str binary representation of big integer
+ *
+ * @return ASN.1-encoded string
+ * @access private
+ */
+ function _ASN1StoreInt($str)
+ {
+ $str = strrev($str);
+ return Crypt_RSA_KeyPair::_ASN1Store($str, 0x02);
+ }
+
+ /**
+ * Crypt_RSA_KeyPair constructor.
+ *
+ * Wrapper: name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ *
+ * @param int $key_len bit length of key pair, which will be generated in constructor
+ * @param string $wrapper_name wrapper name
+ * @param string $error_handler name of error handler function
+ * @param callback $random_generator function which will be used as random generator
+ *
+ * @access public
+ */
+ function Crypt_RSA_KeyPair($key_len, $wrapper_name = 'default', $error_handler = '', $random_generator = null)
+ {
+ // set error handler
+ $this->setErrorHandler($error_handler);
+ // try to load math wrapper
+ $obj = &Crypt_RSA_MathLoader::loadWrapper($wrapper_name);
+ if ($this->isError($obj)) {
+ // error during loading of math wrapper
+ $this->pushError($obj);
+ return;
+ }
+ $this->_math_obj = &$obj;
+
+ // set random generator
+ if (!$this->setRandomGenerator($random_generator)) {
+ // error in setRandomGenerator() function
+ return;
+ }
+
+ if (is_array($key_len)) {
+ // ugly BC hack - it is possible to pass RSA private key attributes [version, n, e, d, p, q, dmp1, dmq1, iqmp]
+ // as associative array instead of key length to Crypt_RSA_KeyPair constructor
+ $rsa_attrs = $key_len;
+
+ // convert attributes to big integers
+ $attr_names = $this->_get_attr_names();
+ foreach ($attr_names as $attr) {
+ if (!isset($rsa_attrs[$attr])) {
+ $this->pushError("missing required RSA attribute [$attr]");
+ return;
+ }
+ ${$attr} = $this->_math_obj->bin2int($rsa_attrs[$attr]);
+ }
+
+ // check primality of p and q
+ if (!$this->_math_obj->isPrime($p)) {
+ $this->pushError("[p] must be prime");
+ return;
+ }
+ if (!$this->_math_obj->isPrime($q)) {
+ $this->pushError("[q] must be prime");
+ return;
+ }
+
+ // check n = p * q
+ $n1 = $this->_math_obj->mul($p, $q);
+ if ($this->_math_obj->cmpAbs($n, $n1)) {
+ $this->pushError("n != p * q");
+ return;
+ }
+
+ // check e * d = 1 mod (p-1) * (q-1)
+ $p1 = $this->_math_obj->dec($p);
+ $q1 = $this->_math_obj->dec($q);
+ $p1q1 = $this->_math_obj->mul($p1, $q1);
+ $ed = $this->_math_obj->mul($e, $d);
+ $one = $this->_math_obj->mod($ed, $p1q1);
+ if (!$this->_math_obj->isOne($one)) {
+ $this->pushError("e * d != 1 mod (p-1)*(q-1)");
+ return;
+ }
+
+ // check dmp1 = d mod (p-1)
+ $dmp = $this->_math_obj->mod($d, $p1);
+ if ($this->_math_obj->cmpAbs($dmp, $dmp1)) {
+ $this->pushError("dmp1 != d mod (p-1)");
+ return;
+ }
+
+ // check dmq1 = d mod (q-1)
+ $dmq = $this->_math_obj->mod($d, $q1);
+ if ($this->_math_obj->cmpAbs($dmq, $dmq1)) {
+ $this->pushError("dmq1 != d mod (q-1)");
+ return;
+ }
+
+ // check iqmp = 1/q mod p
+ $q1 = $this->_math_obj->invmod($iqmp, $p);
+ if ($this->_math_obj->cmpAbs($q, $q1)) {
+ $this->pushError("iqmp != 1/q mod p");
+ return;
+ }
+
+ // try to create public key object
+ $public_key = &new Crypt_RSA_Key($rsa_attrs['n'], $rsa_attrs['e'], 'public', $wrapper_name, $error_handler);
+ if ($public_key->isError()) {
+ // error during creating public object
+ $this->pushError($public_key->getLastError());
+ return;
+ }
+
+ // try to create private key object
+ $private_key = &new Crypt_RSA_Key($rsa_attrs['n'], $rsa_attrs['d'], 'private', $wrapper_name, $error_handler);
+ if ($private_key->isError()) {
+ // error during creating private key object
+ $this->pushError($private_key->getLastError());
+ return;
+ }
+
+ $this->_public_key = $public_key;
+ $this->_private_key = $private_key;
+ $this->_key_len = $public_key->getKeyLength();
+ $this->_attrs = $rsa_attrs;
+ } else {
+ // generate key pair
+ if (!$this->generate($key_len)) {
+ // error during generating key pair
+ return;
+ }
+ }
+ }
+
+ /**
+ * Crypt_RSA_KeyPair factory.
+ *
+ * Wrapper - Name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ *
+ * @param int $key_len bit length of key pair, which will be generated in constructor
+ * @param string $wrapper_name wrapper name
+ * @param string $error_handler name of error handler function
+ * @param callback $random_generator function which will be used as random generator
+ *
+ * @return object new Crypt_RSA_KeyPair object on success or PEAR_Error object on failure
+ * @access public
+ */
+ function &factory($key_len, $wrapper_name = 'default', $error_handler = '', $random_generator = null)
+ {
+ $obj = &new Crypt_RSA_KeyPair($key_len, $wrapper_name, $error_handler, $random_generator);
+ if ($obj->isError()) {
+ // error during creating a new object. Return PEAR_Error object
+ return $obj->getLastError();
+ }
+ // object created successfully. Return it
+ return $obj;
+ }
+
+ /**
+ * Generates new Crypt_RSA key pair with length $key_len.
+ * If $key_len is missed, use an old key length from $this->_key_len
+ *
+ * @param int $key_len bit length of key pair, which will be generated
+ *
+ * @return bool true on success or false on error
+ * @access public
+ */
+ function generate($key_len = null)
+ {
+ if (is_null($key_len)) {
+ // use an old key length
+ $key_len = $this->_key_len;
+ if (is_null($key_len)) {
+ $this->pushError('missing key_len parameter', CRYPT_RSA_ERROR_MISSING_KEY_LEN);
+ return false;
+ }
+ }
+
+ // minimal key length is 8 bit ;)
+ if ($key_len < 8) {
+ $key_len = 8;
+ }
+ // store key length in the _key_len property
+ $this->_key_len = $key_len;
+
+ // set [e] to 0x10001 (65537)
+ $e = $this->_math_obj->bin2int("\x01\x00\x01");
+
+ // generate [p], [q] and [n]
+ $p_len = intval(($key_len + 1) / 2);
+ $q_len = $key_len - $p_len;
+ $p1 = $q1 = 0;
+ do {
+ // generate prime number [$p] with length [$p_len] with the following condition:
+ // GCD($e, $p - 1) = 1
+ do {
+ $p = $this->_math_obj->getPrime($p_len, $this->_random_generator);
+ $p1 = $this->_math_obj->dec($p);
+ $tmp = $this->_math_obj->GCD($e, $p1);
+ } while (!$this->_math_obj->isOne($tmp));
+ // generate prime number [$q] with length [$q_len] with the following conditions:
+ // GCD($e, $q - 1) = 1
+ // $q != $p
+ do {
+ $q = $this->_math_obj->getPrime($q_len, $this->_random_generator);
+ $q1 = $this->_math_obj->dec($q);
+ $tmp = $this->_math_obj->GCD($e, $q1);
+ } while (!$this->_math_obj->isOne($tmp) && !$this->_math_obj->cmpAbs($q, $p));
+ // if (p < q), then exchange them
+ if ($this->_math_obj->cmpAbs($p, $q) < 0) {
+ $tmp = $p;
+ $p = $q;
+ $q = $tmp;
+ $tmp = $p1;
+ $p1 = $q1;
+ $q1 = $tmp;
+ }
+ // calculate n = p * q
+ $n = $this->_math_obj->mul($p, $q);
+ } while ($this->_math_obj->bitLen($n) != $key_len);
+
+ // calculate d = 1/e mod (p - 1) * (q - 1)
+ $pq = $this->_math_obj->mul($p1, $q1);
+ $d = $this->_math_obj->invmod($e, $pq);
+
+ // calculate dmp1 = d mod (p - 1)
+ $dmp1 = $this->_math_obj->mod($d, $p1);
+
+ // calculate dmq1 = d mod (q - 1)
+ $dmq1 = $this->_math_obj->mod($d, $q1);
+
+ // calculate iqmp = 1/q mod p
+ $iqmp = $this->_math_obj->invmod($q, $p);
+
+ // store RSA keypair attributes
+ $this->_attrs = array(
+ 'version' => "\x00",
+ 'n' => $this->_math_obj->int2bin($n),
+ 'e' => $this->_math_obj->int2bin($e),
+ 'd' => $this->_math_obj->int2bin($d),
+ 'p' => $this->_math_obj->int2bin($p),
+ 'q' => $this->_math_obj->int2bin($q),
+ 'dmp1' => $this->_math_obj->int2bin($dmp1),
+ 'dmq1' => $this->_math_obj->int2bin($dmq1),
+ 'iqmp' => $this->_math_obj->int2bin($iqmp),
+ );
+
+ $n = $this->_attrs['n'];
+ $e = $this->_attrs['e'];
+ $d = $this->_attrs['d'];
+
+ // try to create public key object
+ $obj = &new Crypt_RSA_Key($n, $e, 'public', $this->_math_obj->getWrapperName(), $this->_error_handler);
+ if ($obj->isError()) {
+ // error during creating public object
+ $this->pushError($obj->getLastError());
+ return false;
+ }
+ $this->_public_key = &$obj;
+
+ // try to create private key object
+ $obj = &new Crypt_RSA_Key($n, $d, 'private', $this->_math_obj->getWrapperName(), $this->_error_handler);
+ if ($obj->isError()) {
+ // error during creating private key object
+ $this->pushError($obj->getLastError());
+ return false;
+ }
+ $this->_private_key = &$obj;
+
+ return true; // key pair successfully generated
+ }
+
+ /**
+ * Returns public key from the pair
+ *
+ * @return object public key object of class Crypt_RSA_Key
+ * @access public
+ */
+ function getPublicKey()
+ {
+ return $this->_public_key;
+ }
+
+ /**
+ * Returns private key from the pair
+ *
+ * @return object private key object of class Crypt_RSA_Key
+ * @access public
+ */
+ function getPrivateKey()
+ {
+ return $this->_private_key;
+ }
+
+ /**
+ * Sets name of random generator function for key generation.
+ * If parameter is skipped, then sets to default random generator.
+ *
+ * Random generator function must return integer with at least 8 lower
+ * significant bits, which will be used as random values.
+ *
+ * @param string $random_generator name of random generator function
+ *
+ * @return bool true on success or false on error
+ * @access public
+ */
+ function setRandomGenerator($random_generator = null)
+ {
+ static $default_random_generator = null;
+
+ if (is_string($random_generator)) {
+ // set user's random generator
+ if (!function_exists($random_generator)) {
+ $this->pushError("can't find random generator function with name [{$random_generator}]");
+ return false;
+ }
+ $this->_random_generator = $random_generator;
+ } else {
+ // set default random generator
+ $this->_random_generator = is_null($default_random_generator) ?
+ ($default_random_generator = create_function('', '$a=explode(" ",microtime());return(int)($a[0]*1000000);')) :
+ $default_random_generator;
+ }
+ return true;
+ }
+
+ /**
+ * Returns length of each key in the key pair
+ *
+ * @return int bit length of each key in key pair
+ * @access public
+ */
+ function getKeyLength()
+ {
+ return $this->_key_len;
+ }
+
+ /**
+ * Retrieves RSA keypair from PEM-encoded string, containing RSA private key.
+ * Example of such string:
+ * -----BEGIN RSA PRIVATE KEY-----
+ * MCsCAQACBHtvbSECAwEAAQIEeYrk3QIDAOF3AgMAjCcCAmdnAgJMawIDALEk
+ * -----END RSA PRIVATE KEY-----
+ *
+ * Wrapper: Name of math wrapper, which will be used to
+ * perform different operations with big integers.
+ * See contents of Crypt/RSA/Math folder for examples of wrappers.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details.
+ *
+ * @param string $str PEM-encoded string
+ * @param string $wrapper_name Wrapper name
+ * @param string $error_handler name of error handler function
+ *
+ * @return Crypt_RSA_KeyPair object on success, PEAR_Error object on error
+ * @access public
+ * @static
+ */
+ function &fromPEMString($str, $wrapper_name = 'default', $error_handler = '')
+ {
+ if (isset($this)) {
+ if ($wrapper_name == 'default') {
+ $wrapper_name = $this->_math_obj->getWrapperName();
+ }
+ if ($error_handler == '') {
+ $error_handler = $this->_error_handler;
+ }
+ }
+ $err_handler = &new Crypt_RSA_ErrorHandler;
+ $err_handler->setErrorHandler($error_handler);
+
+ // search for base64-encoded private key
+ if (!preg_match('/-----BEGIN RSA PRIVATE KEY-----([^-]+)-----END RSA PRIVATE KEY-----/', $str, $matches)) {
+ $err_handler->pushError("can't find RSA private key in the string [{$str}]");
+ return $err_handler->getLastError();
+ }
+
+ // parse private key. It is ASN.1-encoded
+ $str = base64_decode($matches[1]);
+ $pos = 0;
+ $tmp = Crypt_RSA_KeyPair::_ASN1Parse($str, $pos, $err_handler);
+ if ($err_handler->isError()) {
+ return $err_handler->getLastError();
+ }
+ if ($tmp['tag'] != 0x10) {
+ $errstr = sprintf("wrong ASN tag value: 0x%02x. Expected 0x10 (SEQUENCE)", $tmp['tag']);
+ $err_handler->pushError($errstr);
+ return $err_handler->getLastError();
+ }
+
+ // parse ASN.1 SEQUENCE for RSA private key
+ $attr_names = Crypt_RSA_KeyPair::_get_attr_names();
+ $n = sizeof($attr_names);
+ $rsa_attrs = array();
+ for ($i = 0; $i < $n; $i++) {
+ $tmp = Crypt_RSA_KeyPair::_ASN1ParseInt($str, $pos, $err_handler);
+ if ($err_handler->isError()) {
+ return $err_handler->getLastError();
+ }
+ $attr = $attr_names[$i];
+ $rsa_attrs[$attr] = $tmp;
+ }
+
+ // create Crypt_RSA_KeyPair object.
+ $keypair = &new Crypt_RSA_KeyPair($rsa_attrs, $wrapper_name, $error_handler);
+ if ($keypair->isError()) {
+ return $keypair->getLastError();
+ }
+
+ return $keypair;
+ }
+
+ /**
+ * converts keypair to PEM-encoded string, which can be stroed in
+ * .pem compatible files, contianing RSA private key.
+ *
+ * @return string PEM-encoded keypair on success, false on error
+ * @access public
+ */
+ function toPEMString()
+ {
+ // store RSA private key attributes into ASN.1 string
+ $str = '';
+ $attr_names = $this->_get_attr_names();
+ $n = sizeof($attr_names);
+ $rsa_attrs = $this->_attrs;
+ for ($i = 0; $i < $n; $i++) {
+ $attr = $attr_names[$i];
+ if (!isset($rsa_attrs[$attr])) {
+ $this->pushError("Cannot find value for ASN.1 attribute [$attr]");
+ return false;
+ }
+ $tmp = $rsa_attrs[$attr];
+ $str .= Crypt_RSA_KeyPair::_ASN1StoreInt($tmp);
+ }
+
+ // prepend $str by ASN.1 SEQUENCE (0x10) header
+ $str = Crypt_RSA_KeyPair::_ASN1Store($str, 0x10, true);
+
+ // encode and format PEM string
+ $str = base64_encode($str);
+ $str = chunk_split($str, 64, "\n");
+ return "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
+ }
+
+ /**
+ * Compares keypairs in Crypt_RSA_KeyPair objects $this and $key_pair
+ *
+ * @param Crypt_RSA_KeyPair $key_pair keypair to compare
+ *
+ * @return bool true, if keypair stored in $this equal to keypair stored in $key_pair
+ * @access public
+ */
+ function isEqual($key_pair)
+ {
+ $attr_names = $this->_get_attr_names();
+ foreach ($attr_names as $attr) {
+ if ($this->_attrs[$attr] != $key_pair->_attrs[$attr]) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+?>
diff --git a/mod/openid_server/Crypt/RSA/Math/BCMath.php b/mod/openid_server/Crypt/RSA/Math/BCMath.php
new file mode 100644
index 000000000..646ff6710
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/Math/BCMath.php
@@ -0,0 +1,482 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version 1.2.0b
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * Crypt_RSA_Math_BCMath class.
+ *
+ * Provides set of math functions, which are used by Crypt_RSA package
+ * This class is a wrapper for PHP BCMath extension.
+ * See http://php.net/manual/en/ref.bc.php for details.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_RSA_Math_BCMath
+{
+ /**
+ * error description
+ *
+ * @var string
+ * @access public
+ */
+ var $errstr = '';
+
+ /**
+ * Performs Miller-Rabin primality test for number $num
+ * with base $base. Returns true, if $num is strong pseudoprime
+ * by base $base. Else returns false.
+ *
+ * @param string $num
+ * @param string $base
+ * @return bool
+ * @access private
+ */
+ function _millerTest($num, $base)
+ {
+ if (!bccomp($num, '1')) {
+ // 1 is not prime ;)
+ return false;
+ }
+ $tmp = bcsub($num, '1');
+
+ $zero_bits = 0;
+ while (!bccomp(bcmod($tmp, '2'), '0')) {
+ $zero_bits++;
+ $tmp = bcdiv($tmp, '2');
+ }
+
+ $tmp = $this->powmod($base, $tmp, $num);
+ if (!bccomp($tmp, '1')) {
+ // $num is probably prime
+ return true;
+ }
+
+ while ($zero_bits--) {
+ if (!bccomp(bcadd($tmp, '1'), $num)) {
+ // $num is probably prime
+ return true;
+ }
+ $tmp = $this->powmod($tmp, '2', $num);
+ }
+ // $num is composite
+ return false;
+ }
+
+ /**
+ * Crypt_RSA_Math_BCMath constructor.
+ * Checks an existance of PHP BCMath extension.
+ * On failure saves error description in $this->errstr
+ *
+ * @access public
+ */
+ function Crypt_RSA_Math_BCMath()
+ {
+ if (!extension_loaded('bcmath')) {
+ if (!@dl('bcmath.' . PHP_SHLIB_SUFFIX) && !@dl('php_bcmath.' . PHP_SHLIB_SUFFIX)) {
+ // cannot load BCMath extension. Set error string
+ $this->errstr = 'Crypt_RSA package requires the BCMath extension. See http://php.net/manual/en/ref.bc.php for details';
+ return;
+ }
+ }
+ }
+
+ /**
+ * Transforms binary representation of large integer into its native form.
+ *
+ * Example of transformation:
+ * $str = "\x12\x34\x56\x78\x90";
+ * $num = 0x9078563412;
+ *
+ * @param string $str
+ * @return string
+ * @access public
+ */
+ function bin2int($str)
+ {
+ $result = '0';
+ $n = strlen($str);
+ do {
+ $result = bcadd(bcmul($result, '256'), ord($str{--$n}));
+ } while ($n > 0);
+ return $result;
+ }
+
+ /**
+ * Transforms large integer into binary representation.
+ *
+ * Example of transformation:
+ * $num = 0x9078563412;
+ * $str = "\x12\x34\x56\x78\x90";
+ *
+ * @param string $num
+ * @return string
+ * @access public
+ */
+ function int2bin($num)
+ {
+ $result = '';
+ do {
+ $result .= chr(bcmod($num, '256'));
+ $num = bcdiv($num, '256');
+ } while (bccomp($num, '0'));
+ return $result;
+ }
+
+ /**
+ * Calculates pow($num, $pow) (mod $mod)
+ *
+ * @param string $num
+ * @param string $pow
+ * @param string $mod
+ * @return string
+ * @access public
+ */
+ function powmod($num, $pow, $mod)
+ {
+ if (function_exists('bcpowmod')) {
+ // bcpowmod is only available under PHP5
+ return bcpowmod($num, $pow, $mod);
+ }
+
+ // emulate bcpowmod
+ $result = '1';
+ do {
+ if (!bccomp(bcmod($pow, '2'), '1')) {
+ $result = bcmod(bcmul($result, $num), $mod);
+ }
+ $num = bcmod(bcpow($num, '2'), $mod);
+ $pow = bcdiv($pow, '2');
+ } while (bccomp($pow, '0'));
+ return $result;
+ }
+
+ /**
+ * Calculates $num1 * $num2
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return string
+ * @access public
+ */
+ function mul($num1, $num2)
+ {
+ return bcmul($num1, $num2);
+ }
+
+ /**
+ * Calculates $num1 % $num2
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return string
+ * @access public
+ */
+ function mod($num1, $num2)
+ {
+ return bcmod($num1, $num2);
+ }
+
+ /**
+ * Compares abs($num1) to abs($num2).
+ * Returns:
+ * -1, if abs($num1) < abs($num2)
+ * 0, if abs($num1) == abs($num2)
+ * 1, if abs($num1) > abs($num2)
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return int
+ * @access public
+ */
+ function cmpAbs($num1, $num2)
+ {
+ return bccomp($num1, $num2);
+ }
+
+ /**
+ * Tests $num on primality. Returns true, if $num is strong pseudoprime.
+ * Else returns false.
+ *
+ * @param string $num
+ * @return bool
+ * @access private
+ */
+ function isPrime($num)
+ {
+ static $primes = null;
+ static $primes_cnt = 0;
+ if (is_null($primes)) {
+ // generate all primes up to 10000
+ $primes = array();
+ for ($i = 0; $i < 10000; $i++) {
+ $primes[] = $i;
+ }
+ $primes[0] = $primes[1] = 0;
+ for ($i = 2; $i < 100; $i++) {
+ while (!$primes[$i]) {
+ $i++;
+ }
+ $j = $i;
+ for ($j += $i; $j < 10000; $j += $i) {
+ $primes[$j] = 0;
+ }
+ }
+ $j = 0;
+ for ($i = 0; $i < 10000; $i++) {
+ if ($primes[$i]) {
+ $primes[$j++] = $primes[$i];
+ }
+ }
+ $primes_cnt = $j;
+ }
+
+ // try to divide number by small primes
+ for ($i = 0; $i < $primes_cnt; $i++) {
+ if (bccomp($num, $primes[$i]) <= 0) {
+ // number is prime
+ return true;
+ }
+ if (!bccomp(bcmod($num, $primes[$i]), '0')) {
+ // number divides by $primes[$i]
+ return false;
+ }
+ }
+
+ /*
+ try Miller-Rabin's probable-primality test for first
+ 7 primes as bases
+ */
+ for ($i = 0; $i < 7; $i++) {
+ if (!$this->_millerTest($num, $primes[$i])) {
+ // $num is composite
+ return false;
+ }
+ }
+ // $num is strong pseudoprime
+ return true;
+ }
+
+ /**
+ * Generates prime number with length $bits_cnt
+ * using $random_generator as random generator function.
+ *
+ * @param int $bits_cnt
+ * @param string $rnd_generator
+ * @access public
+ */
+ function getPrime($bits_cnt, $random_generator)
+ {
+ $bytes_n = intval($bits_cnt / 8);
+ $bits_n = $bits_cnt % 8;
+ do {
+ $str = '';
+ for ($i = 0; $i < $bytes_n; $i++) {
+ $str .= chr(call_user_func($random_generator) & 0xff);
+ }
+ $n = call_user_func($random_generator) & 0xff;
+ $n |= 0x80;
+ $n >>= 8 - $bits_n;
+ $str .= chr($n);
+ $num = $this->bin2int($str);
+
+ // search for the next closest prime number after [$num]
+ if (!bccomp(bcmod($num, '2'), '0')) {
+ $num = bcadd($num, '1');
+ }
+ while (!$this->isPrime($num)) {
+ $num = bcadd($num, '2');
+ }
+ } while ($this->bitLen($num) != $bits_cnt);
+ return $num;
+ }
+
+ /**
+ * Calculates $num - 1
+ *
+ * @param string $num
+ * @return string
+ * @access public
+ */
+ function dec($num)
+ {
+ return bcsub($num, '1');
+ }
+
+ /**
+ * Returns true, if $num is equal to one. Else returns false
+ *
+ * @param string $num
+ * @return bool
+ * @access public
+ */
+ function isOne($num)
+ {
+ return !bccomp($num, '1');
+ }
+
+ /**
+ * Finds greatest common divider (GCD) of $num1 and $num2
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return string
+ * @access public
+ */
+ function GCD($num1, $num2)
+ {
+ do {
+ $tmp = bcmod($num1, $num2);
+ $num1 = $num2;
+ $num2 = $tmp;
+ } while (bccomp($num2, '0'));
+ return $num1;
+ }
+
+ /**
+ * Finds inverse number $inv for $num by modulus $mod, such as:
+ * $inv * $num = 1 (mod $mod)
+ *
+ * @param string $num
+ * @param string $mod
+ * @return string
+ * @access public
+ */
+ function invmod($num, $mod)
+ {
+ $x = '1';
+ $y = '0';
+ $num1 = $mod;
+ do {
+ $tmp = bcmod($num, $num1);
+ $q = bcdiv($num, $num1);
+ $num = $num1;
+ $num1 = $tmp;
+
+ $tmp = bcsub($x, bcmul($y, $q));
+ $x = $y;
+ $y = $tmp;
+ } while (bccomp($num1, '0'));
+ if (bccomp($x, '0') < 0) {
+ $x = bcadd($x, $mod);
+ }
+ return $x;
+ }
+
+ /**
+ * Returns bit length of number $num
+ *
+ * @param string $num
+ * @return int
+ * @access public
+ */
+ function bitLen($num)
+ {
+ $tmp = $this->int2bin($num);
+ $bit_len = strlen($tmp) * 8;
+ $tmp = ord($tmp{strlen($tmp) - 1});
+ if (!$tmp) {
+ $bit_len -= 8;
+ }
+ else {
+ while (!($tmp & 0x80)) {
+ $bit_len--;
+ $tmp <<= 1;
+ }
+ }
+ return $bit_len;
+ }
+
+ /**
+ * Calculates bitwise or of $num1 and $num2,
+ * starting from bit $start_pos for number $num1
+ *
+ * @param string $num1
+ * @param string $num2
+ * @param int $start_pos
+ * @return string
+ * @access public
+ */
+ function bitOr($num1, $num2, $start_pos)
+ {
+ $start_byte = intval($start_pos / 8);
+ $start_bit = $start_pos % 8;
+ $tmp1 = $this->int2bin($num1);
+
+ $num2 = bcmul($num2, 1 << $start_bit);
+ $tmp2 = $this->int2bin($num2);
+ if ($start_byte < strlen($tmp1)) {
+ $tmp2 |= substr($tmp1, $start_byte);
+ $tmp1 = substr($tmp1, 0, $start_byte) . $tmp2;
+ }
+ else {
+ $tmp1 = str_pad($tmp1, $start_byte, "\0") . $tmp2;
+ }
+ return $this->bin2int($tmp1);
+ }
+
+ /**
+ * Returns part of number $num, starting at bit
+ * position $start with length $length
+ *
+ * @param string $num
+ * @param int start
+ * @param int length
+ * @return string
+ * @access public
+ */
+ function subint($num, $start, $length)
+ {
+ $start_byte = intval($start / 8);
+ $start_bit = $start % 8;
+ $byte_length = intval($length / 8);
+ $bit_length = $length % 8;
+ if ($bit_length) {
+ $byte_length++;
+ }
+ $num = bcdiv($num, 1 << $start_bit);
+ $tmp = substr($this->int2bin($num), $start_byte, $byte_length);
+ $tmp = str_pad($tmp, $byte_length, "\0");
+ $tmp = substr_replace($tmp, $tmp{$byte_length - 1} & chr(0xff >> (8 - $bit_length)), $byte_length - 1, 1);
+ return $this->bin2int($tmp);
+ }
+
+ /**
+ * Returns name of current wrapper
+ *
+ * @return string name of current wrapper
+ * @access public
+ */
+ function getWrapperName()
+ {
+ return 'BCMath';
+ }
+}
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/Crypt/RSA/Math/BigInt.php b/mod/openid_server/Crypt/RSA/Math/BigInt.php
new file mode 100644
index 000000000..b7ac24cb6
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/Math/BigInt.php
@@ -0,0 +1,313 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version 1.2.0b
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * Crypt_RSA_Math_BigInt class.
+ *
+ * Provides set of math functions, which are used by Crypt_RSA package
+ * This class is a wrapper for big_int PECL extension,
+ * which could be loaded from http://pecl.php.net/packages/big_int
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_RSA_Math_BigInt
+{
+ /**
+ * error description
+ *
+ * @var string
+ * @access public
+ */
+ var $errstr = '';
+
+ /**
+ * Crypt_RSA_Math_BigInt constructor.
+ * Checks an existance of big_int PECL math package.
+ * This package is available at http://pecl.php.net/packages/big_int
+ * On failure saves error description in $this->errstr
+ *
+ * @access public
+ */
+ function Crypt_RSA_Math_BigInt()
+ {
+ if (!extension_loaded('big_int')) {
+ if (!@dl('big_int.' . PHP_SHLIB_SUFFIX) && !@dl('php_big_int.' . PHP_SHLIB_SUFFIX)) {
+ // cannot load big_int extension
+ $this->errstr = 'Crypt_RSA package requires big_int PECL package. ' .
+ 'It is available at http://pecl.php.net/packages/big_int';
+ return;
+ }
+ }
+
+ // check version of big_int extension ( Crypt_RSA requires version 1.0.2 and higher )
+ if (!in_array('bi_info', get_extension_funcs('big_int'))) {
+ // there is no bi_info() function in versions, older than 1.0.2
+ $this->errstr = 'Crypt_RSA package requires big_int package version 1.0.2 and higher';
+ }
+ }
+
+ /**
+ * Transforms binary representation of large integer into its native form.
+ *
+ * Example of transformation:
+ * $str = "\x12\x34\x56\x78\x90";
+ * $num = 0x9078563412;
+ *
+ * @param string $str
+ * @return big_int resource
+ * @access public
+ */
+ function bin2int($str)
+ {
+ return bi_unserialize($str);
+ }
+
+ /**
+ * Transforms large integer into binary representation.
+ *
+ * Example of transformation:
+ * $num = 0x9078563412;
+ * $str = "\x12\x34\x56\x78\x90";
+ *
+ * @param big_int resource $num
+ * @return string
+ * @access public
+ */
+ function int2bin($num)
+ {
+ return bi_serialize($num);
+ }
+
+ /**
+ * Calculates pow($num, $pow) (mod $mod)
+ *
+ * @param big_int resource $num
+ * @param big_int resource $pow
+ * @param big_int resource $mod
+ * @return big_int resource
+ * @access public
+ */
+ function powmod($num, $pow, $mod)
+ {
+ return bi_powmod($num, $pow, $mod);
+ }
+
+ /**
+ * Calculates $num1 * $num2
+ *
+ * @param big_int resource $num1
+ * @param big_int resource $num2
+ * @return big_int resource
+ * @access public
+ */
+ function mul($num1, $num2)
+ {
+ return bi_mul($num1, $num2);
+ }
+
+ /**
+ * Calculates $num1 % $num2
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return string
+ * @access public
+ */
+ function mod($num1, $num2)
+ {
+ return bi_mod($num1, $num2);
+ }
+
+ /**
+ * Compares abs($num1) to abs($num2).
+ * Returns:
+ * -1, if abs($num1) < abs($num2)
+ * 0, if abs($num1) == abs($num2)
+ * 1, if abs($num1) > abs($num2)
+ *
+ * @param big_int resource $num1
+ * @param big_int resource $num2
+ * @return int
+ * @access public
+ */
+ function cmpAbs($num1, $num2)
+ {
+ return bi_cmp_abs($num1, $num2);
+ }
+
+ /**
+ * Tests $num on primality. Returns true, if $num is strong pseudoprime.
+ * Else returns false.
+ *
+ * @param string $num
+ * @return bool
+ * @access private
+ */
+ function isPrime($num)
+ {
+ return bi_is_prime($num) ? true : false;
+ }
+
+ /**
+ * Generates prime number with length $bits_cnt
+ * using $random_generator as random generator function.
+ *
+ * @param int $bits_cnt
+ * @param string $rnd_generator
+ * @access public
+ */
+ function getPrime($bits_cnt, $random_generator)
+ {
+ $bytes_n = intval($bits_cnt / 8);
+ $bits_n = $bits_cnt % 8;
+ do {
+ $str = '';
+ for ($i = 0; $i < $bytes_n; $i++) {
+ $str .= chr(call_user_func($random_generator) & 0xff);
+ }
+ $n = call_user_func($random_generator) & 0xff;
+ $n |= 0x80;
+ $n >>= 8 - $bits_n;
+ $str .= chr($n);
+ $num = $this->bin2int($str);
+
+ // search for the next closest prime number after [$num]
+ $num = bi_next_prime($num);
+ } while ($this->bitLen($num) != $bits_cnt);
+ return $num;
+ }
+
+ /**
+ * Calculates $num - 1
+ *
+ * @param big_int resource $num
+ * @return big_int resource
+ * @access public
+ */
+ function dec($num)
+ {
+ return bi_dec($num);
+ }
+
+ /**
+ * Returns true, if $num is equal to 1. Else returns false
+ *
+ * @param big_int resource $num
+ * @return bool
+ * @access public
+ */
+ function isOne($num)
+ {
+ return bi_is_one($num);
+ }
+
+ /**
+ * Finds greatest common divider (GCD) of $num1 and $num2
+ *
+ * @param big_int resource $num1
+ * @param big_int resource $num2
+ * @return big_int resource
+ * @access public
+ */
+ function GCD($num1, $num2)
+ {
+ return bi_gcd($num1, $num2);
+ }
+
+ /**
+ * Finds inverse number $inv for $num by modulus $mod, such as:
+ * $inv * $num = 1 (mod $mod)
+ *
+ * @param big_int resource $num
+ * @param big_int resource $mod
+ * @return big_int resource
+ * @access public
+ */
+ function invmod($num, $mod)
+ {
+ return bi_invmod($num, $mod);
+ }
+
+ /**
+ * Returns bit length of number $num
+ *
+ * @param big_int resource $num
+ * @return int
+ * @access public
+ */
+ function bitLen($num)
+ {
+ return bi_bit_len($num);
+ }
+
+ /**
+ * Calculates bitwise or of $num1 and $num2,
+ * starting from bit $start_pos for number $num1
+ *
+ * @param big_int resource $num1
+ * @param big_int resource $num2
+ * @param int $start_pos
+ * @return big_int resource
+ * @access public
+ */
+ function bitOr($num1, $num2, $start_pos)
+ {
+ return bi_or($num1, $num2, $start_pos);
+ }
+
+ /**
+ * Returns part of number $num, starting at bit
+ * position $start with length $length
+ *
+ * @param big_int resource $num
+ * @param int start
+ * @param int length
+ * @return big_int resource
+ * @access public
+ */
+ function subint($num, $start, $length)
+ {
+ return bi_subint($num, $start, $length);
+ }
+
+ /**
+ * Returns name of current wrapper
+ *
+ * @return string name of current wrapper
+ * @access public
+ */
+ function getWrapperName()
+ {
+ return 'BigInt';
+ }
+}
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/Crypt/RSA/Math/GMP.php b/mod/openid_server/Crypt/RSA/Math/GMP.php
new file mode 100644
index 000000000..54e4c34fc
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/Math/GMP.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version 1.2.0b
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * Crypt_RSA_Math_GMP class.
+ *
+ * Provides set of math functions, which are used by Crypt_RSA package
+ * This class is a wrapper for PHP GMP extension.
+ * See http://php.net/gmp for details.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright 2005, 2006 Alexander Valyalkin
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @version @package_version@
+ * @access public
+ */
+class Crypt_RSA_Math_GMP
+{
+ /**
+ * error description
+ *
+ * @var string
+ * @access public
+ */
+ var $errstr = '';
+
+ /**
+ * Crypt_RSA_Math_GMP constructor.
+ * Checks an existance of PHP GMP package.
+ * See http://php.net/gmp for details.
+ *
+ * On failure saves error description in $this->errstr
+ *
+ * @access public
+ */
+ function Crypt_RSA_Math_GMP()
+ {
+ if (!extension_loaded('gmp')) {
+ if (!@dl('gmp.' . PHP_SHLIB_SUFFIX) && !@dl('php_gmp.' . PHP_SHLIB_SUFFIX)) {
+ // cannot load GMP extension
+ $this->errstr = 'Crypt_RSA package requires PHP GMP package. ' .
+ 'See http://php.net/gmp for details';
+ return;
+ }
+ }
+ }
+
+ /**
+ * Transforms binary representation of large integer into its native form.
+ *
+ * Example of transformation:
+ * $str = "\x12\x34\x56\x78\x90";
+ * $num = 0x9078563412;
+ *
+ * @param string $str
+ * @return gmp resource
+ * @access public
+ */
+ function bin2int($str)
+ {
+ $result = 0;
+ $n = strlen($str);
+ do {
+ // dirty hack: GMP returns FALSE, when second argument equals to int(0).
+ // so, it must be converted to string '0'
+ $result = gmp_add(gmp_mul($result, 256), strval(ord($str{--$n})));
+ } while ($n > 0);
+ return $result;
+ }
+
+ /**
+ * Transforms large integer into binary representation.
+ *
+ * Example of transformation:
+ * $num = 0x9078563412;
+ * $str = "\x12\x34\x56\x78\x90";
+ *
+ * @param gmp resource $num
+ * @return string
+ * @access public
+ */
+ function int2bin($num)
+ {
+ $result = '';
+ do {
+ $result .= chr(gmp_intval(gmp_mod($num, 256)));
+ $num = gmp_div($num, 256);
+ } while (gmp_cmp($num, 0));
+ return $result;
+ }
+
+ /**
+ * Calculates pow($num, $pow) (mod $mod)
+ *
+ * @param gmp resource $num
+ * @param gmp resource $pow
+ * @param gmp resource $mod
+ * @return gmp resource
+ * @access public
+ */
+ function powmod($num, $pow, $mod)
+ {
+ return gmp_powm($num, $pow, $mod);
+ }
+
+ /**
+ * Calculates $num1 * $num2
+ *
+ * @param gmp resource $num1
+ * @param gmp resource $num2
+ * @return gmp resource
+ * @access public
+ */
+ function mul($num1, $num2)
+ {
+ return gmp_mul($num1, $num2);
+ }
+
+ /**
+ * Calculates $num1 % $num2
+ *
+ * @param string $num1
+ * @param string $num2
+ * @return string
+ * @access public
+ */
+ function mod($num1, $num2)
+ {
+ return gmp_mod($num1, $num2);
+ }
+
+ /**
+ * Compares abs($num1) to abs($num2).
+ * Returns:
+ * -1, if abs($num1) < abs($num2)
+ * 0, if abs($num1) == abs($num2)
+ * 1, if abs($num1) > abs($num2)
+ *
+ * @param gmp resource $num1
+ * @param gmp resource $num2
+ * @return int
+ * @access public
+ */
+ function cmpAbs($num1, $num2)
+ {
+ return gmp_cmp($num1, $num2);
+ }
+
+ /**
+ * Tests $num on primality. Returns true, if $num is strong pseudoprime.
+ * Else returns false.
+ *
+ * @param string $num
+ * @return bool
+ * @access private
+ */
+ function isPrime($num)
+ {
+ return gmp_prob_prime($num) ? true : false;
+ }
+
+ /**
+ * Generates prime number with length $bits_cnt
+ * using $random_generator as random generator function.
+ *
+ * @param int $bits_cnt
+ * @param string $rnd_generator
+ * @access public
+ */
+ function getPrime($bits_cnt, $random_generator)
+ {
+ $bytes_n = intval($bits_cnt / 8);
+ $bits_n = $bits_cnt % 8;
+ do {
+ $str = '';
+ for ($i = 0; $i < $bytes_n; $i++) {
+ $str .= chr(call_user_func($random_generator) & 0xff);
+ }
+ $n = call_user_func($random_generator) & 0xff;
+ $n |= 0x80;
+ $n >>= 8 - $bits_n;
+ $str .= chr($n);
+ $num = $this->bin2int($str);
+
+ // search for the next closest prime number after [$num]
+ if (!gmp_cmp(gmp_mod($num, '2'), '0')) {
+ $num = gmp_add($num, '1');
+ }
+ while (!gmp_prob_prime($num)) {
+ $num = gmp_add($num, '2');
+ }
+ } while ($this->bitLen($num) != $bits_cnt);
+ return $num;
+ }
+
+ /**
+ * Calculates $num - 1
+ *
+ * @param gmp resource $num
+ * @return gmp resource
+ * @access public
+ */
+ function dec($num)
+ {
+ return gmp_sub($num, 1);
+ }
+
+ /**
+ * Returns true, if $num is equal to one. Else returns false
+ *
+ * @param gmp resource $num
+ * @return bool
+ * @access public
+ */
+ function isOne($num)
+ {
+ return !gmp_cmp($num, 1);
+ }
+
+ /**
+ * Finds greatest common divider (GCD) of $num1 and $num2
+ *
+ * @param gmp resource $num1
+ * @param gmp resource $num2
+ * @return gmp resource
+ * @access public
+ */
+ function GCD($num1, $num2)
+ {
+ return gmp_gcd($num1, $num2);
+ }
+
+ /**
+ * Finds inverse number $inv for $num by modulus $mod, such as:
+ * $inv * $num = 1 (mod $mod)
+ *
+ * @param gmp resource $num
+ * @param gmp resource $mod
+ * @return gmp resource
+ * @access public
+ */
+ function invmod($num, $mod)
+ {
+ return gmp_invert($num, $mod);
+ }
+
+ /**
+ * Returns bit length of number $num
+ *
+ * @param gmp resource $num
+ * @return int
+ * @access public
+ */
+ function bitLen($num)
+ {
+ $tmp = $this->int2bin($num);
+ $bit_len = strlen($tmp) * 8;
+ $tmp = ord($tmp{strlen($tmp) - 1});
+ if (!$tmp) {
+ $bit_len -= 8;
+ }
+ else {
+ while (!($tmp & 0x80)) {
+ $bit_len--;
+ $tmp <<= 1;
+ }
+ }
+ return $bit_len;
+ }
+
+ /**
+ * Calculates bitwise or of $num1 and $num2,
+ * starting from bit $start_pos for number $num1
+ *
+ * @param gmp resource $num1
+ * @param gmp resource $num2
+ * @param int $start_pos
+ * @return gmp resource
+ * @access public
+ */
+ function bitOr($num1, $num2, $start_pos)
+ {
+ $start_byte = intval($start_pos / 8);
+ $start_bit = $start_pos % 8;
+ $tmp1 = $this->int2bin($num1);
+
+ $num2 = gmp_mul($num2, 1 << $start_bit);
+ $tmp2 = $this->int2bin($num2);
+ if ($start_byte < strlen($tmp1)) {
+ $tmp2 |= substr($tmp1, $start_byte);
+ $tmp1 = substr($tmp1, 0, $start_byte) . $tmp2;
+ }
+ else {
+ $tmp1 = str_pad($tmp1, $start_byte, "\0") . $tmp2;
+ }
+ return $this->bin2int($tmp1);
+ }
+
+ /**
+ * Returns part of number $num, starting at bit
+ * position $start with length $length
+ *
+ * @param gmp resource $num
+ * @param int start
+ * @param int length
+ * @return gmp resource
+ * @access public
+ */
+ function subint($num, $start, $length)
+ {
+ $start_byte = intval($start / 8);
+ $start_bit = $start % 8;
+ $byte_length = intval($length / 8);
+ $bit_length = $length % 8;
+ if ($bit_length) {
+ $byte_length++;
+ }
+ $num = gmp_div($num, 1 << $start_bit);
+ $tmp = substr($this->int2bin($num), $start_byte, $byte_length);
+ $tmp = str_pad($tmp, $byte_length, "\0");
+ $tmp = substr_replace($tmp, $tmp{$byte_length - 1} & chr(0xff >> (8 - $bit_length)), $byte_length - 1, 1);
+ return $this->bin2int($tmp);
+ }
+
+ /**
+ * Returns name of current wrapper
+ *
+ * @return string name of current wrapper
+ * @access public
+ */
+ function getWrapperName()
+ {
+ return 'GMP';
+ }
+}
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/Crypt/RSA/MathLoader.php b/mod/openid_server/Crypt/RSA/MathLoader.php
new file mode 100644
index 000000000..de6c94642
--- /dev/null
+++ b/mod/openid_server/Crypt/RSA/MathLoader.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Crypt_RSA allows to do following operations:
+ * - key pair generation
+ * - encryption and decryption
+ * - signing and sign validation
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright Alexander Valyalkin 2005
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id: MathLoader.php,v 1.5 2009/01/05 08:30:29 clockwerx Exp $
+ * @link http://pear.php.net/package/Crypt_RSA
+ */
+
+/**
+ * RSA error handling facilities
+ */
+require_once 'Crypt/RSA/ErrorHandler.php';
+
+/**
+ * Crypt_RSA_MathLoader class.
+ *
+ * Provides static function:
+ * - loadWrapper($wrapper_name) - loads RSA math wrapper with name $wrapper_name
+ * or most suitable wrapper if $wrapper_name == 'default'
+ *
+ * Example usage:
+ * // load BigInt wrapper
+ * $big_int_wrapper = Crypt_RSA_MathLoader::loadWrapper('BigInt');
+ *
+ * // load BCMath wrapper
+ * $bcmath_wrapper = Crypt_RSA_MathLoader::loadWrapper('BCMath');
+ *
+ * // load the most suitable wrapper
+ * $bcmath_wrapper = Crypt_RSA_MathLoader::loadWrapper();
+ *
+ * @category Encryption
+ * @package Crypt_RSA
+ * @author Alexander Valyalkin <valyala@gmail.com>
+ * @copyright Alexander Valyalkin 2005
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/Crypt_RSA
+ * @access public
+ */
+class Crypt_RSA_MathLoader
+{
+ /**
+ * Loads RSA math wrapper with name $wrapper_name.
+ * Implemented wrappers can be found at Crypt/RSA/Math folder.
+ * Read docs/Crypt_RSA/docs/math_wrappers.txt for details
+ *
+ * This is a static function:
+ * // load BigInt wrapper
+ * $big_int_wrapper = &Crypt_RSA_MathLoader::loadWrapper('BigInt');
+ *
+ * // load BCMath wrapper
+ * $bcmath_wrapper = &Crypt_RSA_MathLoader::loadWrapper('BCMath');
+ *
+ * @param string $wrapper_name Name of wrapper
+ *
+ * @return object
+ * Reference to object of wrapper with name $wrapper_name on success
+ * or PEAR_Error object on error
+ *
+ * @access public
+ */
+ function loadWrapper($wrapper_name = 'default')
+ {
+ static $math_objects = array();
+ // ordered by performance. GMP is the fastest math library, BCMath - the slowest.
+ static $math_wrappers = array('GMP', 'BigInt', 'BCMath',);
+
+ if (isset($math_objects[$wrapper_name])) {
+ /*
+ wrapper with name $wrapper_name is already loaded and created.
+ Return reference to existing copy of wrapper
+ */
+ return $math_objects[$wrapper_name];
+ }
+
+ $err_handler = new Crypt_RSA_ErrorHandler();
+
+ if ($wrapper_name === 'default') {
+ // try to load the most suitable wrapper
+ $n = sizeof($math_wrappers);
+ for ($i = 0; $i < $n; $i++) {
+ $obj = Crypt_RSA_MathLoader::loadWrapper($math_wrappers[$i]);
+ if (!$err_handler->isError($obj)) {
+ // wrapper for $math_wrappers[$i] successfully loaded
+ // register it as default wrapper and return reference to it
+ return $math_objects['default'] = $obj;
+ }
+ }
+ // can't load any wrapper
+ $err_handler->pushError("can't load any wrapper for existing math libraries", CRYPT_RSA_ERROR_NO_WRAPPERS);
+ return $err_handler->getLastError();
+ }
+
+ $class_name = 'Crypt_RSA_Math_' . $wrapper_name;
+ $class_filename = dirname(__FILE__) . '/Math/' . $wrapper_name . '.php';
+
+ if (!is_file($class_filename)) {
+ $err_handler->pushError("can't find file [{$class_filename}] for RSA math wrapper [{$wrapper_name}]", CRYPT_RSA_ERROR_NO_FILE);
+ return $err_handler->getLastError();
+ }
+
+ include_once $class_filename;
+ if (!class_exists($class_name)) {
+ $err_handler->pushError("can't find class [{$class_name}] in file [{$class_filename}]", CRYPT_RSA_ERROR_NO_CLASS);
+ return $err_handler->getLastError();
+ }
+
+ // create and return wrapper object on success or PEAR_Error object on error
+ $obj = new $class_name;
+ if ($obj->errstr) {
+ // cannot load required extension for math wrapper
+ $err_handler->pushError($obj->errstr, CRYPT_RSA_ERROR_NO_EXT);
+ return $err_handler->getLastError();
+ }
+ return $math_objects[$wrapper_name] = $obj;
+ }
+}
+
+?>
diff --git a/mod/openid_server/actions/admin.php b/mod/openid_server/actions/admin.php
new file mode 100755
index 000000000..bdf3b8261
--- /dev/null
+++ b/mod/openid_server/actions/admin.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * Elgg openid_server admin action page
+ *
+ * @package openid_server
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardiner <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.com/
+ *
+ * @uses the following values in $vars:
+ *
+ * 'trust' the trust object with the database information and action type
+ */
+
+require_once('../openid_server_include.php');
+
+if (isadminloggedin()) {
+ $action = trim(get_input('action'));
+ $trust_id = get_input('trust_id');
+ $show_full_form = true;
+ $body = '';
+ if ($action) {
+ $trust = new StdClass;
+ $trust->trust_root = get_input('trust_root');
+ $trust->site_name = get_input('site_name');
+ $trust->auto_login = get_input('auto_login');
+ $trust->auto_logout = get_input('auto_logout');
+ $trust->width = get_input('width');
+ $trust->height = get_input('height');
+
+ switch($action) {
+ case 'change':
+ $trust->ident = $trust_id;
+ $store->update_default_trust_root($trust_id,$trust);
+ system_message(elgg_echo('openid_server:trust_root_updated'));
+ break;
+ case 'add':
+ $store->insert_default_trust_root($trust);
+ system_message(elgg_echo('openid_server:trust_root_added'));
+ break;
+ case 'delete':
+ $store->delete_default_trust_root($trust_id);
+ system_message(elgg_echo('openid_server:trust_root_deleted'));
+ break;
+ }
+ } else {
+ if ($trust_id) {
+ $trust = $store->get_trust_root($trust_id);
+ $trust->action = 'change';
+ $body = generate_trust_form($trust);
+ $title = elgg_echo('openid_server:edit_trust_root_title');
+ $show_full_form = false;
+ }
+ }
+
+ if ($show_full_form) {
+
+ // KJ - TODO: Move this into a separate form view
+ $edit_url = $CFG->wwwroot.'mod/openid_server/admin.php?trust_id=';
+ $delete_url = $CFG->wwwroot.'mod/openid_server/admin.php?action=delete&trust_id=';
+ $title = elgg_echo('openid_server:manage_trust_root_title');
+ $results = $store->get_all_default_trust_roots();
+ if ($results) {
+ $body .= '<h2>'.elgg_echo('openid_server:trust_root_title').'</h2>'."\n";
+ $body.= '<table border="0">'."\n";
+ foreach($results as $item) {
+ $body .= '<tr><td width="150">'.$item->site_name.'</td><td width="250">'.$item->trust_root.'</td><td><a href="'
+ .$edit_url.$item->ident.'">'.elgg_echo('openid_server:edit_option').'</a></td><td><a href="'
+ .$delete_url.$item->ident.'">'.elgg_echo('openid_server:delete_option').'</a></td></tr>'."\n";
+ }
+ }
+ $body .= "</table>\n";
+ $body .= '<h2>'.elgg_echo('openid_server:add_trust_root_title').'</h2>';
+ $trust = new StdClass;
+ $trust->trust_root = '';
+ $trust->site_name = '';
+ $trust->auto_login = '';
+ $trust->auto_logout = '';
+ $trust->width = 0;
+ $trust->height = 0;
+ $trust->action = 'add';
+ $body .= generate_trust_form($trust);
+ }
+}
+
+elgg_view_page($title,$body);
+
+?>
diff --git a/mod/openid_server/actions/autologin.php b/mod/openid_server/actions/autologin.php
new file mode 100755
index 000000000..4a200fcfb
--- /dev/null
+++ b/mod/openid_server/actions/autologin.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Elgg openid_server: autologin form
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.org/
+ */
+
+require_once(dirname(dirname(__FILE__)).'/openid_server_include.php');
+
+require_once ('lib/common.php');
+require_once ('lib/session.php');
+
+$iframe_template = <<<END
+<iframe
+width="%s"
+height="%s"
+src="%s"
+>
+</iframe>');
+END;
+
+$openid_url = getLoggedinUser();
+$store = getOpenIDServerStore();
+$sites = $store->getAutoLoginSites();
+$request = getRequestInfo();
+if ($request) {
+ $return_url = $request->return_to;
+ setRequestInfo(null);
+} else {
+ $return_url = $CONFIG->wwwroot;
+}
+// TODO: get this to work with posts
+$iframes = '';
+foreach ($sites as $site) {
+ $iframes .= sprintf($iframe_template,$site->width,$site->height,sprintf($site->auto_login,$openid_url));
+}
+$body = elgg_view("openid_server/forms/autologin",
+ array(
+ 'iframes' => $iframes,
+ 'return_to' => $return_url,
+
+ ));
+$CONFIG->events['login'] = array();
+login();
+header("Content-type:text/html");
+print $body;
+?>
diff --git a/mod/openid_server/actions/autologout.php b/mod/openid_server/actions/autologout.php
new file mode 100755
index 000000000..36a7191c2
--- /dev/null
+++ b/mod/openid_server/actions/autologout.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * Elgg openid_server: autologout form
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.org/
+ */
+
+require_once(dirname(dirname(__FILE__)).'/openid_server_include.php');
+
+require_once ('lib/common.php');
+require_once ('lib/session.php');
+
+$iframe_template = <<<END
+<iframe
+width="%s"
+height="%s"
+src="%s"
+>
+</iframe>');
+END;
+
+$store = getOpenIDServerStore();
+
+$openid_url = getLoggedinUser();
+$sites = $store->getAutoLogoutSites();
+
+// TODO: get this to work with posts
+$iframes = '';
+foreach ($sites as $site) {
+ $iframes .= sprintf($iframe_template,$site->width,$site->height,sprintf($site->auto_logout,$openid_url));
+}
+$body = elgg_view("openid_server/forms/autologout",
+ array(
+ 'iframes' => $iframes,
+
+ ));
+
+$CONFIG->events['logout'] = array();
+
+logout();
+header("Content-type:text/html");
+print $body;
+?>
diff --git a/mod/openid_server/actions/trust.php b/mod/openid_server/actions/trust.php
new file mode 100755
index 000000000..3f882125d
--- /dev/null
+++ b/mod/openid_server/actions/trust.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * Elgg openid_server: handle trust form
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.org/
+ */
+
+//error_log("in trust.php");
+
+require_once(dirname(dirname(__FILE__)).'/openid_server_include.php');
+
+require_once ('lib/common.php');
+require_once ('lib/session.php');
+
+$info = getRequestInfo();
+$trusted = get_input('trust');
+$remember = get_input('remember');
+$trust_root = get_input('trust_root');
+
+$store = getOpenIDServerStore();
+if ($remember) {
+ $store->setTrustedSite($info);
+ //$store->setTrustedSite($info->trust_root);
+}
+
+if (!$info) {
+ // There is no authentication information, so bail
+ system_message(elgg_echo("openid_server:cancelled"));
+ forward();
+} else {
+
+ if ($idpSelect = $info->idSelect()) {
+ if ($idpSelect) {
+ $identity = getLoggedInUser();
+ //$req_url = idURL($idpSelect);
+ $req_url = $info->identity;
+ //XXX fixing dirty https stuff
+ //$req_url = str_replace('http', 'https', $req_url);
+ } else {
+ $trusted = false;
+ }
+ } else {
+ $req_url = normaliseUsername($info->identity);
+ }
+
+
+ $user = getLoggedInUser();
+ $identity = $user;
+
+ setRequestInfo($info);
+ $req_url_path = substr($req_url, strpos($req_url, ":"));
+ $user_path = substr($user, strpos($user, ":"));
+
+ if ($info->message->isOpenID1() && $req_url_path != $user_path) {
+ register_error(sprintf(elgg_echo("openid_server:loggedin_as_wrong_user"),$req_url, $user));
+ forward();
+ } else {
+ $trust_root = $info->trust_root;
+ $trusted = isset($trusted) ? $trusted : isTrusted($identity, $trust_root);
+ if ($trusted) {
+ setRequestInfo();
+ $server =& getServer();
+ if ($info->message->isOpenID1())
+ $response =& $info->answer(true, null, $req_url);
+ else
+ $response =& $info->answer(true, null, getServerURL(), $identity);
+
+ addSregFields($response, $info, $identity);
+ $webresponse =& $server->encodeResponse($response);
+
+ $new_headers = array();
+
+ foreach ($webresponse->headers as $k => $v) {
+ $new_headers[] = $k.": ".$v;
+ }
+
+ writeResponse( array($new_headers, $webresponse->body));
+ exit(0);
+ } elseif ($fail_cancels) {
+ setRequestInfo();
+ forward($info->getCancelURL());
+ } else {
+ writeResponse(trust_render($info));
+ }
+ }
+}
+
+?>
diff --git a/mod/openid_server/languages/ca.php b/mod/openid_server/languages/ca.php
new file mode 100644
index 000000000..0b0e67659
--- /dev/null
+++ b/mod/openid_server/languages/ca.php
@@ -0,0 +1,40 @@
+<?php
+
+// Generat per translationbrowser
+
+$catalan = array(
+ 'openid_server:trust_title' => "Verifica" ,
+ 'openid_server:trust_question' => "Vols confirmar el teu OpenID ( %s ) amb %s ?" ,
+ 'openid_server:remember_trust' => "Recorda la decisió" ,
+ 'openid_server:confirm_trust' => "Si" ,
+ 'openid_server:reject_trust' => "No" ,
+ 'openid_server:not_logged_in' => "T'hauries d'identificar per aprovar la petició." ,
+ 'openid_server:loggedin_as_wrong_user' => "T'has d'identificar com %s per aprovar la petició. Ara mateix estàs identificat com %s." ,
+ 'openid_server:trust_root' => "Verifica l'arrel" ,
+ 'openid_server:trust_site' => "Verifica la xarxa" ,
+ 'openid_server:autologin_url' => "Auto-login URL:" ,
+ 'openid_server:autologout_url' => "Auto-logout URL:" ,
+ 'openid_server:iframe_width' => "amplada de l'iframe (en píxels)" ,
+ 'openid_server:iframe_height' => "alçada de l'iframe (en píxels)" ,
+ 'openid_server:change_button' => "Canviar" ,
+ 'openid_server:add_button' => "Afegir" ,
+ 'openid_server:trust_root_updated' => "Verificació de l'arrel actualitzada" ,
+ 'openid_server:trust_root_added' => "Verificació de l'arrel afegida" ,
+ 'openid_server:trust_root_deleted' => "Verificació de l'arrel esborrada" ,
+ 'openid_server:edit_trust_root_title' => "Modifica la verificació" ,
+ 'openid_server:manage_trust_root_title' => "Organitza la verificació d'arrels per defecte" ,
+ 'openid_server:trust_root_title' => "Verificació d'arrels per defecte" ,
+ 'openid_server:edit_option' => "Modifica" ,
+ 'openid_server:delete_option' => "Esborra" ,
+ 'openid_server:add_trust_root_title' => "Afegir verificació de l'arrel per defecte" ,
+ 'openid_server:autologin_title' => "Entrant" ,
+ 'openid_server:autologin_body' => "Entrant... siusplau, espera" ,
+ 'openid_server:autologout_title' => "Sortint" ,
+ 'openid_server:autologout_body' => "Sortint... siusplau, espera" ,
+ 'item:object:openid_server::trusted_root' => "Accessos openid" ,
+ 'openid_server:admin_explanation' => "Pots fer servir aquesta pàgina per a definir l'arrel verificada del teu servidor OpenID. Aquestes aplicacions client per a OpenID es verifiquen automàticament per a persones que fan servir l'OpenID que proveeix al teu servidor i són realment útils si només vols fer servir OpenID de forma integrada en una federació d'aplicacions verificades. (No necessites fer res si no tens cap aplicació d'aquest tipus.) Pots configurar les URL de autologin i autologout per a algunes o totes les aplicacions verificades si vols que els teus usuaris s'identifiquin i es desconnectin automàticament contra un servidor OpenID. Normalment els autologin i els autologout es col·loquen a iframes invisibles. Si estàs debuggant això i vols que l'iframe sigui visible, pots configurar l'ample i l'alçada més avall."
+);
+
+add_translation('ca', $catalan);
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/languages/en.php b/mod/openid_server/languages/en.php
new file mode 100755
index 000000000..994240861
--- /dev/null
+++ b/mod/openid_server/languages/en.php
@@ -0,0 +1,47 @@
+<?php
+
+ $english = array(
+ 'item:user:openid' => "OpenID users",
+ 'openid_server:trust_title' => "Trust",
+ 'openid_server:trust_question' => "Do you wish to confirm your OpenID (<code>%s</code>) with <code>%s</code>?",
+ 'openid_server:remember_trust' => "Remember this decision",
+ 'openid_server:confirm_trust' => "Yes",
+ 'openid_server:reject_trust' => "No",
+ 'openid_server:not_logged_in' => "You must be logged-in to approve this request. Please login now.",
+ 'openid_server:loggedin_as_wrong_user' => "You must be logged-in as %s to approve this request."
+ ." You are currently logged-in as %s instead.",
+ 'openid_server:trust_root' => "Trust root",
+ 'openid_server:trust_site' => "Trust site",
+ 'openid_server:autologin_url' => "Auto-login URL:",
+ 'openid_server:autologout_url' => "Auto-logout URL:",
+ 'openid_server:iframe_width' => "Iframe width (in pixels)",
+ 'openid_server:iframe_height' => "Iframe height (in pixels)",
+ 'openid_server:change_button' => "Change",
+ 'openid_server:add_button' => "Add",
+ 'openid_server:admin_explanation' => "You can use this page to set default trust roots for your OpenID server."
+ ." These are OpenID client applications that are automatically trusted by people using OpenIDs provided by your server and are"
+ ." useful only if you are using OpenID to integrate a federation of trusted applications. (You need do nothing here if you have no"
+ ." trusted applications.) You can also set autologin and autologout URLs for some or all of your trusted applications if you"
+ ." want your users to be automatically logged in or logged out of these applications when they login and logout of your"
+ ." OpenID server. Normally the autologin and autologout takes place in invisible iframes. If you are debugging this and want"
+ ." the iframes to be visible, you can set the width and height below.",
+ 'openid_server:trust_root_updated' => "Trust root updated",
+ 'openid_server:trust_root_added' => "Trust root added",
+ 'openid_server:trust_root_deleted' => "Trust root deleted",
+ 'openid_server:edit_trust_root_title' => "Edit trust record",
+ 'openid_server:manage_trust_root_title' => "Manage default trust roots",
+ 'openid_server:trust_root_title' => "Default trust roots",
+ 'openid_server:edit_option' => "Edit",
+ 'openid_server:delete_option' => "Delete",
+ 'openid_server:add_trust_root_title' => "Add default trust root",
+ 'openid_server:autologin_title' => "Logging in",
+ 'openid_server:autologin_body' => "Logging in ... please wait",
+ 'openid_server:autologout_title' => "Logging out",
+ 'openid_server:autologout_body' => "Logging out ... please wait",
+ 'item:object:openid_server::trusted_root' => "Openid trusted sites",
+
+ );
+
+ add_translation("en",$english);
+
+?>
diff --git a/mod/openid_server/languages/es.php b/mod/openid_server/languages/es.php
new file mode 100755
index 000000000..eada7cd72
--- /dev/null
+++ b/mod/openid_server/languages/es.php
@@ -0,0 +1,40 @@
+<?php
+
+// Generado por translationbrowser
+
+$spanish = array(
+ 'openid_server:trust_title' => "Verificar" ,
+ 'openid_server:trust_question' => "¿Quieres confirmar tu OpenID (<code>%s</code>) con <code>%s</code>?" ,
+ 'openid_server:remember_trust' => "Recordar la decisión" ,
+ 'openid_server:confirm_trust' => "Sí" ,
+ 'openid_server:reject_trust' => "No" ,
+ 'openid_server:not_logged_in' => "Tienes que haber iniciado sesión para aprobar la petición." ,
+ 'openid_server:loggedin_as_wrong_user' => "Tienes que haber iniciado sesión como %s para aprobar la petición. Ahora mismo apareces como %s." ,
+ 'openid_server:trust_root' => "Verificar raíz" ,
+ 'openid_server:trust_site' => "Verificar sitio" ,
+ 'openid_server:autologin_url' => "Url de autoinicio de sesión:" ,
+ 'openid_server:autologout_url' => "Url de autocierre de sesión:" ,
+ 'openid_server:iframe_width' => "Anchura del iframe (en pixels)" ,
+ 'openid_server:iframe_height' => "Altura del iframe (en pixels)" ,
+ 'openid_server:change_button' => "Cambiar" ,
+ 'openid_server:add_button' => "Añadir" ,
+ 'openid_server:admin_explanation' => "Puedes utilizar esta página para definir la raíz verificada de tu servidor OpenID. Estas aplicaciones cliente para OpenID son automáticamente verificadas por gente que utiliza el OpenID que provee tu server y son muy útiles solo si quieres usar OpenID de forma integrada en una federación de aplicaciones verificadas. (No necesitas hacer nada si no tienes ninguna aplicación de ese tipo). Puedes configurar las URLs de autologin y autologout para algunas o todas las aplicaciones verificadas si quieres que las habitantes sean automáticamente logueadas y deslogueadas del OpenID server. Normalmente los autologin y autologout se colocan en iframes invisibles. Si estas debuggeando esto y quieres que el iframe sea visible, puedes configurar el ancho y el alto debajo." ,
+ 'openid_server:trust_root_updated' => "Verificación de raíz actualizada" ,
+ 'openid_server:trust_root_added' => "Verificación de raíz añadida" ,
+ 'openid_server:trust_root_deleted' => "Verificación de raíz borrada" ,
+ 'openid_server:edit_trust_root_title' => "Editar verificación" ,
+ 'openid_server:manage_trust_root_title' => "Organizar verificación de raíces por defecto" ,
+ 'openid_server:trust_root_title' => "Verificación de raíces por defecto" ,
+ 'openid_server:edit_option' => "Editar" ,
+ 'openid_server:delete_option' => "Borrar" ,
+ 'openid_server:add_trust_root_title' => "Añadir verificación de raíz por defecto" ,
+ 'openid_server:autologin_title' => "Logueando" ,
+ 'openid_server:autologin_body' => "Logueando ... por favor espera" ,
+ 'openid_server:autologout_title' => "Logging out" ,
+ 'openid_server:autologout_body' => "Deslogueando... por favor espera" ,
+ 'item:object:openid_server::trusted_root' => "Accesos OpenID"
+);
+
+add_translation('es', $spanish);
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/languages/gl.php b/mod/openid_server/languages/gl.php
new file mode 100644
index 000000000..1fa29af1e
--- /dev/null
+++ b/mod/openid_server/languages/gl.php
@@ -0,0 +1,40 @@
+<?php
+
+// Xerado por translationbrowser
+
+$galician = array(
+ 'openid_server:trust_title' => "Verificar" ,
+ 'openid_server:trust_question' => "Queres confirma-lo teu OpenId (%s) con %s?" ,
+ 'openid_server:remember_trust' => "Recorda-la decisión" ,
+ 'openid_server:confirm_trust' => "Si" ,
+ 'openid_server:reject_trust' => "Non" ,
+ 'openid_server:not_logged_in' => "Tes que ter iniciado a sesión para aproba-la petición." ,
+ 'openid_server:loggedin_as_wrong_user' => "Tes que ter iniciado a sesión como %s para aproba-la petición. Agora xa apareces como %s." ,
+ 'openid_server:trust_root' => "Verifica-la raíz" ,
+ 'openid_server:trust_site' => "Verifica-lo sitio" ,
+ 'openid_server:autologin_url' => "Url do autoinicio da sesión:" ,
+ 'openid_server:autologout_url' => "Url do autopeche da sesión:" ,
+ 'openid_server:iframe_width' => "Anchura do iframe (en pixels)" ,
+ 'openid_server:iframe_height' => "Altura do iframe (en pixels)" ,
+ 'openid_server:change_button' => "Cambiar" ,
+ 'openid_server:add_button' => "Engadir" ,
+ 'openid_server:admin_explanation' => "Podes empregar esta páxina para defini-la raíz verificada do teu servidor OpenID. Estas aplicacións cliente para OpenID son automaticamente verificadas pola xente que emprega o OpenID que provee ó teu server e son moi útiles só se queres usa-lo OpenID de forma integrada nunha federación de aplicacións verificadas. (Non necesitas facer nada se non tes ningunha aplicación deste tipo). Podes configura-las URL do autoinicio e autopeche para algunhas ou toda-las aplicacións verificadas se queres que xs habitantes sexan automaticamente logueadas e deslogueadas do OpenID server. Normalmente os autoinicio e autopeche colócanse en iframes invisibles. Se estás a debuggear isto e queres que o iframe sexa visible, podes configura-lo ancho e o alto embaixo." ,
+ 'openid_server:trust_root_updated' => "Verificación da raíz actualizada" ,
+ 'openid_server:trust_root_added' => "Verificación da raíz engadida" ,
+ 'openid_server:trust_root_deleted' => "Verificación da raíz borrada" ,
+ 'openid_server:edit_trust_root_title' => "Edita-la verificación" ,
+ 'openid_server:manage_trust_root_title' => "Organiza la verificación das raíces por defecto" ,
+ 'openid_server:trust_root_title' => " Verificación das raíces por defecto" ,
+ 'openid_server:edit_option' => "Editar" ,
+ 'openid_server:delete_option' => "Borrar" ,
+ 'openid_server:add_trust_root_title' => "Engadi-la verificación de raíz por defecto" ,
+ 'openid_server:autologin_title' => "Logueando" ,
+ 'openid_server:autologin_body' => "Logueando... por favor agarda un chisco" ,
+ 'openid_server:autologout_title' => "Logging out" ,
+ 'openid_server:autologout_body' => "Deslogueando... por favor agarda un chisco" ,
+ 'item:object:openid_server::trusted_root' => "Accesos OpenID"
+);
+
+add_translation('gl', $galician);
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/languages/pt.php b/mod/openid_server/languages/pt.php
new file mode 100644
index 000000000..eda853302
--- /dev/null
+++ b/mod/openid_server/languages/pt.php
@@ -0,0 +1,27 @@
+<?php
+
+// Gerado pelo browser de tradução.
+
+$portuguese = array(
+ 'item:user:openid' => "Usuarixs OpenID" ,
+ 'openid_server:trust_question' => "Você confirma a tua OpenID (%s) com %s ?" ,
+ 'openid_server:remember_trust' => "Lembrar esta decisão" ,
+ 'openid_server:confirm_trust' => "Sim" ,
+ 'openid_server:reject_trust' => "Não" ,
+ 'openid_server:not_logged_in' => "Você tem que estar autentificado para aprovar este pedido. Por favor autentifique-se agora." ,
+ 'openid_server:loggedin_as_wrong_user' => "Você tem que estar autentificado como %s para aprovar este pedido. Atualmente você está autentificado como %s." ,
+ 'openid_server:autologin_url' => "Link para auto-autentificação:" ,
+ 'openid_server:autologout_url' => "Link para auto-desautentificação:" ,
+ 'openid_server:change_button' => "Mudar" ,
+ 'openid_server:add_button' => "Adicionar" ,
+ 'openid_server:edit_option' => "Editar" ,
+ 'openid_server:delete_option' => "Apagar" ,
+ 'openid_server:autologin_title' => "Autentificando" ,
+ 'openid_server:autologin_body' => "Autentificando... Por favor espere" ,
+ 'openid_server:autologout_title' => "Saindo" ,
+ 'openid_server:autologout_body' => "Saindo... Por favor espere"
+);
+
+add_translation('pt', $portuguese);
+
+?> \ No newline at end of file
diff --git a/mod/openid_server/lib/actions.php b/mod/openid_server/lib/actions.php
new file mode 100755
index 000000000..f5f05d952
--- /dev/null
+++ b/mod/openid_server/lib/actions.php
@@ -0,0 +1,173 @@
+<?php
+
+require_once "common.php";
+require_once "session.php";
+
+require_once "Auth/OpenID.php";
+
+/**
+ * Handle a standard OpenID server request
+ */
+function action_default()
+{
+ global $store;
+
+ $server =& getServer();
+ $method = $_SERVER['REQUEST_METHOD'];
+ /*$request = null;
+ if ($method == 'GET') {
+ $request = $_GET;
+ } else {
+ $request = $_POST;
+ } */
+
+ $request = $server->decodeRequest();
+
+ if (!$request) {
+ return ""; //about_render();
+ }
+
+ setRequestInfo($request);
+
+ if (in_array($request->mode,
+ array('checkid_immediate', 'checkid_setup'))) {
+
+
+ $identity = getLoggedInUser();
+ if (isTrusted($identity, $request->trust_root, $request->return_to)) {
+ if ($request->message->isOpenID1()) {
+ $response =& $request->answer(true);
+ } else {
+ $response =& $request->answer(true, false, getServerURL(), $identity);
+ }
+ } else if ($request->immediate) {
+ $response =& $request->answer(false, getServerURL());
+ } else {
+ if (!getLoggedInUser()) {
+ $_SESSION['last_forward_from'] = current_page_url().'?'.http_build_query(Auth_OpenID::getQuery());
+ system_message(elgg_echo('openid_server:not_logged_in'));
+ forward('login');
+ }
+ return trust_render($request);
+ }
+ addSregFields(&$response);
+
+ } else {
+ $response =& $server->handleRequest($request);
+ }
+
+ $webresponse =& $server->encodeResponse($response);
+
+ foreach ($webresponse->headers as $k => $v) {
+ header("$k: $v");
+ }
+
+ header(header_connection_close);
+ print $webresponse->body;
+ exit(0);
+}
+
+/**
+ * Log out the currently logged in user
+ */
+function action_logout()
+{
+ setLoggedInUser(null);
+ setRequestInfo(null);
+ return authCancel(null);
+}
+
+/**
+ * Check the input values for a login request
+ */
+function login_checkInput($input)
+{
+ $openid_url = false;
+ $errors = array();
+
+ if (!isset($input['openid_url'])) {
+ $errors[] = gettext('Enter an OpenID URL to continue');
+ }
+ if (!isset($input['password'])) {
+ $errors[] = gettext('Enter a password to continue');
+ }
+ if (count($errors) == 0) {
+ $openid_url = $input['openid_url'];
+ // don't normalise yet
+ // $openid_url = Auth_OpenID::normalizeUrl($openid_url);
+ $password = $input['password'];
+ if (!checkLogin($openid_url, $password)) {
+ $errors[] = 'The entered password does not match the ' .
+ 'entered identity URL.';
+ }
+ }
+ return array($errors, $openid_url);
+}
+
+/**
+ * Log in a user and potentially continue the requested identity approval
+ */
+function action_login()
+{
+ $method = $_SERVER['REQUEST_METHOD'];
+ switch ($method) {
+ case 'GET':
+ return login_render();
+ case 'POST':
+ $info = getRequestInfo();
+ $fields = $_POST;
+ if (isset($fields['cancel'])) {
+ return authCancel($info);
+ }
+
+ list ($errors, $openid_url) = login_checkInput($fields);
+ if (count($errors) || !$openid_url) {
+ $needed = $info ? $info->identity : false;
+ //KJ - use $openid_url instead
+ // return login_render($errors, @$fields['openid_url'], $needed);
+ return login_render($errors, $openid_url, $needed);
+ } else {
+ setLoggedInUser(normaliseUsername($openid_url));
+ return doAuth($info);
+ }
+ default:
+ return login_render(array('Unsupported HTTP method: $method'));
+ }
+}
+
+/**
+ * Ask the user whether he wants to trust this site
+ */
+function action_trust()
+{
+ global $store;
+
+ $info = getRequestInfo();
+ $trusted = isset($_POST['trust']);
+ if ($info && isset($_POST['remember'])) {
+ $store->setTrustedSite($info->trust_root);
+ }
+ return doAuth($info, $trusted, true);
+}
+
+function action_sites()
+{
+ global $store;
+
+ $sites = $store->getTrustedSites();
+
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ if (isset($_POST['forget'])) {
+ $store->removeAllTrustedSites();
+ } elseif (isset($_POST['remove'])) {
+ foreach ($_POST as $k => $v) {
+ if (preg_match('/^site[0-9]+$/', $k)) {
+ $store->removeTrustedSite($v);
+ }
+ }
+ }
+ }
+ return sites_render($store->getTrustedSites());
+}
+
+?>
diff --git a/mod/openid_server/lib/common.php b/mod/openid_server/lib/common.php
new file mode 100755
index 000000000..3e3e6b034
--- /dev/null
+++ b/mod/openid_server/lib/common.php
@@ -0,0 +1,164 @@
+<?php
+
+require_once "session.php";
+
+require_once "Auth/OpenID/Server.php";
+require_once "Auth/OpenID/SReg.php";
+try {
+ // include_once "Auth/OpenID/HMACSHA1.php";
+} catch(Exception $e) {
+ // new way :P
+ require_once "Auth/OpenID/HMAC.php";
+}
+
+function getUsernameFromUrl($url)
+{
+ $un = trim($url);
+ $lun = strlen($un);
+ $last_stroke_pos = strrpos($un,"/");
+ if ($last_stroke_pos === false) {
+ // no slash, so assume that this is already a username
+ $username = $url;
+ } else {
+ if ($last_stroke_pos == ($lun - 1)) {
+ // this url ends in a slash - ignore it
+ $un = substr($un, 0,-1);
+ }
+ $last_stroke_pos = strrpos($un,"/");
+ $username = substr($un,$last_stroke_pos+1);
+ }
+
+ return $username;
+}
+
+function normaliseUsername($username)
+// check to see if the current username contains a slash
+// if so, assume that this is an OpenID URL
+// if not, munge it until it is
+// normalise OpenID URLs to include a closing slash
+{
+ global $CONFIG;
+
+ $stroke_pos = strpos($username,"/");
+ if ($stroke_pos === false) {
+ return $CONFIG->wwwroot."profile/".$username;
+ } else {
+ if (substr($username,-1,1) == "/") {
+ return substr($username, 0, strlen($username-1));
+ } else {
+ return $username;
+ }
+ }
+}
+
+function addSregFields(&$response,$info, $req_url)
+{
+ $username = getUsernameFromUrl($req_url);
+ $user = get_user_by_username($username);
+ if ($user) {
+ $email = $user->email;
+ $fullname = $user->name;
+
+ $sreg_data = array(
+ 'fullname' => $fullname,
+ 'email' => $email
+ );
+
+ // Add the simple registration response values to the OpenID
+ // response message.
+ $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($info);
+
+ $sreg_response = Auth_OpenID_SRegResponse::extractResponse(
+ $sreg_request, $sreg_data);
+ //error_log('DEBUG:' . (string)($response->fields));
+ $sreg_response->toMessage($response->fields);
+ }
+
+}
+
+// KJ - this code is now used in trust.php
+
+/*function authCancel($info)
+{
+ if ($info) {
+ setRequestInfo();
+ $url = $info->getCancelURL();
+ } else {
+ $url = getServerURL();
+ }
+ return redirect_render($url);
+}
+
+function doAuth($info, $trusted=null, $fail_cancels=false,$idpSelect=null)
+{
+ if (!$info) {
+ // There is no authentication information, so bail
+ return authCancel(null);
+ }
+
+ if ($info->idSelect()) {
+ if ($idpSelect) {
+ $req_url = idURL($idpSelect);
+ } else {
+ $trusted = false;
+ }
+ } else {
+ $req_url = normaliseUsername($info->identity);
+ }
+
+ $user = getLoggedInUser();
+ setRequestInfo($info);
+
+ if ($req_url != $user) {
+ return login_render(array(), $req_url, $req_url);
+ }
+
+ $trust_root = $info->trust_root;
+ // $fail_cancels = $fail_cancels || isset($sites[$trust_root]);
+ $trusted = isset($trusted) ? $trusted : isTrusted($req_url,$trust_root);
+ if ($trusted) {
+ setRequestInfo();
+ $server =& getServer();
+ $response =& $info->answer(true, null, $req_url);
+
+ addSregFields($response, $info, $req_url);
+
+ $webresponse =& $server->encodeResponse($response);
+
+ $new_headers = array();
+
+ foreach ($webresponse->headers as $k => $v) {
+ $new_headers[] = $k.": ".$v;
+ }
+
+ return array($new_headers, $webresponse->body);
+ } elseif ($fail_cancels) {
+ return authCancel($info);
+ } else {
+ return trust_render($info);
+ }
+}*/
+
+
+function trust_render($info) {
+
+ $vars = array('openid_url' =>getLoggedInUser(), 'openid_trust_root' =>htmlspecialchars($info->trust_root));
+ $title = elgg_echo('openid_server:trust_title');
+ return array(
+ array(),
+ elgg_view_page(
+ $title,
+ elgg_view_layout('content', array(
+ 'title' => $title,
+ 'content' => elgg_view_form("openid_server/trust", array(), $vars),
+ 'filter' => false,
+ ))
+ ));
+}
+
+function login_render($errors=null, $input=null, $needed=null) {
+ system_message(elgg_echo('openid_server:not_logged_in'));
+ forward(current_page_url());
+}
+
+?>
diff --git a/mod/openid_server/lib/session.php b/mod/openid_server/lib/session.php
new file mode 100755
index 000000000..ccd1e8f4c
--- /dev/null
+++ b/mod/openid_server/lib/session.php
@@ -0,0 +1,140 @@
+<?php
+
+//require_once(dirname(dirname(__FILE__)).'/config.php');
+//require_once "render.php";
+
+require_once "Auth/OpenID/Server.php";
+
+// require_once('elgg/includes.php');
+
+/**
+ * Set up the session
+ */
+// get information from Elgg if logged in
+// KJ - this should not be necessary as it can always be generated from the user name
+function init()
+{
+ global $CFG;
+
+ if (elgg_is_logged_in()) {
+ setLoggedInUser(normaliseUsername($_SESSION['user']->username));
+ } else {
+ setLoggedInUser(null);
+ }
+}
+
+
+/**
+ * Get the URL of the current script
+ */
+function getServerURL()
+{
+ global $CONFIG;
+
+ return $CONFIG->wwwroot.'mod/openid_server/server.php';
+}
+
+/**
+ * Build a URL to a server action
+ */
+function buildURL($action=null, $escaped=true)
+{
+ $url = getServerURL();
+ if ($action) {
+ $url .= '/' . $action;
+ }
+ return $escaped ? htmlspecialchars($url, ENT_QUOTES) : $url;
+}
+
+/**
+ * Extract the current action from the request
+ * KJ - this should be replaced by Elgg 1 action system
+ */
+function getAction()
+{
+ $path_info = @$_SERVER['PATH_INFO'];
+ $action = ($path_info) ? substr($path_info, 1) : '';
+ $function_name = 'action_' . $action;
+ return $function_name;
+}
+
+/**
+ * Write the response to the request
+ */
+function writeResponse($resp)
+{
+ list ($headers, $body) = $resp;
+ array_walk($headers, 'header');
+ header(header_connection_close);
+ print $body;
+}
+
+/**
+ * Instantiate a new OpenID server object
+ */
+function getServer()
+{
+ global $CONFIG;
+ static $server;
+ $op_endpoint = getServerURL();
+ if (!isset($server)) {
+ $server =& new Auth_OpenID_Server(getOpenIDServerStore(),$op_endpoint);
+ }
+ return $server;
+}
+
+/**
+ * Return whether the trust root is currently trusted
+ *
+ */
+function isTrusted($identity_url, $trust_root, $return_to)
+{
+ global $store;
+
+ if ($identity_url != getLoggedInUser()) {
+ return false;
+ }
+
+ $sites = $store->getTrustedSites($identity_url);
+
+ if (empty($sites)) {
+ return false;
+ } else {
+ return in_array($trust_root, $sites) && fnmatch($trust_root.'*',$return_to);
+ }
+}
+
+
+/**
+ * Get the openid_url out of the cookie
+ *
+ * @return mixed $openid_url The URL that was stored in the cookie or
+ * false if there is none present or if the cookie is bad.
+ */
+function getLoggedInUser()
+{
+ global $CONFIG;
+ if (elgg_is_logged_in()) {
+ return $CONFIG->wwwroot.'profile/'.$_SESSION['user']->username;
+ } else {
+ return '';
+ }
+}
+
+function getRequestInfo()
+{
+ return isset($_SESSION['openid_server_request'])
+ ? unserialize($_SESSION['openid_server_request'])
+ : false;
+}
+
+function setRequestInfo($info=null)
+{
+ if (!isset($info)) {
+ unset($_SESSION['openid_server_request']);
+ } else {
+ $_SESSION['openid_server_request'] = serialize($info);
+ }
+}
+
+?>
diff --git a/mod/openid_server/manifest.xml b/mod/openid_server/manifest.xml
new file mode 100755
index 000000000..87218e62c
--- /dev/null
+++ b/mod/openid_server/manifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8">
+ <name>OpenID Server</name>
+ <author>Lorea developers</author>
+ <version>1.8.0</version>
+ <description>OpenID provider for Elgg.</description>
+ <category>auth</category>
+ <category>user</category>
+ <website>https://lorea.org/</website>
+ <copyright>(C) Lorea 2012</copyright>
+ <license>GNU General Public License version 2</license>
+ <requires>
+ <type>elgg_release</type>
+ <version>1.8</version>
+ </requires>
+ <requires>
+ <type>plugin</type>
+ <name>openid_api</name>
+ </requires>
+</plugin_manifest>
diff --git a/mod/openid_server/openid_server_include.php b/mod/openid_server/openid_server_include.php
new file mode 100755
index 000000000..6fbd319c4
--- /dev/null
+++ b/mod/openid_server/openid_server_include.php
@@ -0,0 +1,340 @@
+<?php
+/**
+ * An Elgg 1.x compatible store implementation
+ */
+
+ /**
+ * Require base class for creating a new interface.
+ */
+
+require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php");
+
+require_once 'Auth/OpenID.php';
+require_once 'Auth/OpenID/Interface.php';
+require_once 'Auth/OpenID/Consumer.php';
+try {
+ // include_once "Auth/OpenID/HMACSHA1.php";
+} catch(Exception $e) {
+ // new way :P
+ require_once "Auth/OpenID/HMAC.php";
+}
+require_once 'Auth/OpenID/Nonce.php';
+require_once 'Auth/OpenID/SReg.php';
+
+define('header_connection_close', 'Connection: close');
+
+function openid_server_delete_entity($entity)
+{
+ global $CONFIG;
+
+ $entity->clearMetadata();
+ $entity->clearAnnotations();
+ $guid = $entity->getGUID();
+ delete_data("DELETE from {$CONFIG->dbprefix}entities where guid={$guid}");
+}
+
+
+
+function openid_server_delete_entities($type = "", $subtype = "", $owner_guid = 0)
+ {
+ $entities = get_entities($type, $subtype, $owner_guid, "time_created desc", 0);
+
+ foreach ($entities as $entity) {
+ openid_server_delete_entity($entity);
+ }
+
+ return true;
+ }
+
+
+
+class OpenIDServer_ElggStore extends Auth_OpenID_OpenIDStore {
+
+ function resetAssociations () {
+ openid_server_delete_entities('object', 'openid_client::association');
+ }
+ function resetNonces () {
+ openid_server_delete_entities('object', 'openid_client::nonce');
+ }
+ function getAssociation ($server_url, $handle = null) {
+ if (isset($handle)) {
+ $meta_array = array(
+ 'server_url' => $server_url,
+ 'handle' => $handle
+ );
+ $assocs = elgg_get_entities_from_metadata(array('metadata_name_value_pairs' => $meta_array, 'types' => 'object', 'subtypes' => 'openid_client::association', 'metadata_name_value_pairs_operator' => 'and'));
+ } else {
+ $assocs = elgg_get_entities_from_metadata(array('metadata_names' => 'server_url', 'metadata_values' => $server_url, 'types' => 'object', 'subtypes' => 'openid_client::association', 'metadata_case_sensitive' => FALSE));
+ }
+
+ if (!$assocs || (count($assocs) == 0)) {
+ return null;
+ } else {
+ $associations = array();
+
+ foreach ($assocs as $assoc_row) {
+ $assoc = new Auth_OpenID_Association($assoc_row->handle,
+ base64_decode($assoc_row->secret),
+ $assoc_row->issued,
+ $assoc_row->lifetime,
+ $assoc_row->assoc_type);
+
+ if ($assoc->getExpiresIn() == 0) {
+ OpenIDServer_ElggStore::removeAssociation($server_url, $assoc->handle);
+ } else {
+ $associations[] = array($assoc->issued, $assoc);
+ }
+ }
+
+ if ($associations) {
+ $issued = array();
+ $assocs = array();
+ foreach ($associations as $key => $assoc) {
+ $issued[$key] = $assoc[0];
+ $assocs[$key] = $assoc[1];
+ }
+
+ array_multisort($issued, SORT_DESC, $assocs, SORT_DESC,
+ $associations);
+
+ // return the most recently issued one.
+ list($issued, $assoc) = $associations[0];
+ return $assoc;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ function removeAssociation ($server_url, $handle) {
+ if (isset($handle)) {
+ $meta_array = array(
+ 'server_url' => $server_url,
+ 'handle' => $handle
+ );
+ $entities = elgg_get_entities_from_metadata(array('metadata_name_value_pairs' => $meta_array, 'types' => 'object', 'subtypes' => 'openid_client::association', 'metadata_name_value_pairs_operator' => 'and'));
+ } else {
+ $entities = elgg_get_entities_from_metadata(array('metadata_names' => 'server_url', 'metadata_values' => $server_url, 'types' => 'object', 'subtypes' => 'openid_client::association', 'metadata_case_sensitive' => FALSE));
+ }
+ if ($entities) {
+ foreach ($entities as $entity) {
+ openid_server_delete_entity($entity);
+ }
+ }
+ }
+ function reset () {
+ OpenIDServer_ElggStore::resetAssociations ();
+ OpenIDServer_ElggStore::resetNonces ();
+ }
+
+ function storeAssociation ($server_url, $association) {
+
+ // Initialise a new ElggObject
+ $association_obj = new ElggObject();
+
+ $association_obj->subtype = 'openid_client::association';
+ $association_obj->owner_guid = 0;
+ $association_obj->access_id = 2;
+ $association_obj->title = 'association';
+
+ if ($association_obj->save()) {
+ $association_obj->server_url = $server_url;
+ $association_obj->handle = $association->handle;
+ $association_obj->secret = base64_encode($association->secret);
+ $association_obj->issued = $association->issued;
+ $association_obj->lifetime = $association->lifetime;
+ $association_obj->assoc_type = $association->assoc_type;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function useNonce ( $server_url, $timestamp, $salt) {
+ global $Auth_OpenID_SKEW;
+
+ if ( abs($timestamp - time()) > $Auth_OpenID_SKEW ) {
+ return false;
+ }
+
+ // check to see if the nonce already exists
+
+ $meta_array = array(
+ 'server_url' => $server_url,
+ 'timestamp' => $timestamp,
+ 'salt' => $salt
+ );
+
+ $entities = elgg_get_entities_from_metadata(array('metadata_name_value_pairs' => $meta_array, 'types' => 'object', 'subtypes' => 'openid_client::nonce', 'metadata_name_value_pairs_operator' => 'and'));
+
+ if ($entities) {
+ // bad - this nonce is already in use
+ return false;
+ } else {
+ // Initialise a new ElggObject
+ $nonce_obj = new ElggObject();
+
+ $nonce_obj->subtype = 'openid_client::nonce';
+ $nonce_obj->owner_guid = 0;
+ $nonce_obj->title = 'nonce';
+
+ if ($nonce_obj->save()) {
+ $nonce_obj->server_url = $server_url;
+ $nonce_obj->timestamp = $timestamp;
+ $nonce_obj->salt = $salt;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ function getTrustedSites() {
+
+ $results = elgg_get_entities_from_metadata(array('metadata_names' => 'openid_url', 'metadata_values' => getLoggedInUser(), 'types' => 'object', 'subtypes' => 'openid_server::trust_root', 'metadata_case_sensitive' => FALSE));
+
+ $sites = array();
+ if ($results) {
+ foreach ($results as $site) {
+ $sites[] = $site->trust_root;
+ }
+ }
+ return $sites;
+ }
+
+/**
+ * Returns the autologin URLs for every trusted site
+ */
+
+ function getAutoLoginSites() {
+
+ $default_trusted_sites = elgg_get_entities_from_metadata(array('metadata_names' => 'openid_url', 'metadata_values' => '', 'types' => 'object', 'subtypes' => 'openid_server::trust_root', 'metadata_case_sensitive' => FALSE));
+
+ $sites = array();
+ if ($default_trusted_sites) {
+ foreach ($default_trusted_sites as $site) {
+ if ($site->auto_login_url) {
+ $sites[] = $site;
+ }
+ }
+ }
+ return $sites;
+ }
+
+/**
+ * Returns the autologout URLs for every trusted site
+ */
+
+ function getAutoLogoutSites() {
+
+ $default_trusted_sites = elgg_get_entities_from_metadata(array('metadata_names' => 'openid_url', 'metadata_values' => '', 'types' => 'object', 'subtypes' => 'openid_server::trust_root', 'metadata_case_sensitive' => FALSE));
+
+ $sites = array();
+ if ($default_trusted_sites) {
+ foreach ($default_trusted_sites as $site) {
+ if ($site->auto_logout_url) {
+ $sites[] = $site;
+ }
+ }
+ }
+ return $sites;
+ }
+
+
+ function setTrustedSite($trust_root) {
+ $openid_url = getLoggedInUser();
+ $site = new ElggObject();
+ $site->subtype = 'openid_server::trust_root';
+ $site->owner_guid = 0;
+ $site->title = 'association';
+ $site->access_id = 2;
+
+ if ($site->save()) {
+ $site->openid_url = $openid_url;
+ $site->trust_root = $trust_root->trust_root;
+ $site->site_name = $trust_root->site_name;
+ $site->autologin = $trust_root->autologin;
+ $site->autologout = $trust_root->autologout;
+ $site->width = $trust_root->width;
+ $site->height = $trust_root->height;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function removeAllTrustedSites() {
+
+ $openid_url = getLoggedInUser();
+
+ if ($openid_url != null) {
+ $results = elgg_get_entities_from_metadata(array('metadata_names' => 'openid_url', 'metadata_values' => $openid_url, 'types' => 'object', 'subtypes' => 'openid_server::trust_root', 'metadata_case_sensitive' => FALSE));
+
+ if ($results) {
+ foreach($results as $trust_root) {
+ $trust_root->delete();
+ }
+ }
+ }
+ return true;
+ }
+
+ function removeTrustedSite($trust_root) {
+
+ $openid_url = getLoggedInUser();
+
+ if ($openid_url != null) {
+ $meta_array = array(
+ 'openid_url' => $openid_url,
+ 'trust_root' => $trust_root
+ );
+
+ $results = elgg_get_entities_from_metadata(array('metadata_name_value_pairs' => $meta_array, 'types' => 'object', 'subtypes' => 'openid_server::trust_root', 'metadata_name_value_pairs_operator' => 'and'));
+
+ if ($results) {
+ foreach($results as $trust_root) {
+ $trust_root->delete();
+ }
+ }
+ }
+ return true;
+ }
+}
+
+function getOpenIDServerStore() {
+ return new OpenIDServer_ElggStore();
+}
+
+
+if (!function_exists('fnmatch')) {
+function fnmatch($pattern, $string) {
+ for ($op = 0, $npattern = '', $n = 0, $l = strlen($pattern); $n < $l; $n++) {
+ switch ($c = $pattern[$n]) {
+ case '\\':
+ $npattern .= '\\' . @$pattern[++$n];
+ break;
+ case '.': case '+': case '^': case '$': case '(': case ')': case '{': case '}': case '=': case '!': case '<': case '>': case '|':
+ $npattern .= '\\' . $c;
+ break;
+ case '?': case '*':
+ $npattern .= '.' . $c;
+ break;
+ case '[': case ']': default:
+ $npattern .= $c;
+ if ($c == '[') {
+ $op++;
+ } else if ($c == ']') {
+ if ($op == 0) return false;
+ $op--;
+ }
+ break;
+ }
+ }
+
+ if ($op != 0) return false;
+
+ return preg_match('/' . $npattern . '/i', $string);
+}
+}
+
+?>
diff --git a/mod/openid_server/server.php b/mod/openid_server/server.php
new file mode 100755
index 000000000..7ebe70dd4
--- /dev/null
+++ b/mod/openid_server/server.php
@@ -0,0 +1,32 @@
+<?php
+
+require_once('openid_server_include.php');
+require_once 'lib/session.php';
+require_once 'lib/actions.php';
+
+if (elgg_get_viewtype() == 'xrds') {
+ echo elgg_view_page($title, $body);
+ exit(0);
+}
+
+$store = getOpenIDServerStore();
+
+$server =& getServer();
+
+$request = $server->decodeRequest();
+setRequestInfo($request);
+
+$action = getAction();
+if (!function_exists($action)) {
+ $action = 'action_default';
+}
+
+$resp = $action();
+if (!empty($resp)) {
+ writeResponse($resp);
+} else {
+ echo elgg_view_page($title, $body);
+ exit(0);
+
+}
+?>
diff --git a/mod/openid_server/start.php b/mod/openid_server/start.php
new file mode 100755
index 000000000..7129f1497
--- /dev/null
+++ b/mod/openid_server/start.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * Elgg openid server plugin
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.com/
+ */
+
+global $CONFIG;
+if (get_include_path())
+ set_include_path(get_include_path() . PATH_SEPARATOR . $CONFIG->path . 'mod/openid_api/vendors/php-openid/' . PATH_SEPARATOR . $CONFIG->path . 'mod/openid_server/');
+else
+ set_include_path($CONFIG->path . 'mod/openid_api/vendors/php-openid/' . PATH_SEPARATOR . $CONFIG->path . 'mod/openid_server/');
+
+elgg_register_event_handler('init','system','openid_server_init',1);
+
+function openid_server_init() {
+
+ global $CONFIG;
+ elgg_register_event_handler('login','user','openid_server_handle_login');
+ elgg_register_event_handler('logout','user','openid_server_handle_logout');
+
+ elgg_set_view_location("openid_server/forms/trust", $CONFIG->path.'mod/openid_server/views/');
+
+ $base = elgg_get_plugins_path() . 'openid_server/actions';
+ elgg_register_action('openid_server/trust', "$base/trust.php", 'public');
+
+ elgg_extend_view("page/elements/head", "openid_server/metatags");
+ elgg_extend_view("xrds/services", "openid_server/service");
+ elgg_extend_view("user/default", "openid_server/profile");
+}
+
+
+function openid_server_handle_login($event, $object_type, $object) {
+ global $CONFIG;
+
+ require_once('openid_server_include.php');
+
+ $store = getOpenIDServerStore();
+
+ if ($store->getAutoLoginSites()) {
+ forward($CONFIG->wwwroot.'mod/openid_server/actions/autologin.php');
+ }
+
+ return true;
+}
+
+function openid_server_handle_logout($event, $object_type, $object) {
+ global $CONFIG;
+
+ /*$store = getOpenIDServerStore();
+
+ if ($store->getAutoLogoutSites()) {
+ forward($CONFIG->wwwroot.'mod/openid_server/actions/autologout.php');
+ }*/
+
+ return true;
+}
+
+
+?>
diff --git a/mod/openid_server/views/default/forms/openid_server/trust.php b/mod/openid_server/views/default/forms/openid_server/trust.php
new file mode 100755
index 000000000..b9e4c3333
--- /dev/null
+++ b/mod/openid_server/views/default/forms/openid_server/trust.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * Elgg openid_server trust page
+ *
+ * @package openid_server
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardiner <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.com/
+ *
+ * @uses the following values in $vars:
+ *
+ * 'openid' the user's OpenID
+ * 'trust_root' the trust root for the OpenID client requesting authentication
+ */
+
+$user = elgg_get_logged_in_user_entity();
+$openid_trust_root = elgg_extract('openid_trust_root', $vars);
+
+echo '<div>' . elgg_echo('openid_server:trust_question', array($openid_trust_root, elgg_get_site_entity()->name . ":" . $user->username));
+
+/*echo '<div class="mll">'.elgg_view('input/checkbox', array(
+ 'name' => 'name',
+*/
+
+echo '<div class="elgg-footer">';
+echo elgg_view('input/hidden', array('name' => 'trust_root', 'value' => $openid_trust_root));
+echo elgg_view('input/submit', array('name' => 'trust', 'value' => elgg_echo('openid_server:confirm_trust')));
+echo elgg_view('input/submit', array('name' => 'reject', 'value' => elgg_echo('openid_server:reject_trust')));
+echo '</div>';
+
+echo '<div>'.elgg_view('input/checkbox', array('name' => 'remember', 'id' => 'remember', 'checked' => true));
+echo '<label for="remember">'.elgg_echo('openid_server:remember_trust') .'</label></div>';
diff --git a/mod/openid_server/views/default/openid_server/forms/admin.php b/mod/openid_server/views/default/openid_server/forms/admin.php
new file mode 100755
index 000000000..e19a97e8e
--- /dev/null
+++ b/mod/openid_server/views/default/openid_server/forms/admin.php
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * Elgg openid_server trust page
+ *
+ * @package openid_server
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardiner <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.com/
+ *
+ * @uses the following values in $vars:
+ *
+ * 'trust' the trust object with the database information and action type
+ */
+
+global $CONFIG;
+
+$trust = $vars['trust'];
+
+if (!$trust->ident) {
+ $trust->ident = 0;
+}
+
+$trust_root_msg = elgg_echo('openid_server:trust_root');
+$trust_site_msg = elgg_echo('openid_server:trust_site');
+$auto_login_msg = elgg_echo('openid_server:autologin_url');
+$auto_logout_msg = elgg_echo('openid_server:autologout_url');
+$iframe_width_msg = elgg_echo('openid_server:iframe_width');
+$iframe_height_msg = elgg_echo('openid_server:iframe_height');
+$explanation = elgg_echo('openid_server:admin_explanation');
+if ($trust->action == 'change') {
+ $button_msg = elgg_echo('openid_server:change_button');
+} else {
+ $button_msg = elgg_echo('openid_server:add_button');
+}
+
+
+$form = <<< END
+ <style type="text/css">
+ label,input {
+ display: block;
+ float: left;
+ margin-bottom: 5px;
+ }
+ label {
+ text-align: left;
+ width: 125px;
+ padding-right: 20px;
+ }
+ br {
+ clear: left;
+ }
+ </style>
+ $explanation
+ <form action="{$CONFIG->wwwroot}mod/openid_server/actions/admin.php" method="post">
+ <label for="trust_root">$trust_root_msg:</label> <input type="text" name="trust_root" size="80" value="{$trust->trust_root}"><br />
+ <label for="site_name">$trust_site_msg:</label> <input type="text" name="site_name" value="{$trust->site_name}"><br />
+ <label for="auto_login">$auto_login_msg:</label> <input type="text" name="auto_login" size="80" value="{$trust->auto_login}"><br />
+ <label for="auto_logout">$auto_logout_msg:</label> <input type="text" name="auto_logout" size="80" value="{$trust->auto_logout}"><br />
+ <label for="width">$iframe_width_msg:</label> <input type="text" name="width" size="10" value="{$trust->width}"><br />
+ <label for="height">$iframe_height_msg:</label> <input type="text" name="height" size="10" value="{$trust->height}"><br />
+ <input type="hidden" name="action" value="{$trust->action}">
+ <input type="hidden" name="trust_id" value="{$trust->ident}">
+ <input type="submit" name="submit" value="$button_msg">
+ </form>
+END;
+ return $form;
+}
+
+
+if (logged_on && run("users:flags:get", array("admin", $_SESSION['userid']))) {
+ $action = trim(optional_param('action'));
+ $trust_id = optional_param('trust_id',0,PARAM_INT);
+ $show_full_form = true;
+ $body = '';
+ if ($action) {
+ $trust = new StdClass;
+ $trust->trust_root = optional_param('trust_root');
+ $trust->site_name = optional_param('site_name');
+ $trust->auto_login = optional_param('auto_login');
+ $trust->auto_logout = optional_param('auto_logout');
+ $trust->width = optional_param('width');
+ $trust->height = optional_param('height');
+
+ switch($action) {
+ case 'change':
+ $trust->ident = $trust_id;
+ update_record('openid_server_trust',$trust);
+ $messages[] = gettext("Trust root updated");
+ break;
+ case 'add':
+ insert_record('openid_server_trust',$trust,false);
+ $messages[] = gettext("Trust root added");
+ break;
+ case 'delete':
+ delete_records('openid_server_trust','ident',$trust_id);
+ $messages[] = gettext("Trust root deleted");
+ break;
+ }
+ } else {
+ if ($trust_id) {
+ $trust = get_record('openid_server_trust','ident',$trust_id);
+ $trust->action = 'change';
+ $body = generate_trust_form($trust);
+ $title = gettext("Edit trust record");
+ $show_full_form = false;
+ }
+ }
+
+ if ($show_full_form) {
+ $edit_url = $CFG->wwwroot.'mod/openid_server/admin.php?trust_id=';
+ $delete_url = $CFG->wwwroot.'mod/openid_server/admin.php?action=delete&trust_id=';
+ $title = gettext("Manage default trust roots");
+ $results = get_records_sql("SELECT ident, site_name, trust_root FROM {$CFG->prefix}openid_server_trust WHERE openid_url IS NULL OR openid_url = ''");
+ if ($results) {
+ $body .= '<h2>'.gettext("Default trust roots").'</h2>'."\n";
+ $body.= '<table border="0">'."\n";
+ foreach($results as $item) {
+ $body .= '<tr><td width="150">'.$item->site_name.'</td><td width="250">'.$item->trust_root.'</td><td><a href="'
+ .$edit_url.$item->ident.'">'.gettext("Edit").'</a></td><td><a href="'
+ .$delete_url.$item->ident.'">'.gettext("Delete").'</a></td></tr>'."\n";
+ }
+ }
+ $body .= "</table>\n";
+ $body .= '<h2>'.gettext("Add default trust root").'</h2>';
+ $trust = new StdClass;
+ $trust->trust_root = '';
+ $trust->site_name = '';
+ $trust->auto_login = '';
+ $trust->auto_logout = '';
+ $trust->width = 0;
+ $trust->height = 0;
+ $trust->action = 'add';
+ $body .= generate_trust_form($trust);
+ }
+}
+
+define("context", "admin");
+
+templates_page_setup();
+
+echo templates_page_draw( array(
+ sitename,
+ templates_draw(array(
+ 'body' => $body,
+ 'title' => $title,
+ 'context' => 'contentholder'
+ )
+ )
+ )
+ );
+
+?>
diff --git a/mod/openid_server/views/default/openid_server/forms/autologin.php b/mod/openid_server/views/default/openid_server/forms/autologin.php
new file mode 100755
index 000000000..6880e1543
--- /dev/null
+++ b/mod/openid_server/views/default/openid_server/forms/autologin.php
@@ -0,0 +1,22 @@
+<!--
+/**
+ * Elgg openid_server: autologin form view
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.org/
+ */
+-->
+<html>
+<head>
+<title>
+<?php echo elgg_echo('openid_server:autologin_title'); ?>
+</title>
+<meta http-equiv="refresh" content="3;<?php echo $vars['return_url']; ?>"/>
+</head>
+<body>
+<?php echo elgg_echo('openid_server:autologin_body')."<br /><br />\n".$vars['iframes'] ?>
+</body>
+</html> \ No newline at end of file
diff --git a/mod/openid_server/views/default/openid_server/forms/autologout.php b/mod/openid_server/views/default/openid_server/forms/autologout.php
new file mode 100755
index 000000000..86b5c9682
--- /dev/null
+++ b/mod/openid_server/views/default/openid_server/forms/autologout.php
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Elgg openid_server: autologout form view
+ *
+ * @package ElggOpenID
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardine <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.org/
+ */
+
+ -->
+
+<html>
+<head>
+<title>
+<?php echo elgg_echo('openid_server:autologout_title'); ?>
+</title>
+<meta http-equiv="refresh" content="3;<?php echo $CONFIG->wwwroot; ?>"/>
+</head>
+<body>
+<?php echo elgg_echo('openid_server:autologout_body')."<br /><br />\n".$vars['iframes'] ?>
+</body>
+</html> \ No newline at end of file
diff --git a/mod/openid_server/views/default/openid_server/forms/trust.php b/mod/openid_server/views/default/openid_server/forms/trust.php
new file mode 100755
index 000000000..5a1e05ca1
--- /dev/null
+++ b/mod/openid_server/views/default/openid_server/forms/trust.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * Elgg openid_server trust page
+ *
+ * @package openid_server
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Kevin Jardiner <kevin@radagast.biz>
+ * @copyright Curverider Ltd 2008-2009
+ * @link http://elgg.com/
+ *
+ * @uses the following values in $vars:
+ *
+ * 'openid' the user's OpenID
+ * 'trust_root' the trust root for the OpenID client requesting authentication
+ */
+?>
+
+<div class="layout_canvas">
+<div class="one_column">
+<div class="contentWrapper">
+<div class="form">
+ <p><?php echo sprintf(elgg_echo('openid_server:trust_question'),$vars['openid_url'],$vars['openid_trust_root']) ?></p>
+ <form method="post" action="<?php echo $vars['url'] ?>mod/openid_server/actions/trust.php">
+ <input type="checkbox" name="remember" value="on" id="remember" /><label
+ for="remember"><?php echo elgg_echo('openid_server:remember_trust') ?></label>
+ <br />
+ <input type="hidden" name="trust_root" value="<?php echo $vars['openid_trust_root']; ?>" />
+ <input type="submit" name="trust" value="<?php echo elgg_echo('openid_server:confirm_trust') ?>" />
+ <input type="submit" name = "reject" value="<?php echo elgg_echo('openid_server:reject_trust') ?>" />
+ </form>
+</div>
+</div>
+</div>
+</div>
diff --git a/mod/openid_server/views/default/openid_server/metatags.php b/mod/openid_server/views/default/openid_server/metatags.php
new file mode 100755
index 000000000..eddc174d4
--- /dev/null
+++ b/mod/openid_server/views/default/openid_server/metatags.php
@@ -0,0 +1,6 @@
+<?php
+$owner = elgg_get_page_owner_entity();
+echo '<link rel="openid2.provider openid.server" href="' . elgg_get_site_url() . 'mod/openid_server/server.php" />';
+if ($owner) {
+ echo '<link rel="openid2.local_id openid.delegate" href="' . elgg_get_site_url() . 'profile/' . $owner->username . '" />';
+}
diff --git a/mod/openid_server/views/xrds/openid_server/profile.php b/mod/openid_server/views/xrds/openid_server/profile.php
new file mode 100644
index 000000000..9b34a6b7b
--- /dev/null
+++ b/mod/openid_server/views/xrds/openid_server/profile.php
@@ -0,0 +1,11 @@
+<?php
+ /*
+ XRDS info to validate delegated identities
+ */
+ $user = elgg_get_page_owner_entity();
+?>
+ <Service priority="0">
+ <Type>http://specs.openid.net/auth/2.0/signon</Type>
+ <LocalID><?php echo $vars['url']; ?>mod/openid_server/server.php</LocalID>
+ <URI><?php echo $vars['url']; ?>mod/openid_server/server.php</URI>
+ </Service>
diff --git a/mod/openid_server/views/xrds/openid_server/service.php b/mod/openid_server/views/xrds/openid_server/service.php
new file mode 100644
index 000000000..269df5c2e
--- /dev/null
+++ b/mod/openid_server/views/xrds/openid_server/service.php
@@ -0,0 +1,15 @@
+<?php
+ /*
+ XRD info to identify do eaut email to profile mapping
+ and identify openid 2.0 server.
+ */
+?>
+ <Service priority="0">
+ <Type>http://specs.eaut.org/1.0/template</Type>
+ <URI><?php echo $vars['url']; ?>profile/%7Busername%7D</URI>
+ </Service>
+ <Service priority="10">
+ <Type>http://specs.openid.net/auth/2.0/server</Type>
+ <URI><?php echo $vars['url']; ?>mod/openid_server/server.php</URI>
+ </Service>
+