diff --git a/Cargo.lock b/Cargo.lock index 06f806bdfd..56957a842c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,6 +486,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "displaydoc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3274a6bc8a6a4521291b53b9dcb8345e963fe931c3fc462a7d3ead71d7ccd30d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.6.1" @@ -845,6 +856,7 @@ dependencies = [ "block-modes", "criterion", "curve25519-dalek", + "displaydoc", "futures-util", "hex", "hmac", diff --git a/rust/protocol/Cargo.toml b/rust/protocol/Cargo.toml index 1b3466d09e..820614a5b8 100644 --- a/rust/protocol/Cargo.toml +++ b/rust/protocol/Cargo.toml @@ -29,6 +29,7 @@ hex = "0.4" log = "0.4" num_enum = "0.5.1" uuid = "0.8" +displaydoc = "0.2" [features] armv8 = ["aes/armv8", "aes-gcm-siv/armv8"] diff --git a/rust/protocol/src/error.rs b/rust/protocol/src/error.rs index b48a023f70..d71778c566 100644 --- a/rust/protocol/src/error.rs +++ b/rust/protocol/src/error.rs @@ -1,69 +1,106 @@ // -// Copyright 2020 Signal Messenger, LLC. +// Copyright 2020-2021 Signal Messenger, LLC. // SPDX-License-Identifier: AGPL-3.0-only // use crate::curve::KeyType; +use displaydoc::Display; + use std::error::Error; -use std::fmt; use std::panic::UnwindSafe; pub type Result = std::result::Result; -#[derive(Debug)] +#[derive(Debug, Display)] pub enum SignalProtocolError { + /// invalid argument: {0} InvalidArgument(String), + /// invalid state for call to {0} to succeed: {1} InvalidState(&'static str, String), + /// failed to decode protobuf: {0} ProtobufDecodingError(prost::DecodeError), + /// failed to encode protobuf: {0} ProtobufEncodingError(prost::EncodeError), + /// protobuf encoding was invalid InvalidProtobufEncoding, + /// ciphertext serialized bytes were too short <{0}> CiphertextMessageTooShort(usize), + /// ciphertext version was too old <{0}> LegacyCiphertextVersion(u8), + /// ciphertext version was unrecognized <{0}> UnrecognizedCiphertextVersion(u8), + /// unrecognized message version <{0}> UnrecognizedMessageVersion(u32), + /// fingerprint identifiers do not match FingerprintIdentifierMismatch, + /// fingerprint version number mismatch them {0} us {1} FingerprintVersionMismatch(u32, u32), + /// fingerprint parsing error FingerprintParsingError, + /// no key type identifier NoKeyTypeIdentifier, + /// bad key type <{0:#04x}> BadKeyType(u8), + /// bad key length <{1}> for key with type <{0}> BadKeyLength(KeyType, usize), + /// invalid signature detected SignatureValidationFailed, + /// untrusted identity for address {0} UntrustedIdentity(crate::ProtocolAddress), + /// invalid prekey identifier InvalidPreKeyId, + /// invalid signed prekey identifier InvalidSignedPreKeyId, + /// invalid root key length <{0}> InvalidRootKeyLength(usize), + /// invalid chain key length <{0}> InvalidChainKeyLength(usize), + /// invalid MAC key length <{0}> InvalidMacKeyLength(usize), + /// invalid cipher key length <{0}> or nonce length <{1}> InvalidCipherCryptographicParameters(usize, usize), + /// invalid ciphertext message InvalidCiphertext, + /// no sender key state NoSenderKeyState, + /// session with '{0}' not found SessionNotFound(String), + /// invalid session structure InvalidSessionStructure, + /// session for {0} has invalid registration ID {1:X} InvalidRegistrationId(crate::ProtocolAddress, u32), + /// message with old counter {0} / {1} DuplicatedMessage(u32, u32), + /// invalid message {0} InvalidMessage(&'static str), + /// internal error {0} InternalError(&'static str), + /// error while invoking an ffi callback: {0} FfiBindingError(String), + /// error in method call '{0}': {1} ApplicationCallbackError( &'static str, - Box, + Box, ), + /// invalid sealed sender message {0} InvalidSealedSenderMessage(String), + /// unknown sealed sender message version {0} UnknownSealedSenderVersion(u8), + /// self send of a sealed sender message SealedSenderSelfSend, } @@ -89,110 +126,3 @@ impl From for SignalProtocolError { SignalProtocolError::ProtobufEncodingError(value) } } - -impl fmt::Display for SignalProtocolError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SignalProtocolError::ProtobufDecodingError(e) => { - write!(f, "failed to decode protobuf: {}", e) - } - SignalProtocolError::ProtobufEncodingError(e) => { - write!(f, "failed to encode protobuf: {}", e) - } - SignalProtocolError::InvalidProtobufEncoding => { - write!(f, "protobuf encoding was invalid") - } - SignalProtocolError::InvalidArgument(s) => write!(f, "invalid argument: {}", s), - SignalProtocolError::InvalidState(func, s) => { - write!(f, "invalid state for call to {} to succeed: {}", func, s) - } - SignalProtocolError::CiphertextMessageTooShort(size) => { - write!(f, "ciphertext serialized bytes were too short <{}>", size) - } - SignalProtocolError::LegacyCiphertextVersion(version) => { - write!(f, "ciphertext version was too old <{}>", version) - } - SignalProtocolError::UnrecognizedCiphertextVersion(version) => { - write!(f, "ciphertext version was unrecognized <{}>", version) - } - SignalProtocolError::UnrecognizedMessageVersion(message_version) => { - write!(f, "unrecognized message version <{}>", message_version) - } - SignalProtocolError::FingerprintIdentifierMismatch => { - write!(f, "fingerprint identifiers do not match") - } - SignalProtocolError::FingerprintVersionMismatch(theirs, ours) => { - write!( - f, - "fingerprint version number mismatch them {} us {}", - theirs, ours - ) - } - SignalProtocolError::FingerprintParsingError => { - write!(f, "fingerprint parsing error") - } - SignalProtocolError::NoKeyTypeIdentifier => write!(f, "no key type identifier"), - SignalProtocolError::BadKeyType(t) => write!(f, "bad key type <{:#04x}>", t), - SignalProtocolError::BadKeyLength(t, l) => { - write!(f, "bad key length <{}> for key with type <{}>", l, t) - } - SignalProtocolError::InvalidPreKeyId => write!(f, "invalid prekey identifier"), - SignalProtocolError::InvalidSignedPreKeyId => { - write!(f, "invalid signed prekey identifier") - } - SignalProtocolError::InvalidChainKeyLength(l) => { - write!(f, "invalid chain key length <{}>", l) - } - SignalProtocolError::InvalidRootKeyLength(l) => { - write!(f, "invalid root key length <{}>", l) - } - SignalProtocolError::InvalidCipherCryptographicParameters(kl, nl) => write!( - f, - "invalid cipher key length <{}> or nonce length <{}>", - kl, nl - ), - SignalProtocolError::InvalidMacKeyLength(l) => { - write!(f, "invalid MAC key length <{}>", l) - } - SignalProtocolError::UntrustedIdentity(addr) => { - write!(f, "untrusted identity for address {}", addr) - } - SignalProtocolError::SignatureValidationFailed => { - write!(f, "invalid signature detected") - } - SignalProtocolError::InvalidCiphertext => write!(f, "invalid ciphertext message"), - SignalProtocolError::SessionNotFound(who) => { - write!(f, "session with '{}' not found", who) - } - SignalProtocolError::InvalidSessionStructure => write!(f, "invalid session structure"), - SignalProtocolError::InvalidRegistrationId(addr, value) => { - write!( - f, - "session for {} has invalid registration ID {:X}", - addr, value - ) - } - SignalProtocolError::DuplicatedMessage(i, c) => { - write!(f, "message with old counter {} / {}", i, c) - } - SignalProtocolError::InvalidMessage(m) => write!(f, "invalid message {}", m), - SignalProtocolError::InternalError(m) => write!(f, "internal error {}", m), - SignalProtocolError::NoSenderKeyState => write!(f, "no sender key state"), - SignalProtocolError::FfiBindingError(m) => { - write!(f, "error while invoking an ffi callback: {}", m) - } - SignalProtocolError::ApplicationCallbackError(func, c) => { - write!(f, "application callback {} failed with {}", func, c) - } - SignalProtocolError::InvalidSealedSenderMessage(m) => { - write!(f, "invalid sealed sender message {}", m) - } - SignalProtocolError::UnknownSealedSenderVersion(v) => { - write!(f, "unknown sealed sender message version {}", v) - } - SignalProtocolError::SealedSenderSelfSend => { - write!(f, "self send of a sealed sender message") - } - } - } -}