Skip to main content

wire_desktop_core/
error.rs

1//! Typed errors for the Wire reader.
2//!
3//! The load-bearing one is [`WireError::EncryptedPayloadUnrecoverable`]: Wire
4//! encrypts message content client-side (Proteus), and that key is **not** held
5//! in the Chromium OS Safe Storage (unlike Signal/Chrome cookie keys). So when a
6//! caller asks for the plaintext of an encrypted payload we **fail loud** with a
7//! typed error rather than fabricate plausible-but-wrong bytes.
8
9use thiserror::Error;
10
11/// An error interpreting a Wire desktop IndexedDB store.
12#[non_exhaustive]
13#[derive(Debug, Error)]
14pub enum WireError {
15    /// The underlying IndexedDB/LevelDB store could not be read.
16    #[error("failed to read Wire IndexedDB store at {path}: {detail}")]
17    Read {
18        /// The directory that failed to read.
19        path: String,
20        /// The underlying reader's error, verbatim.
21        detail: String,
22    },
23
24    /// A Wire profile base directory did not contain the expected IndexedDB store.
25    #[error("Wire profile at {base} has no IndexedDB store at the expected path {relative}")]
26    StoreNotFound {
27        /// The profile base directory searched.
28        base: String,
29        /// The store path (from the forensicnomicon Wire spec) that was expected.
30        relative: String,
31    },
32
33    /// The caller asked for the plaintext of a client-side-encrypted payload.
34    ///
35    /// Wire's message key is not recoverable from this artifact, so the reader
36    /// refuses rather than fabricate plaintext. Surface the record's cleartext
37    /// metadata (conversation, sender, time) instead.
38    #[error(
39        "message payload is client-side (Proteus) encrypted; Wire's message key is NOT held in \
40         the Chromium OS Safe Storage, so the plaintext is unrecoverable from this artifact"
41    )]
42    EncryptedPayloadUnrecoverable,
43
44    /// The record value could not be decoded from its Blink/V8 structured-clone
45    /// blob upstream; its raw bytes were retained but no plaintext exists.
46    #[error("record value could not be decoded from its Blink/V8 blob: {0}")]
47    UndecodedValue(String),
48}