Fix length bug in nonce generation

This commit is contained in:
Edward Shen 2021-10-30 23:15:41 -07:00
parent 8e05c622af
commit 9a85d13bd9
Signed by: edward
GPG key ID: 19182661E818369F
4 changed files with 24 additions and 25 deletions

11
Cargo.lock generated
View file

@ -953,6 +953,7 @@ dependencies = [
"clap", "clap",
"omegaupload-common", "omegaupload-common",
"reqwest", "reqwest",
"rpassword",
] ]
[[package]] [[package]]
@ -1327,6 +1328,16 @@ dependencies = [
"librocksdb-sys", "librocksdb-sys",
] ]
[[package]]
name = "rpassword"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
version = "1.1.0" version = "1.1.0"

View file

@ -11,4 +11,5 @@ omegaupload-common = { path = "../common" }
anyhow = "1" anyhow = "1"
atty = "0.2" atty = "0.2"
clap = "3.0.0-beta.4" clap = "3.0.0-beta.4"
reqwest = { version = "0.11", default-features = false, features = ["rustls-tls", "blocking"] } reqwest = { version = "0.11", default-features = false, features = ["rustls-tls", "blocking"] }
rpassword = "5"

View file

@ -1,7 +1,7 @@
#![warn(clippy::nursery, clippy::pedantic)] #![warn(clippy::nursery, clippy::pedantic)]
#![deny(unsafe_code)] #![deny(unsafe_code)]
use std::io::{Read, Write}; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
@ -15,6 +15,7 @@ use omegaupload_common::{
use reqwest::blocking::Client; use reqwest::blocking::Client;
use reqwest::header::EXPIRES; use reqwest::header::EXPIRES;
use reqwest::StatusCode; use reqwest::StatusCode;
use rpassword::prompt_password_stderr;
#[derive(Parser)] #[derive(Parser)]
struct Opts { struct Opts {
@ -65,16 +66,12 @@ fn handle_upload(
) -> Result<()> { ) -> Result<()> {
url.set_fragment(None); url.set_fragment(None);
if atty::is(Stream::Stdin) {
bail!("This tool requires non interactive CLI. Pipe something in!");
}
let (data, key) = { let (data, key) = {
let mut container = std::fs::read(path)?; let mut container = std::fs::read(path)?;
let password = if password { let password = if password {
let mut buffer = vec![]; let maybe_password =
std::io::stdin().read_to_end(&mut buffer)?; prompt_password_stderr("Please set the password for this paste: ")?;
Some(SecretVec::new(buffer)) Some(SecretVec::new(maybe_password.into_bytes()))
} else { } else {
None None
}; };
@ -140,21 +137,12 @@ fn handle_download(mut url: ParsedUrl) -> Result<()> {
let mut password = None; let mut password = None;
if url.needs_password { if url.needs_password {
// Only print prompt on interactive, else it messes with output // Only print prompt on interactive, else it messes with output
if atty::is(Stream::Stdout) { let maybe_password =
print!("Please enter the password to access this document: "); prompt_password_stderr("Please enter the password to access this paste: ")?;
std::io::stdout().flush()?; password = Some(SecretVec::new(maybe_password.into_bytes()));
}
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
input.pop(); // last character is \n, we need to drop it.
password = Some(input);
} }
open_in_place( open_in_place(&mut data, &url.decryption_key, password)?;
&mut data,
&url.decryption_key,
password.map(|v| SecretVec::new(v.into_bytes())),
)?;
if atty::is(Stream::Stdout) { if atty::is(Stream::Stdout) {
if let Ok(data) = String::from_utf8(data) { if let Ok(data) = String::from_utf8(data) {

View file

@ -123,9 +123,8 @@ pub fn open_in_place(
key: &Secret<Key>, key: &Secret<Key>,
password: Option<SecretVec<u8>>, password: Option<SecretVec<u8>>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let buffer_len = data.len();
let pw_key = if let Some(password) = password { let pw_key = if let Some(password) = password {
let salt_buf = data.split_off(buffer_len - Salt::SIZE); let salt_buf = data.split_off(data.len() - Salt::SIZE);
let argon = Argon2::default(); let argon = Argon2::default();
let mut pw_key = Key::default(); let mut pw_key = Key::default();
argon.hash_password_into(password.expose_secret(), &salt_buf, &mut pw_key)?; argon.hash_password_into(password.expose_secret(), &salt_buf, &mut pw_key)?;
@ -134,7 +133,7 @@ pub fn open_in_place(
None None
}; };
let nonce = Nonce::from_slice(&data.split_off(buffer_len - Nonce::SIZE)); let nonce = Nonce::from_slice(&data.split_off(data.len() - Nonce::SIZE));
// At this point we should have a buffer that's only the ciphertext. // At this point we should have a buffer that's only the ciphertext.