<?php
namespace ParagonIE\CipherSweet\KeyProvider;
use ParagonIE\CipherSweet\Backend\Key\SymmetricKey;
use ParagonIE\CipherSweet\Contract\BackendInterface;
use ParagonIE\CipherSweet\Contract\KeyProviderInterface;
use ParagonIE\CipherSweet\Exception\CryptoOperationException;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\ConstantTime\Binary;
use ParagonIE\ConstantTime\Hex;
/**
* Class StringProvider
* @package ParagonIE\CipherSweet\KeyProvider
*/
class StringProvider implements KeyProviderInterface
{
/**
* @var BackendInterface $backend
*/
private $backend;
/**
* @var string $rootSymmetricKey
*/
private $rootSymmetricKey;
/**
* StringProvider constructor.
*
* @param BackendInterface $backend
* @param string $rawKey
*
* @throws CryptoOperationException
*/
public function __construct(BackendInterface $backend, $rawKey = '')
{
$this->backend = $backend;
if (Binary::safeStrlen($rawKey) === 64) {
$this->rootSymmetricKey = Hex::decode($rawKey);
} elseif (Binary::safeStrlen($rawKey) === 44) {
$this->rootSymmetricKey = Base64UrlSafe::decode($rawKey);
} elseif (Binary::safeStrlen($rawKey) === 32) {
$this->rootSymmetricKey = $rawKey;
} else {
throw new CryptoOperationException('Invalid key size');
}
}
/**
* Attempt to wipe memory.
*/
public function __destruct()
{
if (\extension_loaded('sodium')) {
\sodium_memzero($this->rootSymmetricKey);
} elseif (\extension_loaded('libsodium')) {
\Sodium\memzero($this->rootSymmetricKey);
} else {
// Worst-case scenario: Best-ditch effort to wipe memory
$m = \str_repeat("\xff", (int) Binary::safeStrlen($this->rootSymmetricKey));
$this->rootSymmetricKey ^= ($this->rootSymmetricKey ^ $m);
unset($this->rootSymmetricKey);
}
}
/**
* @return BackendInterface
*/
public function getBackend()
{
return $this->backend;
}
/**
* @return SymmetricKey
*/
public function getSymmetricKey()
{
return new SymmetricKey($this->backend, $this->rootSymmetricKey);
}
}
|