diff --git a/src/Symmetric/Mcrypt.php b/src/Symmetric/Mcrypt.php deleted file mode 100644 index 8fd3443..0000000 --- a/src/Symmetric/Mcrypt.php +++ /dev/null @@ -1,555 +0,0 @@ - 'rijndael-128', - 'blowfish' => 'blowfish', - 'des' => 'des', - '3des' => 'tripledes', - 'tripledes' => 'tripledes', - 'cast-128' => 'cast-128', - 'cast-256' => 'cast-256', - 'rijndael-128' => 'rijndael-128', - 'rijndael-192' => 'rijndael-192', - 'rijndael-256' => 'rijndael-256', - 'saferplus' => 'saferplus', - 'serpent' => 'serpent', - 'twofish' => 'twofish', - ]; - - /** - * Supported encryption modes - * - * @var array - */ - protected $supportedModes = [ - 'cbc' => 'cbc', - 'cfb' => 'cfb', - 'ctr' => 'ctr', - 'ofb' => 'ofb', - 'nofb' => 'nofb', - 'ncfb' => 'ncfb', - ]; - - /** - * Constructor - * - * @param array|Traversable $options - * @throws Exception\RuntimeException - * @throws Exception\InvalidArgumentException - */ - public function __construct($options = []) - { - if (PHP_VERSION_ID >= 70100) { - trigger_error( - 'The Mcrypt extension is deprecated from PHP 7.1+. ' - . 'We suggest to use Laminas\Crypt\Symmetric\Openssl.', - E_USER_DEPRECATED - ); - } - if (! extension_loaded('mcrypt')) { - throw new Exception\RuntimeException(sprintf( - 'You cannot use %s without the Mcrypt extension', - self::class - )); - } - $this->setOptions($options); - $this->setDefaultOptions($options); - } - - /** - * Set default options - * - * @param array $options - * @return void - */ - public function setOptions($options) - { - if (! empty($options)) { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (! is_array($options)) { - throw new Exception\InvalidArgumentException( - 'The options parameter must be an array or a Traversable' - ); - } - foreach ($options as $key => $value) { - switch (strtolower($key)) { - case 'algo': - case 'algorithm': - $this->setAlgorithm($value); - break; - case 'mode': - $this->setMode($value); - break; - case 'key': - $this->setKey($value); - break; - case 'iv': - case 'salt': - $this->setSalt($value); - break; - case 'padding': - $plugins = static::getPaddingPluginManager(); - $padding = $plugins->get($value); - $this->padding = $padding; - break; - } - } - } - } - - /** - * Set default options - * - * @param array $options - * @return void - */ - protected function setDefaultOptions($options = []) - { - if (! isset($options['padding'])) { - $plugins = static::getPaddingPluginManager(); - $padding = $plugins->get(self::DEFAULT_PADDING); - $this->padding = $padding; - } - } - - /** - * Returns the padding plugin manager. If it doesn't exist it's created. - * - * @return ContainerInterface - */ - public static function getPaddingPluginManager() - { - if (static::$paddingPlugins === null) { - self::setPaddingPluginManager(new PaddingPluginManager()); - } - - return static::$paddingPlugins; - } - - /** - * Set the padding plugin manager - * - * @param string|ContainerInterface $plugins - * @throws Exception\InvalidArgumentException - * @return void - */ - public static function setPaddingPluginManager($plugins) - { - if (is_string($plugins)) { - if (! class_exists($plugins) || ! is_subclass_of($plugins, ContainerInterface::class)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Unable to locate padding plugin manager via class "%s"; ' - . 'class does not exist or does not implement ContainerInterface', - $plugins - )); - } - $plugins = new $plugins(); - } - if (! $plugins instanceof ContainerInterface) { - throw new Exception\InvalidArgumentException(sprintf( - 'Padding plugins must implements Psr\Container\ContainerInterface; received "%s"', - is_object($plugins) ? get_class($plugins) : gettype($plugins) - )); - } - static::$paddingPlugins = $plugins; - } - - /** - * Get the maximum key size for the selected cipher and mode of operation - * - * @return int - */ - public function getKeySize() - { - return mcrypt_get_key_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]); - } - - /** - * Set the encryption key - * If the key is longer than maximum supported, it will be truncated by getKey(). - * - * @param string $key - * @return Mcrypt Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setKey($key) - { - $keyLen = mb_strlen($key, '8bit'); - - if (! $keyLen) { - throw new Exception\InvalidArgumentException('The key cannot be empty'); - } - $keySizes = mcrypt_module_get_supported_key_sizes($this->supportedAlgos[$this->algo]); - $maxKey = $this->getKeySize(); - - /* - * blowfish has $keySizes empty, meaning it can have arbitrary key length. - * the others are more picky. - */ - if (! empty($keySizes) && $keyLen < $maxKey) { - if (! in_array($keyLen, $keySizes)) { - throw new Exception\InvalidArgumentException(sprintf( - 'The size of the key must be %s bytes or longer', - implode(', ', $keySizes) - )); - } - } - $this->key = $key; - - return $this; - } - - /** - * Get the encryption key - * - * @return string - */ - public function getKey() - { - if (empty($this->key)) { - return; - } - return mb_substr($this->key, 0, $this->getKeySize(), '8bit'); - } - - /** - * Set the encryption algorithm (cipher) - * - * @param string $algo - * @return Mcrypt Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setAlgorithm($algo) - { - if (! array_key_exists($algo, $this->supportedAlgos)) { - throw new Exception\InvalidArgumentException(sprintf( - 'The algorithm %s is not supported by %s', - $algo, - self::class - )); - } - $this->algo = $algo; - - return $this; - } - - /** - * Get the encryption algorithm - * - * @return string - */ - public function getAlgorithm() - { - return $this->algo; - } - - /** - * Set the padding object - * - * @return Mcrypt Provides a fluent interface - */ - public function setPadding(Padding\PaddingInterface $padding) - { - $this->padding = $padding; - - return $this; - } - - /** - * Get the padding object - * - * @return Padding\PaddingInterface - */ - public function getPadding() - { - return $this->padding; - } - - /** - * Encrypt - * - * @param string $data - * @throws Exception\InvalidArgumentException - * @return string - */ - public function encrypt($data) - { - // Cannot encrypt empty string - if (! is_string($data) || $data === '') { - throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty'); - } - if (null === $this->getKey()) { - throw new Exception\InvalidArgumentException('No key specified for the encryption'); - } - if (null === $this->getSalt()) { - throw new Exception\InvalidArgumentException('The salt (IV) cannot be empty'); - } - if (null === $this->getPadding()) { - throw new Exception\InvalidArgumentException('You have to specify a padding method'); - } - // padding - $data = $this->padding->pad($data, $this->getBlockSize()); - $iv = $this->getSalt(); - // encryption - $result = mcrypt_encrypt( - $this->supportedAlgos[$this->algo], - $this->getKey(), - $data, - $this->supportedModes[$this->mode], - $iv - ); - - return $iv . $result; - } - - /** - * Decrypt - * - * @param string $data - * @throws Exception\InvalidArgumentException - * @return string - */ - public function decrypt($data) - { - if (empty($data)) { - throw new Exception\InvalidArgumentException('The data to decrypt cannot be empty'); - } - if (null === $this->getKey()) { - throw new Exception\InvalidArgumentException('No key specified for the decryption'); - } - if (null === $this->getPadding()) { - throw new Exception\InvalidArgumentException('You have to specify a padding method'); - } - $iv = mb_substr($data, 0, $this->getSaltSize(), '8bit'); - $ciphertext = mb_substr($data, $this->getSaltSize(), null, '8bit'); - $result = mcrypt_decrypt( - $this->supportedAlgos[$this->algo], - $this->getKey(), - $ciphertext, - $this->supportedModes[$this->mode], - $iv - ); - // unpadding - return $this->padding->strip($result); - } - - /** - * Get the salt (IV) size - * - * @return int - */ - public function getSaltSize() - { - return mcrypt_get_iv_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]); - } - - /** - * Get the supported algorithms - * - * @return array - */ - public function getSupportedAlgorithms() - { - return array_keys($this->supportedAlgos); - } - - /** - * Set the salt (IV) - * - * @param string $salt - * @return Mcrypt Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setSalt($salt) - { - if (empty($salt)) { - throw new Exception\InvalidArgumentException('The salt (IV) cannot be empty'); - } - if (mb_strlen($salt, '8bit') < $this->getSaltSize()) { - throw new Exception\InvalidArgumentException(sprintf( - 'The size of the salt (IV) must be at least %d bytes', - $this->getSaltSize() - )); - } - $this->iv = $salt; - - return $this; - } - - /** - * Get the salt (IV) according to the size requested by the algorithm - * - * @return string - */ - public function getSalt() - { - if (empty($this->iv)) { - return; - } - if (mb_strlen($this->iv, '8bit') < $this->getSaltSize()) { - throw new Exception\RuntimeException(sprintf( - 'The size of the salt (IV) must be at least %d bytes', - $this->getSaltSize() - )); - } - - return mb_substr($this->iv, 0, $this->getSaltSize(), '8bit'); - } - - /** - * Get the original salt value - * - * @return string - */ - public function getOriginalSalt() - { - return $this->iv; - } - - /** - * Set the cipher mode - * - * @param string $mode - * @return Mcrypt Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setMode($mode) - { - if (! empty($mode)) { - $mode = strtolower($mode); - if (! array_key_exists($mode, $this->supportedModes)) { - throw new Exception\InvalidArgumentException(sprintf( - 'The mode %s is not supported by %s', - $mode, - $this->algo - )); - } - $this->mode = $mode; - } - - return $this; - } - - /** - * Get the cipher mode - * - * @return string - */ - public function getMode() - { - return $this->mode; - } - - /** - * Get all supported encryption modes - * - * @return array - */ - public function getSupportedModes() - { - return array_keys($this->supportedModes); - } - - /** - * Get the block size - * - * @return int - */ - public function getBlockSize() - { - return mcrypt_get_block_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]); - } -} diff --git a/test/Symmetric/McryptDeprecatedTest.php b/test/Symmetric/McryptDeprecatedTest.php deleted file mode 100644 index cad84de..0000000 --- a/test/Symmetric/McryptDeprecatedTest.php +++ /dev/null @@ -1,25 +0,0 @@ -markTestSkipped('The Mcrypt deprecated test is for PHP 7.1+'); - } - } - - public function testDeprecated() - { - $this->expectDeprecation(); - new Mcrypt(); - } -}