aboutsummaryrefslogtreecommitdiff
path: root/mod/openid_server/Crypt/RSA/MathLoader.php
blob: de6c94642f0fb6db822dd8d81a72b374e97208c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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;
    }
}

?>