1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
// Copyright 2016 Brian Smith. // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. //! Error reporting. use core; use untrusted; #[cfg(feature = "use_heap")] use std; /// An error with absolutely no details. /// /// *ring* uses this unit type as the error type in most of its results /// because (a) usually the specific reasons for a failure are obvious or are /// not useful to know, and/or (b) providing more details about a failure might /// provide a dangerous side channel, and/or (c) it greatly simplifies the /// error handling logic. /// /// `Result<T, ring::error::Unspecified>` is mostly equivalent to /// `Result<T, ()>`. However, `ring::error::Unspecified` implements /// [`std::error::Error`] and users of *ring* can implement /// `From<ring::error::Unspecified>` to map this to their own error types, as /// described in [“Error Handling” in the Rust Book]: /// /// ``` /// extern crate ring; /// use ring::rand; /// use ring::rand::SecureRandom; /// /// enum Error { /// CryptoError, /// /// # #[cfg(feature = "use_heap")] /// IOError(std::io::Error), /// // [...] /// } /// /// impl From<ring::error::Unspecified> for Error { /// fn from(_: ring::error::Unspecified) -> Self { Error::CryptoError } /// } /// /// fn eight_random_bytes() -> Result<[u8; 8], Error> { /// let rng = rand::SystemRandom::new(); /// let mut bytes = [0; 8]; /// /// // The `From<ring::error::Unspecified>` implementation above makes this /// // equivalent to /// // `rng.fill(&mut bytes).map_err(|_| Error::CryptoError)?`. /// rng.fill(&mut bytes)?; /// /// Ok(bytes) /// } /// /// # fn main() { /// # assert!(eight_random_bytes().is_ok()); /// # } /// ``` /// /// Experience with using and implementing other crypto libraries like has /// shown that sophisticated error reporting facilities often cause significant /// bugs themselves, both within the crypto library and within users of the /// crypto library. This approach attempts to minimize complexity in the hopes /// of avoiding such problems. In some cases, this approach may be too extreme, /// and it may be important for an operation to provide some details about the /// cause of a failure. Users of *ring* are encouraged to report such cases so /// that they can be addressed individually. /// /// [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html /// [“Error Handling” in the Rust Book]: /// https://doc.rust-lang.org/book/first-edition/error-handling.html#the-from-trait #[derive(Clone, Copy, Debug, PartialEq)] pub struct Unspecified; // This is required for the implementation of `std::error::Error`. impl core::fmt::Display for Unspecified { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.write_str("ring::error::Unspecified") } } #[cfg(feature = "use_heap")] impl std::error::Error for Unspecified { #[inline] fn cause(&self) -> Option<&std::error::Error> { None } #[inline] fn description(&self) -> &str { "ring::error::Unspecified" } } impl From<untrusted::EndOfInput> for Unspecified { fn from(_: untrusted::EndOfInput) -> Self { Unspecified } }