perf(android): the derived key is kept in the cache
Opening from the cache derives nothing, so the key learned last session was gone and the FIRST save of every session paid the 4.5 seconds again. It now travels in the sealed blob, next to the plaintext vault and to the password that opens the container - that neighbourhood is what makes it acceptable: it exposes nothing the file does not already hold. The three parts go together or not at all. A key without its salt does not say what it fits, which makes it useless, or worse, used where it does not belong. A cache written by an earlier version carries none: LoadVault returns nil, one derivation happens, and the next write stores it. A freshly registered vault still derives once - EncryptContainer does not hand back the key it just derived. The plan records what the desktop confirmed: the two entries created on the phone imported with nothing to correct.
This commit is contained in:
+20
-9
@@ -717,7 +717,8 @@ begin
|
||||
Log(Format('save: re-encrypt in %d ms', [LSw.ElapsedMilliseconds]));
|
||||
SaveLocalContainer(LBody);
|
||||
try
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False, FPin);
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
end;
|
||||
@@ -768,7 +769,8 @@ begin
|
||||
// prochaine ouverture pour retrouver ce qu'on vient d'ecrire.
|
||||
FETag := LPut.ETag;
|
||||
try
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False, FPin);
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
end;
|
||||
@@ -1147,7 +1149,8 @@ begin
|
||||
// Pas d'ETag : rien n'a ete publie. Le cache s'ecrit quand meme, sinon
|
||||
// la prochaine ouverture redemanderait six secondes de derivation pour
|
||||
// un coffre vide.
|
||||
SaveVault(LPlain, '', APwd, BiometricAvailable, False, FPin);
|
||||
SaveVault(LPlain, '', APwd, BiometricAvailable, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
TThread.Queue(nil,
|
||||
procedure
|
||||
begin
|
||||
@@ -1217,7 +1220,8 @@ begin
|
||||
TThread.Queue(nil, procedure
|
||||
begin Log('Vault belongs to ' + LOwner + ', not ' + AUser); end);
|
||||
|
||||
SaveVault(LPlain, FETag, APwd, BiometricAvailable, False, FPin);
|
||||
SaveVault(LPlain, FETag, APwd, BiometricAvailable, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
TThread.Queue(nil,
|
||||
procedure
|
||||
begin
|
||||
@@ -1252,7 +1256,10 @@ begin
|
||||
// scelle, la mise en forme vers la page, ou le rafraichissement de fond qui
|
||||
// suit - sinon on cherche au hasard.
|
||||
LSw := TStopwatch.StartNew;
|
||||
if LoadVault(LPlain, LETag, LPwd, FPin) then
|
||||
// LA CLE REVIENT AVEC LE CACHE, et c'est tout l'objet de l'y avoir mise :
|
||||
// ouvrir depuis le cache ne derive rien, donc sans cela le PREMIER
|
||||
// enregistrement de chaque session repayait les quatre secondes et demie.
|
||||
if LoadVault(LPlain, LETag, LPwd, FKey, FKeySalt, FKeyIters, FPin) then
|
||||
begin
|
||||
Log('Vault opened from cache in ' + LSw.ElapsedMilliseconds.ToString + ' ms');
|
||||
FETag := LETag;
|
||||
@@ -1284,7 +1291,8 @@ begin
|
||||
if (FPin <> '') and (not VaultNeedsPin) then
|
||||
begin
|
||||
try
|
||||
SaveVault(LPlain, LETag, LPwd, False, False, FPin);
|
||||
SaveVault(LPlain, LETag, LPwd, False, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
if VaultNeedsPin then
|
||||
Log('Cache re-sealed under the unlock code')
|
||||
else
|
||||
@@ -1300,7 +1308,8 @@ begin
|
||||
// protection a tres probablement invalide l'ancienne, et le
|
||||
// chiffrement ne saurait pas le voir - on scellerait un fichier
|
||||
// impossible a rouvrir.
|
||||
SaveVault(LPlain, LETag, LPwd, True, True, FPin);
|
||||
SaveVault(LPlain, LETag, LPwd, True, True, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
if VaultNeedsAuth then
|
||||
Log('Cache re-sealed under authentication')
|
||||
else
|
||||
@@ -1503,7 +1512,8 @@ begin
|
||||
begin
|
||||
// Le coffre local d'abord : s'il est la, on connait deja l'ETag et on
|
||||
// evite les 4 secondes de derivation quand rien n'a change.
|
||||
if (FETag = '') and LoadVault(LCached, LCachedETag, LCachedPwd, FPin) then
|
||||
if (FETag = '') and LoadVault(LCached, LCachedETag, LCachedPwd,
|
||||
FKey, FKeySalt, FKeyIters, FPin) then
|
||||
FETag := LCachedETag;
|
||||
|
||||
LClient := TSyncClient.Create(AUrl, ATok);
|
||||
@@ -1650,7 +1660,8 @@ begin
|
||||
try
|
||||
// Le mot de passe part avec le coffre : c'est lui qui permettra au
|
||||
// prochain lancement de rafraichir sans rien demander.
|
||||
SaveVault(LPlain, FETag, APwd, LCanAuth, False, FPin);
|
||||
SaveVault(LPlain, FETag, APwd, LCanAuth, False, FPin,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
Log(' cache now holds sha: ' + FETag);
|
||||
if VaultNeedsAuth then
|
||||
Log(' cache written - protected by biometrics/PIN')
|
||||
|
||||
Reference in New Issue
Block a user