summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/reader/pem.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/der/src/reader/pem.rs')
-rw-r--r--vendor/der/src/reader/pem.rs83
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)
+ }
+}