Now the MainAccount CryptKey is sealed.

This way change-password extension, Oauth2 and others can easily change the cryptkey seal withoug loosing decrypt functionality
This commit is contained in:
the-djmaze 2024-03-17 14:53:45 +01:00
parent 8c033f53fa
commit 9ccd616132
3 changed files with 20 additions and 32 deletions

View file

@ -201,6 +201,7 @@ class ChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
$oAccount->SetPassword($oNewPassword); $oAccount->SetPassword($oNewPassword);
if ($oAccount instanceof \RainLoop\Model\MainAccount) { if ($oAccount instanceof \RainLoop\Model\MainAccount) {
$oActions->SetAuthToken($oAccount); $oActions->SetAuthToken($oAccount);
$oAccount->resealCryptKey($oPrevPassword);
} }
return $this->jsonResponse(__FUNCTION__, $oActions->AppData(false)); return $this->jsonResponse(__FUNCTION__, $oActions->AppData(false));

View file

@ -77,8 +77,8 @@ class LoginOAuth2Plugin extends \RainLoop\Plugins\AbstractPlugin
* So we need to securely save a cryptkey. * So we need to securely save a cryptkey.
* Encrypted using the old/new refresh token is an option: * Encrypted using the old/new refresh token is an option:
* 1. decrypt cryptkey with the old refresh token * 1. decrypt cryptkey with the old refresh token
* 2. $oAccount->SetCryptKey('cryptkey') * 2. encrypt cryptkey with the new refresh token
* 3. encrypt cryptkey with the new refresh token * = $oAccount->resealCryptKey(new \SnappyMail\SensitiveString('old refresh token'))
*/ */
} }
} }

View file

@ -10,59 +10,46 @@ use SnappyMail\SensitiveString;
class MainAccount extends Account class MainAccount extends Account
{ {
private ?SensitiveString $sCryptKey = null; private ?SensitiveString $sCryptKey = null;
/*
public function resealCryptKey( public function resealCryptKey(SensitiveString $oOldPass) : bool
#[\SensitiveParameter]
string $sOldPass,
#[\SensitiveParameter]
string $sNewPass
) : bool
{ {
$oStorage = \RainLoop\Api::Actions()->StorageProvider(); $sKey = $this->CryptKey();
$sKey = $oStorage->Get($this, StorageType::ROOT, '.cryptkey');
if ($sKey) { if ($sKey) {
$sKey = \SnappyMail\Crypt::DecryptUrlSafe($sKey, $sOldPass); $sKey = \SnappyMail\Crypt::EncryptToJSON(\bin2hex($sKey), $this->IncPassword());
if ($sKey) { if ($sKey) {
$sKey = \SnappyMail\Crypt::EncryptUrlSafe($sKey, $sNewPass); \RainLoop\Api::Actions()->StorageProvider()->Put($this, StorageType::ROOT, '.cryptkey', $sKey);
$sKey = \SnappyMail\Crypt::DecryptFromJSON($sKey, $this->IncPassword());
if ($sKey) { if ($sKey) {
$oStorage->Put($this, StorageType::ROOT, '.cryptkey', $sKey); $this->sCryptKey = new SensitiveString(\hex2bin($sKey));
$sKey = \SnappyMail\Crypt::DecryptUrlSafe($sKey, $sNewPass);
$this->SetCryptKey($sKey);
return true;
} }
return true;
} }
} }
return false; return false;
} }
*/
public function CryptKey() : string public function CryptKey() : string
{ {
if (!$this->sCryptKey) { if (!$this->sCryptKey) {
$sKey = \sha1($this->IncPassword() . APP_SALT, true);
/*
// Seal the cryptkey so that people who change their login password // Seal the cryptkey so that people who change their login password
// can use the old password to re-seal the cryptkey // can use the old password to re-seal the cryptkey
$oStorage = \RainLoop\Api::Actions()->StorageProvider(); $oStorage = \RainLoop\Api::Actions()->StorageProvider();
$sKey = $oStorage->Get($this, StorageType::ROOT, '.cryptkey'); $sKey = $oStorage->Get($this, StorageType::ROOT, '.cryptkey');
if (!$sKey) { if (!$sKey) {
$sKey = \sha1($this->IncPassword() . APP_SALT, true); $sKey = \SnappyMail\Crypt::EncryptToJSON(
$sKey = \SnappyMail\Crypt::EncryptUrlSafe($sKey, $this->IncPassword()); \sha1($this->IncPassword() . APP_SALT),
$this->IncPassword()
);
$oStorage->Put($this, StorageType::ROOT, '.cryptkey', $sKey); $oStorage->Put($this, StorageType::ROOT, '.cryptkey', $sKey);
} }
$sKey = \SnappyMail\Crypt::DecryptUrlSafe($sKey, $this->IncPassword()); $sKey = \SnappyMail\Crypt::DecryptFromJSON($sKey, $this->IncPassword());
*/ if ($sKey) {
$this->SetCryptKey($sKey); $this->sCryptKey = new SensitiveString(\hex2bin($sKey));
}
} }
return $this->sCryptKey; return $this->sCryptKey;
} }
public function SetCryptKey(
#[\SensitiveParameter]
string $sKey
) : void
{
$this->sCryptKey = new SensitiveString($sKey);
}
/* /*
// Stores settings in MainAccount // Stores settings in MainAccount
public function settings() : \RainLoop\Settings public function settings() : \RainLoop\Settings