Skip to content

Commit 0b4564f

Browse files
committed
m
1 parent 95d9d7c commit 0b4564f

File tree

4 files changed

+121
-39
lines changed

4 files changed

+121
-39
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use anyhow::Result;
2+
use clap::{Parser, Subcommand};
3+
4+
#[derive(Parser)]
5+
#[command(version, about, long_about = None)]
6+
#[command(propagate_version = true)]
7+
struct Cli {
8+
#[command(subcommand)]
9+
command: Commands,
10+
}
11+
12+
#[derive(Subcommand)]
13+
enum Commands {
14+
/// Turn an Encrypt Manifest into a Decrypt Manifest
15+
Encrypt {
16+
#[arg(long, help = "where to find encrypt manifest.")]
17+
manifest_path: String,
18+
#[arg(long, help = "where to put the decrypt manifest.")]
19+
decrypt_manifest_path: String,
20+
#[arg(long, help = "id of the test to run.", default_value = "")]
21+
test_name: String,
22+
},
23+
/// Validate a Decrypt Manifest
24+
Decrypt {
25+
#[arg(long, help = "where to find plaintext and ciphertext directories.")]
26+
manifest_path: String,
27+
#[arg(long, help = "where to put the decrypt manifest.")]
28+
manifest_name: String,
29+
#[arg(long, help = "id of the test to run.", default_value = "")]
30+
test_name: String,
31+
},
32+
}
33+
#[tokio::main]
34+
async fn main() -> Result<()> {
35+
let cli = Cli::parse();
36+
37+
match &cli.command {
38+
Commands::Encrypt {
39+
manifest_path,
40+
decrypt_manifest_path,
41+
test_name,
42+
} => aws_esdk::test_vectors::run_tests::encrypt_test_vectors(manifest_path, decrypt_manifest_path, test_name).await,
43+
Commands::Decrypt {
44+
manifest_path,
45+
manifest_name,
46+
test_name,
47+
} => aws_esdk::test_vectors::run_tests::decrypt_test_vectors(manifest_path, manifest_name, test_name).await,
48+
}
49+
}
50+
51+
#[test]
52+
fn verify_cli() {
53+
use clap::CommandFactory;
54+
Cli::command().debug_assert();
55+
}

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/esdk_operations.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,15 +557,16 @@ async fn internal_decrypt(
557557
)?
558558
}
559559
ContentType::Framed => {
560-
if dec_mat.verification_key.is_some() && safety_needed.yes() {
561-
return Err("Streaming Interface can return data before signature has been validated. Set `i_accept_the_danger` in the DecryptStreamInput struct if this is ok.".into());
562-
}
560+
// if dec_mat.verification_key.is_some() && safety_needed.yes() {
561+
// return Err("Streaming Interface can return data before signature has been validated. Set `i_accept_the_danger` in the DecryptStreamInput struct if this is ok.".into());
562+
// }
563+
let fail_if_multi_frame = dec_mat.verification_key.is_some() && safety_needed.yes();
563564

564565
//= compliance/client-apis/decrypt.txt#2.7.4
565566
//# If this decryption fails, this operation MUST immediately halt and
566567
//# fail.
567568
message_body::read_and_decrypt_framed_message_body(
568-
ciphertext, plaintext, &header, &key, &mut dw,
569+
ciphertext, plaintext, &header, &key, &mut dw, fail_if_multi_frame
569570
)?
570571
}
571572
};

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/message_body.rs

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ pub(crate) fn body_aad2(
110110
result.extend_from_slice(&length.to_be_bytes());
111111
}
112112

113-
// FIXME -- if last frame is empty, return penultimate frame.
114113
pub(crate) fn read_and_decrypt_framed_message_body(
115114
r: &mut dyn SafeRead,
116115
w: &mut dyn SafeWrite,
117116
header: &HeaderInfo,
118117
key: &[u8],
119118
raw: &mut dyn SafeWrite,
119+
fail_if_multi_frame: bool,
120120
) -> Result<Vec<u8>, Error> {
121-
let mut expected_frame = START_SEQUENCE_NUMBER;
121+
let mut expected_frame: u32 = START_SEQUENCE_NUMBER;
122122
let mut iv = vec![0u8; get_iv_length(&header.suite) as usize];
123123
let mut auth_tag = vec![0u8; get_tag_length(&header.suite) as usize];
124124
let alg = get_aes_alg(&header.suite);
@@ -151,21 +151,50 @@ pub(crate) fn read_and_decrypt_framed_message_body(
151151
enc_content.len() as u64,
152152
&mut aad,
153153
);
154-
aes_decrypt(
155-
alg,
156-
key,
157-
&enc_content,
158-
&auth_tag,
159-
&iv,
160-
&aad,
161-
&mut result[0..enc_content.len()],
162-
)?;
163-
result.resize(enc_content.len(), 0);
164-
return Ok(result);
154+
if enc_content.is_empty() {
155+
// final frame is empty, to return last full frame
156+
let mut empty_result = Vec::new();
157+
aes_decrypt(
158+
alg,
159+
key,
160+
&enc_content,
161+
&auth_tag,
162+
&iv,
163+
&aad,
164+
&mut empty_result[..],
165+
)?;
166+
return Ok(result);
167+
} else {
168+
// write previous frame's data, now that we know we have another frame.
169+
if expected_frame != START_SEQUENCE_NUMBER {
170+
if fail_if_multi_frame {
171+
return Err("Streaming Interface can return data before signature has been validated. Set `i_accept_the_danger` in the DecryptStreamInput struct if this is ok.".into());
172+
}
173+
serialize_functions::write_bytes(w, &result)?;
174+
}
175+
aes_decrypt(
176+
alg,
177+
key,
178+
&enc_content,
179+
&auth_tag,
180+
&iv,
181+
&aad,
182+
&mut result[0..enc_content.len()],
183+
)?;
184+
result.resize(enc_content.len(), 0);
185+
return Ok(result);
186+
}
165187
}
166188
if seq_num != expected_frame {
167189
return Err("Sequence number out of order.".into());
168190
}
191+
// write previous frame's data, now that we know we have another frame.
192+
if expected_frame != START_SEQUENCE_NUMBER {
193+
if fail_if_multi_frame {
194+
return Err("Streaming Interface can return data before signature has been validated. Set `i_accept_the_danger` in the DecryptStreamInput struct if this is ok.".into());
195+
}
196+
serialize_functions::write_bytes(w, &result)?;
197+
}
169198
expected_frame += 1;
170199
read_bytes(r, &mut iv, raw)?;
171200
read_bytes(r, &mut enc_content, raw)?;
@@ -178,6 +207,5 @@ pub(crate) fn read_and_decrypt_framed_message_body(
178207
&mut aad,
179208
);
180209
aes_decrypt(alg, key, &enc_content, &auth_tag, &iv, &aad, &mut result)?;
181-
serialize_functions::write_bytes(w, &result)?;
182210
}
183211
}

AwsEncryptionSDK/runtimes/rust/esdk_rust/esdk/src/test_vectors/run_tests.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::test_vectors::do_decrypt::read_json;
22
use anyhow::Result;
33

4-
pub async fn do_decrypt(manifest_path: &str, manifest_name: &str) -> Result<()> {
4+
pub async fn decrypt_test_vectors(manifest_path: &str, manifest_name: &str, _test_name : &str) -> Result<()> {
55
let json_data_base = read_json(manifest_name, manifest_path)?;
66
let json_data = json_data_base.as_object().unwrap();
77

@@ -38,7 +38,7 @@ pub async fn do_decrypt(manifest_path: &str, manifest_name: &str) -> Result<()>
3838
Ok(())
3939
}
4040

41-
pub async fn do_encrypt(encrypt_path: &str, decrypt_path: &str) -> Result<()> {
41+
pub async fn encrypt_test_vectors(encrypt_path: &str, decrypt_path: &str, _test_name : &str) -> Result<()> {
4242
drop(std::fs::remove_dir_all(format!(
4343
"{encrypt_path}/plaintexts"
4444
)));
@@ -96,32 +96,30 @@ pub async fn do_encrypt(encrypt_path: &str, decrypt_path: &str) -> Result<()> {
9696
#[cfg(test)]
9797
mod tests {
9898
use super::*;
99-
// #[tokio::test(flavor = "multi_thread")]
100-
// async fn test_do_decrypt() {
101-
// let manifest_path = "test_vectors_java";
102-
// let manifest_name = "decrypt-manifest.json";
103-
// let result = do_decrypt(manifest_path, manifest_name).await;
104-
// println!("{result:?}");
105-
// assert!(result.is_ok());
106-
// }
107-
108-
// #[tokio::test(flavor = "multi_thread")]
109-
// async fn test_python_decrypt() {
110-
// let manifest_path = "test_vectors_python";
111-
// let manifest_name = "decrypt_message.json";
112-
// let result = do_decrypt(manifest_path, manifest_name).await;
113-
// println!("{result:?}");
114-
// assert!(result.is_ok());
115-
// }
99+
#[tokio::test(flavor = "multi_thread")]
100+
async fn test_do_decrypt() {
101+
let manifest_path = "test_vectors_java";
102+
let manifest_name = "decrypt-manifest.json";
103+
let result = decrypt_test_vectors(manifest_path, manifest_name, "").await;
104+
assert!(result.is_ok());
105+
}
106+
107+
#[tokio::test(flavor = "multi_thread")]
108+
async fn test_python_decrypt() {
109+
let manifest_path = "test_vectors_python";
110+
let manifest_name = "decrypt_message.json";
111+
let result = decrypt_test_vectors(manifest_path, manifest_name, "").await;
112+
assert!(result.is_ok());
113+
}
116114
#[tokio::test(flavor = "multi_thread")]
117115
async fn test_do_encrypt() {
118116
let manifest_path = "test_vectors_rust";
119117
let manifest_name = "decrypt-manifest.json";
120118

121-
let result = do_encrypt(manifest_path, manifest_path).await;
119+
let result = encrypt_test_vectors(manifest_path, manifest_path, "").await;
122120
assert!(result.is_ok());
123121

124-
let result = do_decrypt(manifest_path, manifest_name).await;
122+
let result = decrypt_test_vectors(manifest_path, manifest_name, "").await;
125123
assert!(result.is_ok());
126124
}
127125
}

0 commit comments

Comments
 (0)