From e52904256b8b284a7e3a8f0639acbf52bb44891e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 13 May 2017 12:15:31 -1000 Subject: [PATCH] Move RSA signing & verification functional tests to tests/. --- Cargo.toml | 12 +- src/rsa/signing.rs | 123 +-------- src/rsa/verification.rs | 119 --------- {src/rsa => tests}/rsa_pkcs1_sign_tests.txt | 0 {src/rsa => tests}/rsa_pkcs1_verify_tests.txt | 0 .../rsa_primitive_verify_tests.txt | 0 {src/rsa => tests}/rsa_pss_sign_tests.txt | 0 {src/rsa => tests}/rsa_pss_verify_tests.txt | 0 tests/rsa_tests.rs | 238 +++++++++++++++++- 9 files changed, 243 insertions(+), 249 deletions(-) rename {src/rsa => tests}/rsa_pkcs1_sign_tests.txt (100%) rename {src/rsa => tests}/rsa_pkcs1_verify_tests.txt (100%) rename {src/rsa => tests}/rsa_primitive_verify_tests.txt (100%) rename {src/rsa => tests}/rsa_pss_sign_tests.txt (100%) rename {src/rsa => tests}/rsa_pss_verify_tests.txt (100%) diff --git a/Cargo.toml b/Cargo.toml index 8395cca6a..ad13cc627 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,12 +121,7 @@ include = [ "src/rsa/padding.rs", "src/rsa/random.rs", "src/rsa/rsa.rs", - "src/rsa/rsa_pkcs1_sign_tests.txt", - "src/rsa/rsa_pkcs1_verify_tests.txt", - "src/rsa/rsa_primitive_verify_tests.txt", "src/rsa/rsa_pss_padding_tests.txt", - "src/rsa/rsa_pss_sign_tests.txt", - "src/rsa/rsa_pss_verify_tests.txt", "src/rsa/signature_rsa_example_private_key.der", "src/rsa/signature_rsa_example_public_key.der", "src/rsa/signing.rs", @@ -240,12 +235,17 @@ include = [ "tests/ed25519_tests.txt", "tests/ed25519_from_pkcs8_tests.txt", "tests/ed25519_from_pkcs8_unchecked_tests.txt", - "tests/rsa_tests.rs", "tests/pkcs8_test_ecPublicKey_p256.pk8", "tests/pkcs8_test_ecPublicKey_p256_RSAPrivateKey.pk8", "tests/pkcs8_test_rsaEncryption_2048_e3.pk8", "tests/pkcs8_test_rsaEncryption_2048_e65537.pk8", "tests/pkcs8_test_rsaEncryption_3072_e65537.pk8", + "tests/rsa_pkcs1_sign_tests.txt", + "tests/rsa_pkcs1_verify_tests.txt", + "tests/rsa_primitive_verify_tests.txt", + "tests/rsa_pss_sign_tests.txt", + "tests/rsa_pss_verify_tests.txt", + "tests/rsa_tests.rs", "third-party/NIST/README.md", "third-party/NIST/sha256sums.txt", "third-party/NIST/SHAVS/SHA1LongMsg.rsp", diff --git a/src/rsa/signing.rs b/src/rsa/signing.rs index 78231c14e..d5dd7d38b 100644 --- a/src/rsa/signing.rs +++ b/src/rsa/signing.rs @@ -644,54 +644,11 @@ mod tests { // We intentionally avoid `use super::*` so that we are sure to use only // the public API; this ensures that enough of the API is public. use core; - use {error, rand, signature, test}; + use {rand, signature, test}; use std; use super::super::blinding; use untrusted; - #[test] - fn test_signature_rsa_pkcs1_sign() { - let rng = rand::SystemRandom::new(); - test::from_file("src/rsa/rsa_pkcs1_sign_tests.txt", - |section, test_case| { - assert_eq!(section, ""); - - let digest_name = test_case.consume_string("Digest"); - let alg = match digest_name.as_ref() { - "SHA256" => &signature::RSA_PKCS1_SHA256, - "SHA384" => &signature::RSA_PKCS1_SHA384, - "SHA512" => &signature::RSA_PKCS1_SHA512, - _ => { panic!("Unsupported digest: {}", digest_name) } - }; - - let private_key = test_case.consume_bytes("Key"); - let msg = test_case.consume_bytes("Msg"); - let expected = test_case.consume_bytes("Sig"); - let result = test_case.consume_string("Result"); - - let private_key = untrusted::Input::from(&private_key); - let key_pair = signature::RSAKeyPair::from_der(private_key); - if result == "Fail-Invalid-Key" { - assert!(key_pair.is_err()); - return Ok(()); - } - let key_pair = key_pair.unwrap(); - let key_pair = std::sync::Arc::new(key_pair); - - // XXX: This test is too slow on Android ARM Travis CI builds. - // TODO: re-enable these tests on Android ARM. - let mut signing_state = - signature::RSASigningState::new(key_pair).unwrap(); - let mut actual: std::vec::Vec = - vec![0; signing_state.key_pair().public_modulus_len()]; - signing_state.sign(alg, &rng, &msg, actual.as_mut_slice()).unwrap(); - assert_eq!(actual.as_slice() == &expected[..], result == "Pass"); - Ok(()) - }); - } - - - // `RSAKeyPair::sign` requires that the output buffer is the same length as // the public key modulus. Test what happens when it isn't the same length. #[test] @@ -753,7 +710,7 @@ mod tests { MESSAGE, &mut signature); let remaining = signing_state.blinding.remaining(); assert_eq!((remaining + 1) % blinding::REMAINING_MAX, - prev_remaining); + prev_remaining); } } @@ -798,80 +755,4 @@ mod tests { assert!(result.is_err()); } - - #[cfg(feature = "rsa_signing")] - #[test] - fn test_signature_rsa_pss_sign() { - // Outputs the same value whenever a certain length is requested (the - // same as the length of the salt). Otherwise, the rng is used. - struct DeterministicSalt<'a> { - salt: &'a [u8], - rng: &'a rand::SecureRandom - } - impl<'a> rand::SecureRandom for DeterministicSalt<'a> { - fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> { - let dest_len = dest.len(); - if dest_len != self.salt.len() { - try!(self.rng.fill(dest)); - } else { - dest.copy_from_slice(&self.salt); - } - Ok(()) - } - } - let rng = rand::SystemRandom::new(); - - test::from_file("src/rsa/rsa_pss_sign_tests.txt", |section, test_case| { - assert_eq!(section, ""); - - let digest_name = test_case.consume_string("Digest"); - let alg = match digest_name.as_ref() { - "SHA256" => &signature::RSA_PSS_SHA256, - "SHA384" => &signature::RSA_PSS_SHA384, - "SHA512" => &signature::RSA_PSS_SHA512, - _ => { panic!("Unsupported digest: {}", digest_name) } - }; - - let result = test_case.consume_string("Result"); - let private_key = test_case.consume_bytes("Key"); - let private_key = untrusted::Input::from(&private_key); - let key_pair = signature::RSAKeyPair::from_der(private_key); - if key_pair.is_err() && result == "Fail-Invalid-Key" { - return Ok(()); - } - let key_pair = key_pair.unwrap(); - let key_pair = std::sync::Arc::new(key_pair); - let msg = test_case.consume_bytes("Msg"); - let salt = test_case.consume_bytes("Salt"); - let expected = test_case.consume_bytes("Sig"); - - let new_rng = DeterministicSalt { salt: &salt, rng: &rng }; - - let mut signing_state = - signature::RSASigningState::new(key_pair).unwrap(); - let mut actual: std::vec::Vec = - vec![0; signing_state.key_pair().public_modulus_len()]; - try!(signing_state.sign(alg, &new_rng, &msg, actual.as_mut_slice())); - assert_eq!(actual.as_slice() == &expected[..], result == "Pass"); - Ok(()) - }); - } - - - #[test] - fn test_sync_and_send() { - const PRIVATE_KEY_DER: &'static [u8] = - include_bytes!("signature_rsa_example_private_key.der"); - let key_bytes_der = untrusted::Input::from(PRIVATE_KEY_DER); - let key_pair = signature::RSAKeyPair::from_der(key_bytes_der).unwrap(); - let key_pair = std::sync::Arc::new(key_pair); - - let _: &Send = &key_pair; - let _: &Sync = &key_pair; - - let signing_state = signature::RSASigningState::new(key_pair).unwrap(); - let _: &Send = &signing_state; - // TODO: Test that signing_state is NOT Sync; i.e. - // `let _: &Sync = &signing_state;` must fail - } } diff --git a/src/rsa/verification.rs b/src/rsa/verification.rs index f7770b3fd..bc283cc1e 100644 --- a/src/rsa/verification.rs +++ b/src/rsa/verification.rs @@ -159,122 +159,3 @@ pub fn verify_rsa(params: &RSAParameters, untrusted::Input::from(decoded).read_all( error::Unspecified, |m| params.padding_alg.verify(&m_hash, m, n_bits)) } - - -#[cfg(test)] -mod tests { - // We intentionally avoid `use super::*` so that we are sure to use only - // the public API; this ensures that enough of the API is public. - use {der, error, signature, test}; - use untrusted; - - #[test] - fn test_signature_rsa_pkcs1_verify() { - test::from_file("src/rsa/rsa_pkcs1_verify_tests.txt", - |section, test_case| { - assert_eq!(section, ""); - - let digest_name = test_case.consume_string("Digest"); - let alg = match digest_name.as_ref() { - "SHA1" => &signature::RSA_PKCS1_2048_8192_SHA1, - "SHA256" => &signature::RSA_PKCS1_2048_8192_SHA256, - "SHA384" => &signature::RSA_PKCS1_2048_8192_SHA384, - "SHA512" => &signature::RSA_PKCS1_2048_8192_SHA512, - _ => { panic!("Unsupported digest: {}", digest_name) } - }; - - let public_key = test_case.consume_bytes("Key"); - let public_key = untrusted::Input::from(&public_key); - - // Sanity check that we correctly DER-encoded the originally- - // provided separate (n, e) components. When we add test vectors - // for improperly-encoded signatures, we'll have to revisit this. - assert!(public_key.read_all(error::Unspecified, |input| { - der::nested(input, der::Tag::Sequence, error::Unspecified, - |input| { - let _ = try!(der::positive_integer(input)); - let _ = try!(der::positive_integer(input)); - Ok(()) - }) - }).is_ok()); - - let msg = test_case.consume_bytes("Msg"); - let msg = untrusted::Input::from(&msg); - - let sig = test_case.consume_bytes("Sig"); - let sig = untrusted::Input::from(&sig); - - let expected_result = test_case.consume_string("Result"); - - let actual_result = signature::verify(alg, public_key, msg, sig); - assert_eq!(actual_result.is_ok(), expected_result == "P"); - - Ok(()) - }); - } - - #[test] - fn test_signature_rsa_pss_verify() { - test::from_file("src/rsa/rsa_pss_verify_tests.txt", - |section, test_case| { - assert_eq!(section, ""); - - let digest_name = test_case.consume_string("Digest"); - let alg = match digest_name.as_ref() { - "SHA256" => &signature::RSA_PSS_2048_8192_SHA256, - "SHA384" => &signature::RSA_PSS_2048_8192_SHA384, - "SHA512" => &signature::RSA_PSS_2048_8192_SHA512, - _ => { panic!("Unsupported digest: {}", digest_name) } - }; - - let public_key = test_case.consume_bytes("Key"); - let public_key = untrusted::Input::from(&public_key); - - // Sanity check that we correctly DER-encoded the originally- - // provided separate (n, e) components. When we add test vectors - // for improperly-encoded signatures, we'll have to revisit this. - assert!(public_key.read_all(error::Unspecified, |input| { - der::nested(input, der::Tag::Sequence, error::Unspecified, - |input| { - let _ = try!(der::positive_integer(input)); - let _ = try!(der::positive_integer(input)); - Ok(()) - }) - }).is_ok()); - - let msg = test_case.consume_bytes("Msg"); - let msg = untrusted::Input::from(&msg); - - let sig = test_case.consume_bytes("Sig"); - let sig = untrusted::Input::from(&sig); - - let expected_result = test_case.consume_string("Result"); - - let actual_result = signature::verify(alg, public_key, msg, sig); - assert_eq!(actual_result.is_ok(), expected_result == "P"); - - Ok(()) - }); - } - - // Test for `primitive::verify()`. Read public key parts from a file - // and use them to verify a signature. - #[test] - fn test_signature_rsa_primitive_verification() { - test::from_file("src/rsa/rsa_primitive_verify_tests.txt", - |section, test_case| { - assert_eq!(section, ""); - let n = test_case.consume_bytes("n"); - let e = test_case.consume_bytes("e"); - let msg = test_case.consume_bytes("Msg"); - let sig = test_case.consume_bytes("Sig"); - let expected = test_case.consume_string("Result"); - let result = signature::primitive::verify_rsa( - &signature::RSA_PKCS1_2048_8192_SHA256, - (untrusted::Input::from(&n), untrusted::Input::from(&e)), - untrusted::Input::from(&msg), untrusted::Input::from(&sig)); - assert_eq!(result.is_ok(), expected == "Pass"); - Ok(()) - }) - } -} diff --git a/src/rsa/rsa_pkcs1_sign_tests.txt b/tests/rsa_pkcs1_sign_tests.txt similarity index 100% rename from src/rsa/rsa_pkcs1_sign_tests.txt rename to tests/rsa_pkcs1_sign_tests.txt diff --git a/src/rsa/rsa_pkcs1_verify_tests.txt b/tests/rsa_pkcs1_verify_tests.txt similarity index 100% rename from src/rsa/rsa_pkcs1_verify_tests.txt rename to tests/rsa_pkcs1_verify_tests.txt diff --git a/src/rsa/rsa_primitive_verify_tests.txt b/tests/rsa_primitive_verify_tests.txt similarity index 100% rename from src/rsa/rsa_primitive_verify_tests.txt rename to tests/rsa_primitive_verify_tests.txt diff --git a/src/rsa/rsa_pss_sign_tests.txt b/tests/rsa_pss_sign_tests.txt similarity index 100% rename from src/rsa/rsa_pss_sign_tests.txt rename to tests/rsa_pss_sign_tests.txt diff --git a/src/rsa/rsa_pss_verify_tests.txt b/tests/rsa_pss_verify_tests.txt similarity index 100% rename from src/rsa/rsa_pss_verify_tests.txt rename to tests/rsa_pss_verify_tests.txt diff --git a/tests/rsa_tests.rs b/tests/rsa_tests.rs index 2b6ab9ad6..fb1390739 100644 --- a/tests/rsa_tests.rs +++ b/tests/rsa_tests.rs @@ -12,13 +12,16 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![cfg(feature = "rsa_signing")] - extern crate ring; extern crate untrusted; -use ring::signature; +use ring::{der, error, signature, test}; +#[cfg(feature = "rsa_signing")] +use ring::rand; + + +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_rsa_encryption_2048() { const INPUT: &'static [u8] = @@ -27,6 +30,7 @@ fn test_rsa_key_pair_from_pkcs8_rsa_encryption_2048() { untrusted::Input::from(INPUT)).is_ok()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_rsa_encryption_3072() { const INPUT: &'static [u8] = @@ -35,6 +39,7 @@ fn test_rsa_key_pair_from_pkcs8_rsa_encryption_3072() { untrusted::Input::from(INPUT)).is_ok()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_rsa_encryption_invalid_e3() { const INPUT: &'static [u8] = @@ -43,6 +48,7 @@ fn test_rsa_key_pair_from_pkcs8_rsa_encryption_invalid_e3() { untrusted::Input::from(INPUT)).is_err()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_rsa_encryption_2048_truncated() { const INPUT: &'static [u8] = @@ -51,6 +57,7 @@ fn test_rsa_key_pair_from_pkcs8_rsa_encryption_2048_truncated() { untrusted::Input::from(&INPUT[..(INPUT.len() - 1)])).is_err()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_ecc() { // The input is a valid P-256 private key, which isn't a valid RSA key. @@ -60,6 +67,7 @@ fn test_rsa_key_pair_from_pkcs8_ecc() { untrusted::Input::from(INPUT)).is_err()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_rsa_encryption_ecc() { // The input's algorithm ID is rsaEncryption, but it contains a P-256 @@ -70,6 +78,7 @@ fn test_rsa_key_pair_from_pkcs8_rsa_encryption_ecc() { untrusted::Input::from(INPUT)).is_err()); } +#[cfg(feature = "rsa_signing")] #[test] fn test_rsa_key_pair_from_pkcs8_ecc_rsa_private_key() { // The input contains an RSAPrivateKey, but marked as an ecPublicKey w/ @@ -80,3 +89,226 @@ fn test_rsa_key_pair_from_pkcs8_ecc_rsa_private_key() { untrusted::Input::from(INPUT)).is_err()); } +#[cfg(feature = "rsa_signing")] +#[test] +fn test_signature_rsa_pkcs1_sign() { + let rng = rand::SystemRandom::new(); + test::from_file("tests/rsa_pkcs1_sign_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let digest_name = test_case.consume_string("Digest"); + let alg = match digest_name.as_ref() { + "SHA256" => &signature::RSA_PKCS1_SHA256, + "SHA384" => &signature::RSA_PKCS1_SHA384, + "SHA512" => &signature::RSA_PKCS1_SHA512, + _ => { panic!("Unsupported digest: {}", digest_name) } + }; + + let private_key = test_case.consume_bytes("Key"); + let msg = test_case.consume_bytes("Msg"); + let expected = test_case.consume_bytes("Sig"); + let result = test_case.consume_string("Result"); + + let private_key = untrusted::Input::from(&private_key); + let key_pair = signature::RSAKeyPair::from_der(private_key); + if result == "Fail-Invalid-Key" { + assert!(key_pair.is_err()); + return Ok(()); + } + let key_pair = key_pair.unwrap(); + let key_pair = std::sync::Arc::new(key_pair); + + // XXX: This test is too slow on Android ARM Travis CI builds. + // TODO: re-enable these tests on Android ARM. + let mut signing_state = + signature::RSASigningState::new(key_pair).unwrap(); + let mut actual: std::vec::Vec = + vec![0; signing_state.key_pair().public_modulus_len()]; + signing_state.sign(alg, &rng, &msg, actual.as_mut_slice()).unwrap(); + assert_eq!(actual.as_slice() == &expected[..], result == "Pass"); + Ok(()) + }); +} + +#[cfg(feature = "rsa_signing")] +#[test] +fn test_signature_rsa_pss_sign() { + // Outputs the same value whenever a certain length is requested (the same + // as the length of the salt). Otherwise, the rng is used. + struct DeterministicSalt<'a> { + salt: &'a [u8], + rng: &'a rand::SecureRandom + } + impl<'a> rand::SecureRandom for DeterministicSalt<'a> { + fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> { + let dest_len = dest.len(); + if dest_len != self.salt.len() { + try!(self.rng.fill(dest)); + } else { + dest.copy_from_slice(&self.salt); + } + Ok(()) + } + } + let rng = rand::SystemRandom::new(); + + test::from_file("tests/rsa_pss_sign_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let digest_name = test_case.consume_string("Digest"); + let alg = match digest_name.as_ref() { + "SHA256" => &signature::RSA_PSS_SHA256, + "SHA384" => &signature::RSA_PSS_SHA384, + "SHA512" => &signature::RSA_PSS_SHA512, + _ => { panic!("Unsupported digest: {}", digest_name) } + }; + + let result = test_case.consume_string("Result"); + let private_key = test_case.consume_bytes("Key"); + let private_key = untrusted::Input::from(&private_key); + let key_pair = signature::RSAKeyPair::from_der(private_key); + if key_pair.is_err() && result == "Fail-Invalid-Key" { + return Ok(()); + } + let key_pair = key_pair.unwrap(); + let key_pair = std::sync::Arc::new(key_pair); + let msg = test_case.consume_bytes("Msg"); + let salt = test_case.consume_bytes("Salt"); + let expected = test_case.consume_bytes("Sig"); + + let new_rng = DeterministicSalt { salt: &salt, rng: &rng }; + + let mut signing_state = + signature::RSASigningState::new(key_pair).unwrap(); + let mut actual: std::vec::Vec = + vec![0; signing_state.key_pair().public_modulus_len()]; + try!(signing_state.sign(alg, &new_rng, &msg, actual.as_mut_slice())); + assert_eq!(actual.as_slice() == &expected[..], result == "Pass"); + Ok(()) + }); +} + +#[cfg(feature = "rsa_signing")] +#[test] +fn test_rsa_key_pair_sync_and_send() { + const PRIVATE_KEY_DER: &'static [u8] = + include_bytes!("../src/rsa/signature_rsa_example_private_key.der"); + let key_bytes_der = untrusted::Input::from(PRIVATE_KEY_DER); + let key_pair = signature::RSAKeyPair::from_der(key_bytes_der).unwrap(); + let key_pair = std::sync::Arc::new(key_pair); + + let _: &Send = &key_pair; + let _: &Sync = &key_pair; + + let signing_state = signature::RSASigningState::new(key_pair).unwrap(); + let _: &Send = &signing_state; + // TODO: Test that signing_state is NOT Sync; i.e. + // `let _: &Sync = &signing_state;` must fail +} + + +#[test] +fn test_signature_rsa_pkcs1_verify() { + test::from_file("tests/rsa_pkcs1_verify_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let digest_name = test_case.consume_string("Digest"); + let alg = match digest_name.as_ref() { + "SHA1" => &signature::RSA_PKCS1_2048_8192_SHA1, + "SHA256" => &signature::RSA_PKCS1_2048_8192_SHA256, + "SHA384" => &signature::RSA_PKCS1_2048_8192_SHA384, + "SHA512" => &signature::RSA_PKCS1_2048_8192_SHA512, + _ => { panic!("Unsupported digest: {}", digest_name) } + }; + + let public_key = test_case.consume_bytes("Key"); + let public_key = untrusted::Input::from(&public_key); + + // Sanity check that we correctly DER-encoded the originally- + // provided separate (n, e) components. When we add test vectors + // for improperly-encoded signatures, we'll have to revisit this. + assert!(public_key.read_all(error::Unspecified, |input| { + der::nested(input, der::Tag::Sequence, error::Unspecified, |input| { + let _ = try!(der::positive_integer(input)); + let _ = try!(der::positive_integer(input)); + Ok(()) + }) + }).is_ok()); + + let msg = test_case.consume_bytes("Msg"); + let msg = untrusted::Input::from(&msg); + + let sig = test_case.consume_bytes("Sig"); + let sig = untrusted::Input::from(&sig); + + let expected_result = test_case.consume_string("Result"); + + let actual_result = signature::verify(alg, public_key, msg, sig); + assert_eq!(actual_result.is_ok(), expected_result == "P"); + + Ok(()) + }); +} + +#[test] +fn test_signature_rsa_pss_verify() { + test::from_file("tests/rsa_pss_verify_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let digest_name = test_case.consume_string("Digest"); + let alg = match digest_name.as_ref() { + "SHA256" => &signature::RSA_PSS_2048_8192_SHA256, + "SHA384" => &signature::RSA_PSS_2048_8192_SHA384, + "SHA512" => &signature::RSA_PSS_2048_8192_SHA512, + _ => { panic!("Unsupported digest: {}", digest_name) } + }; + + let public_key = test_case.consume_bytes("Key"); + let public_key = untrusted::Input::from(&public_key); + + // Sanity check that we correctly DER-encoded the originally- + // provided separate (n, e) components. When we add test vectors + // for improperly-encoded signatures, we'll have to revisit this. + assert!(public_key.read_all(error::Unspecified, |input| { + der::nested(input, der::Tag::Sequence, error::Unspecified, |input| { + let _ = try!(der::positive_integer(input)); + let _ = try!(der::positive_integer(input)); + Ok(()) + }) + }).is_ok()); + + let msg = test_case.consume_bytes("Msg"); + let msg = untrusted::Input::from(&msg); + + let sig = test_case.consume_bytes("Sig"); + let sig = untrusted::Input::from(&sig); + + let expected_result = test_case.consume_string("Result"); + + let actual_result = signature::verify(alg, public_key, msg, sig); + assert_eq!(actual_result.is_ok(), expected_result == "P"); + + Ok(()) + }); +} + +// Test for `primitive::verify()`. Read public key parts from a file +// and use them to verify a signature. +#[test] +fn test_signature_rsa_primitive_verification() { + test::from_file("tests/rsa_primitive_verify_tests.txt", + |section, test_case| { + assert_eq!(section, ""); + let n = test_case.consume_bytes("n"); + let e = test_case.consume_bytes("e"); + let msg = test_case.consume_bytes("Msg"); + let sig = test_case.consume_bytes("Sig"); + let expected = test_case.consume_string("Result"); + let result = signature::primitive::verify_rsa( + &signature::RSA_PKCS1_2048_8192_SHA256, + (untrusted::Input::from(&n), untrusted::Input::from(&e)), + untrusted::Input::from(&msg), untrusted::Input::from(&sig)); + assert_eq!(result.is_ok(), expected == "Pass"); + Ok(()) + }) +}