#![allow(deprecated, clippy::use_self)]
use std::fmt;
use std::fmt::{Display, Formatter};
#[cfg(feature = "serde-config")]
use serde::{Deserialize, Serialize};
use crate::error::*;
use crate::serialize::binary::*;
#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
#[non_exhaustive]
pub enum Algorithm {
#[deprecated(
note = "this is a compromised hashing function, it is here for backward compatibility"
)]
RSAMD5,
#[deprecated(
note = "this is a compromised hashing function, it is here for backward compatibility"
)]
DSA,
#[deprecated(
note = "this is a compromised hashing function, it is here for backward compatibility"
)]
RSASHA1,
#[deprecated(
note = "this is a compromised hashing function, it is here for backward compatibility"
)]
RSASHA1NSEC3SHA1,
RSASHA256,
RSASHA512,
ECDSAP256SHA256,
ECDSAP384SHA384,
ED25519,
Unknown(u8),
}
impl Algorithm {
pub fn from_u8(value: u8) -> Self {
#[allow(deprecated)]
match value {
1 => Self::RSAMD5,
3 => Self::DSA,
5 => Self::RSASHA1,
7 => Self::RSASHA1NSEC3SHA1,
8 => Self::RSASHA256,
10 => Self::RSASHA512,
13 => Self::ECDSAP256SHA256,
14 => Self::ECDSAP384SHA384,
15 => Self::ED25519,
_ => Self::Unknown(value),
}
}
pub fn hash_len(self) -> Option<usize> {
match self {
Self::RSAMD5 => Some(16), Self::DSA | Self::RSASHA1 | Self::RSASHA1NSEC3SHA1 => Some(20), Self::RSASHA256 | Self::ECDSAP256SHA256 | Self::ED25519 => Some(32), Self::ECDSAP384SHA384 => Some(48),
Self::RSASHA512 => Some(64), Self::Unknown(_) => None,
}
}
#[deprecated(note = "use as_str instead")]
pub fn to_str(self) -> &'static str {
self.as_str()
}
pub fn as_str(self) -> &'static str {
match self {
Self::RSAMD5 => "RSAMD5",
Self::DSA => "DSA",
Self::RSASHA1 => "RSASHA1",
Self::RSASHA256 => "RSASHA256",
Self::RSASHA1NSEC3SHA1 => "RSASHA1-NSEC3-SHA1",
Self::RSASHA512 => "RSASHA512",
Self::ECDSAP256SHA256 => "ECDSAP256SHA256",
Self::ECDSAP384SHA384 => "ECDSAP384SHA384",
Self::ED25519 => "ED25519",
Self::Unknown(_) => "Unknown",
}
}
}
impl BinEncodable for Algorithm {
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
encoder.emit(u8::from(*self))
}
}
impl<'r> BinDecodable<'r> for Algorithm {
fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
let algorithm_id =
decoder.read_u8()?.unverified();
Ok(Self::from_u8(algorithm_id))
}
}
impl From<Algorithm> for &'static str {
fn from(a: Algorithm) -> &'static str {
a.as_str()
}
}
impl From<Algorithm> for u8 {
fn from(a: Algorithm) -> Self {
match a {
Algorithm::RSAMD5 => 1,
Algorithm::DSA => 3,
Algorithm::RSASHA1 => 5,
Algorithm::RSASHA1NSEC3SHA1 => 7,
Algorithm::RSASHA256 => 8,
Algorithm::RSASHA512 => 10,
Algorithm::ECDSAP256SHA256 => 13,
Algorithm::ECDSAP384SHA384 => 14,
Algorithm::ED25519 => 15,
Algorithm::Unknown(v) => v,
}
}
}
impl Display for Algorithm {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(self.as_str())
}
}
#[test]
fn test_into() {
for algorithm in &[
Algorithm::RSAMD5,
Algorithm::DSA,
Algorithm::RSASHA1,
Algorithm::RSASHA256,
Algorithm::RSASHA1NSEC3SHA1,
Algorithm::RSASHA512,
Algorithm::ECDSAP256SHA256,
Algorithm::ECDSAP384SHA384,
Algorithm::ED25519,
] {
assert_eq!(*algorithm, Algorithm::from_u8(Into::<u8>::into(*algorithm)))
}
}
#[test]
fn test_order() {
let mut algorithms = [
Algorithm::RSAMD5,
Algorithm::DSA,
Algorithm::RSASHA1,
Algorithm::RSASHA256,
Algorithm::RSASHA1NSEC3SHA1,
Algorithm::RSASHA512,
Algorithm::ECDSAP256SHA256,
Algorithm::ECDSAP384SHA384,
Algorithm::ED25519,
];
algorithms.sort();
for (got, expect) in algorithms.iter().zip(
[
Algorithm::RSAMD5,
Algorithm::DSA,
Algorithm::RSASHA1,
Algorithm::RSASHA1NSEC3SHA1,
Algorithm::RSASHA256,
Algorithm::RSASHA512,
Algorithm::ECDSAP256SHA256,
Algorithm::ECDSAP384SHA384,
Algorithm::ED25519,
]
.iter(),
) {
assert_eq!(got, expect);
}
}