mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 17:07:03 +03:00
Added support for sodium_crypto_aead_xchacha20poly1305_ietf encryption
This commit is contained in:
parent
492dee5e1a
commit
414a9509aa
4 changed files with 66 additions and 21 deletions
|
|
@ -696,7 +696,7 @@ trait Admin
|
||||||
public function DoAdminPHPExtensions() : array
|
public function DoAdminPHPExtensions() : array
|
||||||
{
|
{
|
||||||
$aResult = [];
|
$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[] = [
|
$aResult[] = [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'loaded' => \extension_loaded(\strtolower($name))
|
'loaded' => \extension_loaded(\strtolower($name))
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,15 @@ trait UserAuth
|
||||||
|
|
||||||
$uuid = \SnappyMail\UUID::generate();
|
$uuid = \SnappyMail\UUID::generate();
|
||||||
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
|
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
|
||||||
$data = \SnappyMail\Crypt::EncryptRaw($oAccount);
|
$data = \SnappyMail\Crypt::Encrypt($oAccount);
|
||||||
|
|
||||||
if ('xxtea' === $data[0]) {
|
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(
|
static::SetSignMeTokenCookie(array(
|
||||||
'e' => $oAccount->Email(),
|
'e' => $oAccount->Email(),
|
||||||
'u' => $uuid,
|
'u' => $uuid,
|
||||||
|
|
@ -247,7 +253,7 @@ trait UserAuth
|
||||||
static::SetSignMeTokenCookie(array(
|
static::SetSignMeTokenCookie(array(
|
||||||
'e' => $oAccount->Email(),
|
'e' => $oAccount->Email(),
|
||||||
'u' => $uuid,
|
'u' => $uuid,
|
||||||
'i' => \base64_encode($data[1])
|
'o' => \base64_encode($data[1])
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,10 +280,12 @@ trait UserAuth
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
|
\SnappyMail\Crypt::setCipher($this->Config()->Get('security', 'encrypt_cipher', ''));
|
||||||
if (!empty($aTokenData['s'])) {
|
if (!empty($aTokenData['x'])) {
|
||||||
$aAccountHash = \SnappyMail\Crypt::XxteaDecrypt($sAuthToken, \base64_decode($aTokenData['s']));
|
$aAccountHash = \SnappyMail\Crypt::XxteaDecrypt($sAuthToken, \base64_decode($aTokenData['x']));
|
||||||
} else if (!empty($aTokenData['i'])) {
|
} else if (!empty($aTokenData['s'])) {
|
||||||
$aAccountHash = \SnappyMail\Crypt::OpenSSLDecrypt($sAuthToken, \base64_decode($aTokenData['i']));
|
$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)) {
|
if (!empty($aAccountHash) && \is_array($aAccountHash)) {
|
||||||
$oAccount = Account::NewInstanceFromTokenArray($this, $aAccountHash);
|
$oAccount = Account::NewInstanceFromTokenArray($this, $aAccountHash);
|
||||||
|
|
|
||||||
|
|
@ -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')) {
|
if (static::$cipher && \is_callable('openssl_encrypt')) {
|
||||||
$iv = \random_bytes(\openssl_cipher_iv_length(static::$cipher));
|
$iv = \random_bytes(\openssl_cipher_iv_length(static::$cipher));
|
||||||
$data = \openssl_encrypt(
|
return ['openssl', $nonce, static::OpenSSLEncrypt($data, $iv)];
|
||||||
\json_encode($data),
|
|
||||||
static::$cipher,
|
|
||||||
static::Passphrase(),
|
|
||||||
OPENSSL_RAW_DATA,
|
|
||||||
$iv
|
|
||||||
);
|
|
||||||
return [static::$cipher, $iv, $data];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$salt = \random_bytes(16);
|
$salt = \random_bytes(16);
|
||||||
return ['xxtea', $salt, static::XxteaEncrypt($data, $salt)];
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
if (!static::$cipher || !\is_callable('openssl_decrypt')) {
|
return \json_decode(\sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||||
return static::XxteaDecrypt($data, $iv);
|
$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(
|
return \json_decode(\openssl_decrypt(
|
||||||
$data,
|
$data,
|
||||||
|
|
@ -103,6 +125,20 @@ abstract class Crypt
|
||||||
), true);
|
), 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)
|
public static function XxteaDecrypt(string $data, string $salt)
|
||||||
{
|
{
|
||||||
if (!$data || !$salt) {
|
if (!$data || !$salt) {
|
||||||
|
|
@ -115,7 +151,7 @@ abstract class Crypt
|
||||||
, true);
|
, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function XxteaEncrypt($data, string $salt) : string
|
public static function XxteaEncrypt($data, string $salt) : ?string
|
||||||
{
|
{
|
||||||
if (!$data || !$salt) {
|
if (!$data || !$salt) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
'OpenSSL' => extension_loaded('openssl'),
|
'OpenSSL' => extension_loaded('openssl'),
|
||||||
'mysql' => extension_loaded('pdo_mysql'),
|
'mysql' => extension_loaded('pdo_mysql'),
|
||||||
'pgsql' => extension_loaded('pdo_pgsql'),
|
'pgsql' => extension_loaded('pdo_pgsql'),
|
||||||
|
'Sodium' => extension_loaded('sodium'),
|
||||||
'sqlite' => extension_loaded('pdo_sqlite'),
|
'sqlite' => extension_loaded('pdo_sqlite'),
|
||||||
'xxtea' => extension_loaded('xxtea'),
|
'xxtea' => extension_loaded('xxtea'),
|
||||||
'zip' => extension_loaded('zip')
|
'zip' => extension_loaded('zip')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue