fix(apk): un faux mot de passe de synchro n'ouvre plus le depot, et il se verifie a l'enregistrement

- OpenContainer reutilisait la cle de l'ancien mot de passe : jamais tant
  qu'un nouveau n'est pas verifie
- un essai rate vidait FKey (parametres out TBytes) : derivation dans des
  locales, rangee seulement apres succes
- Save coffre ouvert : verification immediate (DoSync), le bon mot de passe
  est range dans le coffre scelle ; coffre ferme, le champ est grise

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-09-18 11:51:02 +01:00
parent ac97d6c207
commit 05fc75e8f8
2 changed files with 37 additions and 7 deletions
+27 -7
View File
@@ -972,12 +972,15 @@ end;
/// oublier trois fois - a l'editeur, puis au formulaire de creation.
function TForm8.OpenContainer(const AContainer, APwd: string): string;
var
LSalt: TBytes;
LIters: Integer;
LSalt, LNewKey, LNewSalt: TBytes;
LIters, LNewIters: Integer;
LSw: TStopwatch;
begin
LSw := TStopwatch.StartNew;
if (FKey <> nil) and ContainerKdfParams(AContainer, LSalt, LIters)
// LA CLE EN MAIN EST CELLE DE L'ANCIEN MOT DE PASSE. La reutiliser quand
// l'utilisateur vient d'en enregistrer un autre ouvrait le depot sans jamais
// essayer celui-ci : un mot de passe faux passait pour bon.
if (not FPwdUserSet) and (FKey <> nil) and ContainerKdfParams(AContainer, LSalt, LIters)
and (LIters = FKeyIters) and (Length(LSalt) = Length(FKeySalt))
and CompareMem(Pointer(LSalt), Pointer(FKeySalt), Length(LSalt)) then
begin
@@ -986,7 +989,14 @@ begin
[LSw.ElapsedMilliseconds]));
Exit;
end;
Result := DecryptContainerEx(AContainer, APwd, FKey, FKeySalt, FKeyIters);
// DANS DES LOCALES, rangees seulement apres un dechiffrement reussi : les
// parametres `out` de type TBytes sont vides des l'appel, et un essai rate
// effacait la bonne cle - la publication suivante aurait alors re-derive
// avec le mauvais mot de passe.
Result := DecryptContainerEx(AContainer, APwd, LNewKey, LNewSalt, LNewIters);
FKey := LNewKey;
FKeySalt := LNewSalt;
FKeyIters := LNewIters;
Log(Format(' key derived in %d ms', [LSw.ElapsedMilliseconds]));
end;
@@ -1798,7 +1808,16 @@ begin
FUrl := TNetEncoding.URL.Decode(Param('u')).Trim;
FToken := TNetEncoding.URL.Decode(Param('t')).Trim;
FPwd := TNetEncoding.URL.Decode(Param('p'));
if FPwd <> FPwdShown then FPwdUserSet := True;
if FPwd <> FPwdShown then
begin
FPwdUserSet := True;
FPwdShown := FPwd;
// COFFRE OUVERT : on verifie tout de suite (DoSync retelecharge et
// dechiffre sous ce mot de passe), et un bon mot de passe est range
// dans le coffre scelle - le seul endroit ou il survit a la fermeture.
if (FPlain <> '') and (FUrl <> '') and (FToken <> '') and (FPwd <> '') then
TThread.ForceQueue(nil, procedure begin DoSync(nil); end);
end;
FPin := TNetEncoding.URL.Decode(Param('c'));
// L'empreinte du mot de passe AUSSI : si une saisie destinee au jeton
// atterrit dans le champ voisin - les deux sont masques - c'est celle-ci
@@ -2276,8 +2295,9 @@ begin
else if FPwdUserSet then
begin
// L'utilisateur a enregistre un autre mot de passe de synchro depuis :
// c'est lui qui sert, bon ou mauvais - la synchro le dira.
FSyncPwd := FPwd;
// il RESTE dans les reglages (FPwd), mais seul celui du cache - verifie -
// sert au rafraichissement de fond. Le nouveau se verifie par Sync.
FSyncPwd := LPwd;
Log(' sync password set in Settings kept over the cached one');
end
else