#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, vec::Vec};
use crate::cms::enveloped_data::EnvelopedData;
use crate::cms::signed_data::SignedData;
use crate::der::{Decode, Encode};
use crate::transport::envelopes::TransportEnvelope;
use crate::transport::error::TransportError;
use crate::transport::handshake::HandshakeProtocolKind;
#[cfg(feature = "transport-ecies")]
use crate::transport::handshake::{ClientHello, ClientKeyExchange, ServerHandshake};
impl HandshakeProtocolKind {
pub(crate) fn wrap_client_start(self, message: &[u8]) -> Result<TransportEnvelope, TransportError> {
match self {
#[cfg(feature = "transport-ecies")]
Self::Ecies => {
let client_hello = ClientHello::from_der(message)?;
let signed_data: SignedData = (&client_hello).try_into().map_err(|_| TransportError::InvalidMessage)?;
Ok(TransportEnvelope::SignedData(Box::new(signed_data)))
}
#[cfg(feature = "transport-cms")]
Self::Cms => Ok(TransportEnvelope::EnvelopedData(Box::new(EnvelopedData::from_der(message)?))),
#[cfg(not(feature = "transport-ecies"))]
Self::Ecies => Err(TransportError::UnsupportedHandshakeProtocol(self)),
#[cfg(not(feature = "transport-cms"))]
Self::Cms => Err(TransportError::UnsupportedHandshakeProtocol(self)),
}
}
pub(crate) fn unwrap_server_response(self, envelope: TransportEnvelope) -> Result<Vec<u8>, TransportError> {
let signed_data = match envelope {
TransportEnvelope::SignedData(sd) => sd,
_ => return Err(TransportError::InvalidMessage),
};
match self {
#[cfg(feature = "transport-ecies")]
Self::Ecies => {
let server_handshake: ServerHandshake =
signed_data.as_ref().try_into().map_err(|_| TransportError::InvalidMessage)?;
Ok(server_handshake.to_der()?)
}
#[cfg(feature = "transport-cms")]
Self::Cms => Ok(signed_data.to_der()?),
#[cfg(not(feature = "transport-ecies"))]
Self::Ecies => Err(TransportError::UnsupportedHandshakeProtocol(self)),
#[cfg(not(feature = "transport-cms"))]
Self::Cms => Err(TransportError::UnsupportedHandshakeProtocol(self)),
}
}
pub(crate) fn wrap_client_followup(self, message: &[u8]) -> Result<TransportEnvelope, TransportError> {
match self {
#[cfg(feature = "transport-ecies")]
Self::Ecies => {
let client_kex = ClientKeyExchange::from_der(message)?;
let enveloped_data: EnvelopedData =
(&client_kex).try_into().map_err(|_| TransportError::InvalidMessage)?;
Ok(TransportEnvelope::EnvelopedData(Box::new(enveloped_data)))
}
#[cfg(feature = "transport-cms")]
Self::Cms => Ok(TransportEnvelope::SignedData(Box::new(SignedData::from_der(message)?))),
#[cfg(not(feature = "transport-ecies"))]
Self::Ecies => Err(TransportError::UnsupportedHandshakeProtocol(self)),
#[cfg(not(feature = "transport-cms"))]
Self::Cms => Err(TransportError::UnsupportedHandshakeProtocol(self)),
}
}
pub(crate) fn unwrap_client_request(self, envelope: &TransportEnvelope) -> Result<Vec<u8>, TransportError> {
match (self, envelope) {
#[cfg(feature = "transport-ecies")]
(Self::Ecies, TransportEnvelope::SignedData(sd)) => Ok(ClientHello::try_from(sd.as_ref())
.map_err(|_| TransportError::InvalidMessage)?
.to_der()?),
#[cfg(feature = "transport-ecies")]
(Self::Ecies, TransportEnvelope::EnvelopedData(ed)) => Ok(ClientKeyExchange::try_from(ed.as_ref())
.map_err(|_| TransportError::InvalidMessage)?
.to_der()?),
#[cfg(feature = "transport-cms")]
(Self::Cms, TransportEnvelope::EnvelopedData(ed)) => Ok(ed.to_der()?),
#[cfg(feature = "transport-cms")]
(Self::Cms, TransportEnvelope::SignedData(sd)) => Ok(sd.to_der()?),
#[cfg(not(feature = "transport-ecies"))]
(Self::Ecies, _) => Err(TransportError::UnsupportedHandshakeProtocol(self)),
#[cfg(not(feature = "transport-cms"))]
(Self::Cms, _) => Err(TransportError::UnsupportedHandshakeProtocol(self)),
_ => Err(TransportError::InvalidMessage),
}
}
pub(crate) fn wrap_server_response(self, message: &[u8]) -> Result<TransportEnvelope, TransportError> {
let signed_data = match self {
#[cfg(feature = "transport-ecies")]
Self::Ecies => {
let server_handshake = ServerHandshake::from_der(message)?;
(&server_handshake).try_into().map_err(|_| TransportError::InvalidMessage)?
}
#[cfg(feature = "transport-cms")]
Self::Cms => SignedData::from_der(message)?,
#[cfg(not(feature = "transport-ecies"))]
Self::Ecies => return Err(TransportError::UnsupportedHandshakeProtocol(self)),
#[cfg(not(feature = "transport-cms"))]
Self::Cms => return Err(TransportError::UnsupportedHandshakeProtocol(self)),
};
Ok(TransportEnvelope::SignedData(Box::new(signed_data)))
}
}