//! Implementation of the end-to-end encryption layer of the _Chat Server Protocol_. use core::{cell::RefCell, fmt}; use std::{collections::HashMap, rc::Rc};
use educe::Educe; use libthreema_macros::Name; use tracing::debug;
/// Cause of an internal error. #[derive(Clone, Debug, thiserror::Error)] pubenum InternalErrorCause { /// Exhausted the available sequence numbers (e.g. for `ReflectId`s). Should never happen. #[error("Sequence number overflow happened")]
SequenceNumberOverflow(#[from] SequenceNumberOverflow),
/// Unable to encrypt a message or a struct. #[error("Encrypting '{name}' failed")]
EncryptionFailed { /// Name of the message or struct
name: &'static str,
},
/// Another kind of error occurred #[error("{0}")]
Other(String),
} impl<T: Into<String>> From<T> for InternalErrorCause { fn from(message: T) -> Self { Self::Other(message.into())
}
}
/// An error occurred while running the end-to-end encryption layer of the _Chat Server Protocol_. /// /// TODO(LIB-16): Clarify recoverability and what to do when encountering an error. so far, the idea is that /// an error means unrecoverable and that the CSP or CSP/D2M connection needs to be restarted. a new instance /// of the protocol can then be created with linear/exponential backoff. #[derive(Clone, Debug, thiserror::Error)] #[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] #[cfg_attr(
feature = "wasm",
derive(tsify::Tsify, serde::Serialize),
serde(
tag = "type",
content = "details",
rename_all = "kebab-case",
rename_all_fields = "camelCase"
),
tsify(into_wasm_abi)
)] pubenum CspE2eProtocolError { /// A foreign function considered infallible returned an error. #[cfg(any(test, feature = "uniffi", feature = "cli"))] #[error("Infallible function failed in foreign code: {0}")]
Foreign(String),
/// Invalid state for the requested operation. #[error("Invalid state: {0}")]
InvalidState(&'static str),
/// A desync occurred. /// /// This may be the result of... /// /// - a protocol violation from the client using this state machine (e.g. adding a contact to storage /// without using the appropriate task), or /// - misbehaviour of another device in the device group (e.g. updating a contact without an appropriate /// transaction), or /// - the mediator server misbehaving (e.g. forwarding reflected messages from another device while a /// transaction is ongoing), or /// - an implementation error of this protocol state machine. /// /// If multi-device is active, device group integrity may have been compromised and relinking against /// another device is advisable. #[error("Desync error: {0}")]
DesyncError(String),
/// A network error occurred while communicating with a server. #[error("Network error: {0}")]
NetworkError(String),
/// A server misbehaved in an operation considered infallible. #[error("Server error: {0}")]
ServerError(String),
/// Invalid credentials (should only be relevant for Work and OnPrem) reported by a server caused an /// operation to fail. /// /// When processing this variant, notify the user that the Work credentials are invalid and request new /// ones. A new CSP connection may be retried after the credentials have been validated. #[error("Invalid credentials")]
InvalidCredentials,
/// A rate limit of a server has been exceeded. /// /// When processing this variant, ensure that a new CSP connection attempt is delayed by at least 10s. #[error("Rate limit exceeded")]
RateLimitExceeded,
} impl From<SequenceNumberOverflow> for CspE2eProtocolError { fn from(error: SequenceNumberOverflow) -> Self { Self::InternalError(InternalErrorCause::from(error))
}
} impl From<HttpsEndpointError> for CspE2eProtocolError { fn from(error: HttpsEndpointError) -> Self { match error {
HttpsEndpointError::NetworkError(_) | HttpsEndpointError::ChallengeExpired => {
CspE2eProtocolError::NetworkError(error.to_string())
},
HttpsEndpointError::RateLimitExceeded => CspE2eProtocolError::RateLimitExceeded,
HttpsEndpointError::InvalidCredentials => CspE2eProtocolError::InvalidCredentials,
HttpsEndpointError::Forbidden
| HttpsEndpointError::NotFound
| HttpsEndpointError::InvalidChallengeResponse
| HttpsEndpointError::UnexpectedStatus(_)
| HttpsEndpointError::CustomPossiblyLocalizedError(_)
| HttpsEndpointError::DecodingFailed(_) => CspE2eProtocolError::ServerError(error.to_string()),
}
}
} impl From<ProviderError> for CspE2eProtocolError { fn from(error: ProviderError) -> Self { match error {
ProviderError::InvalidParameter(message) => Self::InternalError(message.into()),
ProviderError::InvalidState(message) => Self::DesyncError(message), #[cfg(any(test, feature = "uniffi", feature = "cli"))]
ProviderError::Foreign(message) => Self::Foreign(message),
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.