mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor(net): box ecies error (#337)
This commit is contained in:
committed by
Georgios Konstantopoulos
parent
b40546b999
commit
0b8d50127c
@ -1,5 +1,6 @@
|
||||
#![allow(missing_docs)]
|
||||
use crate::{
|
||||
error::ECIESErrorImpl,
|
||||
mac::{HeaderBytes, MAC},
|
||||
util::{hmac_sha256, id2pk, pk2id, sha256},
|
||||
ECIESError,
|
||||
@ -80,7 +81,7 @@ pub struct ECIES {
|
||||
|
||||
fn split_at_mut<T>(arr: &mut [T], idx: usize) -> Result<(&mut [T], &mut [T]), ECIESError> {
|
||||
if idx > arr.len() {
|
||||
return Err(ECIESError::OutOfBounds { idx, len: arr.len() })
|
||||
return Err(ECIESErrorImpl::OutOfBounds { idx, len: arr.len() }.into())
|
||||
}
|
||||
Ok(arr.split_at_mut(idx))
|
||||
}
|
||||
@ -224,7 +225,7 @@ impl ECIES {
|
||||
|
||||
let check_tag = hmac_sha256(mac_key.as_ref(), &[iv, encrypted_data], auth_data);
|
||||
if check_tag != tag {
|
||||
return Err(ECIESError::TagCheckFailed)
|
||||
return Err(ECIESErrorImpl::TagCheckFailed.into())
|
||||
}
|
||||
|
||||
let decrypted_data = encrypted_data;
|
||||
@ -302,15 +303,15 @@ impl ECIES {
|
||||
fn parse_auth_unencrypted(&mut self, data: &[u8]) -> Result<(), ECIESError> {
|
||||
let mut data = Rlp::new(data)?;
|
||||
|
||||
let sigdata = data.get_next::<[u8; 65]>()?.ok_or(ECIESError::InvalidAuthData)?;
|
||||
let sigdata = data.get_next::<[u8; 65]>()?.ok_or(ECIESErrorImpl::InvalidAuthData)?;
|
||||
let signature = RecoverableSignature::from_compact(
|
||||
&sigdata[0..64],
|
||||
RecoveryId::from_i32(sigdata[64] as i32)?,
|
||||
)?;
|
||||
let remote_id = data.get_next()?.ok_or(ECIESError::InvalidAuthData)?;
|
||||
let remote_id = data.get_next()?.ok_or(ECIESErrorImpl::InvalidAuthData)?;
|
||||
self.remote_id = Some(remote_id);
|
||||
self.remote_public_key = Some(id2pk(remote_id)?);
|
||||
self.remote_nonce = Some(data.get_next()?.ok_or(ECIESError::InvalidAuthData)?);
|
||||
self.remote_nonce = Some(data.get_next()?.ok_or(ECIESErrorImpl::InvalidAuthData)?);
|
||||
|
||||
let x = ecdh_x(&self.remote_public_key.unwrap(), &self.secret_key);
|
||||
self.remote_ephemeral_public_key = Some(SECP256K1.recover_ecdsa(
|
||||
@ -379,8 +380,8 @@ impl ECIES {
|
||||
fn parse_ack_unencrypted(&mut self, data: &[u8]) -> Result<(), ECIESError> {
|
||||
let mut data = Rlp::new(data)?;
|
||||
self.remote_ephemeral_public_key =
|
||||
Some(id2pk(data.get_next()?.ok_or(ECIESError::InvalidAckData)?)?);
|
||||
self.remote_nonce = Some(data.get_next()?.ok_or(ECIESError::InvalidAckData)?);
|
||||
Some(id2pk(data.get_next()?.ok_or(ECIESErrorImpl::InvalidAckData)?)?);
|
||||
self.remote_nonce = Some(data.get_next()?.ok_or(ECIESErrorImpl::InvalidAckData)?);
|
||||
|
||||
self.ephemeral_shared_secret =
|
||||
Some(ecdh_x(&self.remote_ephemeral_public_key.unwrap(), &self.ephemeral_secret_key));
|
||||
@ -475,12 +476,12 @@ impl ECIES {
|
||||
self.ingress_mac.as_mut().unwrap().update_header(header);
|
||||
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
|
||||
if check_mac != mac {
|
||||
return Err(ECIESError::TagCheckFailed)
|
||||
return Err(ECIESErrorImpl::TagCheckFailed.into())
|
||||
}
|
||||
|
||||
self.ingress_aes.as_mut().unwrap().apply_keystream(header);
|
||||
if header.as_slice().len() < 3 {
|
||||
return Err(ECIESError::InvalidHeader)
|
||||
return Err(ECIESErrorImpl::InvalidHeader.into())
|
||||
}
|
||||
|
||||
let body_size = usize::try_from(header.as_slice().read_uint::<BigEndian>(3)?)?;
|
||||
@ -527,7 +528,7 @@ impl ECIES {
|
||||
self.ingress_mac.as_mut().unwrap().update_body(body);
|
||||
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
|
||||
if check_mac != mac {
|
||||
return Err(ECIESError::TagCheckFailed)
|
||||
return Err(ECIESErrorImpl::TagCheckFailed.into())
|
||||
}
|
||||
|
||||
let size = self.body_size.unwrap();
|
||||
|
||||
@ -1,12 +1,45 @@
|
||||
use crate::IngressECIESValue;
|
||||
use std::fmt;
|
||||
use thiserror::Error;
|
||||
|
||||
/// An error that occurs while reading or writing to an ECIES stream.
|
||||
pub struct ECIESError {
|
||||
inner: Box<ECIESErrorImpl>,
|
||||
}
|
||||
|
||||
// === impl ===
|
||||
|
||||
impl ECIESError {
|
||||
/// Consumes the type and returns the error enum
|
||||
pub fn into_inner(self) -> ECIESErrorImpl {
|
||||
*self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ECIESError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(&*self.inner, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ECIESError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&*self.inner, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ECIESError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
self.inner.source()
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that occurs while reading or writing to an ECIES stream.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ECIESError {
|
||||
pub enum ECIESErrorImpl {
|
||||
/// Error during IO
|
||||
#[error("IO error")]
|
||||
IO(#[from] std::io::Error),
|
||||
IO(std::io::Error),
|
||||
/// Error when checking the HMAC tag against the tag on the data
|
||||
#[error("tag check failure")]
|
||||
TagCheckFailed,
|
||||
@ -21,13 +54,13 @@ pub enum ECIESError {
|
||||
InvalidHeader,
|
||||
/// Error when interacting with secp256k1
|
||||
#[error(transparent)]
|
||||
Secp256k1(#[from] secp256k1::Error),
|
||||
Secp256k1(secp256k1::Error),
|
||||
/// Error when decoding RLP data
|
||||
#[error(transparent)]
|
||||
RLPDecoding(#[from] reth_rlp::DecodeError),
|
||||
RLPDecoding(reth_rlp::DecodeError),
|
||||
/// Error when convering to integer
|
||||
#[error(transparent)]
|
||||
FromInt(#[from] std::num::TryFromIntError),
|
||||
FromInt(std::num::TryFromIntError),
|
||||
/// Error when trying to split an array beyond its length
|
||||
#[error("requested {idx} but array len is {len}")]
|
||||
OutOfBounds {
|
||||
@ -45,3 +78,33 @@ pub enum ECIESError {
|
||||
msg: Option<IngressECIESValue>,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<ECIESErrorImpl> for ECIESError {
|
||||
fn from(source: ECIESErrorImpl) -> Self {
|
||||
ECIESError { inner: Box::new(source) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ECIESError {
|
||||
fn from(source: std::io::Error) -> Self {
|
||||
ECIESErrorImpl::IO(source).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<secp256k1::Error> for ECIESError {
|
||||
fn from(source: secp256k1::Error) -> Self {
|
||||
ECIESErrorImpl::Secp256k1(source).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reth_rlp::DecodeError> for ECIESError {
|
||||
fn from(source: reth_rlp::DecodeError) -> Self {
|
||||
ECIESErrorImpl::RLPDecoding(source).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::num::TryFromIntError> for ECIESError {
|
||||
fn from(source: std::num::TryFromIntError) -> Self {
|
||||
ECIESErrorImpl::FromInt(source).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#![allow(clippy::result_large_err)]
|
||||
#![warn(missing_docs, unreachable_pub)]
|
||||
#![deny(unused_must_use, rust_2018_idioms)]
|
||||
#![doc(test(
|
||||
@ -20,8 +19,8 @@ mod codec;
|
||||
|
||||
use reth_primitives::H512 as PeerId;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// Raw egress values for an ECIES protocol
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum EgressECIESValue {
|
||||
/// The AUTH message being sent out
|
||||
Auth,
|
||||
@ -31,8 +30,8 @@ pub enum EgressECIESValue {
|
||||
Message(bytes::Bytes),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// Raw ingress values for an ECIES protocol
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum IngressECIESValue {
|
||||
/// Receiving a message from a [`PeerId`]
|
||||
AuthReceive(PeerId),
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
//! The ECIES Stream implementation which wraps over [`AsyncRead`] and [`AsyncWrite`].
|
||||
use crate::{codec::ECIESCodec, ECIESError, EgressECIESValue, IngressECIESValue};
|
||||
use crate::{
|
||||
codec::ECIESCodec, error::ECIESErrorImpl, ECIESError, EgressECIESValue, IngressECIESValue,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use futures::{ready, Sink, SinkExt};
|
||||
use reth_primitives::H512 as PeerId;
|
||||
@ -64,7 +66,7 @@ where
|
||||
if matches!(msg, Some(IngressECIESValue::Ack)) {
|
||||
Ok(Self { stream: transport, remote_id })
|
||||
} else {
|
||||
Err(ECIESError::InvalidHandshake { expected: IngressECIESValue::Ack, msg })
|
||||
Err(ECIESErrorImpl::InvalidHandshake { expected: IngressECIESValue::Ack, msg }.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,10 +83,11 @@ where
|
||||
let remote_id = match &msg {
|
||||
Some(IngressECIESValue::AuthReceive(remote_id)) => *remote_id,
|
||||
_ => {
|
||||
return Err(ECIESError::InvalidHandshake {
|
||||
return Err(ECIESErrorImpl::InvalidHandshake {
|
||||
expected: IngressECIESValue::AuthReceive(Default::default()),
|
||||
msg,
|
||||
})
|
||||
}
|
||||
.into())
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user