From 0614b0d44e58a288d14fd03f1cc0df2f466b4b7f Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Fri, 14 Sep 2018 11:37:40 +0200 Subject: [PATCH] secio: don't panic in `agree_ephemeral`. (#480) Given that echoing back our local key and nonce would result in equal digest values, we should treat this as an error instead of panicking. --- protocols/secio/src/error.rs | 60 +++++++++++++++++--------------- protocols/secio/src/handshake.rs | 5 ++- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/protocols/secio/src/error.rs b/protocols/secio/src/error.rs index bcb50887..7de3a4a1 100644 --- a/protocols/secio/src/error.rs +++ b/protocols/secio/src/error.rs @@ -63,35 +63,12 @@ pub enum SecioError { /// The hashes of the message didn't match. HmacNotMatching, + + /// We received an invalid proposition from remote. + InvalidProposition(&'static str), } impl error::Error for SecioError { - #[inline] - fn description(&self) -> &str { - match *self { - SecioError::IoError(_) => "I/O error", - SecioError::HandshakeParsingFailure => { - "Failed to parse one of the handshake protobuf messages" - } - SecioError::NoSupportIntersection => { - "There is no protocol supported by both the local and remote hosts" - } - SecioError::NonceGenerationFailed => "Failed to generate nonce", - SecioError::EphemeralKeyGenerationFailed => "Failed to generate ephemeral key", - SecioError::SigningFailure => "Failed to sign a message with our local private key", - SecioError::SignatureVerificationFailed => { - "The signature of the exchange packet doesn't verify the remote public key" - } - SecioError::SecretGenerationFailed => { - "Failed to generate the secret shared key from the ephemeral key" - } - SecioError::NonceVerificationFailed => "The final check of the handshake failed", - SecioError::CipherError(_) => "Error while decoding/encoding data", - SecioError::FrameTooShort => "The received frame was of invalid length", - SecioError::HmacNotMatching => "The hashes of the message didn't match", - } - } - fn cause(&self) -> Option<&error::Error> { match *self { SecioError::IoError(ref err) => Some(err), @@ -106,8 +83,35 @@ impl error::Error for SecioError { impl fmt::Display for SecioError { #[inline] - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(fmt, "{}", error::Error::description(self)) + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match self { + SecioError::IoError(e) => + write!(f, "I/O error: {}", e), + SecioError::HandshakeParsingFailure => + f.write_str("Failed to parse one of the handshake protobuf messages"), + SecioError::NoSupportIntersection => + f.write_str("There is no protocol supported by both the local and remote hosts"), + SecioError::NonceGenerationFailed => + f.write_str("Failed to generate nonce"), + SecioError::EphemeralKeyGenerationFailed => + f.write_str("Failed to generate ephemeral key"), + SecioError::SigningFailure => + f.write_str("Failed to sign a message with our local private key"), + SecioError::SignatureVerificationFailed => + f.write_str("The signature of the exchange packet doesn't verify the remote public key"), + SecioError::SecretGenerationFailed => + f.write_str("Failed to generate the secret shared key from the ephemeral key"), + SecioError::NonceVerificationFailed => + f.write_str("The final check of the handshake failed"), + SecioError::CipherError(e) => + write!(f, "Error while decoding/encoding data: {:?}", e), + SecioError::FrameTooShort => + f.write_str("The received frame was of invalid length"), + SecioError::HmacNotMatching => + f.write_str("The hashes of the message didn't match"), + SecioError::InvalidProposition(msg) => + write!(f, "invalid proposition: {}", msg) + } } } diff --git a/protocols/secio/src/handshake.rs b/protocols/secio/src/handshake.rs index 4fe31454..62bd6934 100644 --- a/protocols/secio/src/handshake.rs +++ b/protocols/secio/src/handshake.rs @@ -499,7 +499,10 @@ where let (local_infos, remote_infos) = { let (first_half, second_half) = longer_key.split_at(longer_key.len() / 2); match context.hashes_ordering { - Ordering::Equal => panic!(), + Ordering::Equal => { + let msg = "equal digest of public key and nonce for local and remote"; + return Err(SecioError::InvalidProposition(msg)) + } Ordering::Less => (second_half, first_half), Ordering::Greater => (first_half, second_half), }