Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support new backup file format #60

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

pascalgn
Copy link

Fixes #58

I updated the Backups.proto file from here: https://github.com/signalapp/Signal-Android/blob/c6473ca9e63236af3eae9959a50cfa643d53272e/app/src/main/protowire/Backups.proto

I changed it so that the length is decrypted. However, the decryption wasn't straightforward, because the length is not a separate block, so I had to adapt the existing decrypt function a bit

Decryption in Signal:

      int frameLength;
      if (BackupVersions.isFrameLengthEncrypted(version)) {
        mac.update(length);
        // this depends upon cipher being a stream cipher mode in order to get back the length without needing a full AES block-size input
        byte[] decryptedLength = cipher.update(length);
        if (decryptedLength.length != length.length) {
          throw new IOException("Cipher was not a stream cipher!");
        }
        frameLength = Conversions.byteArrayToInt(decryptedLength);
      } else {
        frameLength = Conversions.byteArrayToInt(length);
      }

signalapp/Signal-Android@c6473ca#diff-cf445f7d302fb0629f925b7cf39cb340defe74a485bb7756159c6c9c86b31c0f

@pajowu
Copy link
Owner

pajowu commented Aug 13, 2023

🫶 thanks for digging into this and creating a PR. I’ll try to test it as soon as possible, but since i’m at ccc-camp, this might not be until next week. If you didn’t hear anything back until end of next week, please ping me

@ribbons
Copy link

ribbons commented Sep 2, 2023

From me instead of @pascalgn and a bit more than a week later but here's a gentle nudge 😄

@SloppyPuppy
Copy link

Plz someone merge a fix for this, pascalgn patch works, just need to run cargo update so the build doesn't fail.

@RndUsername
Copy link

@pajowu ping...

@frans-fuerst
Copy link

frans-fuerst commented Oct 29, 2023

For me the change works for newer backup files but older fail (for different reasons):

path/to/signal-backup-decode/target/debug/signal-backup-decode -f /path/to/signal-2021-08-27-09-11-17.backup --password-file /path/to/pw-file
16:32:35 [INFO] Output path: signal-2021-08-27-09-11-17
16:32:35 [INFO] Input file: /path/to/signal-2021-08-27-09-11-17.backup
             Bytes read: [00:00:06] [--------------------------------------------------] 0B/2.15GB
Read vs. written frames: [00:00:06] [--------------------------------------------------]     0/1    
16:32:43 [ERROR] failed to fill whole buffer.
path/to/signal-backup-decode/target/debug/signal-backup-decode -f /path/to/signal-2023-02-10-00-34-13.backup --password-file /path/to/pw-file
16:33:07 [INFO] Output path: signal-2023-02-10-00-34-13
16:33:07 [INFO] Input file: /path/to/signal-2023-02-10-00-34-13.backup
thread '<unnamed>' panicked at /home/frans/.cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-0.10.32/src/symm.rs:597:13:
assertion failed: output.len() <= c_int::max_value() as usize
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Read vs. written frames: [00:00:40] [--------------------------------------------------]     0/1   
[RUNS FOREVER]

Both files worked with the main version of signal-backup-decode, which doesn't work with recent backup files.

Note: I had to change

openssl = "^0.10"

to

openssl = { version = "0.10", features = ["vendored"] }

in Cargo.toml to make cargo build run, see https://stackoverflow.com/questions/65553557/why-rust-is-failing-to-build-command-for-openssl-sys-v0-9-60-even-after-local-in#comment118424959_65554916

@pajowu
Copy link
Owner

pajowu commented Oct 29, 2023

This raises a good point, can we detect older files and use an old version.

PS: I’m still following the discussion but didn’t get to test yet

@frans-fuerst
Copy link

@pajowu : you might also have a look at #63 and my comment #63 (comment)
I didn't have a look at the actual change but it works for older (2019) and recent files

@lapseofreason
Copy link

lapseofreason commented Oct 29, 2023

@pajowu You might want to check out mossblaser/signal_for_android_decryption#6 on how to detect older versions. According to @frans-fuerst it works for older versions.

I in turn used the info on this PR to implement it.

@pascalgn
Copy link
Author

I should've made it a bit clearer, but I'm not really a Rust expert, so this PR was only intended as a proof of concept.

I've now added some more code, to check the backup file version and run the according decryption logic. However, I don't have any old backup files either, so I cannot really test it. I hope it works.

Comment on lines +93 to +103
data = vec![0u8; 4 + length - crate::decrypter::LENGTH_HMAC];

// read data and decrypt
self.reader.read_exact(&mut data[4..])?;
data[0] = encrypted_len[0];
data[1] = encrypted_len[1];
data[2] = encrypted_len[2];
data[3] = encrypted_len[3];

data = self.decrypter.decrypt(&mut data, true);
data = data[4..].to_vec();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does some data copying, so could probably be implemented in a much more efficient manner!

@flberger
Copy link

flberger commented Apr 6, 2024

It's been 5 months, any chance of getting this merged and released? I am still unable to decrypt my backups with the latest official release.

@THEnterprises
Copy link

Let's try to be more patient. This repo is owned by one person, who does this in their spare time. If you're desperate for the merge, then fork it and merge on your fork.

Let's stop contributing to an environment that takes advantage of people who are overworked and unpaid volunteers. Not only does that make it easier for stuff like this to happen, it's just wrong, in and of itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ERROR] failed to fill whole buffer
9 participants