mundane/lib.rs
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
// Copyright 2020 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.
//!
//! 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)]
// just in case we forget to add #[forbid(unsafe_code)] on new module
// definitions
#![deny(unsafe_code)]
#[macro_use]
mod macros;
extern crate bssl_sys;
// 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>();
}
}