Skip to content

Commit b09ff11

Browse files
committed
Make SubjectPublicKeyInfo generic around Params
1 parent 630514d commit b09ff11

File tree

10 files changed

+80
-54
lines changed

10 files changed

+80
-54
lines changed

pkcs1/src/traits.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl<T: pkcs8::DecodePrivateKey> DecodeRsaPrivateKey for T {
183183
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
184184
impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T {
185185
fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> {
186-
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfo {
186+
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfoRef {
187187
algorithm: ALGORITHM_ID,
188188
subject_public_key: public_key,
189189
})?)
@@ -206,7 +206,7 @@ impl<T: pkcs8::EncodePrivateKey> EncodeRsaPrivateKey for T {
206206
impl<T: pkcs8::EncodePublicKey> EncodeRsaPublicKey for T {
207207
fn to_pkcs1_der(&self) -> Result<Document> {
208208
let doc = self.to_public_key_der()?;
209-
let spki = pkcs8::SubjectPublicKeyInfo::from_der(doc.as_bytes())?;
209+
let spki = pkcs8::SubjectPublicKeyInfoRef::from_der(doc.as_bytes())?;
210210
spki.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
211211
RsaPublicKey::from_der(spki.subject_public_key)?.try_into()
212212
}

pkcs8/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ pub use crate::{
8383
version::Version,
8484
};
8585
pub use der::{self, asn1::ObjectIdentifier, oid::AssociatedOid};
86-
pub use spki::{self, AlgorithmIdentifierRef, DecodePublicKey, SubjectPublicKeyInfo};
86+
pub use spki::{
87+
self, AlgorithmIdentifierRef, DecodePublicKey, SubjectPublicKeyInfo, SubjectPublicKeyInfoRef,
88+
};
8789

8890
#[cfg(feature = "alloc")]
8991
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]

spki/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod fingerprint;
4343
pub use crate::{
4444
algorithm::{AlgorithmIdentifier, AlgorithmIdentifierRef},
4545
error::{Error, Result},
46-
spki::SubjectPublicKeyInfo,
46+
spki::{SubjectPublicKeyInfo, SubjectPublicKeyInfoRef},
4747
traits::DecodePublicKey,
4848
};
4949
pub use der::{self, asn1::ObjectIdentifier};

spki/src/spki.rs

+45-21
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! X.509 `SubjectPublicKeyInfo`
22
3-
use crate::{AlgorithmIdentifierRef, Error, Result};
3+
use crate::{AlgorithmIdentifier, Error, Result};
44
use core::cmp::Ordering;
55
use der::{
6-
asn1::BitStringRef, Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd,
6+
asn1::{AnyRef, BitStringRef},
7+
Choice, Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd,
78
};
89

910
#[cfg(feature = "alloc")]
@@ -21,8 +22,8 @@ use {
2122
#[cfg(feature = "pem")]
2223
use der::pem::PemLabel;
2324

24-
#[cfg(doc)]
25-
use crate::AlgorithmIdentifier;
25+
/// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters.
26+
pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo<'a, AnyRef<'a>>;
2627

2728
/// X.509 `SubjectPublicKeyInfo` (SPKI) as defined in [RFC 5280 § 4.1.2.7].
2829
///
@@ -37,15 +38,25 @@ use crate::AlgorithmIdentifier;
3738
///
3839
/// [RFC 5280 § 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7
3940
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
40-
pub struct SubjectPublicKeyInfo<'a> {
41+
pub struct SubjectPublicKeyInfo<'a, Params> {
4142
/// X.509 [`AlgorithmIdentifier`] for the public key type
42-
pub algorithm: AlgorithmIdentifierRef<'a>,
43+
pub algorithm: AlgorithmIdentifier<Params>,
4344

4445
/// Public key data
4546
pub subject_public_key: &'a [u8],
4647
}
4748

48-
impl<'a> SubjectPublicKeyInfo<'a> {
49+
impl<'a, Params> SubjectPublicKeyInfo<'a, Params> {
50+
/// Get a [`BitString`] representing the `subject_public_key`
51+
fn bitstring(&self) -> der::Result<BitStringRef<'a>> {
52+
BitStringRef::from_bytes(self.subject_public_key)
53+
}
54+
}
55+
56+
impl<'a, Params> SubjectPublicKeyInfo<'a, Params>
57+
where
58+
Params: Choice<'a> + Encode,
59+
{
4960
/// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and
5061
/// encode it as a Base64 string.
5162
///
@@ -71,14 +82,12 @@ impl<'a> SubjectPublicKeyInfo<'a> {
7182
self.encode(&mut builder)?;
7283
Ok(builder.finish())
7384
}
74-
75-
/// Get a [`BitString`] representing the `subject_public_key`
76-
fn bitstring(&self) -> der::Result<BitStringRef<'a>> {
77-
BitStringRef::from_bytes(self.subject_public_key)
78-
}
7985
}
8086

81-
impl<'a> DecodeValue<'a> for SubjectPublicKeyInfo<'a> {
87+
impl<'a, Params> DecodeValue<'a> for SubjectPublicKeyInfo<'a, Params>
88+
where
89+
Params: Choice<'a> + Encode,
90+
{
8291
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
8392
reader.read_nested(header.length, |reader| {
8493
Ok(Self {
@@ -91,7 +100,10 @@ impl<'a> DecodeValue<'a> for SubjectPublicKeyInfo<'a> {
91100
}
92101
}
93102

94-
impl<'a> Sequence<'a> for SubjectPublicKeyInfo<'a> {
103+
impl<'a, Params> Sequence<'a> for SubjectPublicKeyInfo<'a, Params>
104+
where
105+
Params: Choice<'a> + Encode,
106+
{
95107
fn fields<F, T>(&self, f: F) -> der::Result<T>
96108
where
97109
F: FnOnce(&[&dyn Encode]) -> der::Result<T>,
@@ -100,15 +112,21 @@ impl<'a> Sequence<'a> for SubjectPublicKeyInfo<'a> {
100112
}
101113
}
102114

103-
impl<'a> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<'a> {
115+
impl<'a, Params> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<'a, Params>
116+
where
117+
Params: Choice<'a> + Encode,
118+
{
104119
type Error = Error;
105120

106121
fn try_from(bytes: &'a [u8]) -> Result<Self> {
107122
Ok(Self::from_der(bytes)?)
108123
}
109124
}
110125

111-
impl ValueOrd for SubjectPublicKeyInfo<'_> {
126+
impl<'a, Params> ValueOrd for SubjectPublicKeyInfo<'a, Params>
127+
where
128+
Params: Choice<'a> + DerOrd + Encode,
129+
{
112130
fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
113131
match self.algorithm.der_cmp(&other.algorithm)? {
114132
Ordering::Equal => self.bitstring()?.der_cmp(&other.bitstring()?),
@@ -119,26 +137,32 @@ impl ValueOrd for SubjectPublicKeyInfo<'_> {
119137

120138
#[cfg(feature = "alloc")]
121139
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
122-
impl TryFrom<SubjectPublicKeyInfo<'_>> for Document {
140+
impl<'a, Params> TryFrom<SubjectPublicKeyInfo<'a, Params>> for Document
141+
where
142+
Params: Choice<'a> + Encode,
143+
{
123144
type Error = Error;
124145

125-
fn try_from(spki: SubjectPublicKeyInfo<'_>) -> Result<Document> {
146+
fn try_from(spki: SubjectPublicKeyInfo<'a, Params>) -> Result<Document> {
126147
Self::try_from(&spki)
127148
}
128149
}
129150

130151
#[cfg(feature = "alloc")]
131152
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
132-
impl TryFrom<&SubjectPublicKeyInfo<'_>> for Document {
153+
impl<'a, Params> TryFrom<&SubjectPublicKeyInfo<'a, Params>> for Document
154+
where
155+
Params: Choice<'a> + Encode,
156+
{
133157
type Error = Error;
134158

135-
fn try_from(spki: &SubjectPublicKeyInfo<'_>) -> Result<Document> {
159+
fn try_from(spki: &SubjectPublicKeyInfo<'a, Params>) -> Result<Document> {
136160
Ok(Self::encode_msg(spki)?)
137161
}
138162
}
139163

140164
#[cfg(feature = "pem")]
141165
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
142-
impl PemLabel for SubjectPublicKeyInfo<'_> {
166+
impl<Params> PemLabel for SubjectPublicKeyInfo<'_, Params> {
143167
const PEM_LABEL: &'static str = "PUBLIC KEY";
144168
}

spki/src/traits.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Traits for encoding/decoding SPKI public keys.
22
3-
use crate::{Error, Result, SubjectPublicKeyInfo};
3+
use crate::{Error, Result, SubjectPublicKeyInfoRef};
44

55
#[cfg(feature = "alloc")]
66
use der::Document;
@@ -16,15 +16,15 @@ use std::path::Path;
1616

1717
/// Parse a public key object from an encoded SPKI document.
1818
pub trait DecodePublicKey:
19-
for<'a> TryFrom<SubjectPublicKeyInfo<'a>, Error = Error> + Sized
19+
for<'a> TryFrom<SubjectPublicKeyInfoRef<'a>, Error = Error> + Sized
2020
{
21-
/// Deserialize object from ASN.1 DER-encoded [`SubjectPublicKeyInfo`]
21+
/// Deserialize object from ASN.1 DER-encoded `SubjectPublicKeyInfo`
2222
/// (binary format).
2323
fn from_public_key_der(bytes: &[u8]) -> Result<Self> {
24-
Self::try_from(SubjectPublicKeyInfo::try_from(bytes)?)
24+
Self::try_from(SubjectPublicKeyInfoRef::try_from(bytes)?)
2525
}
2626

27-
/// Deserialize PEM-encoded [`SubjectPublicKeyInfo`].
27+
/// Deserialize PEM-encoded `SubjectPublicKeyInfo`.
2828
///
2929
/// Keys in this format begin with the following delimiter:
3030
///
@@ -35,7 +35,7 @@ pub trait DecodePublicKey:
3535
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
3636
fn from_public_key_pem(s: &str) -> Result<Self> {
3737
let (label, doc) = Document::from_pem(s)?;
38-
SubjectPublicKeyInfo::validate_pem_label(label)?;
38+
SubjectPublicKeyInfoRef::validate_pem_label(label)?;
3939
Self::from_public_key_der(doc.as_bytes())
4040
}
4141

@@ -53,7 +53,7 @@ pub trait DecodePublicKey:
5353
#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "std"))))]
5454
fn read_public_key_pem_file(path: impl AsRef<Path>) -> Result<Self> {
5555
let (label, doc) = Document::read_pem_file(path)?;
56-
SubjectPublicKeyInfo::validate_pem_label(&label)?;
56+
SubjectPublicKeyInfoRef::validate_pem_label(&label)?;
5757
Self::from_public_key_der(doc.as_bytes())
5858
}
5959
}
@@ -70,7 +70,7 @@ pub trait EncodePublicKey {
7070
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
7171
fn to_public_key_pem(&self, line_ending: LineEnding) -> Result<String> {
7272
let doc = self.to_public_key_der()?;
73-
Ok(doc.to_pem(SubjectPublicKeyInfo::PEM_LABEL, line_ending)?)
73+
Ok(doc.to_pem(SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?)
7474
}
7575

7676
/// Write ASN.1 DER-encoded public key to the given path
@@ -89,6 +89,6 @@ pub trait EncodePublicKey {
8989
line_ending: LineEnding,
9090
) -> Result<()> {
9191
let doc = self.to_public_key_der()?;
92-
Ok(doc.write_pem_file(path, SubjectPublicKeyInfo::PEM_LABEL, line_ending)?)
92+
Ok(doc.write_pem_file(path, SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?)
9393
}
9494
}

spki/tests/spki.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! `SubjectPublicKeyInfo` tests.
22
33
use hex_literal::hex;
4-
use spki::SubjectPublicKeyInfo;
4+
use spki::SubjectPublicKeyInfoRef;
55

66
#[cfg(feature = "alloc")]
77
use der::Encode;
@@ -46,7 +46,7 @@ const ED25519_SPKI_FINGERPRINT: &[u8] =
4646

4747
#[test]
4848
fn decode_ec_p256_der() {
49-
let spki = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
49+
let spki = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap();
5050

5151
assert_eq!(spki.algorithm.oid, "1.2.840.10045.2.1".parse().unwrap());
5252

@@ -62,7 +62,7 @@ fn decode_ec_p256_der() {
6262
#[cfg(feature = "fingerprint")]
6363
fn decode_ed25519_and_fingerprint_spki() {
6464
// Repeat the decode test from the pkcs8 crate
65-
let spki = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap();
65+
let spki = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap();
6666

6767
assert_eq!(spki.algorithm.oid, "1.3.101.112".parse().unwrap());
6868
assert_eq!(spki.algorithm.parameters, None);
@@ -82,7 +82,7 @@ fn decode_ed25519_and_fingerprint_spki() {
8282
#[cfg(all(feature = "fingerprint", feature = "alloc"))]
8383
fn decode_ed25519_and_fingerprint_base64() {
8484
// Repeat the decode test from the pkcs8 crate
85-
let spki = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap();
85+
let spki = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap();
8686

8787
assert_eq!(spki.algorithm.oid, "1.3.101.112".parse().unwrap());
8888
assert_eq!(spki.algorithm.parameters, None);
@@ -100,7 +100,7 @@ fn decode_ed25519_and_fingerprint_base64() {
100100

101101
#[test]
102102
fn decode_rsa_2048_der() {
103-
let spki = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
103+
let spki = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap();
104104

105105
assert_eq!(spki.algorithm.oid, "1.2.840.113549.1.1.1".parse().unwrap());
106106
assert!(spki.algorithm.parameters.unwrap().is_null());
@@ -110,47 +110,47 @@ fn decode_rsa_2048_der() {
110110
#[test]
111111
#[cfg(feature = "alloc")]
112112
fn encode_ec_p256_der() {
113-
let pk = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
113+
let pk = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap();
114114
let pk_encoded = pk.to_vec().unwrap();
115115
assert_eq!(EC_P256_DER_EXAMPLE, pk_encoded.as_slice());
116116
}
117117

118118
#[test]
119119
#[cfg(feature = "alloc")]
120120
fn encode_ed25519_der() {
121-
let pk = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap();
121+
let pk = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap();
122122
let pk_encoded = pk.to_vec().unwrap();
123123
assert_eq!(ED25519_DER_EXAMPLE, pk_encoded.as_slice());
124124
}
125125

126126
#[test]
127127
#[cfg(feature = "alloc")]
128128
fn encode_rsa_2048_der() {
129-
let pk = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
129+
let pk = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap();
130130
let pk_encoded = pk.to_vec().unwrap();
131131
assert_eq!(RSA_2048_DER_EXAMPLE, pk_encoded.as_slice());
132132
}
133133

134134
#[test]
135135
#[cfg(feature = "pem")]
136136
fn encode_ec_p256_pem() {
137-
let pk = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
137+
let pk = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap();
138138
let pk_encoded = pk.to_pem(LineEnding::LF).unwrap();
139139
assert_eq!(EC_P256_PEM_EXAMPLE, pk_encoded);
140140
}
141141

142142
#[test]
143143
#[cfg(feature = "pem")]
144144
fn encode_ed25519_pem() {
145-
let pk = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap();
145+
let pk = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap();
146146
let pk_encoded = pk.to_pem(LineEnding::LF).unwrap();
147147
assert_eq!(ED25519_PEM_EXAMPLE, pk_encoded);
148148
}
149149

150150
#[test]
151151
#[cfg(feature = "pem")]
152152
fn encode_rsa_2048_pem() {
153-
let pk = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
153+
let pk = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap();
154154
let pk_encoded = pk.to_pem(LineEnding::LF).unwrap();
155155
assert_eq!(RSA_2048_PEM_EXAMPLE, pk_encoded);
156156
}

spki/tests/traits.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![cfg(any(feature = "pem", feature = "std"))]
44

55
use der::{Decode, Encode};
6-
use spki::{DecodePublicKey, Document, EncodePublicKey, Error, Result, SubjectPublicKeyInfo};
6+
use spki::{DecodePublicKey, Document, EncodePublicKey, Error, Result, SubjectPublicKeyInfoRef};
77

88
#[cfg(feature = "pem")]
99
use spki::der::pem::LineEnding;
@@ -42,10 +42,10 @@ impl EncodePublicKey for MockKey {
4242
}
4343
}
4444

45-
impl TryFrom<SubjectPublicKeyInfo<'_>> for MockKey {
45+
impl TryFrom<SubjectPublicKeyInfoRef<'_>> for MockKey {
4646
type Error = Error;
4747

48-
fn try_from(spki: SubjectPublicKeyInfo<'_>) -> Result<MockKey> {
48+
fn try_from(spki: SubjectPublicKeyInfoRef<'_>) -> Result<MockKey> {
4949
Ok(MockKey(spki.to_vec()?))
5050
}
5151
}

x509-cert/src/anchor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{Certificate, TbsCertificate};
77
use der::asn1::{OctetStringRef, Utf8StringRef};
88
use der::{Choice, Enumerated, Sequence};
99
use flagset::{flags, FlagSet};
10-
use spki::SubjectPublicKeyInfo;
10+
use spki::SubjectPublicKeyInfoRef;
1111

1212
/// Version identifier for TrustAnchorInfo
1313
#[derive(Clone, Debug, Copy, PartialEq, Eq, Enumerated)]
@@ -45,7 +45,7 @@ pub struct TrustAnchorInfo<'a> {
4545
#[asn1(default = "Default::default")]
4646
pub version: Version,
4747

48-
pub pub_key: SubjectPublicKeyInfo<'a>,
48+
pub pub_key: SubjectPublicKeyInfoRef<'a>,
4949

5050
pub key_id: OctetStringRef<'a>,
5151

0 commit comments

Comments
 (0)