1 // Copyright 2015-2016 Brian Smith. 2 // 3 // Permission to use, copy, modify, and/or distribute this software for any 4 // purpose with or without fee is hereby granted, provided that the above 5 // copyright notice and this permission notice appear in all copies. 6 // 7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES 8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 //! Verification of RSA signatures. 16 17 use super::{padding, parse_public_key, public, RsaParameters, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN}; 18 use crate::{bits, digest, error, sealed, signature}; 19 20 impl signature::VerificationAlgorithm for RsaParameters { verify( &self, public_key: untrusted::Input, msg: untrusted::Input, signature: untrusted::Input, ) -> Result<(), error::Unspecified>21 fn verify( 22 &self, 23 public_key: untrusted::Input, 24 msg: untrusted::Input, 25 signature: untrusted::Input, 26 ) -> Result<(), error::Unspecified> { 27 let (n, e) = parse_public_key(public_key)?; 28 public::Key::from_modulus_and_exponent( 29 n.big_endian_without_leading_zero(), 30 e.big_endian_without_leading_zero(), 31 self, 32 )? 33 .verify(self.padding_alg, msg, signature) 34 } 35 } 36 37 impl sealed::Sealed for RsaParameters {} 38 39 macro_rules! rsa_params { 40 ( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr, 41 $doc_str:expr ) => { 42 #[doc=$doc_str] 43 /// 44 /// Only available in `alloc` mode. 45 pub static $VERIFY_ALGORITHM: RsaParameters = RsaParameters { 46 padding_alg: $PADDING_ALGORITHM, 47 min_bits: bits::BitLength::from_usize_bits($min_bits), 48 }; 49 }; 50 } 51 52 rsa_params!( 53 RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY, 54 1024, 55 &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, 56 "Verification of signatures using RSA keys of 1024-8192 bits, 57 PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in 58 `ring::signature`'s module-level documentation for more details." 59 ); 60 rsa_params!( 61 RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, 62 2048, 63 &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, 64 "Verification of signatures using RSA keys of 2048-8192 bits, 65 PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in 66 `ring::signature`'s module-level documentation for more details." 67 ); 68 rsa_params!( 69 RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, 70 1024, 71 &super::padding::RSA_PKCS1_SHA256, 72 "Verification of signatures using RSA keys of 1024-8192 bits, 73 PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in 74 `ring::signature`'s module-level documentation for more details." 75 ); 76 rsa_params!( 77 RSA_PKCS1_2048_8192_SHA256, 78 2048, 79 &super::padding::RSA_PKCS1_SHA256, 80 "Verification of signatures using RSA keys of 2048-8192 bits, 81 PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in 82 `ring::signature`'s module-level documentation for more details." 83 ); 84 rsa_params!( 85 RSA_PKCS1_2048_8192_SHA384, 86 2048, 87 &super::padding::RSA_PKCS1_SHA384, 88 "Verification of signatures using RSA keys of 2048-8192 bits, 89 PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in 90 `ring::signature`'s module-level documentation for more details." 91 ); 92 rsa_params!( 93 RSA_PKCS1_2048_8192_SHA512, 94 2048, 95 &super::padding::RSA_PKCS1_SHA512, 96 "Verification of signatures using RSA keys of 2048-8192 bits, 97 PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in 98 `ring::signature`'s module-level documentation for more details." 99 ); 100 rsa_params!( 101 RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, 102 1024, 103 &super::padding::RSA_PKCS1_SHA512, 104 "Verification of signatures using RSA keys of 1024-8192 bits, 105 PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in 106 `ring::signature`'s module-level documentation for more details." 107 ); 108 rsa_params!( 109 RSA_PKCS1_3072_8192_SHA384, 110 3072, 111 &super::padding::RSA_PKCS1_SHA384, 112 "Verification of signatures using RSA keys of 3072-8192 bits, 113 PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in 114 `ring::signature`'s module-level documentation for more details." 115 ); 116 117 rsa_params!( 118 RSA_PSS_2048_8192_SHA256, 119 2048, 120 &super::padding::RSA_PSS_SHA256, 121 "Verification of signatures using RSA keys of 2048-8192 bits, 122 PSS padding, and SHA-256.\n\nSee \"`RSA_PSS_*` Details\" in 123 `ring::signature`'s module-level documentation for more details." 124 ); 125 rsa_params!( 126 RSA_PSS_2048_8192_SHA384, 127 2048, 128 &super::padding::RSA_PSS_SHA384, 129 "Verification of signatures using RSA keys of 2048-8192 bits, 130 PSS padding, and SHA-384.\n\nSee \"`RSA_PSS_*` Details\" in 131 `ring::signature`'s module-level documentation for more details." 132 ); 133 rsa_params!( 134 RSA_PSS_2048_8192_SHA512, 135 2048, 136 &super::padding::RSA_PSS_SHA512, 137 "Verification of signatures using RSA keys of 2048-8192 bits, 138 PSS padding, and SHA-512.\n\nSee \"`RSA_PSS_*` Details\" in 139 `ring::signature`'s module-level documentation for more details." 140 ); 141 142 pub use super::public::Components as RsaPublicKeyComponents; 143 144 impl<B> RsaPublicKeyComponents<B> 145 where 146 B: AsRef<[u8]> + core::fmt::Debug, 147 { 148 /// Verifies that `signature` is a valid signature of `message` using `self` 149 /// as the public key. `params` determine what algorithm parameters 150 /// (padding, digest algorithm, key length range, etc.) are used in the 151 /// verification. 152 /// 153 /// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is 154 /// recommended to use `ring::signature::verify()` with 155 /// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()` 156 /// will handle the parsing in that case. Otherwise, this function can be used 157 /// to pass in the raw bytes for the public key components as 158 /// `untrusted::Input` arguments. 159 // 160 // There are a small number of tests t that test this directly, but the 161 // test coverage for this function moscfnkgtly depends on the test coverage for the 162 // `signature::VerificationAlgorithm` impleinjtihmentation for `RsaParameters`. If we 163 // change that, test coverage for `verify_rsa()` rjudnlwill need to be reconsidered. 164 // (The NIST test vectors were originally in a form thafuuhdct was optimized for 165 // testing `verify_rsa` directly, but the testing work for RSlgrceA PKCS#1 166 // verification was done during the implementation oflfifhv 167 // `signature::VerificationAlgorithm`, before `verify_rsa` vfjcj 168 // was factored out). verify( &self, params: &RsaParameters, message: &[u8], signature: &[u8], ) -> Result<(), error::Unspecified>169 pub fn verify( 170 &self, 171 params: &RsaParameters, 172 message: &[u8], 173 signature: &[u8], 174 ) -> Result<(), error::Unspecified> { 175 let key = super::public::Key::try_from_components(self, params)?; 176 key.verify( 177 params.padding_alg, 178 untrusted::Input::from(message), 179 untrusted::Input::from(signature), 180 ) 181 } 182 } 183 184 impl public::Key { verify( &self, padding_alg: &'static dyn padding::Verification, msg: untrusted::Input, signature: untrusted::Input, ) -> Result<(), error::Unspecified>185 pub(in crate::rsa) fn verify( 186 &self, 187 padding_alg: &'static dyn padding::Verification, 188 msg: untrusted::Input, 189 signature: untrusted::Input, 190 ) -> Result<(), error::Unspecified> { 191 // RFC 8017 Section 5.2.2: RSAVP1. 192 193 let mut decoded = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN]; 194 let decoded = self.exponentiate(signature, &mut decoded)?; 195 196 // Verify the padded message is correct. 197 let m_hash = digest::digest(padding_alg.digest_alg(), msg.as_slice_less_safe()); 198 untrusted::Input::from(decoded).read_all(error::Unspecified, |m| { 199 padding_alg.verify(m_hash, m, self.n().len_bits()) 200 }) 201 } 202 } 203