fix(core): stop corrupted state from permanently breaking SSL and wallet loading

CertificatePinStore.Load threw on a corrupted pin file, blocking every SSL
connection until the user manually deleted it; EncryptedFile.IsEncrypted
threw on valid JSON with a non-object root or invalid UTF-16 instead of
returning false. Both now degrade gracefully. Found by property-based tests
while extending the test suite.
This commit is contained in:
2026-07-02 23:19:43 +02:00
parent eb7ec9e835
commit 27231c8eec
2 changed files with 24 additions and 5 deletions
+15 -4
View File
@@ -58,10 +58,21 @@ public sealed class CertificatePinStore(string filePath)
} }
} }
private Dictionary<string, string> Load() => private Dictionary<string, string> Load()
File.Exists(filePath) {
? JsonSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllText(filePath)) ?? [] if (!File.Exists(filePath))
: []; return [];
try
{
return JsonSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllText(filePath)) ?? [];
}
catch (JsonException)
{
// A corrupt pin file must not make every SSL connection fail forever:
// fall back to first-contact TOFU (same trust level as the bootstrap).
return [];
}
}
private void Save(Dictionary<string, string> pins) private void Save(Dictionary<string, string> pins)
{ {
+9 -1
View File
@@ -26,13 +26,21 @@ public static class EncryptedFile
try try
{ {
using var doc = JsonDocument.Parse(fileContent); using var doc = JsonDocument.Parse(fileContent);
return doc.RootElement.TryGetProperty("Format", out var f) return doc.RootElement.ValueKind == JsonValueKind.Object
&& doc.RootElement.TryGetProperty("Format", out var f)
&& f.ValueKind == JsonValueKind.String
&& f.GetString() == Format; && f.GetString() == Format;
} }
catch (JsonException) catch (JsonException)
{ {
return false; return false;
} }
catch (ArgumentException)
{
// Invalid UTF-16 (lone surrogates) cannot be transcoded for parsing:
// certainly not an encrypted container.
return false;
}
} }
public static string Encrypt(string plaintext, string password) public static string Encrypt(string plaintext, string password)