Retrieve data and parse index

This commit is contained in:
Emi Simpson 2022-08-13 21:56:38 -04:00
parent b3a6c51ff8
commit 7c2eb4d88e
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847
4 changed files with 63 additions and 4 deletions

View file

@ -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<u8> {
result
}
pub fn decrypt<'p>(key: &[u8; 32], encrypted: &[u8], plaintext_dest: &'p mut Vec<u8>) -> Option<&'p mut Vec<u8>> {
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");

View file

@ -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:?}");
}

View file

@ -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,
}

View file

@ -18,3 +18,15 @@ pub fn put_data(agent: &Agent, server: &str, data: &[u8]) -> Result<String, ureq
.set("Content-Type", "multipart/form-data; boundary=FuckLiterallyAllCops")
.send(DATA_HEADER.chain(data).chain(DATA_FOOTER))?.into_string()?)
}
pub fn get_data<'b>(agent: &Agent, location: &str, size_limit: u64, buffer: &'b mut Vec<u8>) -> Result<&'b mut Vec<u8>, 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)
}