// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! Cryptography in Rust.
//!
//! Mundane is a Rust cryptography library backed by BoringSSL that is difficult
//! to misuse, ergonomic, and performant (in that order).
//!
//! # Features
//!
//! By default, Mundane provides only high-level cryptographic primitives.
//! Unless you are implementing cryptographic protocols, these high-level
//! primitives should be all you need. However, if you are sure that you need
//! something lower level, Mundane provides features to enable a number of
//! different low level primitives.
//!
//! WARNING: Being low level, these primitives provide the programmer with more
//! degrees of freedom. There are more conditions that the programmer must meet
//! in order to guarantee security, and thus more ways for the programmer to
//! shoot themself in the foot. Please only use these primitives if you're aware
//! of the risks and are comfortable with the responsibility of using them
//! correctly!
//!
//! **Features**
//!
//! | Name           | Description                         |
//! | -------------- | ------------------------------------|
//! | `kdf`          | Key derivation functions            |
//! | `bytes`        | Low-level operations on byte slices |
//! | `rsa-pkcs1v15` | RSA-PKCS1v1.5 signatures            |
//!
//! # Insecure Operations
//!
//! Mundane supports one additional feature not listed in the previous section:
//! `insecure`. This enables some cryptographic primitives which are today
//! considered insecure. These should only be used for compatibility with legacy
//! systems - never in new systems! When the `insecure` feature is used, an
//! `insecure` module is added to the crate root. All insecure primitives are
//! exposed through this module.

#![deny(missing_docs)]
#![deny(warnings)]
// We use the `must_use` attribute liberally, including in cases where it's
// technically unnecessary because the return type itself is marked as
// `must_use`. We prefer to do this rather than make the lint happy because it
// makes it less likely for us to forget a `must_use` attribute in the future if
// we change the function's signature.
#![allow(clippy::double_must_use)]
// just in case we forget to add #[forbid(unsafe_code)] on new module
// definitions
#![deny(unsafe_code)]

#[macro_use]
mod macros;

// Forbid unsafe code except in the boringssl module.
#[allow(unsafe_code)]
mod boringssl;
#[cfg(any(doc, feature = "bytes"))]
#[forbid(unsafe_code)]
pub mod bytes;
#[forbid(unsafe_code)]
pub mod hash;
#[forbid(unsafe_code)]
pub mod hmac;
#[cfg(any(doc, feature = "insecure"))]
#[forbid(unsafe_code)]
pub mod insecure;
#[cfg(any(doc, feature = "insecure"))]
#[forbid(unsafe_code)]
mod insecure_rc4;
#[cfg(any(doc, feature = "kdf"))]
#[forbid(unsafe_code)]
pub mod kdf;
#[forbid(unsafe_code)]
pub mod password;
#[forbid(unsafe_code)]
pub mod public;
#[forbid(unsafe_code)]
mod util;

use std::fmt::{self, Debug, Display, Formatter};

use boringssl::BoringError;

/// Errors generated by this crate.
///
/// `Error` represents two types of errors: errors generated by BoringSSL, and
/// errors generated by the Rust code in this crate. When printed (using either
/// `Display` or `Debug`), BoringSSL errors are of the form `boringssl:
/// <error>`, while errors generated by Rust code are of the form `<error>`.
pub struct Error(ErrorInner);

impl Error {
    fn new(s: String) -> Error {
        Error(ErrorInner::Mundane(s))
    }
}

#[doc(hidden)]
impl From<BoringError> for Error {
    fn from(err: BoringError) -> Error {
        Error(ErrorInner::Boring(err))
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match &self.0 {
            ErrorInner::Mundane(err) => write!(f, "{}", err),
            ErrorInner::Boring(err) => write!(f, "boringssl: {}", err),
        }
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match &self.0 {
            ErrorInner::Mundane(err) => write!(f, "{}", err),

            ErrorInner::Boring(err) => {
                if err.stack_depth() == 1 {
                    // Either there was no stack trace, or the stack trace only
                    // contained a single frame. In either case, don't bother
                    // printing a preceding newline.
                    write!(f, "boringssl: {:?}", err)
                } else {
                    // There's a multi-line stack trace, so print a preceding
                    // newline.
                    write!(f, "boringssl:\n{:?}", err)
                }
            }
        }
    }
}

impl std::error::Error for Error {}

enum ErrorInner {
    Mundane(String),
    Boring(BoringError),
}

#[cfg(test)]
mod tests {
    use super::Error;

    #[test]
    fn test_send() {
        fn assert_send<T: Send>() {}
        assert_send::<Error>();
    }

    #[test]
    fn test_sync() {
        fn assert_sync<T: Sync>() {}
        assert_sync::<Error>();
    }
}
