From 7c2eb4d88e8135f571ce937f4b478eb44e8ea41d Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Sat, 13 Aug 2022 21:56:38 -0400 Subject: [PATCH] Retrieve data and parse index --- src/crypto.rs | 18 ++++++++++++++++++ src/main.rs | 20 ++++++++++++++++---- src/parse.rs | 17 +++++++++++++++++ src/upload.rs | 12 ++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/crypto.rs b/src/crypto.rs index 9165d9f..dc67b91 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -1,3 +1,4 @@ +use crypto::Error; use crypto::ciphers::{ aes_gcm::Aes256Gcm, traits::Aead, @@ -19,6 +20,23 @@ pub fn encrypt(key: &[u8; 32], plaintext: &[u8]) -> Vec { result } +pub fn decrypt<'p>(key: &[u8; 32], encrypted: &[u8], plaintext_dest: &'p mut Vec) -> Option<&'p mut Vec> { + let (cyphertext, tag) = encrypted.split_at(encrypted.len() - 16); + plaintext_dest.resize(cyphertext.len(), 0); + let e = Aes256Gcm::try_decrypt( + key, + &NONCE, + &[], + plaintext_dest, + cyphertext, + tag); + match e { + Ok(_) => Some(plaintext_dest), + Err(Error::CipherError { alg: "AES-256-GCM" }) => None, // Invalid key or tag + Err(e) => panic!("Unexpected decryption return value: {e:?}"), + } +} + pub fn make_key() -> [u8; 32] { let mut result = [0; 32]; rand::fill(&mut result).expect("Unexpected error generating random data"); diff --git a/src/main.rs b/src/main.rs index d337f57..061b53a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ mod thumbnailing; mod protobuf; mod errors; -use std::io::Read; use std::{borrow::Cow, io::stdout}; +use std::io::{Read, Write}; use std::fs::File; use std::path::Path; @@ -157,7 +157,19 @@ fn create(server: &str, args: CreateArgs) { } fn download(server: &str, args: DownloadArgs) { - drop(server); - drop(args); - todo!("Unimplemented... yet") + let mut download_buffer = Vec::with_capacity(5_000_000); + let mut decrypt_buffer = Vec::with_capacity(5_000_000); + let index_url = format!("{}/{}.bin", server, args.id); + let key: [u8; 32] = base64::decode(args.key) + .expect("key is malformed b64") + .try_into() + .expect("key is the wrong size"); + let download_agent = upload::get_agent(); + let encrypted_index = upload::get_data(&download_agent, &index_url, 500_000, &mut download_buffer) + .expect("GET failed"); + let serialized_index = crypto::decrypt(&key, &encrypted_index, &mut decrypt_buffer) + .expect("wrong key or corrupt index"); + let index = protobuf::index::Index::parse_from_bytes(&serialized_index) + .expect("malformed index"); + println!("{index:?}"); } diff --git a/src/parse.rs b/src/parse.rs index b6c8d94..817375c 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -36,4 +36,21 @@ pub struct CreateArgs { #[argh(subcommand, name = "download")] /// download a gallery pub struct DownloadArgs { + #[argh(positional)] + /// the file id + /// + /// This is a short series of characters that identifies the file + /// For the url: + /// https://0x0.st/asdj.bin#omONdEzrY6SfdBgHn/2P6yG33PeIhuj3/SGm/lDhd2U= + /// the file id is asdj + pub id: String, + + #[argh(positional)] + /// the encryption key + /// + /// This is the text after the # sign which is the secret for decrypting the pictures. + /// For the url: + /// https://0x0.st/asdj.bin#omONdEzrY6SfdBgHn/2P6yG33PeIhuj3/SGm/lDhd2U= + /// the encryption key is omONdEzrY6SfdBgHn/2P6yG33PeIhuj3/SGm/lDhd2U= + pub key: String, } diff --git a/src/upload.rs b/src/upload.rs index 1f8ff6d..d061ac1 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -18,3 +18,15 @@ pub fn put_data(agent: &Agent, server: &str, data: &[u8]) -> Result(agent: &Agent, location: &str, size_limit: u64, buffer: &'b mut Vec) -> Result<&'b mut Vec, ureq::Error> { + buffer.clear(); + println!("{}", location); + let read = agent.get(location) + .call()? + .into_reader() + .take(size_limit) + .read_to_end(buffer)?; + println!("{}", read); + Ok(buffer) +}