// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Cryptography in Rust.

#![deny(missing_docs)]
#![deny(warnings)]
// just in case we forget to add #[forbid(unsafe_code)] on new module
// definitions
#![deny(unsafe_code)]

extern crate boringssl_sys;
extern crate failure;

// Forbid unsafe code except in the boringssl module.
#[allow(unsafe_code)]
mod boringssl;
#[forbid(unsafe_code)]
pub mod hash;
#[forbid(unsafe_code)]
pub mod hmac;
#[forbid(unsafe_code)]
pub mod insecure;
#[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 failure::Fail;

use boringssl::BoringError;

/// Reads cryptographically-secure random bytes.
///
/// This is a low-level primitive often used to construct higher-level
/// protocols. Unless you're sure that this is what you need, you should
/// probably be using something else. For example, all key types can be randomly
/// generated using higher-level functions (e.g., [`EcPrivKey::generate`]),
/// scrypt nonces are generated using the [`scrypt_generate`] function, etc.
///
/// [`EcPrivKey::generate`]: ::public::ec::EcPrivKey::generate
/// [`scrypt_generate`]: ::password::scrypt::scrypt_generate
pub fn rand_bytes(bytes: &mut [u8]) {
    boringssl::rand_bytes(bytes);
}

/// 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 `boring: <error>`,
/// while errors generated by Rust code are of the form `mundane: <error>`.
pub struct Error(ErrorInner);

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

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, "mundane: {}", err),
            ErrorInner::Boring(err) => write!(f, "boring: {}", err),
        }
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match &self.0 {
            ErrorInner::Mundane(err) => write!(f, "mundane: {}", 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, "boring: {:?}", err)
                } else {
                    // There's a multi-line stack trace, so print a preceding
                    // newline.
                    write!(f, "boring:\n{:?}", err)
                }
            }
        }
    }
}

impl Fail for Error {}

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