diff --git a/Cargo.lock b/Cargo.lock index 3bdb2b4b74fa9161aaf6c5ee57f927d60a4f6fa1..34cd5f77fb4a932b5e279c4b79986544f307114b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -844,11 +844,10 @@ dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "scrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2720,6 +2719,24 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thiserror" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -3344,6 +3361,8 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termion 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "818ef3700c2a7b447dca1a1dd28341fe635e6ee103c806c636bb9c929991b2cd" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +"checksum thiserror-impl 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" diff --git a/lib/crypto/Cargo.toml b/lib/crypto/Cargo.toml index 6b6d1212370c54d3936a90f54baa3dd51fa8a6b7..63fd11e8e7209a7edad8999e3ca54a9a59477f5a 100644 --- a/lib/crypto/Cargo.toml +++ b/lib/crypto/Cargo.toml @@ -16,11 +16,10 @@ path = "src/lib.rs" base64 = "0.11.0" bs58 = "0.3.0" byteorder = "1.3.2" -failure = "0.1.5" ring = "0.16.9" scrypt = { version = "0.2", default-features = false } -serde = "1.0.*" -serde_derive = "1.0.*" +serde = { version = "1.0.*", features = ["derive"] } +thiserror = "1.0.11" unwrap = "1.2.1" zeroize = { version = "1.1.0", features = ["zeroize_derive"] } diff --git a/lib/crypto/src/bases/mod.rs b/lib/crypto/src/bases/mod.rs index 4bb0dc9f75b197aa65c1433a088387e7496c5988..961006443ab75d3e6fe3b6980f12ff4d2fa4070f 100644 --- a/lib/crypto/src/bases/mod.rs +++ b/lib/crypto/src/bases/mod.rs @@ -15,6 +15,8 @@ //! Provide base convertion tools +use thiserror::Error; + /// Base16 conversion tools pub mod b16; @@ -25,12 +27,9 @@ pub mod b58; pub mod b64; /// Errors enumeration for Base58/64 strings convertion. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Fail)] +#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)] pub enum BaseConvertionError { - #[fail( - display = "Data have invalid key length : expected {}, found {}.", - expected, found - )] + #[error("Data have invalid key length : expected {expected:?}, found {found:?}.")] /// Data have invalid length. InvalidLength { /// Expected length @@ -38,7 +37,7 @@ pub enum BaseConvertionError { /// Actual length found: usize, }, - #[fail(display = "Invalid character '{}' at offset {}.", character, offset)] + #[error("Invalid character '{character:?}' at offset {offset:?}.")] /// Base58/64 have an invalid character. InvalidCharacter { /// Character @@ -46,10 +45,10 @@ pub enum BaseConvertionError { /// Offset (=position) offset: usize, }, - #[fail(display = "Invalid base converter length.")] + #[error("Invalid base converter length.")] /// Base58/64 have invalid lendth InvalidBaseConverterLength, - #[fail(display = "Invalid last symbol '{}' at offset {}.", symbol, offset)] + #[error("Invalid last symbol '{symbol:?}' at offset {offset:?}.")] /// Base64 have invalid last symbol (symbol, offset) InvalidLastSymbol { /// Symbol @@ -58,7 +57,7 @@ pub enum BaseConvertionError { offset: usize, }, /// Unknown error - #[fail(display = "Unknown error.")] + #[error("Unknown error.")] UnknownError, } diff --git a/lib/crypto/src/errors.rs b/lib/crypto/src/errors.rs deleted file mode 100644 index c7cd399bb40a8cf28bbec3fb53ec38f0b71529e7..0000000000000000000000000000000000000000 --- a/lib/crypto/src/errors.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2017-2019 The AXIOM TEAM Association. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -//! Manage cryptographic errors. - -/// An error with absolutely no details. -/// -/// *dup-crypto* 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. -/// -/// 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 *dup-crypto* are encouraged to report such cases so -/// that they can be addressed individually. -pub type Unspecified = ring::error::Unspecified; diff --git a/lib/crypto/src/hashs/mod.rs b/lib/crypto/src/hashs/mod.rs index c12b43a03fed6d84b9a8cf26ef8fb69767bf9173..c844978abc9003eaa3c86eedb40932afb94c471d 100644 --- a/lib/crypto/src/hashs/mod.rs +++ b/lib/crypto/src/hashs/mod.rs @@ -16,7 +16,9 @@ //! Provide wrappers for cryptographic hashs use crate::bases::*; +use crate::rand::UnspecifiedRandError; use ring::{digest, rand}; +use serde::{Deserialize, Serialize}; use std::fmt::{Debug, Display, Error, Formatter}; /// A hash wrapper. @@ -49,8 +51,9 @@ impl Hash { /// Generate a random Hash #[inline] - pub fn random() -> Result<Self, crate::errors::Unspecified> { - let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new())?; + pub fn random() -> Result<Self, UnspecifiedRandError> { + let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) + .map_err(|_| UnspecifiedRandError)?; Ok(Hash(random_bytes.expose())) } diff --git a/lib/crypto/src/keys/bin_signable.rs b/lib/crypto/src/keys/bin_signable.rs index 7ae96fb108f110564b45cc299a3610e5cfd2135d..3693d40329c11ac44759c147c4159cb651053ce1 100644 --- a/lib/crypto/src/keys/bin_signable.rs +++ b/lib/crypto/src/keys/bin_signable.rs @@ -20,6 +20,9 @@ use serde::{Deserialize, Serialize}; /// Signatureable in binary format pub trait BinSignable<'de>: Serialize + Deserialize<'de> { + /// Error when serialize self into binary + type SerdeError: std::error::Error; + /// Return entity issuer pubkey fn issuer_pubkey(&self) -> PubKey; /// Return signature @@ -27,7 +30,7 @@ pub trait BinSignable<'de>: Serialize + Deserialize<'de> { /// Change signature fn set_signature(&mut self, _signature: Sig); /// Get binary datas without signature - fn get_bin_without_sig(&self) -> Result<Vec<u8>, failure::Error>; + fn get_bin_without_sig(&self) -> Result<Vec<u8>, Self::SerdeError>; /// Add signature to bin datas fn add_sig_to_bin_datas(&self, bin_datas: &mut Vec<u8>); /// Sign entity with a signator @@ -90,13 +93,15 @@ mod tests { } impl BinSignable<'_> for BinSignableTestImpl { + type SerdeError = bincode::Error; + #[inline] fn add_sig_to_bin_datas(&self, bin_datas: &mut Vec<u8>) { bin_datas .extend_from_slice(&bincode::serialize(&self.sig).expect("Fail to binarize sig !")); } #[inline] - fn get_bin_without_sig(&self) -> Result<Vec<u8>, failure::Error> { + fn get_bin_without_sig(&self) -> Result<Vec<u8>, bincode::Error> { let mut bin_msg = bincode::serialize(&self)?; let sig_size = bincode::serialized_size(&self.signature())?; let bin_msg_len = bin_msg.len(); diff --git a/lib/crypto/src/keys/ed25519.rs b/lib/crypto/src/keys/ed25519.rs index a9abfe0afc81451dc982f96155f3223c19344c77..33f22e445acfba3e4e001129f61085302d84cfd7 100644 --- a/lib/crypto/src/keys/ed25519.rs +++ b/lib/crypto/src/keys/ed25519.rs @@ -23,11 +23,13 @@ use super::PublicKey as PublicKeyMethods; use super::{PubkeyFromBytesError, SigError}; use crate::bases::b58::{bytes_to_str_base58, ToBase58}; use crate::bases::*; +use crate::rand::UnspecifiedRandError; use crate::seeds::Seed32; use base64; use ring::signature::{Ed25519KeyPair as RingKeyPair, KeyPair, UnparsedPublicKey, ED25519}; -use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor}; -use serde::ser::{Serialize, SerializeTuple, Serializer}; +use serde::de::{Deserializer, Error, SeqAccess, Visitor}; +use serde::ser::{SerializeTuple, Serializer}; +use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use std::fmt; use std::fmt::{Debug, Display, Formatter}; @@ -309,7 +311,7 @@ impl super::KeyPair for Ed25519KeyPair { impl Ed25519KeyPair { /// Generate random keypair - pub fn generate_random() -> Result<Self, crate::errors::Unspecified> { + pub fn generate_random() -> Result<Self, UnspecifiedRandError> { Ok(KeyPairFromSeed32Generator::generate(Seed32::random()?)) } } diff --git a/lib/crypto/src/keys/mod.rs b/lib/crypto/src/keys/mod.rs index b28b431d9072e25a694dc256883cfbe0c499626e..79573f4aa9348524289cc16d35b7b20c3f3b3fd5 100644 --- a/lib/crypto/src/keys/mod.rs +++ b/lib/crypto/src/keys/mod.rs @@ -56,7 +56,7 @@ pub use crate::seeds::Seed32; use crate::bases::b58::ToBase58; use crate::bases::BaseConvertionError; -use failure::Fail; +use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use std::fmt::Debug; use std::fmt::Display; @@ -64,6 +64,7 @@ use std::fmt::Error; use std::fmt::Formatter; use std::hash::Hash; use std::str::FromStr; +use thiserror::Error; /// Cryptographic keys algorithms list #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] @@ -81,39 +82,39 @@ pub trait GetKeysAlgo: Clone + Debug + PartialEq + Eq { } /// Errors enumeration for signature verification. -#[derive(Debug, Eq, Fail, PartialEq)] +#[derive(Debug, Eq, Error, PartialEq)] pub enum SigError { /// Signature and pubkey are not the same algo - #[fail(display = "Signature and pubkey are not the same algo.")] + #[error("Signature and pubkey are not the same algo.")] NotSameAlgo, /// Invalid signature - #[fail(display = "Invalid signature.")] + #[error("Invalid signature.")] InvalidSig, /// Absence of signature - #[fail(display = "Absence of signature.")] + #[error("Absence of signature.")] NotSig, /// Serialization error - #[fail(display = "Serialization error: {}", _0)] + #[error("Serialization error: {0}")] SerdeError(String), } /// SignError -#[derive(Debug, Eq, Fail, PartialEq)] +#[derive(Debug, Eq, Error, PartialEq)] pub enum SignError { /// Corrupted key pair - #[fail(display = "Corrupted key pair.")] + #[error("Corrupted key pair.")] CorruptedKeyPair, /// WrongAlgo - #[fail(display = "Wrong algo.")] + #[error("Wrong algo.")] WrongAlgo, /// WrongPrivkey - #[fail(display = "Wrong private key.")] + #[error("Wrong private key.")] WrongPrivkey, /// AlreadySign - #[fail(display = "Already signed.")] + #[error("Already signed.")] AlreadySign, /// Serialization error - #[fail(display = "Serialization error: {}", _0)] + #[error("Serialization error: {0}")] SerdeError(String), } @@ -596,14 +597,13 @@ mod tests { } #[test] - #[should_panic( - expected = "Try to verify a signature with key pair of a different algorithm !\n\ - Signature=Schnorr\nKeyPair=(4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS, hidden)" - )] fn key_pair_verify_wrong_sig_algo() { let false_key_pair_ed25519 = false_key_pair_ed25519(); let false_key_pair = KeyPairEnum::Ed25519(false_key_pair_ed25519); - let _ = false_key_pair.verify(b"message", &Sig::Schnorr()); + assert_eq!( + Err(SigError::NotSameAlgo), + false_key_pair.verify(b"message", &Sig::Schnorr()), + ); } #[test] @@ -656,13 +656,12 @@ mod tests { } #[test] - #[should_panic( - expected = "Try to verify a signature with public key of a different algorithm !\n\ - Signature=Schnorr\nPublickey=Ed25519(PublicKey { 11111111111111111111111111111111 })" - )] fn pubkey_verify_sig_wrong_algo() { let pubkey = PubKey::default(); - let _ = pubkey.verify(b"message", &Sig::Schnorr()); + assert_eq!( + Err(SigError::NotSameAlgo), + pubkey.verify(b"message", &Sig::Schnorr()), + ); } #[test] diff --git a/lib/crypto/src/lib.rs b/lib/crypto/src/lib.rs index ebc1f0aa222bc8e8e943dc7aa7509b022277aa1b..4c36431b691ce4533866f4d9716c21a975d0adc1 100644 --- a/lib/crypto/src/lib.rs +++ b/lib/crypto/src/lib.rs @@ -29,13 +29,7 @@ )] #![allow(non_camel_case_types)] -#[macro_use] -extern crate failure; -#[macro_use] -extern crate serde_derive; - pub mod bases; -pub mod errors; pub mod hashs; pub mod keys; pub mod rand; diff --git a/lib/crypto/src/rand.rs b/lib/crypto/src/rand.rs index a0f82b6274c43483f1e1f5081a39c624bd7da04b..1b6f1024d61691b53377082b0843b7ace12ea232 100644 --- a/lib/crypto/src/rand.rs +++ b/lib/crypto/src/rand.rs @@ -18,11 +18,30 @@ use byteorder::ByteOrder; use ring::rand; +/// An error with absolutely no details. +/// +/// *dup-crypto* 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. +/// +/// 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 *dup-crypto* are encouraged to report such cases so +/// that they can be addressed individually. +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct UnspecifiedRandError; + #[inline] /// Generate random u32 -pub fn gen_u32() -> Result<u32, crate::errors::Unspecified> { +pub fn gen_u32() -> Result<u32, UnspecifiedRandError> { let rng = rand::SystemRandom::new(); - let random_bytes = rand::generate::<[u8; 4]>(&rng)?; + let random_bytes = rand::generate::<[u8; 4]>(&rng).map_err(|_| UnspecifiedRandError)?; Ok(byteorder::BigEndian::read_u32(&random_bytes.expose())) } diff --git a/lib/crypto/src/seeds.rs b/lib/crypto/src/seeds.rs index c35865ac586554a0a575a2bdc441a158b8916463..57b6873bc797164cc32f45f40aee41d33347d6ae 100644 --- a/lib/crypto/src/seeds.rs +++ b/lib/crypto/src/seeds.rs @@ -17,7 +17,9 @@ use crate::bases::b58::{bytes_to_str_base58, ToBase58}; use crate::bases::*; +use crate::rand::UnspecifiedRandError; use ring::rand; +use serde::{Deserialize, Serialize}; use std::fmt::{self, Debug, Display, Formatter}; use zeroize::Zeroize; @@ -63,8 +65,9 @@ impl Seed32 { } #[inline] /// Generate random seed - pub fn random() -> Result<Seed32, crate::errors::Unspecified> { - let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new())?; + pub fn random() -> Result<Seed32, UnspecifiedRandError> { + let random_bytes = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) + .map_err(|_| UnspecifiedRandError)?; Ok(Seed32::new(random_bytes.expose())) } } diff --git a/lib/modules/ws2p/ws2p-messages/lib.rs b/lib/modules/ws2p/ws2p-messages/lib.rs index 3ca06a2196989091aaa5d111f0cc3d7f834d08b3..661bdbbcf28b158a1fe86d43509f74f6b940a204 100644 --- a/lib/modules/ws2p/ws2p-messages/lib.rs +++ b/lib/modules/ws2p/ws2p-messages/lib.rs @@ -116,6 +116,8 @@ impl WS2PMessage { } impl<'de> BinSignable<'de> for WS2PMessage { + type SerdeError = bincode::Error; + #[inline] fn add_sig_to_bin_datas(&self, bin_datas: &mut Vec<u8>) { bin_datas.extend_from_slice( @@ -123,7 +125,7 @@ impl<'de> BinSignable<'de> for WS2PMessage { ); } #[inline] - fn get_bin_without_sig(&self) -> Result<Vec<u8>, failure::Error> { + fn get_bin_without_sig(&self) -> Result<Vec<u8>, bincode::Error> { let mut bin_msg = bincode::serialize(&self)?; let sig_size = bincode::serialized_size(&self.signature())?; let bin_msg_len = bin_msg.len();