Improve security of SensitiveString

This commit is contained in:
the-djmaze 2023-12-04 01:36:21 +01:00
parent b7b266defc
commit 95ec5e6bb0

View file

@ -2,23 +2,10 @@
namespace SnappyMail; namespace SnappyMail;
function xorIt(
#[\SensitiveParameter]
string $value
) : string
{
$key = APP_SALT;
$kl = \strlen($key);
$i = \strlen($value);
while ($i--) {
$value[$i] = $value[$i] ^ $key[$i % $kl];
}
return $value;
}
class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ implements \Stringable class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ implements \Stringable
{ {
private string $value, $nonce; private string $value, $nonce;
private static ?string $key = null;
public function __construct( public function __construct(
#[\SensitiveParameter] #[\SensitiveParameter]
@ -31,9 +18,9 @@ class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */
public function getValue(): string public function getValue(): string
{ {
if (\is_callable('sodium_crypto_secretbox')) { if (\is_callable('sodium_crypto_secretbox')) {
return \sodium_crypto_secretbox_open($this->value, $this->nonce, APP_SALT); return \sodium_crypto_secretbox_open($this->value, $this->nonce, static::$key);
} }
return xorIt($this->value); return static::xorIt($this->value);
} }
public function setValue( public function setValue(
@ -43,13 +30,31 @@ class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */
{ {
if (\is_callable('sodium_crypto_secretbox')) { if (\is_callable('sodium_crypto_secretbox')) {
$this->nonce = \random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $this->nonce = \random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
// $this->key = \sodium_crypto_secretbox_keygen(); if (!static::$key) {
$this->value = \sodium_crypto_secretbox($value, $this->nonce, APP_SALT); static::$key = \sodium_crypto_secretbox_keygen();
}
$this->value = \sodium_crypto_secretbox($value, $this->nonce, static::$key);
} else { } else {
$this->value = xorIt($value); $this->value = static::xorIt($value);
} }
} }
private static function xorIt(
#[\SensitiveParameter]
string $value
) : string
{
if (!static::$key) {
static::$key = \random_bytes(32);
}
$kl = \strlen(static::$key);
$i = \strlen($value);
while ($i--) {
$value[$i] = $value[$i] ^ static::$key[$i % $kl];
}
return $value;
}
public function __toString(): string public function __toString(): string
{ {
return $this->getValue(); return $this->getValue();
@ -62,11 +67,11 @@ class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */
public function __serialize(): array public function __serialize(): array
{ {
throw new \Exception("Serialization of 'SensitiveString' is not allowed"); throw new \Exception("Serialization of 'SnappyMail\\SensitiveString' is not allowed");
} }
public function __unserialize(array $data): void public function __unserialize(array $data): void
{ {
throw new \Exception("Unserialization of 'SensitiveString' is not allowed"); throw new \Exception("Unserialization of 'SnappyMail\\SensitiveString' is not allowed");
} }
} }