Example #1
0
 /**
  * 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($in[$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);
 }
Example #2
0
 /**
  * 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;
 }
Example #3
0
 /**
  * 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;
 }