diff --git a/src/main.rs b/src/main.rs index 3fd4fe4..cbac36d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,33 +8,26 @@ extern crate rand; extern crate reqwest; #[macro_use] extern crate serde_derive; -extern crate serde_json; extern crate sha2; mod b64; +mod metadata; mod reader; -use std::fmt; use std::fs::File; use std::io::BufReader; use std::path::Path; use clap::{App, Arg}; use hkdf::Hkdf; -use hyper::error::Error as HyperError; -use mime_guess::Mime; use openssl::symm::{Cipher, encrypt_aead}; use rand::{Rng, thread_rng}; -use reqwest::header::{ - Authorization, - Formatter as HeaderFormatter, - Header, - Raw -}; +use reqwest::header::Authorization; use reqwest::mime::APPLICATION_OCTET_STREAM; use reqwest::multipart::Part; use sha2::Sha256; +use metadata::{Metadata, XFileMetadata}; use reader::EncryptedFileReaderTagged; fn main() { @@ -188,77 +181,6 @@ fn derive_meta_key(secret: &[u8]) -> Vec { hkdf(16, secret, Some(b"metadata")) } -/// File metadata, which is send to the server. -#[derive(Serialize)] -struct Metadata { - /// The input vector. - iv: String, - - /// The file name. - name: String, - - /// The file mimetype. - #[serde(rename="type")] - mime: String, -} - -impl Metadata { - /// Construct metadata from the given properties. - /// - /// Parameters: - /// * iv: initialisation vector - /// * name: file name - /// * mime: file mimetype - pub fn from(iv: &[u8], name: String, mime: Mime) -> Self { - Metadata { - iv: base64_encode(iv), - name, - mime: mime.to_string(), - } - } - - /// Convert this structure to a JSON string. - pub fn to_json(&self) -> String { - serde_json::to_string(&self).unwrap() - } -} - -/// A X-File-Metadata header for reqwest, that is used to pass encrypted -/// metadata to the server. -/// -/// The encrypted metadata (bytes) is base64 encoded when constructing this -/// header using `from`. -#[derive(Clone)] -struct XFileMetadata { - /// The metadata, as a base64 encoded string. - metadata: String, -} - -impl XFileMetadata { - /// Construct the header from the given encrypted metadata. - pub fn from(bytes: &[u8]) -> Self { - XFileMetadata { - metadata: base64_encode(bytes), - } - } -} - -impl Header for XFileMetadata { - fn header_name() -> &'static str { - "X-File-Metadata" - } - - fn parse_header(_raw: &Raw) -> Result { - // TODO: implement this some time - unimplemented!(); - } - - fn fmt_header(&self, f: &mut HeaderFormatter) -> fmt::Result { - // TODO: is this encoding base64 for us? - f.fmt_line(&self.metadata) - } -} - /// The response from the server after a file has been uploaded. /// This response contains the file ID and owner key, to manage the file. /// diff --git a/src/metadata.rs b/src/metadata.rs new file mode 100644 index 0000000..1443110 --- /dev/null +++ b/src/metadata.rs @@ -0,0 +1,85 @@ +extern crate serde_json; + +use std::fmt; + +use hyper::error::Error as HyperError; +use mime_guess::Mime; +use reqwest::header::{ + Formatter as HeaderFormatter, + Header, + Raw, +}; + +use b64; + +/// File metadata, which is send to the server. +#[derive(Serialize)] +pub struct Metadata { + /// The input vector. + iv: String, + + /// The file name. + name: String, + + /// The file mimetype. + #[serde(rename="type")] + mime: String, +} + +impl Metadata { + /// Construct metadata from the given properties. + /// + /// Parameters: + /// * iv: initialisation vector + /// * name: file name + /// * mime: file mimetype + pub fn from(iv: &[u8], name: String, mime: Mime) -> Self { + Metadata { + iv: b64::encode(iv), + name, + mime: mime.to_string(), + } + } + + /// Convert this structure to a JSON string. + pub fn to_json(&self) -> String { + serde_json::to_string(&self).unwrap() + } +} + +/// A X-File-Metadata header for reqwest, that is used to pass encrypted +/// metadata to the server. +/// +/// The encrypted metadata (bytes) is base64 encoded when constructing this +/// header using `from`. +#[derive(Clone)] +pub struct XFileMetadata { + /// The metadata, as a base64 encoded string. + metadata: String, +} + +impl XFileMetadata { + /// Construct the header from the given encrypted metadata. + pub fn from(bytes: &[u8]) -> Self { + XFileMetadata { + metadata: b64::encode(bytes), + } + } +} + +/// Make this struct usable as reqwest header. +impl Header for XFileMetadata { + fn header_name() -> &'static str { + "X-File-Metadata" + } + + fn parse_header(_raw: &Raw) -> Result { + // TODO: implement this some time + unimplemented!(); + } + + fn fmt_header(&self, f: &mut HeaderFormatter) -> fmt::Result { + // TODO: is this encoding base64 for us? + f.fmt_line(&self.metadata) + } +}