1 | // Copyright 2015-2017 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 | //! Public key signatures: signing and verification. |
16 | //! |
17 | //! Use the `verify` function to verify signatures, passing a reference to the |
18 | //! algorithm that identifies the algorithm. See the documentation for `verify` |
19 | //! for examples. |
20 | //! |
21 | //! For signature verification, this API treats each combination of parameters |
22 | //! as a separate algorithm. For example, instead of having a single "RSA" |
23 | //! algorithm with a verification function that takes a bunch of parameters, |
24 | //! there are `RSA_PKCS1_2048_8192_SHA256`, `RSA_PKCS1_2048_8192_SHA384`, etc., |
25 | //! which encode sets of parameter choices into objects. This is designed to |
26 | //! reduce the risks of algorithm agility and to provide consistency with ECDSA |
27 | //! and EdDSA. |
28 | //! |
29 | //! Currently this module does not support digesting the message to be signed |
30 | //! separately from the public key operation, as it is currently being |
31 | //! optimized for Ed25519 and for the implementation of protocols that do not |
32 | //! requiring signing large messages. An interface for efficiently supporting |
33 | //! larger messages may be added later. |
34 | //! |
35 | //! |
36 | //! # Algorithm Details |
37 | //! |
38 | //! ## `ECDSA_*_ASN1` Details: ASN.1-encoded ECDSA Signatures |
39 | //! |
40 | //! The signature is a ASN.1 DER-encoded `Ecdsa-Sig-Value` as described in |
41 | //! [RFC 3279 Section 2.2.3]. This is the form of ECDSA signature used in |
42 | //! X.509-related structures and in TLS's `ServerKeyExchange` messages. |
43 | //! |
44 | //! The public key is encoding in uncompressed form using the |
45 | //! Octet-String-to-Elliptic-Curve-Point algorithm in |
46 | //! [SEC 1: Elliptic Curve Cryptography, Version 2.0]. |
47 | //! |
48 | //! During verification, the public key is validated using the ECC Partial |
49 | //! Public-Key Validation Routine from Section 5.6.2.3.3 of |
50 | //! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the |
51 | //! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained |
52 | //! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC |
53 | //! Full Public-Key Validation for prime-order curves like this one. |
54 | //! |
55 | //! ## `ECDSA_*_FIXED` Details: Fixed-length (PKCS#11-style) ECDSA Signatures |
56 | //! |
57 | //! The signature is *r*||*s*, where || denotes concatenation, and where both |
58 | //! *r* and *s* are both big-endian-encoded values that are left-padded to the |
59 | //! maximum length. A P-256 signature will be 64 bytes long (two 32-byte |
60 | //! components) and a P-384 signature will be 96 bytes long (two 48-byte |
61 | //! components). This is the form of ECDSA signature used PKCS#11 and DNSSEC. |
62 | //! |
63 | //! The public key is encoding in uncompressed form using the |
64 | //! Octet-String-to-Elliptic-Curve-Point algorithm in |
65 | //! [SEC 1: Elliptic Curve Cryptography, Version 2.0]. |
66 | //! |
67 | //! During verification, the public key is validated using the ECC Partial |
68 | //! Public-Key Validation Routine from Section 5.6.2.3.3 of |
69 | //! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the |
70 | //! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained |
71 | //! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC |
72 | //! Full Public-Key Validation for prime-order curves like this one. |
73 | //! |
74 | //! ## `RSA_PKCS1_*` Details: RSA PKCS#1 1.5 Signatures |
75 | //! |
76 | //! The signature is an RSASSA-PKCS1-v1_5 signature as described in |
77 | //! [RFC 3447 Section 8.2]. |
78 | //! |
79 | //! The public key is encoded as an ASN.1 `RSAPublicKey` as described in |
80 | //! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to |
81 | //! the nearest (larger) multiple of 8 bits, must be in the range given in the |
82 | //! name of the algorithm. The public exponent must be an odd integer of 2-33 |
83 | //! bits, inclusive. |
84 | //! |
85 | //! |
86 | //! ## `RSA_PSS_*` Details: RSA PSS Signatures |
87 | //! |
88 | //! The signature is an RSASSA-PSS signature as described in |
89 | //! [RFC 3447 Section 8.1]. |
90 | //! |
91 | //! The public key is encoded as an ASN.1 `RSAPublicKey` as described in |
92 | //! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to |
93 | //! the nearest (larger) multiple of 8 bits, must be in the range given in the |
94 | //! name of the algorithm. The public exponent must be an odd integer of 2-33 |
95 | //! bits, inclusive. |
96 | //! |
97 | //! During verification, signatures will only be accepted if the MGF1 digest |
98 | //! algorithm is the same as the message digest algorithm and if the salt |
99 | //! length is the same length as the message digest. This matches the |
100 | //! requirements in TLS 1.3 and other recent specifications. |
101 | //! |
102 | //! During signing, the message digest algorithm will be used as the MGF1 |
103 | //! digest algorithm. The salt will be the same length as the message digest. |
104 | //! This matches the requirements in TLS 1.3 and other recent specifications. |
105 | //! Additionally, the entire salt is randomly generated separately for each |
106 | //! signature using the secure random number generator passed to `sign()`. |
107 | //! |
108 | //! |
109 | //! [SEC 1: Elliptic Curve Cryptography, Version 2.0]: |
110 | //! http://www.secg.org/sec1-v2.pdf |
111 | //! [NIST Special Publication 800-56A, revision 2]: |
112 | //! http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf |
113 | //! [Suite B implementer's guide to FIPS 186-3]: |
114 | //! https://github.com/briansmith/ring/blob/main/doc/ecdsa.pdf |
115 | //! [RFC 3279 Section 2.2.3]: |
116 | //! https://tools.ietf.org/html/rfc3279#section-2.2.3 |
117 | //! [RFC 3447 Section 8.2]: |
118 | //! https://tools.ietf.org/html/rfc3447#section-7.2 |
119 | //! [RFC 3447 Section 8.1]: |
120 | //! https://tools.ietf.org/html/rfc3447#section-8.1 |
121 | //! [RFC 3447 Appendix-A.1.1]: |
122 | //! https://tools.ietf.org/html/rfc3447#appendix-A.1.1 |
123 | //! |
124 | //! |
125 | //! # Examples |
126 | //! |
127 | //! ## Signing and verifying with Ed25519 |
128 | //! |
129 | //! ``` |
130 | //! use ring::{ |
131 | //! rand, |
132 | //! signature::{self, KeyPair}, |
133 | //! }; |
134 | //! |
135 | //! # fn main() -> Result<(), ring::error::Unspecified> { |
136 | //! // Generate a key pair in PKCS#8 (v2) format. |
137 | //! let rng = rand::SystemRandom::new(); |
138 | //! let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)?; |
139 | //! |
140 | //! // Normally the application would store the PKCS#8 file persistently. Later |
141 | //! // it would read the PKCS#8 file from persistent storage to use it. |
142 | //! |
143 | //! let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref())?; |
144 | //! |
145 | //! // Sign the message "hello, world". |
146 | //! const MESSAGE: &[u8] = b"hello, world" ; |
147 | //! let sig = key_pair.sign(MESSAGE); |
148 | //! |
149 | //! // Normally an application would extract the bytes of the signature and |
150 | //! // send them in a protocol message to the peer(s). Here we just get the |
151 | //! // public key key directly from the key pair. |
152 | //! let peer_public_key_bytes = key_pair.public_key().as_ref(); |
153 | //! |
154 | //! // Verify the signature of the message using the public key. Normally the |
155 | //! // verifier of the message would parse the inputs to this code out of the |
156 | //! // protocol message(s) sent by the signer. |
157 | //! let peer_public_key = |
158 | //! signature::UnparsedPublicKey::new(&signature::ED25519, peer_public_key_bytes); |
159 | //! peer_public_key.verify(MESSAGE, sig.as_ref())?; |
160 | //! |
161 | //! # Ok(()) |
162 | //! # } |
163 | //! ``` |
164 | //! |
165 | //! ## Signing and verifying with RSA (PKCS#1 1.5 padding) |
166 | //! |
167 | //! By default OpenSSL writes RSA public keys in SubjectPublicKeyInfo format, |
168 | //! not RSAPublicKey format, and Base64-encodes them (“PEM” format). |
169 | //! |
170 | //! To convert the PEM SubjectPublicKeyInfo format (“BEGIN PUBLIC KEY”) to the |
171 | //! binary RSAPublicKey format needed by `verify()`, use: |
172 | //! |
173 | //! ```sh |
174 | //! openssl rsa -pubin \ |
175 | //! -in public_key.pem \ |
176 | //! -inform PEM \ |
177 | //! -RSAPublicKey_out \ |
178 | //! -outform DER \ |
179 | //! -out public_key.der |
180 | //! ``` |
181 | //! |
182 | //! To extract the RSAPublicKey-formatted public key from an ASN.1 (binary) |
183 | //! DER-encoded RSAPrivateKey format private key file, use: |
184 | //! |
185 | //! ```sh |
186 | //! openssl rsa -in private_key.der \ |
187 | //! -inform DER \ |
188 | //! -RSAPublicKey_out \ |
189 | //! -outform DER \ |
190 | //! -out public_key.der |
191 | //! ``` |
192 | //! |
193 | //! ``` |
194 | //! # #[cfg (feature = "std" )] |
195 | //! use ring::{rand, rsa, signature}; |
196 | //! |
197 | //! # #[cfg (feature = "std" )] |
198 | //! fn sign_and_verify_rsa(private_key_path: &std::path::Path, |
199 | //! public_key_path: &std::path::Path) |
200 | //! -> Result<(), MyError> { |
201 | //! // Create an RSA keypair from the DER-encoded bytes. This example uses |
202 | //! // a 2048-bit key, but larger keys are also supported. |
203 | //! let private_key_der = read_file(private_key_path)?; |
204 | //! let key_pair = rsa::KeyPair::from_der(&private_key_der) |
205 | //! .map_err(|_| MyError::BadPrivateKey)?; |
206 | //! |
207 | //! // Sign the message "hello, world", using PKCS#1 v1.5 padding and the |
208 | //! // SHA256 digest algorithm. |
209 | //! const MESSAGE: &'static [u8] = b"hello, world" ; |
210 | //! let rng = rand::SystemRandom::new(); |
211 | //! let mut signature = vec![0; key_pair.public().modulus_len()]; |
212 | //! key_pair.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature) |
213 | //! .map_err(|_| MyError::OOM)?; |
214 | //! |
215 | //! // Verify the signature. |
216 | //! let public_key = |
217 | //! signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, |
218 | //! read_file(public_key_path)?); |
219 | //! public_key.verify(MESSAGE, &signature) |
220 | //! .map_err(|_| MyError::BadSignature) |
221 | //! } |
222 | //! |
223 | //! #[derive(Debug)] |
224 | //! enum MyError { |
225 | //! # #[cfg (feature = "std" )] |
226 | //! IO(std::io::Error), |
227 | //! BadPrivateKey, |
228 | //! OOM, |
229 | //! BadSignature, |
230 | //! } |
231 | //! |
232 | //! # #[cfg (feature = "std" )] |
233 | //! fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> { |
234 | //! use std::io::Read; |
235 | //! |
236 | //! let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?; |
237 | //! let mut contents: Vec<u8> = Vec::new(); |
238 | //! file.read_to_end(&mut contents).map_err(|e| MyError::IO(e))?; |
239 | //! Ok(contents) |
240 | //! } |
241 | //! # |
242 | //! # #[cfg (not(feature = "std" ))] |
243 | //! # fn sign_and_verify_rsa(_private_key_path: &std::path::Path, |
244 | //! # _public_key_path: &std::path::Path) |
245 | //! # -> Result<(), ()> { |
246 | //! # Ok(()) |
247 | //! # } |
248 | //! # |
249 | //! # fn main() { |
250 | //! # let private_key_path = |
251 | //! # std::path::Path::new("src/rsa/signature_rsa_example_private_key.der" ); |
252 | //! # let public_key_path = |
253 | //! # std::path::Path::new("src/rsa/signature_rsa_example_public_key.der" ); |
254 | //! # sign_and_verify_rsa(&private_key_path, &public_key_path).unwrap() |
255 | //! # } |
256 | //! ``` |
257 | |
258 | use crate::{cpu, debug, ec, error, sealed}; |
259 | |
260 | pub use crate::ec::{ |
261 | curve25519::ed25519::{ |
262 | signing::Ed25519KeyPair, |
263 | verification::{EdDSAParameters, ED25519}, |
264 | ED25519_PUBLIC_KEY_LEN, |
265 | }, |
266 | suite_b::ecdsa::{ |
267 | signing::{ |
268 | EcdsaKeyPair, EcdsaSigningAlgorithm, ECDSA_P256_SHA256_ASN1_SIGNING, |
269 | ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_ASN1_SIGNING, |
270 | ECDSA_P384_SHA384_FIXED_SIGNING, |
271 | }, |
272 | verification::{ |
273 | EcdsaVerificationAlgorithm, ECDSA_P256_SHA256_ASN1, ECDSA_P256_SHA256_FIXED, |
274 | ECDSA_P256_SHA384_ASN1, ECDSA_P384_SHA256_ASN1, ECDSA_P384_SHA384_ASN1, |
275 | ECDSA_P384_SHA384_FIXED, |
276 | }, |
277 | }, |
278 | }; |
279 | |
280 | #[cfg (feature = "alloc" )] |
281 | pub use crate::rsa::{ |
282 | padding::{ |
283 | RsaEncoding, RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512, RSA_PSS_SHA256, |
284 | RSA_PSS_SHA384, RSA_PSS_SHA512, |
285 | }, |
286 | verification::{ |
287 | RsaPublicKeyComponents, RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY, |
288 | RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, |
289 | RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, |
290 | RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY, RSA_PKCS1_2048_8192_SHA256, |
291 | RSA_PKCS1_2048_8192_SHA384, RSA_PKCS1_2048_8192_SHA512, RSA_PKCS1_3072_8192_SHA384, |
292 | RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA384, RSA_PSS_2048_8192_SHA512, |
293 | }, |
294 | RsaParameters, |
295 | }; |
296 | |
297 | /// An RSA key pair, used for signing. |
298 | #[cfg (feature = "alloc" )] |
299 | pub type RsaKeyPair = crate::rsa::KeyPair; |
300 | |
301 | /// A public key signature returned from a signing operation. |
302 | #[derive (Clone, Copy)] |
303 | pub struct Signature { |
304 | value: [u8; MAX_LEN], |
305 | len: usize, |
306 | } |
307 | |
308 | impl Signature { |
309 | // Panics if `value` is too long. |
310 | pub(crate) fn new<F>(fill: F) -> Self |
311 | where |
312 | F: FnOnce(&mut [u8; MAX_LEN]) -> usize, |
313 | { |
314 | let mut r: Signature = Self { |
315 | value: [0; MAX_LEN], |
316 | len: 0, |
317 | }; |
318 | r.len = fill(&mut r.value); |
319 | r |
320 | } |
321 | } |
322 | |
323 | impl AsRef<[u8]> for Signature { |
324 | fn as_ref(&self) -> &[u8] { |
325 | &self.value[..self.len] |
326 | } |
327 | } |
328 | |
329 | /// Key pairs for signing messages (private key and public key). |
330 | pub trait KeyPair: core::fmt::Debug + Send + Sized + Sync { |
331 | /// The type of the public key. |
332 | type PublicKey: AsRef<[u8]> + core::fmt::Debug + Clone + Send + Sized + Sync; |
333 | |
334 | /// The public key for the key pair. |
335 | fn public_key(&self) -> &Self::PublicKey; |
336 | } |
337 | |
338 | /// The longest signature is an ASN.1 P-384 signature where *r* and *s* are of |
339 | /// maximum length with the leading high bit set on each. Then each component |
340 | /// will have a tag, a one-byte length, and a one-byte “I'm not negative” |
341 | /// prefix, and the outer sequence will have a two-byte length. |
342 | pub(crate) const MAX_LEN: usize = 1/*tag:SEQUENCE*/ + 2/*len*/ + |
343 | (2 * (1/*tag:INTEGER*/ + 1/*len*/ + 1/*zero*/ + ec::SCALAR_MAX_BYTES)); |
344 | |
345 | /// A signature verification algorithm. |
346 | pub trait VerificationAlgorithm: core::fmt::Debug + Sync + sealed::Sealed { |
347 | /// Verify the signature `signature` of message `msg` with the public key |
348 | /// `public_key`. |
349 | fn verify( |
350 | &self, |
351 | public_key: untrusted::Input, |
352 | msg: untrusted::Input, |
353 | signature: untrusted::Input, |
354 | ) -> Result<(), error::Unspecified>; |
355 | } |
356 | |
357 | /// An unparsed, possibly malformed, public key for signature verification. |
358 | #[derive (Clone, Copy)] |
359 | pub struct UnparsedPublicKey<B> { |
360 | algorithm: &'static dyn VerificationAlgorithm, |
361 | bytes: B, |
362 | } |
363 | |
364 | impl<B> AsRef<[u8]> for UnparsedPublicKey<B> |
365 | where |
366 | B: AsRef<[u8]>, |
367 | { |
368 | fn as_ref(&self) -> &[u8] { |
369 | self.bytes.as_ref() |
370 | } |
371 | } |
372 | |
373 | impl<B: core::fmt::Debug> core::fmt::Debug for UnparsedPublicKey<B> |
374 | where |
375 | B: AsRef<[u8]>, |
376 | { |
377 | fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { |
378 | f&mut DebugStruct<'_, '_>.debug_struct("UnparsedPublicKey" ) |
379 | .field("algorithm" , &self.algorithm) |
380 | .field(name:"bytes" , &debug::HexStr(self.bytes.as_ref())) |
381 | .finish() |
382 | } |
383 | } |
384 | |
385 | impl<B> UnparsedPublicKey<B> { |
386 | /// Construct a new `UnparsedPublicKey`. |
387 | /// |
388 | /// No validation of `bytes` is done until `verify()` is called. |
389 | #[inline ] |
390 | pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self { |
391 | Self { algorithm, bytes } |
392 | } |
393 | |
394 | /// Parses the public key and verifies `signature` is a valid signature of |
395 | /// `message` using it. |
396 | /// |
397 | /// See the [crate::signature] module-level documentation for examples. |
398 | pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> |
399 | where |
400 | B: AsRef<[u8]>, |
401 | { |
402 | let _ = cpu::features(); |
403 | self.algorithm.verify( |
404 | untrusted::Input::from(self.bytes.as_ref()), |
405 | untrusted::Input::from(message), |
406 | untrusted::Input::from(signature), |
407 | ) |
408 | } |
409 | } |
410 | |