Skip to content

Commit 06ff4ec

Browse files
authored
pkcs8+spki: use blanket impls for Decode* traits (#785)
Previously these traits had `TryFrom` bounds for e.g. `PrivateKeyInfo`, which limits the applicability of these traits. This commit changes to using blanket impls for `TryFrom`, which allows types to handle parsing raw DER on their own, as in the `ring-compat` crate.
1 parent 28f5e0c commit 06ff4ec

File tree

6 files changed

+34
-25
lines changed

6 files changed

+34
-25
lines changed

pkcs1/src/traits.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ pub trait EncodeRsaPublicKey {
169169

170170
#[cfg(feature = "pkcs8")]
171171
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
172-
impl<T: pkcs8::DecodePrivateKey> DecodeRsaPrivateKey for T {
172+
impl<T> DecodeRsaPrivateKey for T
173+
where
174+
T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>,
175+
{
173176
fn from_pkcs1_der(private_key: &[u8]) -> Result<Self> {
174177
Ok(Self::try_from(pkcs8::PrivateKeyInfo {
175178
algorithm: ALGORITHM_ID,
@@ -181,7 +184,10 @@ impl<T: pkcs8::DecodePrivateKey> DecodeRsaPrivateKey for T {
181184

182185
#[cfg(feature = "pkcs8")]
183186
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
184-
impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T {
187+
impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T
188+
where
189+
T: for<'a> TryFrom<pkcs8::SubjectPublicKeyInfo<'a>, Error = pkcs8::Error>,
190+
{
185191
fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> {
186192
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfo {
187193
algorithm: ALGORITHM_ID,

pkcs8/src/traits.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ use der::pem::PemLabel;
2121
use std::path::Path;
2222

2323
/// Parse a private key object from a PKCS#8 encoded document.
24-
pub trait DecodePrivateKey: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error> + Sized {
24+
pub trait DecodePrivateKey: Sized {
2525
/// Deserialize PKCS#8 private key from ASN.1 DER-encoded data
2626
/// (binary format).
27-
fn from_pkcs8_der(bytes: &[u8]) -> Result<Self> {
28-
Self::try_from(PrivateKeyInfo::try_from(bytes)?)
29-
}
27+
fn from_pkcs8_der(bytes: &[u8]) -> Result<Self>;
3028

3129
/// Deserialize encrypted PKCS#8 private key from ASN.1 DER-encoded data
3230
/// (binary format) and attempt to decrypt it using the provided password.
@@ -87,6 +85,15 @@ pub trait DecodePrivateKey: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error> +
8785
}
8886
}
8987

88+
impl<T> DecodePrivateKey for T
89+
where
90+
T: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error>,
91+
{
92+
fn from_pkcs8_der(bytes: &[u8]) -> Result<Self> {
93+
Self::try_from(PrivateKeyInfo::try_from(bytes)?)
94+
}
95+
}
96+
9097
/// Serialize a private key object to a PKCS#8 encoded document.
9198
#[cfg(feature = "alloc")]
9299
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]

pkcs8/tests/traits.rs

-6
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ impl AsRef<[u8]> for MockKey {
3030
}
3131
}
3232

33-
impl DecodePrivateKey for MockKey {
34-
fn from_pkcs8_der(bytes: &[u8]) -> Result<MockKey> {
35-
Ok(MockKey(bytes.to_vec()))
36-
}
37-
}
38-
3933
impl EncodePrivateKey for MockKey {
4034
fn to_pkcs8_der(&self) -> Result<SecretDocument> {
4135
Ok(SecretDocument::try_from(self.as_ref())?)

sec1/src/traits.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ pub trait EncodeEcPrivateKey {
9797

9898
#[cfg(feature = "pkcs8")]
9999
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
100-
impl<T: pkcs8::DecodePrivateKey> DecodeEcPrivateKey for T {
100+
impl<T> DecodeEcPrivateKey for T
101+
where
102+
T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>,
103+
{
101104
fn from_sec1_der(private_key: &[u8]) -> Result<Self> {
102105
let params_oid = EcPrivateKey::from_der(private_key)?
103106
.parameters

spki/src/traits.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,10 @@ use {
1515
use std::path::Path;
1616

1717
/// Parse a public key object from an encoded SPKI document.
18-
pub trait DecodePublicKey:
19-
for<'a> TryFrom<SubjectPublicKeyInfo<'a>, Error = Error> + Sized
20-
{
18+
pub trait DecodePublicKey: Sized {
2119
/// Deserialize object from ASN.1 DER-encoded [`SubjectPublicKeyInfo`]
2220
/// (binary format).
23-
fn from_public_key_der(bytes: &[u8]) -> Result<Self> {
24-
Self::try_from(SubjectPublicKeyInfo::try_from(bytes)?)
25-
}
21+
fn from_public_key_der(bytes: &[u8]) -> Result<Self>;
2622

2723
/// Deserialize PEM-encoded [`SubjectPublicKeyInfo`].
2824
///
@@ -58,6 +54,15 @@ pub trait DecodePublicKey:
5854
}
5955
}
6056

57+
impl<T> DecodePublicKey for T
58+
where
59+
T: for<'a> TryFrom<SubjectPublicKeyInfo<'a>, Error = Error>,
60+
{
61+
fn from_public_key_der(bytes: &[u8]) -> Result<Self> {
62+
Self::try_from(SubjectPublicKeyInfo::try_from(bytes)?)
63+
}
64+
}
65+
6166
/// Serialize a public key object to a SPKI-encoded document.
6267
#[cfg(feature = "alloc")]
6368
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]

spki/tests/traits.rs

-6
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ impl AsRef<[u8]> for MockKey {
3030
}
3131
}
3232

33-
impl DecodePublicKey for MockKey {
34-
fn from_public_key_der(bytes: &[u8]) -> Result<MockKey> {
35-
Ok(MockKey(bytes.to_vec()))
36-
}
37-
}
38-
3933
impl EncodePublicKey for MockKey {
4034
fn to_public_key_der(&self) -> Result<Document> {
4135
Ok(Document::from_der(self.as_ref())?)

0 commit comments

Comments
 (0)