Properly compute metadata crypto signature with signer

This commit is contained in:
timvisee 2018-03-20 18:19:49 +01:00
parent 5b1724ef9e
commit f63b86f0ec
No known key found for this signature in database
GPG key ID: 109CBA0BF74036C2
3 changed files with 31 additions and 22 deletions

View file

@ -1,7 +1,10 @@
use std::path::Path;
use mime_guess::{get_mime_type, Mime};
use openssl::symm::{decrypt_aead, encrypt_aead};
use openssl::hash::MessageDigest;
use openssl::pkey::PKey;
use openssl::sign::Signer;
use openssl::symm::decrypt_aead;
use reqwest::{
Client,
Error as ReqwestError,
@ -73,7 +76,7 @@ impl<'a> Download<'a> {
// Get the authentication nonce
// TODO: don't unwrap here, return an error
let nonce = b64::decode(
let nonce = b64::decode_standard(
response.headers()
.get_raw(HEADER_AUTH_NONCE)
.expect("missing authenticate header")
@ -88,18 +91,16 @@ impl<'a> Download<'a> {
.expect("missing authentication nonce")
).expect("failed to decode authentication nonce");
// Determine the signature
// TODO: use a tag length const here
// Compute the cryptographic signature
// TODO: do not unwrap, return an error
let mut sig = vec![0u8; 16];
encrypt_aead(
KeySet::cipher(),
key.auth_key().unwrap(),
None,
&[],
&nonce,
&mut sig,
).expect("failed to derive signature");
let pkey = PKey::hmac(key.auth_key().unwrap())
.expect("failed to build HMAC key for signing");
let mut signer = Signer::new(MessageDigest::sha256(), &pkey)
.expect("failed to build signer");
signer.update(&nonce)
.expect("failed to feed signer");
let sig: Vec<u8> = signer.sign_to_vec()
.expect("failed to compute signature");
let sig_encoded = b64::encode(&sig);
// Get the meta URL, fetch the metadata
@ -121,7 +122,7 @@ impl<'a> Download<'a> {
// Get the metadata nonce
// TODO: don't unwrap here, return an error
let nonce = b64::decode(
let nonce = b64::decode_url(
response.headers()
.get_raw(HEADER_AUTH_NONCE)
.expect("missing authenticate header")
@ -143,8 +144,6 @@ impl<'a> Download<'a> {
// Decrypt the metadata
let metadata = meta_response.decrypt_metadata(&key);
println!("GOT METADATA: {:?}", metadata);
// // Crpate metadata and a file reader
// let metadata = self.create_metadata(&key, &file)?;
// let reader = self.create_reader(&key, reporter.clone())?;
@ -336,7 +335,7 @@ impl MetadataResponse {
// TODO: do not unwrap, return a proper error
pub fn decrypt_metadata(&self, key_set: &KeySet) -> Result<Metadata> {
// Decode the metadata
let raw = b64::decode(&self.meta)
let raw = b64::decode_url(&self.meta)
.expect("failed to decode metadata from server");
// Get the encrypted metadata, and it's tag

View file

@ -6,14 +6,24 @@
extern crate base64;
use self::base64::DecodeError;
pub use self::base64::{Config, DecodeError};
/// Encode the given byte slice using base64, in an URL-safe manner.
pub fn encode(input: &[u8]) -> String {
base64::encode_config(input, base64::URL_SAFE_NO_PAD)
}
/// Decode the given string as base64, in an URL-safe manner.
pub fn decode(input: &str) -> Result<Vec<u8>, DecodeError> {
base64::decode_config(input, base64::URL_SAFE_NO_PAD)
/// Decode the given string as base64, with the given configuration.
pub fn decode(input: &str, config: Config) -> Result<Vec<u8>, DecodeError> {
base64::decode_config(input, config)
}
/// Decode the given string as base64, in an URL-safe manner.
pub fn decode_url(input: &str) -> Result<Vec<u8>, DecodeError> {
decode(input, base64::URL_SAFE_NO_PAD)
}
/// Decode the given string as base64, with the standaard character set.
pub fn decode_standard(input: &str) -> Result<Vec<u8>, DecodeError> {
decode(input, base64::STANDARD_NO_PAD)
}

View file

@ -181,7 +181,7 @@ impl DownloadFile {
.ok_or(FileParseError::InvalidSecret)?
.get(1)
{
secret = b64::decode(raw.as_str().trim())
secret = b64::decode_url(raw.as_str().trim())
.map_err(|_| FileParseError::InvalidSecret)?
}
}