Cap native input buffer length
ober
b6cb83c6d8f0aa29928090a1a61649063408abbc
--- a/pgp-native/src/age_mod.rs +++ b/pgp-native/src/age_mod.rs @@ -36,8 +36,9 @@ pub fn encrypt(plaintext: &[u8], recipients_str: &str) -> Result<Vec<u8>, i32> { let mut out: Vec<u8> = Vec::new(); { - let armored = age::armor::ArmoredWriter::wrap_output(&mut out, age::armor::Format::AsciiArmor) - .map_err(|_| JPGP_E_ENCRYPT)?; + let armored = + age::armor::ArmoredWriter::wrap_output(&mut out, age::armor::Format::AsciiArmor) + .map_err(|_| JPGP_E_ENCRYPT)?; let mut writer = encryptor.wrap_output(armored).map_err(|_| JPGP_E_ENCRYPT)?; writer.write_all(plaintext).map_err(|_| JPGP_E_ENCRYPT)?; let armored = writer.finish().map_err(|_| JPGP_E_ENCRYPT)?; @@ -49,9 +50,7 @@ pub fn encrypt(plaintext: &[u8], recipients_str: &str) -> Result<Vec<u8>, i32> { /// Decrypt an age-armored ciphertext using a single X25519 identity /// supplied as an `AGE-SECRET-KEY-1...` string. pub fn decrypt(ciphertext: &[u8], identity_str: &str) -> Result<Vec<u8>, i32> { - let id: age::x25519::Identity = identity_str - .parse() - .map_err(|_| JPGP_E_PARSE_KEY)?; + let id: age::x25519::Identity = identity_str.parse().map_err(|_| JPGP_E_PARSE_KEY)?; let armored = age::armor::ArmoredReader::new(ciphertext); let decryptor = age::Decryptor::new(armored).map_err(|_| JPGP_E_DECRYPT)?; @@ -66,6 +65,8 @@ pub fn decrypt(ciphertext: &[u8], identity_str: &str) -> Result<Vec<u8>, i32> { }; let mut plaintext = Vec::new(); - reader.read_to_end(&mut plaintext).map_err(|_| JPGP_E_DECRYPT)?; + reader + .read_to_end(&mut plaintext) + .map_err(|_| JPGP_E_DECRYPT)?; Ok(plaintext) } --- a/pgp-native/src/lib.rs +++ b/pgp-native/src/lib.rs @@ -10,8 +10,8 @@ mod age_mod; mod error; mod pass_mod; -mod pgp_mod; mod pgp_io; +mod pgp_mod; mod sig_mod; mod util; @@ -363,11 +363,7 @@ pub unsafe extern "C" fn jpgp_pgp_verify( /// SHA-256 of `input` written to `out` (must be 32 bytes). #[no_mangle] -pub unsafe extern "C" fn jpgp_sha256( - input: *const u8, - input_len: u32, - out: *mut u8, -) -> i32 { +pub unsafe extern "C" fn jpgp_sha256(input: *const u8, input_len: u32, out: *mut u8) -> i32 { guard(|| { if out.is_null() { return JPGP_E_INVALID_INPUT; --- a/pgp-native/src/pass_mod.rs +++ b/pgp-native/src/pass_mod.rs @@ -13,8 +13,9 @@ pub fn encrypt(plaintext: &[u8], passphrase: &str) -> Result<Vec<u8>, i32> { let mut out: Vec<u8> = Vec::new(); { - let armored = age::armor::ArmoredWriter::wrap_output(&mut out, age::armor::Format::AsciiArmor) - .map_err(|_| JPGP_E_ENCRYPT)?; + let armored = + age::armor::ArmoredWriter::wrap_output(&mut out, age::armor::Format::AsciiArmor) + .map_err(|_| JPGP_E_ENCRYPT)?; let mut writer = encryptor.wrap_output(armored).map_err(|_| JPGP_E_ENCRYPT)?; writer.write_all(plaintext).map_err(|_| JPGP_E_ENCRYPT)?; let armored = writer.finish().map_err(|_| JPGP_E_ENCRYPT)?; @@ -36,6 +37,8 @@ pub fn decrypt(ciphertext: &[u8], passphrase: &str) -> Result<Vec<u8>, i32> { }; let mut plaintext = Vec::new(); - reader.read_to_end(&mut plaintext).map_err(|_| JPGP_E_DECRYPT)?; + reader + .read_to_end(&mut plaintext) + .map_err(|_| JPGP_E_DECRYPT)?; Ok(plaintext) } --- a/pgp-native/src/pgp_io.rs +++ b/pgp-native/src/pgp_io.rs @@ -22,8 +22,7 @@ pub fn decrypt(secret_armor: &str, passphrase: &str, ciphertext: &[u8]) -> Resul .map_err(|_| JPGP_E_PARSE_KEY)?; skey.verify().map_err(|_| JPGP_E_PARSE_KEY)?; - let (msg, _) = - Message::from_armor_single(ciphertext).map_err(|_| JPGP_E_PARSE_KEY)?; + let (msg, _) = Message::from_armor_single(ciphertext).map_err(|_| JPGP_E_PARSE_KEY)?; let pass = passphrase.to_owned(); let (decrypted, _ids) = msg --- a/pgp-native/src/pgp_mod.rs +++ b/pgp-native/src/pgp_mod.rs @@ -18,10 +18,7 @@ pub fn encrypt(pubkey_armor: &str, plaintext: &[u8]) -> Result<String, i32> { let lit = Message::new_literal_bytes("msg.bin", plaintext); let mut rng = thread_rng(); - let enc_subkey = pkey - .public_subkeys - .iter() - .find(|sk| sk.is_encryption_key()); + let enc_subkey = pkey.public_subkeys.iter().find(|sk| sk.is_encryption_key()); let encrypted = if let Some(sub) = enc_subkey { lit.encrypt_to_keys_seipdv1(&mut rng, SymmetricKeyAlgorithm::AES256, &[sub]) --- a/pgp-native/src/util.rs +++ b/pgp-native/src/util.rs @@ -4,6 +4,8 @@ use crate::error::*; use std::slice; +pub const MAX_INPUT_LEN: u32 = 64 * 1024 * 1024; + /// Write `src` into the caller-provided buffer. /// /// - Writes `src.len()` to `*out_len` always (even when `out` is null). @@ -39,6 +41,9 @@ pub unsafe fn write_out(src: &[u8], out: *mut u8, out_len_in: u32, out_len: *mut /// # Safety /// `ptr` (if non-null) must be readable for `len` bytes. pub unsafe fn slice_from(ptr: *const u8, len: u32) -> Option<&'static [u8]> { + if len > MAX_INPUT_LEN { + return None; + } if ptr.is_null() { if len == 0 { return Some(&[]);