Skip to content

Commit 156e8a4

Browse files
committed
[WIP] der: Document and SecretDocument types
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.
1 parent 88362a2 commit 156e8a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+975
-1787
lines changed

.github/workflows/pkcs8.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
target: ${{ matrix.target }}
4343
override: true
4444
- uses: RustCrypto/actions/cargo-hack-install@master
45-
- run: cargo hack build --target ${{ matrix.target }} --feature-powerset --exclude-features std,rand
45+
- run: cargo hack build --target ${{ matrix.target }} --feature-powerset --exclude-features getrandom,std,rand
4646

4747
minimal-versions:
4848
uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

der/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ der_derive = { version = "=0.6.0-pre.3", optional = true, path = "derive" }
2121
flagset = { version = "0.4.3", optional = true }
2222
pem-rfc7468 = { version = "0.5", optional = true, path = "../pem-rfc7468" }
2323
time = { version = "0.3.4", optional = true, default-features = false }
24+
zeroize = { version = "1.5", optional = true, default-features = false, features = ["alloc"] }
2425

2526
[dev-dependencies]
2627
hex-literal = "0.3.3"
@@ -30,7 +31,7 @@ proptest = "1"
3031
alloc = []
3132
derive = ["der_derive"]
3233
oid = ["const-oid"]
33-
pem = ["alloc", "pem-rfc7468/alloc"]
34+
pem = ["alloc", "pem-rfc7468/alloc", "zeroize"]
3435
std = ["alloc"]
3536

3637
[package.metadata.docs.rs]

der/src/decode.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
33
use crate::{Decoder, FixedTag, Header, Result};
44

5+
#[cfg(feature = "pem")]
6+
use {
7+
crate::pem::{self, PemLabel},
8+
zeroize::Zeroize,
9+
};
10+
511
#[cfg(doc)]
612
use crate::{Length, Tag};
713

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

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

59+
/// PEM decoding trait.
60+
///
61+
/// This trait is automatically impl'd for any type which impls both
62+
/// [`DecodeOwned`] and [`PemLabel`].
63+
#[cfg(feature = "pem")]
64+
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
65+
pub trait DecodePem: DecodeOwned + PemLabel {
66+
/// Try to decode this type from PEM.
67+
fn from_pem(pem: &str) -> Result<Self>;
68+
}
69+
70+
#[cfg(feature = "pem")]
71+
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
72+
impl<T: DecodeOwned + PemLabel> DecodePem for T {
73+
fn from_pem(pem: &str) -> Result<Self> {
74+
// TODO(tarcieri): support for decoding directly from PEM (instead of two-pass)
75+
let (label, mut der_bytes) = pem::decode_vec(pem.as_bytes())?;
76+
Self::validate_pem_label(label)?;
77+
78+
let result = T::from_der(&der_bytes);
79+
der_bytes.zeroize();
80+
result
81+
}
82+
}
83+
5384
/// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
5485
/// and [`Length`].
5586
pub trait DecodeValue<'a>: Sized {

0 commit comments

Comments
 (0)