From f3452ef077cc2994a49f6ffbcac6a90d94eed40e Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 28 Jun 2016 21:38:44 +0200 Subject: [PATCH] Expose rsa::verify as ring::signature::verify_rsa. I agree to license my contributions to each file under the terms given at the top of each file I changed. --- src/rsa/rsa_primitive_verify_tests.txt | 7 ++++ src/rsa/verification.rs | 48 +++++++++++++++++++++++--- src/signature.rs | 7 ++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/rsa/rsa_primitive_verify_tests.txt diff --git a/src/rsa/rsa_primitive_verify_tests.txt b/src/rsa/rsa_primitive_verify_tests.txt new file mode 100644 index 000000000..b4bed1e1b --- /dev/null +++ b/src/rsa/rsa_primitive_verify_tests.txt @@ -0,0 +1,7 @@ +# Big-endian public key parts for signature_rsa_example_public_key.der, +# encoded in hex. + +Msg = 68656c6c6f2c20776f726c64 +Sig = 048efbc9eb5f7a6f55f6d7b9f7e6c3ce58e2db226562ca905e7f972e8f43b6969b0ad878e0d6b290c5bbf2c05410a1efc9de051d91e5faa537e454306f5f526c828379fe28a17e50c8bd4e7c834479da482305a78e198c988a177b9263cea27a2a99c0da98e03b0cc8d880eccdeba7c16dd07f78d980739753690953d1b63106145a80059ed38f52100a9a8d2c7c5371d91b70ce5b7b36d6b97ebef8798d09c01e5b6cb8a6a7fd1a4100d3527327b7d23f8a26187985d8702f8951346ea4a7253e87f765ef587a728021bff37be55d1a8639809e3453ea5a2da482bfedeae18579b51037cfecff5bece21d8c82ee6fa8eb0f43c43c3a23a983c3a2eea4e7d2dc +n = CEA80475324C1DC8347827818DA58BAC069D3419C614A6EA1AC6A3B510DCD72CC516954905E9FEF908D45E13006ADF27D467A7D83C111D1A5DF15EF293771AEFB920032A5BB989F8E4F5E1B05093D3F130F984C07A772A3683F4DC6FB28A96815B32123CCDD13954F19D5B8B24A103E771A34C328755C65ED64E1924FFD04D30B2142CC262F6E0048FEF6DBC652F21479EA1C4B1D66D28F4D46EF7185E390CBFA2E02380582F3188BB94EBBF05D31487A09AFF01FCBB4CD4BFD1F0A833B38C11813C84360BB53C7D4481031C40BAD8713BB6B835CB08098ED15BA31EE4BA728A8C8E10F7294E1B4163B7AEE57277BFD881A6F9D43E02C6925AA3A043FB7FB78D +e = 260445 diff --git a/src/rsa/verification.rs b/src/rsa/verification.rs index 1734658a0..53dece9df 100644 --- a/src/rsa/verification.rs +++ b/src/rsa/verification.rs @@ -62,10 +62,28 @@ rsa_pkcs1!(RSA_PKCS1_3072_8192_SHA384, 3072, &super::RSA_PKCS1_SHA384, "Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384."); -fn verify_rsa(params: &RSAParameters, - (n, e): (untrusted::Input, untrusted::Input), - msg: untrusted::Input, signature: untrusted::Input) - -> Result<(), error::Unspecified> { +/// Lower-level API for the verification of RSA signatures. +/// +/// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is +/// recommended to use `ring::signature::verify()` with +/// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()` +/// will handle the parsing in that case. Otherwise, this function can be used +/// to pass in the raw bytes for the public key components as +/// `untrusted::Input` arguments. +/// +/// `params` determine what algorithm parameters (padding, digest algorithm, +/// key length range, etc.) are used in the verification. `n` is the public key +/// modulus and `e` is the public key exponent. `msg` is the message and +/// `signature` is the signature. +// +// The test coverage for this function almost completely depends on the test +// coverage for the `signature::VerificationAlgorithm` implementation for +// `RSAParameters`. If we change that, test coverage for `verify_rsa()` will +// need to be reconsidered. +pub fn verify_rsa(params: &RSAParameters, + (n, e): (untrusted::Input, untrusted::Input), + msg: untrusted::Input, signature: untrusted::Input) + -> Result<(), error::Unspecified> { const MAX_BITS: usize = 8192; let signature = signature.as_slice_less_safe(); @@ -191,4 +209,26 @@ mod tests { 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 = verify_rsa(&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/signature.rs b/src/signature.rs index 896b5a7ac..277263a3d 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -191,6 +191,13 @@ pub use rsa::verification::{ RSA_PKCS1_3072_8192_SHA384, }; +/// Lower-level verification primitives. Usage of `ring::signature::verify()` +/// is preferred when the public key and signature are encoded in standard +/// formats, as it also handles the parsing. +pub mod primitive { + pub use rsa::verification::verify_rsa; +} + /// A public key signature returned from a signing operation. pub struct Signature { value: [u8; 64],