/rust/registry/src/index.crates.io-6f17d22bba15001f/ring-0.17.14/src/rsa/verification.rs
Line | Count | Source (jump to first uncovered line) |
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 AUTHOR DISCLAIMS ALL WARRANTIES |
8 | | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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::{ |
18 | | parse_public_key, public_key, PublicExponent, RsaParameters, PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN, |
19 | | }; |
20 | | use crate::{ |
21 | | bits::{self, FromByteLen as _}, |
22 | | cpu, digest, |
23 | | error::{self, InputTooLongError}, |
24 | | sealed, signature, |
25 | | }; |
26 | | |
27 | | impl signature::VerificationAlgorithm for RsaParameters { |
28 | 0 | fn verify( |
29 | 0 | &self, |
30 | 0 | public_key: untrusted::Input, |
31 | 0 | msg: untrusted::Input, |
32 | 0 | signature: untrusted::Input, |
33 | 0 | ) -> Result<(), error::Unspecified> { |
34 | 0 | let (n, e) = parse_public_key(public_key)?; |
35 | 0 | verify_rsa_( |
36 | 0 | self, |
37 | 0 | ( |
38 | 0 | n.big_endian_without_leading_zero_as_input(), |
39 | 0 | e.big_endian_without_leading_zero_as_input(), |
40 | 0 | ), |
41 | 0 | msg, |
42 | 0 | signature, |
43 | 0 | cpu::features(), |
44 | 0 | ) |
45 | 0 | } |
46 | | } |
47 | | |
48 | | impl sealed::Sealed for RsaParameters {} |
49 | | |
50 | | macro_rules! rsa_params { |
51 | | ( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr, |
52 | | $doc_str:expr ) => { |
53 | | #[doc=$doc_str] |
54 | | /// |
55 | | /// Only available in `alloc` mode. |
56 | | pub static $VERIFY_ALGORITHM: RsaParameters = RsaParameters { |
57 | | padding_alg: $PADDING_ALGORITHM, |
58 | | min_bits: bits::BitLength::from_bits($min_bits), |
59 | | }; |
60 | | }; |
61 | | } |
62 | | |
63 | | rsa_params!( |
64 | | RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY, |
65 | | 1024, |
66 | | &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, |
67 | | "Verification of signatures using RSA keys of 1024-8192 bits, |
68 | | PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in |
69 | | `ring::signature`'s module-level documentation for more details." |
70 | | ); |
71 | | rsa_params!( |
72 | | RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, |
73 | | 2048, |
74 | | &super::padding::RSA_PKCS1_SHA1_FOR_LEGACY_USE_ONLY, |
75 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
76 | | PKCS#1.5 padding, and SHA-1.\n\nSee \"`RSA_PKCS1_*` Details\" in |
77 | | `ring::signature`'s module-level documentation for more details." |
78 | | ); |
79 | | rsa_params!( |
80 | | RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, |
81 | | 1024, |
82 | | &super::padding::RSA_PKCS1_SHA256, |
83 | | "Verification of signatures using RSA keys of 1024-8192 bits, |
84 | | PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in |
85 | | `ring::signature`'s module-level documentation for more details." |
86 | | ); |
87 | | rsa_params!( |
88 | | RSA_PKCS1_2048_8192_SHA256, |
89 | | 2048, |
90 | | &super::padding::RSA_PKCS1_SHA256, |
91 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
92 | | PKCS#1.5 padding, and SHA-256.\n\nSee \"`RSA_PKCS1_*` Details\" in |
93 | | `ring::signature`'s module-level documentation for more details." |
94 | | ); |
95 | | rsa_params!( |
96 | | RSA_PKCS1_2048_8192_SHA384, |
97 | | 2048, |
98 | | &super::padding::RSA_PKCS1_SHA384, |
99 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
100 | | PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in |
101 | | `ring::signature`'s module-level documentation for more details." |
102 | | ); |
103 | | rsa_params!( |
104 | | RSA_PKCS1_2048_8192_SHA512, |
105 | | 2048, |
106 | | &super::padding::RSA_PKCS1_SHA512, |
107 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
108 | | PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in |
109 | | `ring::signature`'s module-level documentation for more details." |
110 | | ); |
111 | | rsa_params!( |
112 | | RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, |
113 | | 1024, |
114 | | &super::padding::RSA_PKCS1_SHA512, |
115 | | "Verification of signatures using RSA keys of 1024-8192 bits, |
116 | | PKCS#1.5 padding, and SHA-512.\n\nSee \"`RSA_PKCS1_*` Details\" in |
117 | | `ring::signature`'s module-level documentation for more details." |
118 | | ); |
119 | | rsa_params!( |
120 | | RSA_PKCS1_3072_8192_SHA384, |
121 | | 3072, |
122 | | &super::padding::RSA_PKCS1_SHA384, |
123 | | "Verification of signatures using RSA keys of 3072-8192 bits, |
124 | | PKCS#1.5 padding, and SHA-384.\n\nSee \"`RSA_PKCS1_*` Details\" in |
125 | | `ring::signature`'s module-level documentation for more details." |
126 | | ); |
127 | | |
128 | | rsa_params!( |
129 | | RSA_PSS_2048_8192_SHA256, |
130 | | 2048, |
131 | | &super::padding::RSA_PSS_SHA256, |
132 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
133 | | PSS padding, and SHA-256.\n\nSee \"`RSA_PSS_*` Details\" in |
134 | | `ring::signature`'s module-level documentation for more details." |
135 | | ); |
136 | | rsa_params!( |
137 | | RSA_PSS_2048_8192_SHA384, |
138 | | 2048, |
139 | | &super::padding::RSA_PSS_SHA384, |
140 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
141 | | PSS padding, and SHA-384.\n\nSee \"`RSA_PSS_*` Details\" in |
142 | | `ring::signature`'s module-level documentation for more details." |
143 | | ); |
144 | | rsa_params!( |
145 | | RSA_PSS_2048_8192_SHA512, |
146 | | 2048, |
147 | | &super::padding::RSA_PSS_SHA512, |
148 | | "Verification of signatures using RSA keys of 2048-8192 bits, |
149 | | PSS padding, and SHA-512.\n\nSee \"`RSA_PSS_*` Details\" in |
150 | | `ring::signature`'s module-level documentation for more details." |
151 | | ); |
152 | | |
153 | | pub use super::PublicKeyComponents as RsaPublicKeyComponents; |
154 | | |
155 | | impl<B> super::PublicKeyComponents<B> |
156 | | where |
157 | | B: AsRef<[u8]>, |
158 | | { |
159 | | /// Verifies that `signature` is a valid signature of `message` using `self` |
160 | | /// as the public key. `params` determine what algorithm parameters |
161 | | /// (padding, digest algorithm, key length range, etc.) are used in the |
162 | | /// verification. |
163 | | /// |
164 | | /// When the public key is in DER-encoded PKCS#1 ASN.1 format, it is |
165 | | /// recommended to use `ring::signature::verify()` with |
166 | | /// `ring::signature::RSA_PKCS1_*`, because `ring::signature::verify()` |
167 | | /// will handle the parsing in that case. Otherwise, this function can be used |
168 | | /// to pass in the raw bytes for the public key components as |
169 | | /// `untrusted::Input` arguments. |
170 | | // |
171 | | // There are a small number of tests that test this directly, but the |
172 | | // test coverage for this function mostly depends on the test coverage for the |
173 | | // `signature::VerificationAlgorithm` implementation for `RsaParameters`. If we |
174 | | // change that, test coverage for `verify_rsa()` will need to be reconsidered. |
175 | | // (The NIST test vectors were originally in a form that was optimized for |
176 | | // testing `verify_rsa` directly, but the testing work for RSA PKCS#1 |
177 | | // verification was done during the implementation of |
178 | | // `signature::VerificationAlgorithm`, before `verify_rsa` was factored out). |
179 | 0 | pub fn verify( |
180 | 0 | &self, |
181 | 0 | params: &RsaParameters, |
182 | 0 | message: &[u8], |
183 | 0 | signature: &[u8], |
184 | 0 | ) -> Result<(), error::Unspecified> { |
185 | 0 | verify_rsa_( |
186 | 0 | params, |
187 | 0 | ( |
188 | 0 | untrusted::Input::from(self.n.as_ref()), |
189 | 0 | untrusted::Input::from(self.e.as_ref()), |
190 | 0 | ), |
191 | 0 | untrusted::Input::from(message), |
192 | 0 | untrusted::Input::from(signature), |
193 | 0 | cpu::features(), |
194 | 0 | ) |
195 | 0 | } |
196 | | } |
197 | | |
198 | 0 | pub(crate) fn verify_rsa_( |
199 | 0 | params: &RsaParameters, |
200 | 0 | (n, e): (untrusted::Input, untrusted::Input), |
201 | 0 | msg: untrusted::Input, |
202 | 0 | signature: untrusted::Input, |
203 | 0 | cpu_features: cpu::Features, |
204 | 0 | ) -> Result<(), error::Unspecified> { |
205 | 0 | let max_bits: bits::BitLength = |
206 | 0 | bits::BitLength::from_byte_len(PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN) |
207 | 0 | .map_err(error::erase::<InputTooLongError>)?; |
208 | | |
209 | | // XXX: FIPS 186-4 seems to indicate that the minimum |
210 | | // exponent value is 2**16 + 1, but it isn't clear if this is just for |
211 | | // signing or also for verification. We support exponents of 3 and larger |
212 | | // for compatibility with other commonly-used crypto libraries. |
213 | 0 | let key = public_key::Inner::from_modulus_and_exponent( |
214 | 0 | n, |
215 | 0 | e, |
216 | 0 | params.min_bits, |
217 | 0 | max_bits, |
218 | 0 | PublicExponent::_3, |
219 | 0 | cpu_features, |
220 | 0 | )?; |
221 | | |
222 | | // RFC 8017 Section 5.2.2: RSAVP1. |
223 | 0 | let mut decoded = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN]; |
224 | 0 | let decoded = key.exponentiate(signature, &mut decoded, cpu_features)?; |
225 | | |
226 | | // Verify the padded message is correct. |
227 | 0 | let m_hash = digest::digest(params.padding_alg.digest_alg(), msg.as_slice_less_safe()); |
228 | 0 | untrusted::Input::from(decoded).read_all(error::Unspecified, |m| { |
229 | 0 | params.padding_alg.verify(m_hash, m, key.n().len_bits()) |
230 | 0 | }) |
231 | 0 | } |