fix(android): le cache retient le secret qui ouvre CE coffre
La separation laissait FVaultPwd vide apres une ouverture depuis le cache - seules la creation et la connexion le posaient - et la reconciliation refusait donc en boucle, "open vault first" alors que le coffre etait ouvert. Le cache porte un secret et un seul : celui du conteneur local pour un coffre ne ici, celui du depot pour un coffre publie. Les deux ne coexistent jamais, puisque la reconciliation detruit le conteneur local en passant l'autorite au depot. CachePwd choisit a l'ecriture, et la relecture le range dans la meme case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+38
-15
@@ -322,6 +322,14 @@ type
|
||||
procedure PublishPending;
|
||||
/// Demande au depot s'il a bouge, sans rien adopter.
|
||||
procedure ProbeRemote;
|
||||
/// LE SECRET QUE LE CACHE DOIT RETENIR, et il n'y en a qu'un a la fois.
|
||||
///
|
||||
/// Un coffre ne ici s'ouvre par le mot de passe de son conteneur ; un
|
||||
/// coffre publie s'ouvre par le secret du depot. Les deux ne coexistent
|
||||
/// jamais - la reconciliation detruit le conteneur local en passant
|
||||
/// l'autorite au depot - donc une seule case suffit, a condition de
|
||||
/// toujours y mettre le bon.
|
||||
function CachePwd: string;
|
||||
/// Retire le code de deverrouillage : le cache se rescelle sous la seule
|
||||
/// cle de l'appareil. Exige un coffre ouvert.
|
||||
procedure ClearUnlockCode;
|
||||
@@ -965,7 +973,7 @@ begin
|
||||
|
||||
if LLocalOnly then SaveLocalContainer(LBody);
|
||||
try
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False,
|
||||
SaveVault(LNew, FETag, CachePwd, BiometricAvailable, False,
|
||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
@@ -1024,7 +1032,7 @@ begin
|
||||
// Le cache suit la fusion : sans cela il resterait sur notre
|
||||
// version d'avant, et le prochain essai repartirait de la.
|
||||
try
|
||||
SaveVault(LNew, FETag, FSyncPwd, BiometricAvailable, False,
|
||||
SaveVault(LNew, FETag, CachePwd, BiometricAvailable, False,
|
||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
@@ -1193,7 +1201,7 @@ begin
|
||||
begin
|
||||
FETag := LPut.ETag;
|
||||
try
|
||||
SaveVault(LMerged, FETag, FSyncPwd, BiometricAvailable, False,
|
||||
SaveVault(LMerged, FETag, CachePwd, BiometricAvailable, False,
|
||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
@@ -1354,7 +1362,7 @@ begin
|
||||
DropLocalContainer;
|
||||
FVaultPwd := '';
|
||||
try
|
||||
SaveVault(LMerged, FETag, FSyncPwd, BiometricAvailable, False,
|
||||
SaveVault(LMerged, FETag, CachePwd, BiometricAvailable, False,
|
||||
FPinSealed, FKey, FKeySalt, FKeyIters);
|
||||
except
|
||||
on E: Exception do Log(' cache not written: ' + E.Message);
|
||||
@@ -2012,15 +2020,25 @@ begin
|
||||
Log(' WARNING: cache has no fingerprint - the refresh will re-derive');
|
||||
if LPwd <> '' then
|
||||
begin
|
||||
FSyncPwd := LPwd;
|
||||
// ET LES REGLAGES AVEC. C'est ICI que tout passe - a chaque lancement -
|
||||
// et non par la creation ni par la connexion, qui n'arrivent qu'une fois.
|
||||
// Corriger celles-la seules ne changeait donc rien : PushConfig reposait
|
||||
// la valeur de premier lancement au demarrage, l'ouverture ne la
|
||||
// remplacait pas, et DoSync la PREFERE a celle du coffre.
|
||||
FPwd := LPwd;
|
||||
WebCall(Format('PM.setConfig(%s, %s, %s, false)',
|
||||
[JsArg(FUrl), JsArg(FToken), JsArg(FPwd)]));
|
||||
// DANS LA CASE QUI CONVIENT. Le cache d'un coffre ne ici porte le mot de
|
||||
// passe de son conteneur, pas un secret de depot : le ranger dans
|
||||
// FSyncPwd le ferait servir a sceller l'instantane, ce qu'on vient
|
||||
// justement de defaire. Et sans cette relecture, FVaultPwd restait vide
|
||||
// apres une ouverture depuis le cache - la reconciliation refusait alors
|
||||
// en boucle, "open vault first" alors que le coffre etait ouvert.
|
||||
if HasLocalContainer then
|
||||
FVaultPwd := LPwd
|
||||
else
|
||||
begin
|
||||
FSyncPwd := LPwd;
|
||||
// ET LES REGLAGES AVEC. C'est ICI que tout passe - a chaque lancement -
|
||||
// et non par la creation ni par la connexion, qui n'arrivent qu'une
|
||||
// fois : PushConfig reposait la valeur de premier lancement au
|
||||
// demarrage, l'ouverture ne la remplacait pas, et DoSync la PREFERE.
|
||||
FPwd := LPwd;
|
||||
WebCall(Format('PM.setConfig(%s, %s, %s, false)',
|
||||
[JsArg(FUrl), JsArg(FToken), JsArg(FPwd)]));
|
||||
end;
|
||||
end;
|
||||
|
||||
// LA PROTECTION RATTRAPE LE CACHE. Elle se decidait a l'ecriture seule,
|
||||
@@ -2866,7 +2884,7 @@ begin
|
||||
try
|
||||
// ARequireAuth a FAUX : les deux protections s'excluent, un cache scelle
|
||||
// par un code porte VER_PIN et non VER_WRAP.
|
||||
SaveVault(FPlain, FETag, FSyncPwd, False, False, ANew,
|
||||
SaveVault(FPlain, FETag, CachePwd, False, False, ANew,
|
||||
FKey, FKeySalt, FKeyIters);
|
||||
if not VaultNeedsPin then
|
||||
begin
|
||||
@@ -2890,6 +2908,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TForm8.CachePwd: string;
|
||||
begin
|
||||
if HasLocalContainer then Result := FVaultPwd else Result := FSyncPwd;
|
||||
end;
|
||||
|
||||
procedure TForm8.ClearUnlockCode;
|
||||
begin
|
||||
if FBusy then Exit;
|
||||
@@ -2906,7 +2929,7 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
try
|
||||
SaveVault(FPlain, FETag, FSyncPwd, BiometricAvailable, False, '',
|
||||
SaveVault(FPlain, FETag, CachePwd, BiometricAvailable, False, '',
|
||||
FKey, FKeySalt, FKeyIters, True);
|
||||
if VaultNeedsPin then
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user