From fb788083d456e24593aa62431f7f377bb793daf4 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 | 5 ++-- src/rsa/oaep/commands.rs | 50 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 4 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..03a87313 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ bitflags = "2" cmac = "0.7" cbc = "0.1" ccm = { version = "0.5", features = ["std"] } +digest = { version = "0.10", default-features = false } ecdsa = { version = "0.16", default-features = false, features = ["pkcs8"] } ed25519 = "2" log = "0.4" @@ -41,12 +42,12 @@ uuid = { version = "1", default-features = false } zeroize = { version = "1", features = ["zeroize_derive"] } # optional dependencies -digest = { version = "0.10", optional = true, default-features = false } ed25519-dalek = { version = "2", optional = true, features = ["rand_core"] } hmac = { version = "0.12", optional = true } k256 = { version = "0.13", optional = true, features = ["ecdsa", "sha256"] } pbkdf2 = { version = "0.12", optional = true, default-features = false, features = ["hmac"] } serde_json = { version = "1", optional = true } +sha1 = { version = "0.10", optional = true } rusb = { version = "0.9", optional = true } tiny_http = { version = "0.12", optional = true } @@ -60,7 +61,7 @@ x509-cert = { version = "0.2.5", features = ["builder"] } default = ["http", "passwords", "setup"] http-server = ["tiny_http"] http = [] -mockhsm = ["digest", "ecdsa/arithmetic", "ed25519-dalek", "p256/ecdsa", "secp256k1"] +mockhsm = ["ecdsa/arithmetic", "ed25519-dalek", "p256/ecdsa", "secp256k1", "sha1"] passwords = ["hmac", "pbkdf2"] secp256k1 = ["k256"] setup = ["passwords", "serde_json", "uuid/serde"] diff --git a/src/rsa/oaep/commands.rs b/src/rsa/oaep/commands.rs index c58f39e4..df6b4bb5 100644 --- a/src/rsa/oaep/commands.rs +++ b/src/rsa/oaep/commands.rs @@ -6,10 +6,13 @@ use crate::{ response::Response, rsa, }; -use serde::{Deserialize, Serialize}; +use digest::{typenum::Unsigned, OutputSizeUser}; +use serde::{de::Deserializer, Deserialize, Serialize}; +use sha1::Sha1; +use sha2::{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 +44,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, + }) + } +}