Skip to content

Commit

Permalink
der: Document and SecretDocument types (#571)
Browse files Browse the repository at this point in the history
Replaces the previous `Document` trait with types for wrapping
serialized ASN.1 DER SEQUENCEs stored on the heap.

The `SecretDocument` is composed in terms of `Document` and provides
some additional hardening for sensitive data, namely zeroize-on-drop and
file permissions hardening when writing to disk.

This commit also removes all of the format-specific `*Document` types
found in the `pkcs1`, `pkcs8`, `spki`, and `sec1` crates with the new
`Document` and `SecretDocument` types.
  • Loading branch information
tarcieri authored Apr 5, 2022
1 parent c8a157b commit 71bb668
Show file tree
Hide file tree
Showing 59 changed files with 1,375 additions and 1,895 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pkcs8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
target: ${{ matrix.target }}
override: true
- uses: RustCrypto/actions/cargo-hack-install@master
- run: cargo hack build --target ${{ matrix.target }} --feature-powerset --exclude-features std,rand
- run: cargo hack build --target ${{ matrix.target }} --feature-powerset --exclude-features getrandom,std,rand

minimal-versions:
uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
Expand Down
6 changes: 5 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion der/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ der_derive = { version = "=0.6.0-pre.3", optional = true, path = "derive" }
flagset = { version = "0.4.3", optional = true }
pem-rfc7468 = { version = "0.5", optional = true, path = "../pem-rfc7468" }
time = { version = "0.3.4", optional = true, default-features = false }
zeroize = { version = "1.5", optional = true, default-features = false, features = ["alloc"] }

[dev-dependencies]
hex-literal = "0.3.3"
Expand All @@ -30,7 +31,7 @@ proptest = "1"
alloc = []
derive = ["der_derive"]
oid = ["const-oid"]
pem = ["alloc", "pem-rfc7468/alloc"]
pem = ["alloc", "pem-rfc7468/alloc", "zeroize"]
std = ["alloc"]

[package.metadata.docs.rs]
Expand Down
31 changes: 31 additions & 0 deletions der/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
use crate::{Decoder, FixedTag, Header, Result};

#[cfg(feature = "pem")]
use {
crate::pem::{self, PemLabel},
zeroize::Zeroize,
};

#[cfg(doc)]
use crate::{Length, Tag};

Expand Down Expand Up @@ -50,6 +56,31 @@ pub trait DecodeOwned: for<'a> Decode<'a> {}

impl<T> DecodeOwned for T where T: for<'a> Decode<'a> {}

/// PEM decoding trait.
///
/// This trait is automatically impl'd for any type which impls both
/// [`DecodeOwned`] and [`PemLabel`].
#[cfg(feature = "pem")]
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
pub trait DecodePem: DecodeOwned + PemLabel {
/// Try to decode this type from PEM.
fn from_pem(pem: &str) -> Result<Self>;
}

#[cfg(feature = "pem")]
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
impl<T: DecodeOwned + PemLabel> DecodePem for T {
fn from_pem(pem: &str) -> Result<Self> {
// TODO(tarcieri): support for decoding directly from PEM (instead of two-pass)
let (label, mut der_bytes) = pem::decode_vec(pem.as_bytes())?;
Self::validate_pem_label(label)?;

let result = T::from_der(&der_bytes);
der_bytes.zeroize();
result
}
}

/// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
/// and [`Length`].
pub trait DecodeValue<'a>: Sized {
Expand Down
Loading

0 comments on commit 71bb668

Please sign in to comment.