diff --git a/Cargo.lock b/Cargo.lock index 584cab33..225f1623 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -206,6 +215,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.14" @@ -228,6 +243,49 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.3.3" @@ -249,6 +307,18 @@ dependencies = [ "polyval", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hex" version = "0.4.3" @@ -282,6 +352,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "inout" version = "0.2.0-rc.6" @@ -371,6 +451,18 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs1" version = "0.8.0-rc.4" @@ -430,6 +522,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.101" @@ -518,12 +619,41 @@ dependencies = [ "rand_core", ] +[[package]] +name = "regex" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "rsa" version = "0.10.0-rc.8" @@ -542,6 +672,7 @@ dependencies = [ "rand_chacha", "rand_core", "rand_xorshift", + "rstest", "serde", "serde_json", "serde_test", @@ -555,6 +686,44 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rstest" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", +] + +[[package]] +name = "rstest_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.2" @@ -607,6 +776,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.227" @@ -721,6 +896,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "spki" version = "0.8.0-rc.4" @@ -761,6 +942,36 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "toml_datetime" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ + "winnow", +] + [[package]] name = "typenum" version = "1.18.0" @@ -831,6 +1042,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.46.0" diff --git a/Cargo.toml b/Cargo.toml index 6d5c01af..86e25939 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ sha3 = { version = "0.11.0-rc.2", default-features = false, features = ["oid"] } hex = { version = "0.4.3", features = ["serde"] } serde_json = "1.0.138" serde = { version = "1.0.184", features = ["derive"] } +rstest = "0.26.1" [[bench]] name = "key" diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index 439cc134..1a9fff1e 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -258,6 +258,7 @@ mod tests { rand_core::{RngCore, SeedableRng}, ChaCha8Rng, }; + use rstest::rstest; use sha1::{Digest, Sha1}; use sha2::Sha256; use sha3::Sha3_256; @@ -290,35 +291,30 @@ mod tests { ).unwrap() } - #[test] - fn test_decrypt_pkcs1v15() { + #[rstest] + #[case( + "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==", + "x" + )] + #[case( + "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==", + "testing." + )] + #[case( + "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==", + "testing.\n" + )] + #[case( + "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==", + "01234567890123456789012345678901234567890123456789012" + )] + fn test_decrypt_pkcs1v15(#[case] ciphertext: &str, #[case] plaintext: &str) { let priv_key = get_private_key(); - let tests = [ - [ - "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==", - "x", - ], - [ - "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==", - "testing.", - ], - [ - "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==", - "testing.\n", - ], - [ - "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==", - "01234567890123456789012345678901234567890123456789012", - ], - ]; - - for test in &tests { - let out = priv_key - .decrypt(Pkcs1v15Encrypt, &Base64::decode_vec(test[0]).unwrap()) - .unwrap(); - assert_eq!(out, test[1].as_bytes()); - } + let out = priv_key + .decrypt(Pkcs1v15Encrypt, &Base64::decode_vec(ciphertext).unwrap()) + .unwrap(); + assert_eq!(out, plaintext.as_bytes()); } #[test] @@ -345,36 +341,31 @@ mod tests { } } - #[test] - fn test_decrypt_pkcs1v15_traits() { + #[rstest] + #[case( + "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==", + "x" + )] + #[case( + "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==", + "testing." + )] + #[case( + "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==", + "testing.\n" + )] + #[case( + "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==", + "01234567890123456789012345678901234567890123456789012" + )] + fn test_decrypt_pkcs1v15_traits(#[case] ciphertext: &str, #[case] plaintext: &str) { let priv_key = get_private_key(); let decrypting_key = DecryptingKey::new(priv_key); - let tests = [ - [ - "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==", - "x", - ], - [ - "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==", - "testing.", - ], - [ - "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==", - "testing.\n", - ], - [ - "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==", - "01234567890123456789012345678901234567890123456789012", - ], - ]; - - for test in &tests { - let out = decrypting_key - .decrypt(&Base64::decode_vec(test[0]).unwrap()) - .unwrap(); - assert_eq!(out, test[1].as_bytes()); - } + let out = decrypting_key + .decrypt(&Base64::decode_vec(ciphertext).unwrap()) + .unwrap(); + assert_eq!(out, plaintext.as_bytes()); } #[test] @@ -407,261 +398,225 @@ mod tests { } } - #[test] - fn test_sign_pkcs1v15() { + #[rstest] + #[case("Test.\n", hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae")) + ] + fn test_sign_pkcs1v15(#[case] text: &str, #[case] expected: [u8; 64]) { let priv_key = get_private_key(); - let tests = [( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - )]; - - for (text, expected) in &tests { - let digest = Sha1::digest(text.as_bytes()).to_vec(); - - let out = priv_key.sign(Pkcs1v15Sign::new::(), &digest).unwrap(); - assert_ne!(out, digest); - assert_eq!(out, expected); - - let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = priv_key - .sign_with_rng(&mut rng, Pkcs1v15Sign::new::(), &digest) - .unwrap(); - assert_eq!(out2, expected); - } + let digest = Sha1::digest(text.as_bytes()).to_vec(); + + let out = priv_key.sign(Pkcs1v15Sign::new::(), &digest).unwrap(); + assert_ne!(out, digest); + assert_eq!(out, expected); + + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let out2 = priv_key + .sign_with_rng(&mut rng, Pkcs1v15Sign::new::(), &digest) + .unwrap(); + assert_eq!(out2, expected); } - #[test] - fn test_sign_pkcs1v15_signer() { + #[rstest] + #[case("Test.\n", hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae")) + ] + fn test_sign_pkcs1v15_signer(#[case] text: &str, #[case] expected: [u8; 64]) { let priv_key = get_private_key(); - let tests = [( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - )]; - let signing_key = SigningKey::::new(priv_key); + let out = signing_key.sign(text.as_bytes()).to_bytes(); + assert_ne!(out.as_ref(), text.as_bytes()); + assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec()); + assert_eq!(out.as_ref(), expected); - for (text, expected) in &tests { - let out = signing_key.sign(text.as_bytes()).to_bytes(); - assert_ne!(out.as_ref(), text.as_bytes()); - assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec()); - assert_eq!(out.as_ref(), expected); - - let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = signing_key - .sign_with_rng(&mut rng, text.as_bytes()) - .to_bytes(); - assert_eq!(out2.as_ref(), expected); - } + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let out2 = signing_key + .sign_with_rng(&mut rng, text.as_bytes()) + .to_bytes(); + assert_eq!(out2.as_ref(), expected); } - #[test] - fn test_sign_pkcs1v15_signer_sha2_256() { + #[rstest] + #[case("Test.\n", hex!( + "2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea" + "02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b")) + ] + fn test_sign_pkcs1v15_signer_sha2_256(#[case] text: &str, #[case] expected: [u8; 64]) { let priv_key = get_private_key(); - - let tests = [( - "Test.\n", - hex!( - "2ffae3f3e130287b3a1dcb320e46f52e8f3f7969b646932273a7e3a6f2a182ea" - "02d42875a7ffa4a148aa311f9e4b562e4e13a2223fb15f4e5bf5f2b206d9451b" - ), - )]; - let signing_key = SigningKey::::new(priv_key); - for (text, expected) in &tests { - let out = signing_key.sign(text.as_bytes()).to_bytes(); - assert_ne!(out.as_ref(), text.as_bytes()); - assert_eq!(out.as_ref(), expected); + let out = signing_key.sign(text.as_bytes()).to_bytes(); + assert_ne!(out.as_ref(), text.as_bytes()); + assert_eq!(out.as_ref(), expected); - let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = signing_key - .sign_with_rng(&mut rng, text.as_bytes()) - .to_bytes(); - assert_eq!(out2.as_ref(), expected); - } + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let out2 = signing_key + .sign_with_rng(&mut rng, text.as_bytes()) + .to_bytes(); + assert_eq!(out2.as_ref(), expected); } - #[test] - fn test_sign_pkcs1v15_signer_sha3_256() { + #[rstest] + #[case("Test.\n", hex!( + "55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7" + "2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9")) + ] + fn test_sign_pkcs1v15_signer_sha3_256(#[case] text: &str, #[case] expected: [u8; 64]) { let priv_key = get_private_key(); - - let tests = [( - "Test.\n", - hex!( - "55e9fba3354dfb51d2c8111794ea552c86afc2cab154652c03324df8c2c51ba7" - "2ff7c14de59a6f9ba50d90c13a7537cc3011948369f1f0ec4a49d21eb7e723f9" - ), - )]; - let signing_key = SigningKey::::new(priv_key); - for (text, expected) in &tests { - let out = signing_key.sign(text.as_bytes()).to_bytes(); - assert_ne!(out.as_ref(), text.as_bytes()); - assert_eq!(out.as_ref(), expected); + let out = signing_key.sign(text.as_bytes()).to_bytes(); + assert_ne!(out.as_ref(), text.as_bytes()); + assert_eq!(out.as_ref(), expected); - let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = signing_key - .sign_with_rng(&mut rng, text.as_bytes()) - .to_bytes(); - assert_eq!(out2.as_ref(), expected); - } + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let out2 = signing_key + .sign_with_rng(&mut rng, text.as_bytes()) + .to_bytes(); + assert_eq!(out2.as_ref(), expected); } - #[test] - fn test_sign_pkcs1v15_digest_signer() { + #[rstest] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" + ) + )] + fn test_sign_pkcs1v15_digest_signer(#[case] text: &str, #[case] expected: [u8; 64]) { let priv_key = get_private_key(); - - let tests = [( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - )]; - let signing_key = SigningKey::new(priv_key); - for (text, expected) in &tests { - let mut digest = Sha1::new(); - digest.update(text.as_bytes()); - let out = signing_key - .sign_digest(|digest: &mut Sha1| digest.update(text.as_bytes())) - .to_bytes(); - assert_ne!(out.as_ref(), text.as_bytes()); - assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec()); - assert_eq!(out.as_ref(), expected); - - let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = signing_key - .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(text.as_bytes())) - .to_bytes(); - assert_eq!(out2.as_ref(), expected); - } + let mut digest = Sha1::new(); + digest.update(text.as_bytes()); + let out = signing_key + .sign_digest(|digest: &mut Sha1| digest.update(text.as_bytes())) + .to_bytes(); + assert_ne!(out.as_ref(), text.as_bytes()); + assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec()); + assert_eq!(out.as_ref(), expected); + + let mut rng = ChaCha8Rng::from_seed([42; 32]); + let out2 = signing_key + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(text.as_bytes())) + .to_bytes(); + assert_eq!(out2.as_ref(), expected); } - #[test] - fn test_verify_pkcs1v15() { + #[rstest] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" + ), + true + )] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" + ), + false + )] + fn test_verify_pkcs1v15(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) { let priv_key = get_private_key(); - - let tests = [ - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - true, - ), - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); - for (text, sig, expected) in &tests { - let digest = Sha1::digest(text.as_bytes()).to_vec(); + let digest = Sha1::digest(text.as_bytes()).to_vec(); - let result = pub_key.verify(Pkcs1v15Sign::new::(), &digest, sig); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = pub_key.verify(Pkcs1v15Sign::new::(), &digest, &sig); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_verify_pkcs1v15_signer() { + #[rstest] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" + ), + true + )] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" + ), + false + )] + fn test_verify_pkcs1v15_signer( + #[case] text: &str, + #[case] sig: [u8; 64], + #[case] expected: bool, + ) { let priv_key = get_private_key(); - let tests = [ - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - true, - ), - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); let verifying_key = VerifyingKey::::new(pub_key); - for (text, sig, expected) in &tests { - let result = verifying_key.verify( - text.as_bytes(), - &Signature::try_from(sig.as_slice()).unwrap(), - ); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = verifying_key.verify( + text.as_bytes(), + &Signature::try_from(sig.as_slice()).unwrap(), + ); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_verify_pkcs1v15_digest_signer() { + #[rstest] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" + ), + true + )] + #[case( + "Test.\n", + hex!( + "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" + "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" + ), + false + )] + fn test_verify_pkcs1v15_digest_signer( + #[case] text: &str, + #[case] sig: [u8; 64], + #[case] expected: bool, + ) { let priv_key = get_private_key(); - let tests = [ - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae" - ), - true, - ), - ( - "Test.\n", - hex!( - "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e33" - "6ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362af" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); let verifying_key = VerifyingKey::new(pub_key); - for (text, sig, expected) in &tests { - let result = verifying_key.verify_digest( - |digest: &mut Sha1| { - digest.update(text.as_bytes()); - Ok(()) - }, - &Signature::try_from(sig.as_slice()).unwrap(), - ); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = verifying_key.verify_digest( + |digest: &mut Sha1| { + digest.update(text.as_bytes()); + Ok(()) + }, + &Signature::try_from(sig.as_slice()).unwrap(), + ); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } diff --git a/src/pss.rs b/src/pss.rs index 830d9e40..d27dc1ab 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -266,6 +266,7 @@ mod test { use hex_literal::hex; use pkcs1::DecodeRsaPrivateKey; use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng}; + use rstest::rstest; use sha1::{Digest, Sha1}; use signature::hazmat::{PrehashVerifier, RandomizedPrehashSigner}; use signature::{DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner, Verifier}; @@ -296,321 +297,293 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V RsaPrivateKey::from_pkcs1_pem(pem).unwrap() } - #[test] - fn test_verify_pss() { + #[rstest] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" + ), + true, + )] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" + ), + false, + )] + fn test_verify_pss(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) { let priv_key = get_private_key(); - - let tests = [ - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" - ), - true, - ), - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); - for (text, sig, expected) in &tests { - let digest = Sha1::digest(text.as_bytes()).to_vec(); - let result = pub_key.verify(Pss::new::(), &digest, sig); + let digest = Sha1::digest(text.as_bytes()).to_vec(); + let result = pub_key.verify(Pss::new::(), &digest, &sig); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_verify_pss_signer() { + #[rstest] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" + ), + true, + )] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" + ), + false, + )] + fn test_verify_pss_signer(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) { let priv_key = get_private_key(); - - let tests = [ - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" - ), - true, - ), - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); let verifying_key: VerifyingKey = VerifyingKey::new(pub_key); - for (text, sig, expected) in &tests { - let result = verifying_key.verify( - text.as_bytes(), - &Signature::try_from(sig.as_slice()).unwrap(), - ); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = verifying_key.verify( + text.as_bytes(), + &Signature::try_from(sig.as_slice()).unwrap(), + ); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_verify_pss_digest_signer() { + #[rstest] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" + ), + true, + )] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" + ), + false, + )] + fn test_verify_pss_digest_signer( + #[case] text: &str, + #[case] sig: [u8; 64], + #[case] expected: bool, + ) { let priv_key = get_private_key(); - - let tests = [ - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" - ), - true, - ), - ( - "test\n", - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); let verifying_key = VerifyingKey::new(pub_key); - for (text, sig, expected) in &tests { - let result = verifying_key.verify_digest( - |digest: &mut Sha1| { - digest.update(text.as_bytes()); - Ok(()) - }, - &Signature::try_from(sig.as_slice()).unwrap(), - ); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = verifying_key.verify_digest( + |digest: &mut Sha1| { + digest.update(text.as_bytes()); + Ok(()) + }, + &Signature::try_from(sig.as_slice()).unwrap(), + ); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_sign_and_verify_roundtrip() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_roundtrip(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let rng = ChaCha8Rng::from_seed([42; 32]); - for test in &tests { - let digest = Sha1::digest(test.as_bytes()).to_vec(); - let sig = priv_key - .sign_with_rng(&mut rng.clone(), Pss::new::(), &digest) - .expect("failed to sign"); + let digest = Sha1::digest(test.as_bytes()).to_vec(); + let sig = priv_key + .sign_with_rng(&mut rng.clone(), Pss::new::(), &digest) + .expect("failed to sign"); - priv_key - .to_public_key() - .verify(Pss::new::(), &digest, &sig) - .expect("failed to verify"); - } + priv_key + .to_public_key() + .verify(Pss::new::(), &digest, &sig) + .expect("failed to verify"); } - #[test] - fn test_sign_blinded_and_verify_roundtrip() { + #[rstest] + #[case("test\n")] + fn test_sign_blinded_and_verify_roundtrip(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let rng = ChaCha8Rng::from_seed([42; 32]); - for test in &tests { - let digest = Sha1::digest(test.as_bytes()).to_vec(); - let sig = priv_key - .sign_with_rng(&mut rng.clone(), Pss::new_blinded::(), &digest) - .expect("failed to sign"); + let digest = Sha1::digest(test.as_bytes()).to_vec(); + let sig = priv_key + .sign_with_rng(&mut rng.clone(), Pss::new_blinded::(), &digest) + .expect("failed to sign"); - priv_key - .to_public_key() - .verify(Pss::new::(), &digest, &sig) - .expect("failed to verify"); - } + priv_key + .to_public_key() + .verify(Pss::new::(), &digest, &sig) + .expect("failed to verify"); } - #[test] - fn test_sign_and_verify_roundtrip_signer() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_roundtrip_signer(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = SigningKey::::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); - verifying_key - .verify(test.as_bytes(), &sig) - .expect("failed to verify"); - } + let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); + verifying_key + .verify(test.as_bytes(), &sig) + .expect("failed to verify"); } - #[test] - fn test_sign_and_verify_roundtrip_blinded_signer() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_roundtrip_blinded_signer(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = BlindedSigningKey::::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); - verifying_key - .verify(test.as_bytes(), &sig) - .expect("failed to verify"); - } + let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); + verifying_key + .verify(test.as_bytes(), &sig) + .expect("failed to verify"); } - #[test] - fn test_sign_and_verify_roundtrip_digest_signer() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_roundtrip_digest_signer(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = SigningKey::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key - .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); + let sig = signing_key + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); - verifying_key - .verify_digest( - |digest: &mut Sha1| { - digest.update(test.as_bytes()); - Ok(()) - }, - &sig, - ) - .expect("failed to verify"); - } + verifying_key + .verify_digest( + |digest: &mut Sha1| { + digest.update(test.as_bytes()); + Ok(()) + }, + &sig, + ) + .expect("failed to verify"); } - #[test] - fn test_sign_and_verify_roundtrip_blinded_digest_signer() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_roundtrip_blinded_digest_signer(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = BlindedSigningKey::::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key - .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); + let sig = signing_key + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); - verifying_key - .verify_digest( - |digest: &mut Sha1| { - digest.update(test.as_bytes()); - Ok(()) - }, - &sig, - ) - .expect("failed to verify"); - } + verifying_key + .verify_digest( + |digest: &mut Sha1| { + digest.update(test.as_bytes()); + Ok(()) + }, + &sig, + ) + .expect("failed to verify"); } - #[test] - fn test_verify_pss_hazmat() { + #[rstest] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" + ), + true + )] + #[case( + "test\n", + hex!( + "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" + "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" + ), + false + )] + fn test_verify_pss_hazmat(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) { + let text = Sha1::digest(text); let priv_key = get_private_key(); - let tests = [ - ( - Sha1::digest("test\n"), - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f" - ), - true, - ), - ( - Sha1::digest("test\n"), - hex!( - "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae" - "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e" - ), - false, - ), - ]; let pub_key: RsaPublicKey = priv_key.into(); let verifying_key = VerifyingKey::::new(pub_key); - for (text, sig, expected) in &tests { - let result = verifying_key - .verify_prehash(text.as_ref(), &Signature::try_from(sig.as_slice()).unwrap()); - match expected { - true => result.expect("failed to verify"), - false => { - result.expect_err("expected verifying error"); - } + let result = verifying_key + .verify_prehash(text.as_ref(), &Signature::try_from(sig.as_slice()).unwrap()); + match expected { + true => result.expect("failed to verify"), + false => { + result.expect_err("expected verifying error"); } } } - #[test] - fn test_sign_and_verify_pss_hazmat() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_pss_hazmat(#[case] test: &str) { + let test = &Sha1::digest(test); let priv_key = get_private_key(); - let tests = [Sha1::digest("test\n")]; let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = SigningKey::::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key - .sign_prehash_with_rng(&mut rng, test) - .expect("failed to sign"); - verifying_key - .verify_prehash(test, &sig) - .expect("failed to verify"); - } + let sig = signing_key + .sign_prehash_with_rng(&mut rng, test) + .expect("failed to sign"); + verifying_key + .verify_prehash(test, &sig) + .expect("failed to verify"); } - #[test] - fn test_sign_and_verify_pss_blinded_hazmat() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_pss_blinded_hazmat(#[case] test: &str) { let priv_key = get_private_key(); - let tests = [Sha1::digest("test\n")]; + let test = &Sha1::digest(test); let mut rng = ChaCha8Rng::from_seed([42; 32]); let signing_key = BlindedSigningKey::::new(priv_key); let verifying_key = signing_key.verifying_key(); - for test in &tests { - let sig = signing_key - .sign_prehash_with_rng(&mut rng, test) - .expect("failed to sign"); - verifying_key - .verify_prehash(test, &sig) - .expect("failed to verify"); - } + let sig = signing_key + .sign_prehash_with_rng(&mut rng, test) + .expect("failed to sign"); + verifying_key + .verify_prehash(test, &sig) + .expect("failed to verify"); } #[test] @@ -634,13 +607,13 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V } } - #[test] // Tests the case where the salt length used for signing differs from the default length // while the verifier uses auto-detection. - fn test_sign_and_verify_pss_differing_salt_len() { + #[rstest] + #[case("test\n")] + fn test_sign_and_verify_pss_differing_salt_len(#[case] test: &str) { let priv_key = get_private_key(); - let tests = ["test\n"]; let mut rng = ChaCha8Rng::from_seed([42; 32]); // signing keys using different salt lengths @@ -659,13 +632,11 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V // verifying key uses default salt length strategy let verifying_key = VerifyingKey::::new_with_auto_salt_len(priv_key.to_public_key()); - for test in tests { - for signing_key in &signing_keys { - let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); - verifying_key - .verify(test.as_bytes(), &sig) - .expect("verification to succeed"); - } + for signing_key in &signing_keys { + let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); + verifying_key + .verify(test.as_bytes(), &sig) + .expect("verification to succeed"); } } } diff --git a/tests/wycheproof.rs b/tests/wycheproof.rs index 768abc23..ca0d6bba 100644 --- a/tests/wycheproof.rs +++ b/tests/wycheproof.rs @@ -13,6 +13,7 @@ use rsa::{ signature::{Error as SignatureError, Verifier}, RsaPublicKey, }; +use rstest::rstest; use serde::Deserialize; use sha1::Sha1; use sha2::{Sha224, Sha256, Sha384, Sha512}; @@ -133,151 +134,135 @@ impl Drop for Summary { } } -#[test] -fn test_rsa_pkcs1_verify() { - for file in &[ - "rsa_signature_2048_sha256_test.json", - "rsa_signature_2048_sha384_test.json", - "rsa_signature_2048_sha512_test.json", - "rsa_signature_3072_sha256_test.json", - "rsa_signature_3072_sha384_test.json", - "rsa_signature_3072_sha512_test.json", - "rsa_signature_4096_sha256_test.json", - "rsa_signature_4096_sha384_test.json", - "rsa_signature_4096_sha512_test.json", - // "rsa_signature_8192_sha256_test.json", TODO: needs disabling of maxsize - // "rsa_signature_8192_sha384_test.json", TODO: needs disabling of maxsize - // "rsa_signature_8192_sha512_test.json", TODO: needs disabling of maxsize - ] { - let path = format!("thirdparty/wycheproof/testvectors_v1/{file}"); - let data_file = File::open(&path).expect("failed to open data file"); - println!("Loading file: {path}"); - - let tests: TestFile = serde_json::from_reader(data_file).expect("invalid test JSON"); - - println!("{}:\n{}\n", tests.algorithm, tests.header.join("")); - let mut summary = Summary::new(); - - for group in tests.groups { - summary.group(&group); - - let key = RsaPublicKey::from_pkcs1_der(&group.public_key_asn).unwrap(); - println!("key is {:?}", key); - - for test in group.tests { - summary.start(&test); - - let sig = pkcs1v15::Signature::try_from(&test.sig[..]).expect("invalid signature"); - let result = match group.sha.as_ref() { - "SHA-256" => { - let vk = pkcs1v15::VerifyingKey::::new(key.clone()); - vk.verify(&test.msg, &sig) - } - "SHA-384" => { - let vk = pkcs1v15::VerifyingKey::::new(key.clone()); - vk.verify(&test.msg, &sig) - } - "SHA-512" => { - let vk = pkcs1v15::VerifyingKey::::new(key.clone()); - vk.verify(&test.msg, &sig) - } - other => panic!("unhandled sha {other:?}"), - }; - - match (test.result, &result) { - (ExpectedResult::Valid, Ok(())) => {} - (ExpectedResult::Invalid | ExpectedResult::Acceptable, Err(_err)) => {} - _ => summary.fail(test, result.err()), +#[rstest] +#[case("rsa_signature_2048_sha256_test.json")] +#[case("rsa_signature_2048_sha384_test.json")] +#[case("rsa_signature_2048_sha512_test.json")] +#[case("rsa_signature_3072_sha256_test.json")] +#[case("rsa_signature_3072_sha384_test.json")] +#[case("rsa_signature_3072_sha512_test.json")] +#[case("rsa_signature_4096_sha256_test.json")] +#[case("rsa_signature_4096_sha384_test.json")] +#[case("rsa_signature_4096_sha512_test.json")] +// #[case("rsa_signature_8192_sha256_test.json")] TODO: needs disabling of maxsize +// #[case("rsa_signature_8192_sha384_test.json")] TODO: needs disabling of maxsize +// #[case("rsa_signature_8192_sha512_test.json")] TODO: needs disabling of maxsize +fn test_rsa_pkcs1_verify(#[case] file: &str) { + let path = format!("thirdparty/wycheproof/testvectors_v1/{file}"); + let data_file = File::open(&path).expect("failed to open data file"); + println!("Loading file: {path}"); + + let tests: TestFile = serde_json::from_reader(data_file).expect("invalid test JSON"); + + println!("{}:\n{}\n", tests.algorithm, tests.header.join("")); + let mut summary = Summary::new(); + + for group in tests.groups { + summary.group(&group); + + let key = RsaPublicKey::from_pkcs1_der(&group.public_key_asn).unwrap(); + println!("key is {:?}", key); + + for test in group.tests { + summary.start(&test); + + let sig = pkcs1v15::Signature::try_from(&test.sig[..]).expect("invalid signature"); + let result = match group.sha.as_ref() { + "SHA-256" => { + let vk = pkcs1v15::VerifyingKey::::new(key.clone()); + vk.verify(&test.msg, &sig) } + "SHA-384" => { + let vk = pkcs1v15::VerifyingKey::::new(key.clone()); + vk.verify(&test.msg, &sig) + } + "SHA-512" => { + let vk = pkcs1v15::VerifyingKey::::new(key.clone()); + vk.verify(&test.msg, &sig) + } + other => panic!("unhandled sha {other:?}"), + }; + + match (test.result, &result) { + (ExpectedResult::Valid, Ok(())) => {} + (ExpectedResult::Invalid | ExpectedResult::Acceptable, Err(_err)) => {} + _ => summary.fail(test, result.err()), } } } } -#[test] -fn test_rsa_pss_verify() { - for file in &[ - "rsa_pss_2048_sha256_mgf1_0_test.json", - "rsa_pss_2048_sha256_mgf1_32_test.json", - "rsa_pss_2048_sha384_mgf1_48_test.json", - "rsa_pss_3072_sha256_mgf1_32_test.json", - "rsa_pss_4096_sha256_mgf1_32_test.json", - "rsa_pss_4096_sha384_mgf1_48_test.json", - "rsa_pss_4096_sha512_mgf1_64_test.json", - "rsa_pss_misc_test.json", - ] { - let path = format!("thirdparty/wycheproof/testvectors_v1/{file}"); - let data_file = File::open(&path).expect("failed to open data file"); - println!("Loading file: {path}"); - - let tests: TestFile = serde_json::from_reader(data_file).expect("invalid test JSON"); - - println!("{}:\n{}\n", tests.algorithm, tests.header.join("")); - let mut summary = Summary::new(); - - for group in tests.groups { - summary.group(&group); - - let key = rsa::RsaPublicKey::from_pkcs1_der(&group.public_key_asn).unwrap(); - println!("key is {:?}", key); - - for test in group.tests { - summary.start(&test); - - if group.sha != group.mgf_sha { - summary.skipped(&format!( - "pss with sha={} mgf={} salt_len={} not supported", - group.sha, group.mgf_sha, group.salt_len, - )); - } - let sig = pss::Signature::try_from(&test.sig[..]).expect("invalid signature"); - let result = match group.sha.as_ref() { - "SHA-1" => { - let vk = pss::VerifyingKey::::new_with_salt_len( - key.clone(), - group.salt_len, - ); - vk.verify(&test.msg, &sig) - } - "SHA-256" => { - let vk = pss::VerifyingKey::::new_with_salt_len( - key.clone(), - group.salt_len, - ); - vk.verify(&test.msg, &sig) - } - "SHA-224" => { - let vk = pss::VerifyingKey::::new_with_salt_len( - key.clone(), - group.salt_len, - ); - vk.verify(&test.msg, &sig) - } - "SHA-384" => { - let vk = pss::VerifyingKey::::new_with_salt_len( - key.clone(), - group.salt_len, - ); - vk.verify(&test.msg, &sig) - } - "SHA-512" => { - let vk = pss::VerifyingKey::::new_with_salt_len( - key.clone(), - group.salt_len, - ); - vk.verify(&test.msg, &sig) - } - other => panic!("unhandled sha {other:?}"), - }; - - match (test.result, &result) { - (ExpectedResult::Valid, Ok(())) => {} - (ExpectedResult::Invalid | ExpectedResult::Acceptable, Err(_err)) => {} - _ => { - summary.fail(test, result.err()); - } - }; +#[rstest] +#[case("rsa_pss_2048_sha256_mgf1_0_test.json")] +#[case("rsa_pss_2048_sha256_mgf1_32_test.json")] +#[case("rsa_pss_2048_sha384_mgf1_48_test.json")] +#[case("rsa_pss_3072_sha256_mgf1_32_test.json")] +#[case("rsa_pss_4096_sha256_mgf1_32_test.json")] +#[case("rsa_pss_4096_sha384_mgf1_48_test.json")] +#[case("rsa_pss_4096_sha512_mgf1_64_test.json")] +#[case("rsa_pss_misc_test.json")] +fn test_rsa_pss_verify(#[case] file: &str) { + let path = format!("thirdparty/wycheproof/testvectors_v1/{file}"); + let data_file = File::open(&path).expect("failed to open data file"); + println!("Loading file: {path}"); + + let tests: TestFile = serde_json::from_reader(data_file).expect("invalid test JSON"); + + println!("{}:\n{}\n", tests.algorithm, tests.header.join("")); + let mut summary = Summary::new(); + + for group in tests.groups { + summary.group(&group); + + let key = rsa::RsaPublicKey::from_pkcs1_der(&group.public_key_asn).unwrap(); + println!("key is {:?}", key); + + for test in group.tests { + summary.start(&test); + + if group.sha != group.mgf_sha { + summary.skipped(&format!( + "pss with sha={} mgf={} salt_len={} not supported", + group.sha, group.mgf_sha, group.salt_len, + )); } + let sig = pss::Signature::try_from(&test.sig[..]).expect("invalid signature"); + let result = match group.sha.as_ref() { + "SHA-1" => { + let vk = + pss::VerifyingKey::::new_with_salt_len(key.clone(), group.salt_len); + vk.verify(&test.msg, &sig) + } + "SHA-256" => { + let vk = + pss::VerifyingKey::::new_with_salt_len(key.clone(), group.salt_len); + vk.verify(&test.msg, &sig) + } + "SHA-224" => { + let vk = + pss::VerifyingKey::::new_with_salt_len(key.clone(), group.salt_len); + vk.verify(&test.msg, &sig) + } + "SHA-384" => { + let vk = + pss::VerifyingKey::::new_with_salt_len(key.clone(), group.salt_len); + vk.verify(&test.msg, &sig) + } + "SHA-512" => { + let vk = + pss::VerifyingKey::::new_with_salt_len(key.clone(), group.salt_len); + vk.verify(&test.msg, &sig) + } + other => panic!("unhandled sha {other:?}"), + }; + + match (test.result, &result) { + (ExpectedResult::Valid, Ok(())) => {} + (ExpectedResult::Invalid | ExpectedResult::Acceptable, Err(_err)) => {} + _ => { + summary.fail(test, result.err()); + } + }; } } }