Added support for sodium_crypto_aead_xchacha20poly1305_ietf encryption

This commit is contained in:
djmaze 2021-11-10 10:36:16 +01:00
parent 492dee5e1a
commit 414a9509aa
4 changed files with 66 additions and 21 deletions

View file

@ -696,7 +696,7 @@ trait Admin
public function DoAdminPHPExtensions() : array
{
$aResult = [];
foreach (['APCu', 'cURL','GD','Gmagick','Imagick','intl','LDAP','pdo_mysql','pdo_pgsql','pdo_sqlite','XXTEA','Zip'] as $name) {
foreach (['APCu', 'cURL','GD','Gmagick','Imagick','intl','LDAP','OpenSSL','pdo_mysql','pdo_pgsql','pdo_sqlite','Sodium','XXTEA','Zip'] as $name) {
$aResult[] = [
'name' => $name,
'loaded' => \extension_loaded(\strtolower($name))

View file

@ -235,9 +235,15 @@ trait UserAuth
$uuid = \SnappyMail\UUID::generate();
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
$data = \SnappyMail\Crypt::EncryptRaw($oAccount);
$data = \SnappyMail\Crypt::Encrypt($oAccount);
if ('xxtea' === $data[0]) {
static::SetSignMeTokenCookie(array(
'e' => $oAccount->Email(),
'u' => $uuid,
'x' => \base64_encode($data[1])
));
} else if ('sodium' === $data[0]) {
static::SetSignMeTokenCookie(array(
'e' => $oAccount->Email(),
'u' => $uuid,
@ -247,7 +253,7 @@ trait UserAuth
static::SetSignMeTokenCookie(array(
'e' => $oAccount->Email(),
'u' => $uuid,
'i' => \base64_encode($data[1])
'o' => \base64_encode($data[1])
));
}
@ -274,10 +280,12 @@ trait UserAuth
return null;
}
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
if (!empty($aTokenData['s'])) {
$aAccountHash = \SnappyMail\Crypt::XxteaDecrypt($sAuthToken, \base64_decode($aTokenData['s']));
} else if (!empty($aTokenData['i'])) {
$aAccountHash = \SnappyMail\Crypt::OpenSSLDecrypt($sAuthToken, \base64_decode($aTokenData['i']));
if (!empty($aTokenData['x'])) {
$aAccountHash = \SnappyMail\Crypt::XxteaDecrypt($sAuthToken, \base64_decode($aTokenData['x']));
} else if (!empty($aTokenData['s'])) {
$aAccountHash = \SnappyMail\Crypt::SodiumDecrypt($sAuthToken, \base64_decode($aTokenData['s']));
} else if (!empty($aTokenData['o'])) {
$aAccountHash = \SnappyMail\Crypt::OpenSSLDecrypt($sAuthToken, \base64_decode($aTokenData['o']));
}
if (!empty($aAccountHash) && \is_array($aAccountHash)) {
$oAccount = Account::NewInstanceFromTokenArray($this, $aAccountHash);

View file

@ -68,31 +68,53 @@ abstract class Crypt
);
}
public static function EncryptRaw($data) : array
public static function Encrypt($data) : array
{
if (\is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) {
$nonce = \random_bytes(24);
return ['sodium', $nonce, static::SodiumEncrypt($data, $nonce)];
}
if (static::$cipher && \is_callable('openssl_encrypt')) {
$iv = \random_bytes(\openssl_cipher_iv_length(static::$cipher));
$data = \openssl_encrypt(
\json_encode($data),
static::$cipher,
static::Passphrase(),
OPENSSL_RAW_DATA,
$iv
);
return [static::$cipher, $iv, $data];
return ['openssl', $nonce, static::OpenSSLEncrypt($data, $iv)];
}
$salt = \random_bytes(16);
return ['xxtea', $salt, static::XxteaEncrypt($data, $salt)];
}
public static function OpenSSLDecrypt(string $data, string $iv)
public static function SodiumDecrypt(string $data, string $nonce)
{
if (!$data || !$iv) {
if (!\is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) {
return null;
}
if (!static::$cipher || !\is_callable('openssl_decrypt')) {
return static::XxteaDecrypt($data, $iv);
return \json_decode(\sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
$data,
APP_SALT,
$nonce,
static::Passphrase()
));
}
public static function SodiumEncrypt($data, string $nonce) : ?string
{
if (!\is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) {
return null;
}
return \sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
\json_encode($data),
APP_SALT,
$nonce,
\str_pad('', \SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES, static::Passphrase())
);
}
public static function OpenSSLDecrypt(string $data, string $iv)
{
if (!$data || !$iv || !static::$cipher || !\is_callable('openssl_decrypt')) {
return null;
}
return \json_decode(\openssl_decrypt(
$data,
@ -103,6 +125,20 @@ abstract class Crypt
), true);
}
public static function OpenSSLEncrypt($data, string $iv) : ?string
{
if (!$data || !$iv || !static::$cipher || !\is_callable('openssl_encrypt')) {
return null;
}
return \openssl_encrypt(
\json_encode($data),
static::$cipher,
static::Passphrase(),
OPENSSL_RAW_DATA,
$iv
);
}
public static function XxteaDecrypt(string $data, string $salt)
{
if (!$data || !$salt) {
@ -115,7 +151,7 @@ abstract class Crypt
, true);
}
public static function XxteaEncrypt($data, string $salt) : string
public static function XxteaEncrypt($data, string $salt) : ?string
{
if (!$data || !$salt) {
return null;

View file

@ -20,6 +20,7 @@
'OpenSSL' => extension_loaded('openssl'),
'mysql' => extension_loaded('pdo_mysql'),
'pgsql' => extension_loaded('pdo_pgsql'),
'Sodium' => extension_loaded('sodium'),
'sqlite' => extension_loaded('pdo_sqlite'),
'xxtea' => extension_loaded('xxtea'),
'zip' => extension_loaded('zip')