use vodozemac::{
Curve25519PublicKey,
ecies::{CheckCode, Ecies, EstablishedEcies, InboundCreationResult, InitialMessage, Message},
};
use crate::authentication::oauth::qrcode::SecureChannelError as Error;
pub(super) enum CryptoChannel {
Ecies(Ecies),
}
impl CryptoChannel {
pub(super) fn new_ecies() -> Self {
CryptoChannel::Ecies(Ecies::new())
}
pub(super) fn public_key(&self) -> Curve25519PublicKey {
match self {
CryptoChannel::Ecies(ecies) => ecies.public_key(),
}
}
pub(super) fn establish_inbound_channel(
self,
message: &str,
) -> Result<CryptoChannelCreationResult, Error> {
match self {
CryptoChannel::Ecies(ecies) => {
let message = InitialMessage::decode(message)?;
Ok(CryptoChannelCreationResult::Ecies(ecies.establish_inbound_channel(&message)?))
}
}
}
}
pub(super) enum CryptoChannelCreationResult {
Ecies(InboundCreationResult),
}
impl CryptoChannelCreationResult {
pub(super) fn plaintext(&self) -> &[u8] {
match self {
CryptoChannelCreationResult::Ecies(inbound_creation_result) => {
&inbound_creation_result.message
}
}
}
}
pub(super) enum EstablishedCryptoChannel {
Ecies(EstablishedEcies),
}
impl EstablishedCryptoChannel {
pub(super) fn check_code(&self) -> &CheckCode {
match self {
EstablishedCryptoChannel::Ecies(established_ecies) => established_ecies.check_code(),
}
}
pub(super) fn seal(&mut self, plaintext: &str) -> String {
match self {
EstablishedCryptoChannel::Ecies(channel) => {
let message = channel.encrypt(plaintext.as_bytes());
message.encode()
}
}
}
pub(super) fn open(&mut self, message: &str) -> Result<String, Error> {
let plaintext = match self {
EstablishedCryptoChannel::Ecies(channel) => {
let message = Message::decode(message)?;
channel.decrypt(&message)?
}
};
Ok(String::from_utf8(plaintext).map_err(|e| e.utf8_error())?)
}
}