feat(android): dire pourquoi le cache est illisible, et accepter un mot de passe comme code

"Local vault unreadable" laissait croire a une corruption, donc a une
perte, alors que le coffre est intact dans le depot. Quand Android a
lui-meme detruit la cle - verrouillage d'ecran retire ou reinitialise -
l'application le dit maintenant, et dit aussi que rien n'est perdu.

Le tri passe par un drapeau pose la ou l'invalidation se constate, pas
par un test sur le texte du message : c'est ce tri-la, fait sur des
chaines, qui detruisait autrefois le cache en se trompant.

Le code de deverrouillage accepte un mot de passe, et l'a toujours
accepte - aucune validation n'a jamais impose des chiffres. Seul
inputmode="numeric" le laissait croire, et le clavier numerique
decourageait d'essayer. Clavier complet, libelles et note mis a jour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-08-28 15:24:29 +01:00
parent 8b4130f13e
commit ea2450abfd
3 changed files with 44 additions and 7 deletions
+16
View File
@@ -101,6 +101,15 @@ procedure SaveVault(const APlainJson, AETag, ASyncPwd: string;
const ASalt: TBytes = nil; AIterations: Integer = 0;
AClearPin: Boolean = False);
/// VRAI quand la derniere lecture a echoue parce que la cle protegee a ete
/// DETRUITE par le systeme - verrouillage d'ecran retire ou reinitialise.
///
/// Un drapeau, et non un test sur le texte du message : c'est exactement ce
/// tri-la, fait sur des chaines, qui detruisait autrefois le cache en se
/// trompant. Ici l'information vient du systeme lui-meme, une seule fois, a
/// l'endroit ou elle est certaine.
function LastStoreKeyInvalidated: Boolean;
/// Le fichier local est-il scelle sous un code d'application ? Lu dans
/// l'en-tete, sans rien dechiffrer.
function VaultNeedsPin: Boolean;
@@ -241,12 +250,18 @@ const
var
FLastStoreError: string = '';
FLastStoreKeyInvalidated: Boolean = False;
function LastStoreError: string;
begin
Result := FLastStoreError;
end;
function LastStoreKeyInvalidated: Boolean;
begin
Result := FLastStoreKeyInvalidated;
end;
function LocalContainerPath: string;
begin
Result := TPath.Combine(TPath.GetHomePath, LOCAL_FILE);
@@ -1217,6 +1232,7 @@ begin
// rien ne pourra rouvrir.
if Pos('KeyPermanentlyInvalidated', E.ClassName + E.Message) > 0 then
try
FLastStoreKeyInvalidated := True;
OpenKeyStore.deleteEntry(StringToJString(KEY_ALIAS_WRAP));
FLastStoreError := FLastStoreError + ' (cle invalidee, jetee)';
except
+13 -6
View File
@@ -410,8 +410,13 @@
JAMAIS PRE-REMPLI : le retenir reviendrait a ne rien proteger. -->
<div id="pinbox">
<div class="in-wrap">
<input class="field-in" id="pin" placeholder="unlock code"
type="password" inputmode="numeric" autocomplete="off">
<!-- PAS DE inputmode="numeric". Rien n'a jamais impose des chiffres -
aucune validation ne filtre, ni ici ni cote Delphi - mais le
clavier numerique le laissait croire, et personne n'essayait un
mot de passe. Le clavier complet rend le choix visible ; les
chiffres y sont toujours. -->
<input class="field-in" id="pin" placeholder="unlock code or password"
type="password" autocomplete="off">
<div class="in-x" data-clear="pin">&#215;</div>
</div>
</div>
@@ -539,14 +544,16 @@
<h2>Unlock code</h2>
<div class="in-wrap">
<input class="field-in" id="sPinNew" placeholder="new unlock code"
type="password" inputmode="numeric" autocomplete="off">
<input class="field-in" id="sPinNew" placeholder="new unlock code or password"
type="password" autocomplete="off">
<div class="in-x" data-clear="sPinNew">&#215;</div>
</div>
<button class="btn wide" id="sPinSet">Set this code</button>
<button class="btn wide danger" id="sPinClear">Remove the unlock code</button>
<div class="note">The code seals the copy kept on this device. Removing it
leaves the vault readable by anyone holding the phone unlocked.</div>
<div class="note">The code seals the copy kept on this device. It can be
digits or a full password - a longer one is harder to guess, and it is
asked for only when the vault opens. Removing it leaves the vault
readable by anyone holding the phone unlocked.</div>
<h2>Diagnostics</h2>
<button class="btn wide" id="sLog">Show the log</button>