Skip to content

Commit 763cc8f

Browse files
committed
spki: make key param an attribute of spki
1 parent 1efe27a commit 763cc8f

File tree

5 files changed

+63
-34
lines changed

5 files changed

+63
-34
lines changed

der/src/asn1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mod videotex_string;
2727

2828
pub use self::{
2929
any::AnyRef,
30-
bit_string::{BitStringIter, BitStringRef},
30+
bit_string::{BitStringIter, BitStringLike, BitStringRef},
3131
choice::Choice,
3232
context_specific::{ContextSpecific, ContextSpecificRef},
3333
generalized_time::GeneralizedTime,

der/src/asn1/bit_string.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! ASN.1 `BIT STRING` support.
22
33
use crate::{
4-
asn1::AnyRef, ByteSlice, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header,
5-
Length, Reader, Result, Tag, ValueOrd, Writer,
4+
asn1::AnyRef, ByteSlice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind,
5+
FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer,
66
};
77
use core::{cmp::Ordering, iter::FusedIterator};
88

@@ -153,8 +153,8 @@ impl ValueOrd for BitStringRef<'_> {
153153
}
154154
}
155155

156-
impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
157-
fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
156+
impl<'a, 'k> From<&'k BitStringRef<'a>> for BitStringRef<'a> {
157+
fn from(value: &'k BitStringRef<'a>) -> BitStringRef<'a> {
158158
*value
159159
}
160160
}
@@ -441,6 +441,19 @@ where
441441
}
442442
}
443443

444+
/// Trait used as a marker to ensure the type can hold the content of a Bit String
445+
pub trait BitStringLike<'pointer, 'slice: 'pointer>
446+
where
447+
Self: Decode<'slice> + Encode + FixedTag + 'pointer,
448+
BitStringRef<'slice>: From<&'pointer Self>,
449+
{
450+
}
451+
452+
impl<'slice: 'pointer, 'pointer> BitStringLike<'pointer, 'slice> for BitStringRef<'slice> {}
453+
454+
#[cfg(feature = "alloc")]
455+
impl<'a> BitStringLike<'a, 'a> for BitString {}
456+
444457
#[cfg(test)]
445458
mod tests {
446459
use super::{BitStringRef, Result, Tag};

pkcs1/src/traits.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use {
1818
#[cfg(feature = "pkcs8")]
1919
use {
2020
crate::{ALGORITHM_ID, ALGORITHM_OID},
21-
der::asn1::BitString,
21+
der::asn1::BitStringRef,
2222
};
2323

2424
#[cfg(feature = "std")]
@@ -188,7 +188,7 @@ impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T {
188188
fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> {
189189
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfoRef {
190190
algorithm: ALGORITHM_ID,
191-
subject_public_key: BitString::from_bytes(public_key)?,
191+
subject_public_key: BitStringRef::from_bytes(public_key)?,
192192
})?)
193193
}
194194
}

spki/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ pub use crate::{
4949
pub use der::{self, asn1::ObjectIdentifier};
5050

5151
#[cfg(feature = "alloc")]
52-
pub use {crate::traits::EncodePublicKey, der::Document};
52+
pub use {
53+
crate::{spki::SubjectPublicKeyInfoOwned, traits::EncodePublicKey},
54+
der::Document,
55+
};
5356

5457
#[cfg(feature = "fingerprint")]
5558
pub use crate::fingerprint::FingerprintBytes;

spki/src/spki.rs

+39-26
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
use crate::{AlgorithmIdentifier, Error, Result};
44
use core::cmp::Ordering;
55
use der::{
6-
asn1::{AnyRef, BitString, BitStringRef},
6+
asn1::{AnyRef, BitStringLike, BitStringRef},
77
Choice, Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd,
88
};
99

1010
#[cfg(feature = "alloc")]
11-
use der::Document;
11+
use der::{
12+
asn1::{Any, BitString},
13+
Document,
14+
};
1215

1316
#[cfg(feature = "fingerprint")]
1417
use crate::{fingerprint, FingerprintBytes};
@@ -22,8 +25,12 @@ use {
2225
#[cfg(feature = "pem")]
2326
use der::pem::PemLabel;
2427

25-
/// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters.
26-
pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo<AnyRef<'a>>;
28+
/// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters, and [`BitStringRef`] params.
29+
pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo<AnyRef<'a>, BitStringRef<'a>>;
30+
31+
/// [`SubjectPublicKeyInfo`] with [`Any`] algorithm parameters, and [`BitString`] params.
32+
#[cfg(feature = "alloc")]
33+
pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo<Any, BitString>;
2734

2835
/// X.509 `SubjectPublicKeyInfo` (SPKI) as defined in [RFC 5280 § 4.1.2.7].
2936
///
@@ -38,24 +45,19 @@ pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo<AnyRef<'a>>;
3845
///
3946
/// [RFC 5280 § 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7
4047
#[derive(Clone, Debug, Eq, PartialEq)]
41-
pub struct SubjectPublicKeyInfo<Params> {
48+
pub struct SubjectPublicKeyInfo<Params, Key> {
4249
/// X.509 [`AlgorithmIdentifier`] for the public key type
4350
pub algorithm: AlgorithmIdentifier<Params>,
4451

4552
/// Public key data
46-
pub subject_public_key: BitString,
47-
}
48-
49-
impl<Params> SubjectPublicKeyInfo<Params> {
50-
/// Get a [`BitString`] representing the `subject_public_key`
51-
fn bitstring(&self) -> BitStringRef<'_> {
52-
BitStringRef::from(&self.subject_public_key)
53-
}
53+
pub subject_public_key: Key,
5454
}
5555

56-
impl<'a, Params> SubjectPublicKeyInfo<Params>
56+
impl<'a: 'k, 'k, Params, Key: 'k> SubjectPublicKeyInfo<Params, Key>
5757
where
5858
Params: Choice<'a> + Encode,
59+
Key: BitStringLike<'k, 'a>,
60+
BitStringRef<'a>: From<&'k Key>,
5961
{
6062
/// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and
6163
/// encode it as a Base64 string.
@@ -84,35 +86,41 @@ where
8486
}
8587
}
8688

87-
impl<'a, Params> DecodeValue<'a> for SubjectPublicKeyInfo<Params>
89+
impl<'a: 'k, 'k, Params, Key: 'k> DecodeValue<'a> for SubjectPublicKeyInfo<Params, Key>
8890
where
8991
Params: Choice<'a> + Encode,
92+
Key: Decode<'a>,
93+
BitStringRef<'a>: From<&'k Key>,
9094
{
9195
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
9296
reader.read_nested(header.length, |reader| {
9397
Ok(Self {
9498
algorithm: reader.decode()?,
95-
subject_public_key: BitString::decode(reader)?,
99+
subject_public_key: Key::decode(reader)?,
96100
})
97101
})
98102
}
99103
}
100104

101-
impl<'a, Params> Sequence<'a> for SubjectPublicKeyInfo<Params>
105+
impl<'a: 'k, 'k, Params, Key: 'k> Sequence<'a> for SubjectPublicKeyInfo<Params, Key>
102106
where
103107
Params: Choice<'a> + Encode,
108+
Key: BitStringLike<'k, 'a>,
109+
BitStringRef<'a>: From<&'k Key>,
104110
{
105111
fn fields<F, T>(&self, f: F) -> der::Result<T>
106112
where
107113
F: FnOnce(&[&dyn Encode]) -> der::Result<T>,
108114
{
109-
f(&[&self.algorithm, &self.bitstring()])
115+
f(&[&self.algorithm, &self.subject_public_key])
110116
}
111117
}
112118

113-
impl<'a, Params> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<Params>
119+
impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<Params, Key>
114120
where
115121
Params: Choice<'a> + Encode,
122+
Key: BitStringLike<'k, 'a>,
123+
BitStringRef<'a>: From<&'k Key>,
116124
{
117125
type Error = Error;
118126

@@ -121,46 +129,51 @@ where
121129
}
122130
}
123131

124-
impl<'a, Params> ValueOrd for SubjectPublicKeyInfo<Params>
132+
impl<'a, Params, Key> ValueOrd for SubjectPublicKeyInfo<Params, Key>
125133
where
126134
Params: Choice<'a> + DerOrd + Encode,
135+
Key: ValueOrd,
127136
{
128137
fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
129138
match self.algorithm.der_cmp(&other.algorithm)? {
130-
Ordering::Equal => self.bitstring().der_cmp(&other.bitstring()),
139+
Ordering::Equal => self.subject_public_key.value_cmp(&other.subject_public_key),
131140
other => Ok(other),
132141
}
133142
}
134143
}
135144

136145
#[cfg(feature = "alloc")]
137146
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
138-
impl<'a, Params> TryFrom<SubjectPublicKeyInfo<Params>> for Document
147+
impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<SubjectPublicKeyInfo<Params, Key>> for Document
139148
where
140149
Params: Choice<'a> + Encode,
150+
Key: BitStringLike<'k, 'a>,
151+
BitStringRef<'a>: From<&'k Key>,
141152
{
142153
type Error = Error;
143154

144-
fn try_from(spki: SubjectPublicKeyInfo<Params>) -> Result<Document> {
155+
fn try_from(spki: SubjectPublicKeyInfo<Params, Key>) -> Result<Document> {
145156
Self::try_from(&spki)
146157
}
147158
}
148159

149160
#[cfg(feature = "alloc")]
150161
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
151-
impl<'a, Params> TryFrom<&SubjectPublicKeyInfo<Params>> for Document
162+
impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&SubjectPublicKeyInfo<Params, Key>> for Document
152163
where
153164
Params: Choice<'a> + Encode,
165+
Key: BitStringLike<'k, 'a>,
166+
BitStringRef<'a>: From<&'k Key>,
154167
{
155168
type Error = Error;
156169

157-
fn try_from(spki: &SubjectPublicKeyInfo<Params>) -> Result<Document> {
170+
fn try_from(spki: &SubjectPublicKeyInfo<Params, Key>) -> Result<Document> {
158171
Ok(Self::encode_msg(spki)?)
159172
}
160173
}
161174

162175
#[cfg(feature = "pem")]
163176
#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
164-
impl<Params> PemLabel for SubjectPublicKeyInfo<Params> {
177+
impl<Params, Key> PemLabel for SubjectPublicKeyInfo<Params, Key> {
165178
const PEM_LABEL: &'static str = "PUBLIC KEY";
166179
}

0 commit comments

Comments
 (0)