summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2023-05-30 13:24:01 +0200
committerNeal H. Walfield <neal@pep.foundation>2023-05-30 13:24:01 +0200
commitb30501cf7519593b445707db9e19174d64b53572 (patch)
treed3d0392a16d7654a7067ca420922cb3560e619b6
parentb1f7a3330fb052dd68ec5174d312e94deb47306c (diff)
WIP: sequoia: Port some tests to rstest.neal/rstest
-rw-r--r--Cargo.lock48
-rw-r--r--openpgp/Cargo.toml1
-rw-r--r--openpgp/src/crypto/ecdh.rs191
-rw-r--r--openpgp/src/crypto/s2k.rs242
4 files changed, 259 insertions, 223 deletions
diff --git a/Cargo.lock b/Cargo.lock
index db581028..25ebba71 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1002,6 +1002,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
[[package]]
+name = "futures-timer"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
+
+[[package]]
name = "futures-util"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2142,12 +2148,47 @@ dependencies = [
]
[[package]]
+name = "rstest"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962"
+dependencies = [
+ "futures",
+ "futures-timer",
+ "rstest_macros",
+ "rustc_version",
+]
+
+[[package]]
+name = "rstest_macros"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8"
+dependencies = [
+ "cfg-if",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 1.0.109",
+ "unicode-ident",
+]
+
+[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
name = "rustix"
version = "0.37.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2235,6 +2276,12 @@ dependencies = [
]
[[package]]
+name = "semver"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
+
+[[package]]
name = "sequoia-autocrypt"
version = "0.25.1"
dependencies = [
@@ -2354,6 +2401,7 @@ dependencies = [
"ripemd",
"rpassword",
"rsa",
+ "rstest",
"sha-1",
"sha1collisiondetection",
"sha2 0.10.6",
diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml
index 6e1c950b..6f415135 100644
--- a/openpgp/Cargo.toml
+++ b/openpgp/Cargo.toml
@@ -117,6 +117,7 @@ quickcheck = { version = "1", default-features = false }
rand = { version = "0.8" }
rpassword = "6.0"
criterion = { version = "0.4", features = ["html_reports"] }
+rstest = "0.17"
[features]
default = ["compression", "crypto-nettle"]
diff --git a/openpgp/src/crypto/ecdh.rs b/openpgp/src/crypto/ecdh.rs
index 2092ad07..f02cde70 100644
--- a/openpgp/src/crypto/ecdh.rs
+++ b/openpgp/src/crypto/ecdh.rs
@@ -415,6 +415,8 @@ const AES_KEY_WRAP_IV: u64 = 0xa6a6a6a6a6a6a6a6;
mod tests {
use super::*;
+ use rstest::rstest;
+
#[test]
fn pkcs5_padding() {
let v = pkcs5_pad(vec![0, 0, 0].into(), 8).unwrap();
@@ -428,108 +430,93 @@ mod tests {
assert_eq!(&v, &Protected::from(&[][..]));
}
- #[test]
- fn aes_wrapping() {
- struct Test {
- algo: SymmetricAlgorithm,
- kek: &'static [u8],
- key_data: &'static [u8],
- ciphertext: &'static [u8],
- }
-
- // These are the test vectors from RFC3394.
- const TESTS: &[Test] = &[
- Test {
- algo: SymmetricAlgorithm::AES128,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
- ciphertext: &[0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
- 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
- 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5],
- },
- Test {
- algo: SymmetricAlgorithm::AES192,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
- ciphertext: &[0x96, 0x77, 0x8B, 0x25, 0xAE, 0x6C, 0xA4, 0x35,
- 0xF9, 0x2B, 0x5B, 0x97, 0xC0, 0x50, 0xAE, 0xD2,
- 0x46, 0x8A, 0xB8, 0xA1, 0x7A, 0xD8, 0x4E, 0x5D],
- },
- Test {
- algo: SymmetricAlgorithm::AES256,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
- ciphertext: &[0x64, 0xE8, 0xC3, 0xF9, 0xCE, 0x0F, 0x5B, 0xA2,
- 0x63, 0xE9, 0x77, 0x79, 0x05, 0x81, 0x8A, 0x2A,
- 0x93, 0xC8, 0x19, 0x1E, 0x7D, 0x6E, 0x8A, 0xE7],
- },
- Test {
- algo: SymmetricAlgorithm::AES192,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
- ciphertext: &[0x03, 0x1D, 0x33, 0x26, 0x4E, 0x15, 0xD3, 0x32,
- 0x68, 0xF2, 0x4E, 0xC2, 0x60, 0x74, 0x3E, 0xDC,
- 0xE1, 0xC6, 0xC7, 0xDD, 0xEE, 0x72, 0x5A, 0x93,
- 0x6B, 0xA8, 0x14, 0x91, 0x5C, 0x67, 0x62, 0xD2],
- },
- Test {
- algo: SymmetricAlgorithm::AES256,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
- ciphertext: &[0xA8, 0xF9, 0xBC, 0x16, 0x12, 0xC6, 0x8B, 0x3F,
- 0xF6, 0xE6, 0xF4, 0xFB, 0xE3, 0x0E, 0x71, 0xE4,
- 0x76, 0x9C, 0x8B, 0x80, 0xA3, 0x2C, 0xB8, 0x95,
- 0x8C, 0xD5, 0xD1, 0x7D, 0x6B, 0x25, 0x4D, 0xA1],
- },
- Test {
- algo: SymmetricAlgorithm::AES256,
- kek: &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
- key_data: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F],
- ciphertext: &[0x28, 0xC9, 0xF4, 0x04, 0xC4, 0xB8, 0x10, 0xF4,
- 0xCB, 0xCC, 0xB3, 0x5C, 0xFB, 0x87, 0xF8, 0x26,
- 0x3F, 0x57, 0x86, 0xE2, 0xD8, 0x0E, 0xD3, 0x26,
- 0xCB, 0xC7, 0xF0, 0xE7, 0x1A, 0x99, 0xF4, 0x3B,
- 0xFB, 0x98, 0x8B, 0x9B, 0x7A, 0x02, 0xDD, 0x21],
- },
- ];
-
- for test in TESTS {
- let ciphertext = aes_key_wrap(test.algo,
- &test.kek.into(),
- &test.key_data.into())
- .unwrap();
- assert_eq!(test.ciphertext, &ciphertext[..]);
-
- let key_data = aes_key_unwrap(test.algo,
- &test.kek.into(),
- &ciphertext[..])
- .unwrap();
- assert_eq!(&Protected::from(test.key_data), &key_data);
- }
+ #[rstest]
+ // These are the test vectors from RFC3394.
+ #[case(
+ SymmetricAlgorithm::AES128,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
+ &[0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
+ 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
+ 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5])]
+ #[case(
+ SymmetricAlgorithm::AES192,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
+ &[0x96, 0x77, 0x8B, 0x25, 0xAE, 0x6C, 0xA4, 0x35,
+ 0xF9, 0x2B, 0x5B, 0x97, 0xC0, 0x50, 0xAE, 0xD2,
+ 0x46, 0x8A, 0xB8, 0xA1, 0x7A, 0xD8, 0x4E, 0x5D])]
+ #[case(
+ SymmetricAlgorithm::AES256,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
+ &[0x64, 0xE8, 0xC3, 0xF9, 0xCE, 0x0F, 0x5B, 0xA2,
+ 0x63, 0xE9, 0x77, 0x79, 0x05, 0x81, 0x8A, 0x2A,
+ 0x93, 0xC8, 0x19, 0x1E, 0x7D, 0x6E, 0x8A, 0xE7])]
+ #[case(
+ SymmetricAlgorithm::AES192,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
+ &[0x03, 0x1D, 0x33, 0x26, 0x4E, 0x15, 0xD3, 0x32,
+ 0x68, 0xF2, 0x4E, 0xC2, 0x60, 0x74, 0x3E, 0xDC,
+ 0xE1, 0xC6, 0xC7, 0xDD, 0xEE, 0x72, 0x5A, 0x93,
+ 0x6B, 0xA8, 0x14, 0x91, 0x5C, 0x67, 0x62, 0xD2])]
+ #[case(
+ SymmetricAlgorithm::AES256,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
+ &[0xA8, 0xF9, 0xBC, 0x16, 0x12, 0xC6, 0x8B, 0x3F,
+ 0xF6, 0xE6, 0xF4, 0xFB, 0xE3, 0x0E, 0x71, 0xE4,
+ 0x76, 0x9C, 0x8B, 0x80, 0xA3, 0x2C, 0xB8, 0x95,
+ 0x8C, 0xD5, 0xD1, 0x7D, 0x6B, 0x25, 0x4D, 0xA1])]
+ #[case(
+ SymmetricAlgorithm::AES256,
+ &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F],
+ &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F],
+ &[0x28, 0xC9, 0xF4, 0x04, 0xC4, 0xB8, 0x10, 0xF4,
+ 0xCB, 0xCC, 0xB3, 0x5C, 0xFB, 0x87, 0xF8, 0x26,
+ 0x3F, 0x57, 0x86, 0xE2, 0xD8, 0x0E, 0xD3, 0x26,
+ 0xCB, 0xC7, 0xF0, 0xE7, 0x1A, 0x99, 0xF4, 0x3B,
+ 0xFB, 0x98, 0x8B, 0x9B, 0x7A, 0x02, 0xDD, 0x21])]
+ fn aes_wrapping(#[case] algo: SymmetricAlgorithm,
+ #[case] kek: &'static [u8],
+ #[case] key_data: &'static [u8],
+ #[case] ciphertext: &'static [u8]) {
+ let ciphertext2 = aes_key_wrap(algo,
+ &kek.into(),
+ &key_data.into())
+ .unwrap();
+ assert_eq!(ciphertext, &ciphertext2[..]);
+
+ let key_data2 = aes_key_unwrap(algo,
+ &kek.into(),
+ &ciphertext2[..])
+ .unwrap();
+ assert_eq!(&Protected::from(key_data), &key_data2);
}
#[test]
diff --git a/openpgp/src/crypto/s2k.rs b/openpgp/src/crypto/s2k.rs
index 9b7c24d6..7dc734cf 100644
--- a/openpgp/src/crypto/s2k.rs
+++ b/openpgp/src/crypto/s2k.rs
@@ -419,139 +419,139 @@ impl Arbitrary for S2K {
mod tests {
use super::*;
+ use rstest::rstest;
+
use crate::fmt::to_hex;
use crate::SymmetricAlgorithm;
use crate::Packet;
use crate::parse::{Parse, PacketParser};
- #[test]
- fn s2k_parser_test() {
+ #[rstest]
+ // Note: this test only works with SK-ESK packets that don't
+ // contain an encrypted session key, i.e., the session key is
+ // the result of the s2k function. gpg generates this type of
+ // SK-ESK packet when invoked with -c, but not -e. (When
+ // invoked with -c and -e, it generates SK-ESK packets that
+ // include an encrypted session key.)
+ #[allow(deprecated)]
+ #[case(
+ "mode-0-password-1234.gpg",
+ SymmetricAlgorithm::AES256,
+ S2K::Simple{ hash: HashAlgorithm::SHA1, },
+ "1234".into(),
+ "7110EDA4D09E062AA5E4A390B0A572AC0D2C0220F352B0D292B65164C2A67301",
+ )]
+ #[allow(deprecated)]
+ #[case(
+ "mode-1-password-123456-1.gpg",
+ SymmetricAlgorithm::AES256,
+ S2K::Salted{
+ hash: HashAlgorithm::SHA1,
+ salt: [0xa8, 0x42, 0xa7, 0xa9, 0x59, 0xfa, 0x42, 0x2a],
+ },
+ "123456".into(),
+ "8B79077CA448F6FB3D3AD2A264D3B938D357C9FB3E41219FD962DF960A9AFA08",
+ )]
+ #[allow(deprecated)]
+ #[case(
+ "mode-1-password-foobar-2.gpg",
+ SymmetricAlgorithm::AES256,
+ S2K::Salted{
+ hash: HashAlgorithm::SHA1,
+ salt: [0xbc, 0x95, 0x58, 0x45, 0x81, 0x3c, 0x7c, 0x37],
+ },
+ "foobar".into(),
+ "B7D48AAE9B943B22A4D390083E8460B5EDFA118FE1688BF0C473B8094D1A8D10",
+ )]
+ #[case(
+ "mode-3-password-qwerty-1.gpg",
+ SymmetricAlgorithm::AES256,
+ S2K::Iterated {
+ hash: HashAlgorithm::SHA1,
+ salt: [0x78, 0x45, 0xf0, 0x5b, 0x55, 0xf7, 0xb4, 0x9e],
+ hash_bytes: S2K::decode_count(241),
+ },
+ "qwerty".into(),
+ "575AD156187A3F8CEC11108309236EB499F1E682F0D1AFADFAC4ECF97613108A",
+ )]
+ #[case(
+ "mode-3-password-9876-2.gpg",
+ SymmetricAlgorithm::AES256,
+ S2K::Iterated {
+ hash: HashAlgorithm::SHA1,
+ salt: [0xb9, 0x67, 0xea, 0x96, 0x53, 0xdb, 0x6a, 0xc8],
+ hash_bytes: S2K::decode_count(43),
+ },
+ "9876".into(),
+ "736C226B8C64E4E6D0325C6C552EF7C0738F98F48FED65FD8C93265103EFA23A",
+ )]
+ #[case(
+ "mode-3-aes192-password-123.gpg",
+ SymmetricAlgorithm::AES192,
+ S2K::Iterated {
+ hash: HashAlgorithm::SHA1,
+ salt: [0x8f, 0x81, 0x74, 0xc5, 0xd9, 0x61, 0xc7, 0x79],
+ hash_bytes: S2K::decode_count(238),
+ },
+ "123".into(),
+ "915E96FC694E7F90A6850B740125EA005199C725F3BD27E3",
+ )]
+ #[case(
+ "mode-3-twofish-password-13-times-0123456789.gpg",
+ SymmetricAlgorithm::Twofish,
+ S2K::Iterated {
+ hash: HashAlgorithm::SHA1,
+ salt: [0x51, 0xed, 0xfc, 0x15, 0x45, 0x40, 0x65, 0xac],
+ hash_bytes: S2K::decode_count(238),
+ },
+ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789".into(),
+ "EA264FADA5A859C40D88A159B344ECF1F51FF327FDB3C558B0A7DC299777173E",
+ )]
+ #[case(
+ "mode-3-aes128-password-13-times-0123456789.gpg",
+ SymmetricAlgorithm::AES128,
+ S2K::Iterated {
+ hash: HashAlgorithm::SHA1,
+ salt: [0x06, 0xe4, 0x61, 0x5c, 0xa4, 0x48, 0xf9, 0xdd],
+ hash_bytes: S2K::decode_count(238),
+ },
+ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789".into(),
+ "F3D0CE52ED6143637443E3399437FD0F",
+ )]
+ fn s2k_parser_test(
+ #[case] filename: &'static str,
+ #[case] cipher_algo: SymmetricAlgorithm,
+ #[case] s2k: S2K,
+ #[case] password: Password,
+ #[case] key_hex: &'static str) {
use crate::packet::SKESK;
- struct Test<'a> {
- filename: &'a str,
- s2k: S2K,
- cipher_algo: SymmetricAlgorithm,
- password: Password,
- key_hex: &'a str,
+ if !cipher_algo.is_supported() {
+ return
}
- // Note: this test only works with SK-ESK packets that don't
- // contain an encrypted session key, i.e., the session key is
- // the result of the s2k function. gpg generates this type of
- // SK-ESK packet when invoked with -c, but not -e. (When
- // invoked with -c and -e, it generates SK-ESK packets that
- // include an encrypted session key.)
- #[allow(deprecated)]
- let tests = [
- Test {
- filename: "mode-0-password-1234.gpg",
- cipher_algo: SymmetricAlgorithm::AES256,
- s2k: S2K::Simple{ hash: HashAlgorithm::SHA1, },
- password: "1234".into(),
- key_hex: "7110EDA4D09E062AA5E4A390B0A572AC0D2C0220F352B0D292B65164C2A67301",
- },
- Test {
- filename: "mode-1-password-123456-1.gpg",
- cipher_algo: SymmetricAlgorithm::AES256,
- s2k: S2K::Salted{
- hash: HashAlgorithm::SHA1,
- salt: [0xa8, 0x42, 0xa7, 0xa9, 0x59, 0xfa, 0x42, 0x2a],
- },
- password: "123456".into(),
- key_hex: "8B79077CA448F6FB3D3AD2A264D3B938D357C9FB3E41219FD962DF960A9AFA08",
- },
- Test {
- filename: "mode-1-password-foobar-2.gpg",
- cipher_algo: SymmetricAlgorithm::AES256,
- s2k: S2K::Salted{
- hash: HashAlgorithm::SHA1,
- salt: [0xbc, 0x95, 0x58, 0x45, 0x81, 0x3c, 0x7c, 0x37],
- },
- password: "foobar".into(),
- key_hex: "B7D48AAE9B943B22A4D390083E8460B5EDFA118FE1688BF0C473B8094D1A8D10",
- },
- Test {
- filename: "mode-3-password-qwerty-1.gpg",
- cipher_algo: SymmetricAlgorithm::AES256,
- s2k: S2K::Iterated {
- hash: HashAlgorithm::SHA1,
- salt: [0x78, 0x45, 0xf0, 0x5b, 0x55, 0xf7, 0xb4, 0x9e],
- hash_bytes: S2K::decode_count(241),
- },
- password: "qwerty".into(),
- key_hex: "575AD156187A3F8CEC11108309236EB499F1E682F0D1AFADFAC4ECF97613108A",
- },
- Test {
- filename: "mode-3-password-9876-2.gpg",
- cipher_algo: SymmetricAlgorithm::AES256,
- s2k: S2K::Iterated {
- hash: HashAlgorithm::SHA1,
- salt: [0xb9, 0x67, 0xea, 0x96, 0x53, 0xdb, 0x6a, 0xc8],
- hash_bytes: S2K::decode_count(43),
- },
- password: "9876".into(),
- key_hex: "736C226B8C64E4E6D0325C6C552EF7C0738F98F48FED65FD8C93265103EFA23A",
- },
- Test {
- filename: "mode-3-aes192-password-123.gpg",
- cipher_algo: SymmetricAlgorithm::AES192,
- s2k: S2K::Iterated {
- hash: HashAlgorithm::SHA1,
- salt: [0x8f, 0x81, 0x74, 0xc5, 0xd9, 0x61, 0xc7, 0x79],
- hash_bytes: S2K::decode_count(238),
- },
- password: "123".into(),
- key_hex: "915E96FC694E7F90A6850B740125EA005199C725F3BD27E3",
- },
- Test {
- filename: "mode-3-twofish-password-13-times-0123456789.gpg",
- cipher_algo: SymmetricAlgorithm::Twofish,
- s2k: S2K::Iterated {
- hash: HashAlgorithm::SHA1,
- salt: [0x51, 0xed, 0xfc, 0x15, 0x45, 0x40, 0x65, 0xac],
- hash_bytes: S2K::decode_count(238),
- },
- password: "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789".into(),
- key_hex: "EA264FADA5A859C40D88A159B344ECF1F51FF327FDB3C558B0A7DC299777173E",
- },
- Test {
- filename: "mode-3-aes128-password-13-times-0123456789.gpg",
- cipher_algo: SymmetricAlgorithm::AES128,
- s2k: S2K::Iterated {
- hash: HashAlgorithm::SHA1,
- salt: [0x06, 0xe4, 0x61, 0x5c, 0xa4, 0x48, 0xf9, 0xdd],
- hash_bytes: S2K::decode_count(238),
- },
- password: "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789".into(),
- key_hex: "F3D0CE52ED6143637443E3399437FD0F",
- },
- ];
-
- for test in tests.iter().filter(|t| t.cipher_algo.is_supported()) {
- let path = crate::tests::message(&format!("s2k/{}", test.filename));
- let pp = PacketParser::from_bytes(path).unwrap().unwrap();
- if let Packet::SKESK(SKESK::V4(ref skesk)) = pp.packet {
- assert_eq!(skesk.symmetric_algo(), test.cipher_algo);
- assert_eq!(skesk.s2k(), &test.s2k);
-
- let key = skesk.s2k().derive_key(
- &test.password,
- skesk.symmetric_algo().key_size().unwrap());
- if let Ok(key) = key {
- let key = to_hex(&key[..], false);
- assert_eq!(key, test.key_hex);
- } else {
- panic!("Session key: None!");
- }
+ let path = crate::tests::message(&format!("s2k/{}", filename));
+ let pp = PacketParser::from_bytes(path).unwrap().unwrap();
+ if let Packet::SKESK(SKESK::V4(ref skesk)) = pp.packet {
+ assert_eq!(skesk.symmetric_algo(), cipher_algo);
+ assert_eq!(skesk.s2k(), &s2k);
+
+ let key = skesk.s2k().derive_key(
+ &password,
+ skesk.symmetric_algo().key_size().unwrap());
+ if let Ok(key) = key {
+ let key = to_hex(&key[..], false);
+ assert_eq!(key, key_hex);
} else {
- panic!("Wrong packet!");
+ panic!("Session key: None!");
}
-
- // Get the next packet.
- let (_, ppr) = pp.next().unwrap();
- assert!(ppr.is_eof());
+ } else {
+ panic!("Wrong packet!");
}
+
+ // Get the next packet.
+ let (_, ppr) = pp.next().unwrap();
+ assert!(ppr.is_eof());
}
quickcheck! {