. */ namespace SP\Core\Crypt; use Defuse\Crypto\Exception\CryptoException; use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use Defuse\Crypto\Key; use SP\Http\Request; use SP\Http\RequestInterface; /** * Class SecureKeyCookie * * @package SP\Core\Crypt */ class SecureKeyCookie extends Cookie { /** * Nombre de la cookie */ public const COOKIE_NAME = 'SYSPASS_SK'; /** * Llave usada para encriptar los datos */ private ?Key $securedKey = null; private ?string $cypher = null; public static function factory(RequestInterface $request): SecureKeyCookie { $self = new self(self::COOKIE_NAME, $request); $self->cypher = $self->getCypher(); return $self; } /** * Devolver la llave de cifrado para los datos de la cookie */ public function getCypher(): string { return sha1($this->request->getHeader('User-Agent') . $this->request->getClientAddress()); } /** * Obtener una llave de encriptación * * @return false|Key */ public function getKey() { $cookie = $this->getCookie(); if ($cookie !== false) { $data = $this->getCookieData($cookie, $this->cypher); if ($data !== false) { /** @var Vault $vault */ $vault = unserialize($data, ['allowed_classes' => Vault::class]); if (($vault instanceof Vault) === true ) { try { $this->securedKey = Key::loadFromAsciiSafeString($vault->getData($this->cypher)); return $this->securedKey; } catch (CryptoException $e) { logger($e->getMessage(), 'EXCEPTION'); } return false; } } else { logger('Cookie verification error', 'ERROR'); } } elseif (($this->securedKey instanceof Key) === true) { return $this->securedKey; } return $this->saveKey() ? $this->securedKey : false; } /** * Guardar una llave de encriptación */ public function saveKey(): bool { try { if ($this->setCookie($this->sign($this->generateSecuredData()->getSerialized(), $this->cypher)) === false) { logger('Could not generate session\'s key cookie', 'ERROR'); unset($this->securedKey); return false; } logger('Generating a new session\'s key cookie'); return true; } catch (CryptoException $e) { logger($e->getMessage(), 'EXCEPTION'); } return false; } /** * @throws CryptoException * @throws EnvironmentIsBrokenException */ public function generateSecuredData(): Vault { $this->securedKey = Key::createNewRandomKey(); return (new Vault()) ->saveData($this->securedKey->saveToAsciiSafeString(), $this->cypher); } public function getSecuredKey(): Key { return $this->securedKey; } }