use crate::{AlertDescription, parse};
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub(crate) enum SignatureScheme {
rsa_pkcs1_sha256 = 0x0401,
rsa_pkcs1_sha384 = 0x0501,
rsa_pkcs1_sha512 = 0x0601,
ecdsa_secp256r1_sha256 = 0x0403,
ecdsa_secp384r1_sha384 = 0x0503,
ecdsa_secp521r1_sha512 = 0x0603,
rsa_pss_rsae_sha256 = 0x0804,
rsa_pss_rsae_sha384 = 0x0805,
rsa_pss_rsae_sha512 = 0x0806,
ed25519 = 0x0807,
ed448 = 0x0808,
rsa_pss_pss_sha256 = 0x0809,
rsa_pss_pss_sha384 = 0x080a,
rsa_pss_pss_sha512 = 0x080b,
}
impl SignatureScheme {
pub fn to_be_bytes(self) -> [u8; 2] {
u16::from(self).to_be_bytes()
}
}
impl From<SignatureScheme> for u16 {
fn from(value: SignatureScheme) -> Self {
value as u16
}
}
impl TryFrom<u16> for SignatureScheme {
type Error = u16;
fn try_from(val: u16) -> Result<Self, Self::Error> {
match val {
x if x == (Self::rsa_pkcs1_sha256 as u16) => Ok(Self::rsa_pkcs1_sha256),
x if x == (Self::rsa_pkcs1_sha384 as u16) => Ok(Self::rsa_pkcs1_sha384),
x if x == (Self::rsa_pkcs1_sha512 as u16) => Ok(Self::rsa_pkcs1_sha512),
x if x == (Self::ecdsa_secp256r1_sha256 as u16) => Ok(Self::ecdsa_secp256r1_sha256),
x if x == (Self::ecdsa_secp384r1_sha384 as u16) => Ok(Self::ecdsa_secp384r1_sha384),
x if x == (Self::ecdsa_secp521r1_sha512 as u16) => Ok(Self::ecdsa_secp521r1_sha512),
x if x == (Self::rsa_pss_rsae_sha256 as u16) => Ok(Self::rsa_pss_rsae_sha256),
x if x == (Self::rsa_pss_rsae_sha384 as u16) => Ok(Self::rsa_pss_rsae_sha384),
x if x == (Self::rsa_pss_rsae_sha512 as u16) => Ok(Self::rsa_pss_rsae_sha512),
x if x == (Self::ed25519 as u16) => Ok(Self::ed25519),
x if x == (Self::ed448 as u16) => Ok(Self::ed448),
x if x == (Self::rsa_pss_pss_sha256 as u16) => Ok(Self::rsa_pss_pss_sha256),
x if x == (Self::rsa_pss_pss_sha384 as u16) => Ok(Self::rsa_pss_pss_sha384),
x if x == (Self::rsa_pss_pss_sha512 as u16) => Ok(Self::rsa_pss_pss_sha512),
_ => Err(val),
}
}
}
pub(crate) fn deser_signature_scheme_list(
b: &[u8],
) -> Result<Vec<SignatureScheme>, AlertDescription> {
let (_, vec_data) = parse::vec16(
"SignatureSchemeList supported_signature_algorithms",
b,
2,
2,
)?;
let mut ret: Vec<SignatureScheme> = Vec::with_capacity(b.len() / 2);
for chunk in vec_data.chunks_exact(2) {
let signature_scheme: u16 = u16::from_be_bytes(chunk.try_into().unwrap());
match SignatureScheme::try_from(signature_scheme) {
Ok(signature_scheme) => ret.push(signature_scheme),
Err(val) => {
log::info!("Ignoring unknown SignatureScheme 0x{val:04x}");
}
}
}
Ok(ret)
}