Skip to content

Commit aef9dbb

Browse files
committed
[pkcs8] Added: Coercion to SetOf for encoding
1 parent bb910a2 commit aef9dbb

File tree

4 files changed

+86
-26
lines changed

4 files changed

+86
-26
lines changed

Cargo.lock

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

der/src/asn1/set_of.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![cfg(any(feature = "alloc", feature = "heapless"))]
1212

1313
use crate::{
14-
ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind, FixedTag, Header,
14+
Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind, FixedTag, Header,
1515
Length, Reader, SliceReader, Tag, ValueOrd, Writer, ord::iter_cmp,
1616
ord::iter_cmp_owned,
1717
};
@@ -49,7 +49,7 @@ enum InnerRef<'a, T> {
4949
///
5050
/// This type implements a viewer in a `SET OF` type
5151
/// and does not depend on `alloc` support.
52-
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
52+
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
5353
pub struct SetOfRef<'a, T>
5454
where
5555
T: DerOrd,
@@ -174,6 +174,7 @@ where
174174
}
175175

176176
/// Get the nth element from this [`SetOfRef`].
177+
#[must_use]
177178
pub fn get(&self, index: usize) -> Option<T>
178179
where
179180
T: Decode<'a> + 'a,
@@ -183,6 +184,7 @@ where
183184
}
184185

185186
/// Iterate over the elements of this [`SetOfRef`].
187+
#[must_use]
186188
pub fn iter(&self) -> SetOfRefIter<'a, T>
187189
where
188190
T: Decode<'a> + 'a,
@@ -211,6 +213,7 @@ where
211213
}
212214

213215
/// Is this [`SetOfRef`] empty?
216+
#[must_use]
214217
pub fn is_empty(&self) -> bool {
215218
match self.inner {
216219
InnerRef::BytesRef(inner) => inner.is_empty(),
@@ -219,6 +222,7 @@ where
219222
}
220223

221224
/// Number of elements in this [`SetOfRef`].
225+
#[must_use]
222226
pub fn len(&self) -> usize
223227
where
224228
T: Decode<'a> + 'a,
@@ -367,6 +371,15 @@ where
367371
}
368372
}
369373

374+
impl<'a, T> From<&SetOfRef<'a, T>> for SetOfRef<'a, T>
375+
where
376+
T: Clone + DerOrd,
377+
{
378+
fn from(value: &SetOfRef<'a, T>) -> SetOfRef<'a, T> {
379+
value.clone()
380+
}
381+
}
382+
370383
#[cfg(feature = "heapless")]
371384
impl<T, const N: usize> ValueOrd for SetOf<T, N>
372385
where
@@ -799,8 +812,7 @@ mod allocating {
799812
T: Encode,
800813
T: DerOrd,
801814
{
802-
type Borrowed<'a>
803-
= SetOfRef<'a, T>
815+
type Borrowed<'a> = SetOfRef<'a, T>
804816
where
805817
T: 'a;
806818

@@ -813,12 +825,14 @@ mod allocating {
813825
#[cfg(test)]
814826
#[allow(clippy::unwrap_used)]
815827
mod tests {
816-
use super::SetOfRef;
828+
817829
#[cfg(feature = "alloc")]
818830
use super::SetOfVec;
819831
use crate::ErrorKind;
820832
#[cfg(feature = "heapless")]
821-
use {super::SetOf, crate::DerOrd};
833+
use {super::SetOf};
834+
#[cfg(any(feature = "alloc", feature = "heapless"))]
835+
use {super::SetOfRef, crate::DerOrd};
822836

823837
#[cfg(feature = "heapless")]
824838
#[test]
@@ -891,8 +905,8 @@ mod tests {
891905

892906
let arr1 = [0u16, 1, 2, 3, 5];
893907
let arr2 = [0u16, 1, 2, 3, 4];
894-
let set1 = SetOf::try_from(arr1).unwrap();
895-
let set2 = SetOf::try_from(arr2).unwrap();
908+
let set1 = SetOfRef::try_from(arr1.as_ref()).unwrap();
909+
let set2 = SetOfRef::try_from(arr2.as_ref()).unwrap();
896910
assert_eq!(set1.der_cmp(&set2), Ok(Ordering::Greater));
897911
}
898912

pkcs8/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ edition = "2024"
1717
rust-version = "1.85"
1818

1919
[dependencies]
20-
der = { git = "https://github.com/kraemv/formats", features = ["oid"] }
20+
der = { git = "https://github.com/kraemv/formats", features = ["heapless", "oid"] }
2121
spki = { git = "https://github.com/kraemv/formats" }
2222
x509-cert = { git = "https://github.com/kraemv/formats", default-features = false }
2323

pkcs8/src/private_key_info.rs

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
use crate::{Error, Result, Version};
44
use core::fmt;
55
use der::{
6-
Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, TagMode,
7-
TagNumber, Writer,
8-
asn1::{AnyRef, BitStringRef, ContextSpecific, OctetStringRef, SetOfRef},
6+
Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, TagMode, TagNumber, Writer, asn1::{AnyRef, BitStringRef, ContextSpecific, OctetStringRef, SetOf, SetOfRef}
97
};
108
use spki::AlgorithmIdentifier;
119
use x509_cert::attr::Attribute;
@@ -143,7 +141,7 @@ where
143141
PubKey: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
144142
PubKey: BitStringLike,
145143
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
146-
Attr: EncodeValue,
144+
Attr: SetOfLike<'a>,
147145
{
148146
/// Encrypt this private key using a symmetric encryption key derived
149147
/// from the provided password.
@@ -195,6 +193,25 @@ where
195193
}
196194
}
197195

196+
197+
impl<'a, Params, Key, PubKey, Attr> PrivateKeyInfo<Params, Key, PubKey, Attr>
198+
where
199+
Params: der::Choice<'a> + Encode,
200+
Attr: SetOfLike<'a>,
201+
{
202+
/// Get a `SET OF` representation of the attributes, if present.
203+
fn attributes_string(&self) -> Option<ContextSpecific<SetOfRef<'a, Attr::Item>>> {
204+
self.attributes.as_ref().map(|attributes| {
205+
let value = attributes.as_set_of();
206+
ContextSpecific {
207+
tag_number: ATTRIBUTES_TAG,
208+
tag_mode: TagMode::Implicit,
209+
value,
210+
}
211+
})
212+
}
213+
}
214+
198215
impl<'a, Params, Key, PubKey, Attr> DecodeValue<'a> for PrivateKeyInfo<Params, Key, PubKey, Attr>
199216
where
200217
Params: der::Choice<'a, Error = der::Error> + Encode,
@@ -243,21 +260,22 @@ where
243260
Params: der::Choice<'a, Error = der::Error> + Encode,
244261
Key: EncodeValue + FixedTag,
245262
PubKey: BitStringLike,
246-
Attr: EncodeValue + FixedTag,
263+
Attr: SetOfLike<'a>,
264+
Attr::Item: Clone + Decode<'a> + DerOrd + Encode,
247265
{
248266
fn value_len(&self) -> der::Result<Length> {
249267
self.version().encoded_len()?
250268
+ self.algorithm.encoded_len()?
251269
+ self.private_key.encoded_len()?
252-
+ self.attributes.encoded_len()?
270+
+ self.attributes_string().encoded_len()?
253271
+ self.public_key_bit_string().encoded_len()?
254272
}
255273

256274
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
257275
self.version().encode(writer)?;
258276
self.algorithm.encode(writer)?;
259277
self.private_key.encode(writer)?;
260-
self.attributes.encode(writer)?;
278+
self.attributes_string().encode(writer)?;
261279
self.public_key_bit_string().encode(writer)?;
262280
Ok(())
263281
}
@@ -270,8 +288,8 @@ where
270288
Key: EncodeValue,
271289
PubKey: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
272290
PubKey: BitStringLike,
273-
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
274-
Attr: EncodeValue,
291+
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + SetOfLike<'a> + 'a,
292+
Attr::Item: Clone + Decode<'a> + DerOrd + Encode,
275293
{
276294
}
277295

@@ -282,8 +300,8 @@ where
282300
Key: EncodeValue,
283301
PubKey: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
284302
PubKey: BitStringLike,
285-
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
286-
Attr: EncodeValue,
303+
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + SetOfLike<'a> + 'a,
304+
Attr::Item: Clone + Decode<'a> + DerOrd + Encode,
287305
{
288306
type Error = Error;
289307

@@ -317,8 +335,8 @@ where
317335
Key: EncodeValue,
318336
PubKey: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
319337
PubKey: BitStringLike,
320-
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
321-
Attr: EncodeValue,
338+
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + SetOfLike<'a> + 'a,
339+
Attr::Item: Clone + Decode<'a> + DerOrd + Encode,
322340
{
323341
type Error = Error;
324342

@@ -336,8 +354,8 @@ where
336354
Key: EncodeValue,
337355
PubKey: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
338356
PubKey: BitStringLike,
339-
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + 'a,
340-
Attr: EncodeValue,
357+
Attr: DecodeValue<'a, Error = der::Error> + FixedTag + SetOfLike<'a> + 'a,
358+
Attr::Item: Clone + Decode<'a> + DerOrd + Encode,
341359
{
342360
type Error = Error;
343361

@@ -390,9 +408,8 @@ where
390408
}
391409

392410
/// [`PrivateKeyInfo`] with [`AnyRef`] algorithm parameters, and `&[u8]` key.
393-
// pub type PrivateKeyInfoRef<'a> = PrivateKeyInfo<AnyRef<'a>, &'a OctetStringRef, BitStringRef<'a>, &'a[&'a Attribute]>; // Consider attr and value here
394411
pub type PrivateKeyInfoRef<'a> =
395-
PrivateKeyInfo<AnyRef<'a>, &'a OctetStringRef, BitStringRef<'a>, SetOfRef<'a, Attribute>>; // Consider attr and value here
412+
PrivateKeyInfo<AnyRef<'a>, &'a OctetStringRef, BitStringRef<'a>, SetOfRef<'a, Attribute>>;
396413

397414
/// [`PrivateKeyInfo`] with [`Any`] algorithm parameters, and `Box<[u8]>` key.
398415
#[cfg(feature = "alloc")]
@@ -411,6 +428,23 @@ impl BitStringLike for BitStringRef<'_> {
411428
}
412429
}
413430

431+
pub trait SetOfLike <'a>
432+
{
433+
type Item: Clone + DerOrd + Encode;
434+
fn as_set_of(&self) -> SetOfRef<'a, Self::Item>;
435+
}
436+
437+
impl<'a, T> SetOfLike<'a> for SetOfRef<'a, T>
438+
where
439+
T: Clone + DerOrd + Encode,
440+
{
441+
type Item = T;
442+
443+
fn as_set_of(&self) -> SetOfRef<'a, T> {
444+
SetOfRef::from(self)
445+
}
446+
}
447+
414448
#[cfg(feature = "alloc")]
415449
mod allocating {
416450
use super::*;
@@ -424,6 +458,17 @@ mod allocating {
424458
}
425459
}
426460

461+
impl<'a, T> SetOfLike<'a> for &'a SetOfVec<T>
462+
where
463+
T: Clone + DerOrd + Encode + 'a,
464+
{
465+
type Item = T;
466+
467+
fn as_set_of(&self) -> SetOfRef<'a, T> {
468+
self.owned_to_ref()
469+
}
470+
}
471+
427472
impl<'a> RefToOwned<'a> for PrivateKeyInfoRef<'a> {
428473
type Owned = PrivateKeyInfoOwned;
429474
fn ref_to_owned(&self) -> Self::Owned {

0 commit comments

Comments
 (0)