From 29b5e1eda9869e22c57014c63f87c54d9b3ba670 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 17 Jun 2024 23:09:02 -0700 Subject: [PATCH] oaep: fixup `Deserialize` implementation label_data was always empty because it was consumed by data. This commits re-splits the payload according to the selected mgf hash. --- Cargo.lock | 1 + Cargo.toml | 1 + src/rsa/oaep/commands.rs | 52 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f41f2698..4c6651df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1024,6 +1024,7 @@ dependencies = [ "rusb", "serde", "serde_json", + "sha1", "sha2", "signature", "spki", diff --git a/Cargo.toml b/Cargo.toml index 797c7b2a..a7b3225a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ serde = { version = "1", features = ["serde_derive"] } rand_core = { version = "0.6", features = ["std"] } rsa = "0.9.6" signature = { version = "2", features = ["derive"] } +sha1 = { version = "0.10", default-features = false } sha2 = { version = "0.10", features = ["oid"] } spki = { version = "0.7.3", default-features = false } subtle = "2" diff --git a/src/rsa/oaep/commands.rs b/src/rsa/oaep/commands.rs index c58f39e4..49f0ff81 100644 --- a/src/rsa/oaep/commands.rs +++ b/src/rsa/oaep/commands.rs @@ -6,10 +6,15 @@ use crate::{ response::Response, rsa, }; -use serde::{Deserialize, Serialize}; +use serde::{de::Deserializer, Deserialize, Serialize}; +use sha1::Sha1; +use sha2::{ + digest::{typenum::Unsigned, OutputSizeUser}, + Sha256, Sha384, Sha512, +}; /// Request parameters for `command::decrypt_rsa_oaep` -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Debug)] pub(crate) struct DecryptOaepCommand { /// ID of the decryption key pub key_id: object::Id, @@ -41,3 +46,46 @@ impl From for rsa::oaep::DecryptedData { response.0 } } + +impl<'de> Deserialize<'de> for DecryptOaepCommand { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct DecryptOaepCommand { + /// ID of the decryption key + key_id: object::Id, + + /// Hash algorithm to use for MGF1 + mgf1_hash_alg: rsa::mgf::Algorithm, + + /// Data to be decrypted + data: Vec, + } + + let mut value = DecryptOaepCommand::deserialize(deserializer)?; + + let label_hash = match value.mgf1_hash_alg { + rsa::mgf::Algorithm::Sha1 => value + .data + .split_off(value.data.len() - ::OutputSize::USIZE), + rsa::mgf::Algorithm::Sha256 => value + .data + .split_off(value.data.len() - ::OutputSize::USIZE), + rsa::mgf::Algorithm::Sha384 => value + .data + .split_off(value.data.len() - ::OutputSize::USIZE), + rsa::mgf::Algorithm::Sha512 => value + .data + .split_off(value.data.len() - ::OutputSize::USIZE), + }; + + Ok(Self { + key_id: value.key_id, + mgf1_hash_alg: value.mgf1_hash_alg, + data: value.data, + label_hash, + }) + } +}