PEM format recognised

new-idea
Avril 4 years ago
parent b2caa126f9
commit af3979e6a2
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -26,3 +26,9 @@ pub const POST_EXPIRE: tokio::time::Duration = tokio::time::Duration::from_secs(
/// Max size of encrypted body
pub const POST_BODY_MAX_SIZE: usize = (1024 * 1024) * 20; // 20MB
/// What encoded PEM formats are recognised
pub const RECOGNISABLE_PEM_ENCODES: &'static [&'static str] = &[
"PUBLIC KEY",
"RSA PUBLIC KEY",
];

@ -26,6 +26,16 @@ unsafe impl<F: FormatSpec + ?Sized> std::marker::Sync for FormattedStr<F>{}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FormattedString<F: FormatSpec + ?Sized>(String, PhantomData<F>);
impl<'a, F> fmt::Display for &'a FormattedStr<F>
where F: ?Sized + FormatSpec
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{}", self.as_str())
}
}
// Deserialising
const _:() = {
use serde::{
@ -377,11 +387,58 @@ pub mod formats
}
}
impl PEMFormat
{
#[inline] fn is_allowed(string: &str) -> bool
{
lazy_static! {
static ref ALLOWED_MAP: smallmap::Map<&'static str,()> = defaults::RECOGNISABLE_PEM_ENCODES.iter().map(|&x| (x, ())).collect();
}
ALLOWED_MAP.contains_key(&string)
}
const BEGIN_BLOCK: &'static str = "-----BEGIN ";
const END_BLOCK: &'static str = "-----END ";
const END_ANY_BLOCK: &'static str = "-----";
}
impl FormatSpec for PEMFormat
{
type Error = PEMFormatError;
fn validate(_s: &str) -> Result<(), Self::Error> {
todo!("Learn the PEM ciphertext format");
fn validate(s: &str) -> Result<(), Self::Error> {
macro_rules! enforce {
($e:expr) => {
if !$e {
return Err(PEMFormatError);
}
}
}
let s = s.trim();
let mut lines = s.lines();
let begin = lines.next().ok_or(PEMFormatError)?.trim();
enforce!(begin.starts_with(Self::BEGIN_BLOCK));
enforce!(begin.ends_with(Self::END_ANY_BLOCK));
let val = &begin[Self::BEGIN_BLOCK.len()..];
let val = &val[..(val.len()-Self::END_ANY_BLOCK.len())];
enforce!(Self::is_allowed(val));
let mut lines = lines.map(|x| x.trim()).fuse();
while let Some(line) = lines.next()
{
if line.starts_with(Self::END_BLOCK) {
let eval = &line[Self::END_BLOCK.len()..];
let eval = &eval[..(eval.len()-Self::END_ANY_BLOCK.len())];
enforce!(eval == val);
break;
} else {
enforce!(Base64Format::validate(line.trim()).is_ok());
}
}
enforce!(lines.next().is_none());
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
@ -412,7 +469,7 @@ pub mod formats
while let Some(window) = iter.next()
{
let is_last = iter.peek().is_none();
// eprintln!("Window: {:?} ({})", std::str::from_utf8(window), is_last);
// eprintln!("Window: {:?} ({})", std::str::from_utf8(window), is_last);
for byte in window.iter().copied()
{
if !(CHARSET[byte as usize] || (is_last && byte == b'=')) {
@ -499,6 +556,19 @@ pub mod formats
}
}
#[test]
fn pem_format()
{
const PUBKEY: &'static str = r#"-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2vGFdJ+KCK6Ot8sDcaCXk/9D8
S1InEHi5vGSLdGKJpaRdHhQ08NL5+fv6B9FGKV5KARCYXeW1JGnGNzhRXHhNyOSm
KNi2T+L84xBCTEazlLnnnvqKGaD95rtjwMmkhsErRMfavqUMThEmVca5fwP30Sqm
StF6Y2cSO2eUjqTeUQIDAQAB
-----END PUBLIC KEY-----"#;
let pem = PEMFormattedStr::new(PUBKEY).expect("PEM format");
println!("PEM: {}", pem);
}
}
}

Loading…
Cancel
Save