diff options
Diffstat (limited to 'vendor/der/src/reader/pem.rs')
-rw-r--r-- | vendor/der/src/reader/pem.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/der/src/reader/pem.rs b/vendor/der/src/reader/pem.rs new file mode 100644 index 000000000..01bb4f20e --- /dev/null +++ b/vendor/der/src/reader/pem.rs @@ -0,0 +1,83 @@ +//! Streaming PEM reader. + +use super::Reader; +use crate::{ErrorKind, Header, Length, Result}; +use pem_rfc7468::Decoder; + +/// `Reader` type which decodes PEM on-the-fly. +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +#[derive(Clone)] +pub struct PemReader<'i> { + /// Inner PEM decoder. + decoder: Decoder<'i>, + + /// Input length (in bytes after Base64 decoding). + input_len: Length, + + /// Position in the input buffer (in bytes after Base64 decoding). + position: Length, +} + +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl<'i> PemReader<'i> { + /// Create a new PEM reader which decodes data on-the-fly. + /// + /// Uses the default 64-character line wrapping. + pub fn new(pem: &'i [u8]) -> Result<Self> { + let decoder = Decoder::new(pem)?; + let input_len = Length::try_from(decoder.remaining_len())?; + + Ok(Self { + decoder, + input_len, + position: Length::ZERO, + }) + } + + /// Get the PEM label which will be used in the encapsulation boundaries + /// for this document. + pub fn type_label(&self) -> &'i str { + self.decoder.type_label() + } +} + +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl<'i> Reader<'i> for PemReader<'i> { + fn input_len(&self) -> Length { + self.input_len + } + + fn peek_byte(&self) -> Option<u8> { + // TODO(tarcieri): lookahead buffer + None + } + + fn peek_header(&self) -> Result<Header> { + // TODO(tarcieri): lookahead buffer + Err(ErrorKind::Reader.into()) + } + + fn position(&self) -> Length { + self.position + } + + fn read_slice(&mut self, _len: Length) -> Result<&'i [u8]> { + // Can't borrow from PEM because it requires decoding + Err(ErrorKind::Reader.into()) + } + + fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> { + let bytes = self.decoder.decode(buf)?; + self.position = (self.position + bytes.len())?; + + debug_assert_eq!( + self.position, + (self.input_len - Length::try_from(self.decoder.remaining_len())?)? + ); + + Ok(bytes) + } +} |