Skip to content

Commit 4e2a5ee

Browse files
authored
der: eliminate dynamism from encoding (#828)
Replaces use of `dyn Writer` with `impl Writer`. Removes the `Sequence::fields` method, which was used for a blanket impl of `EncodeValue`. Instead, very small changes to the custom derive can be used to derive a monomorphic implementation of `EncodeValue` that doesn't rely on trait objects, where calls to the `Writer` can be potentially inlined.
1 parent cb984ed commit 4e2a5ee

Some content is hidden

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

64 files changed

+704
-570
lines changed

der/LICENSE-MIT

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2020-2022 The RustCrypto Project Developers
1+
Copyright (c) 2020-2023 The RustCrypto Project Developers
22

33
Permission is hereby granted, free of charge, to any
44
person obtaining a copy of this software and associated

der/derive/src/choice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl DeriveChoice {
108108
}
109109

110110
impl<#lt_params> ::der::EncodeValue for #ident<#lt_params> {
111-
fn encode_value(&self, encoder: &mut dyn ::der::Writer) -> ::der::Result<()> {
111+
fn encode_value(&self, encoder: &mut impl ::der::Writer) -> ::der::Result<()> {
112112
match self {
113113
#(#encode_body)*
114114
}

der/derive/src/enumerated.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl DeriveEnumerated {
130130
::der::EncodeValue::value_len(&(*self as #repr))
131131
}
132132

133-
fn encode_value(&self, encoder: &mut dyn ::der::Writer) -> ::der::Result<()> {
133+
fn encode_value(&self, encoder: &mut impl ::der::Writer) -> ::der::Result<()> {
134134
::der::EncodeValue::encode_value(&(*self as #repr), encoder)
135135
}
136136
}

der/derive/src/sequence.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,16 @@ impl DeriveSequence {
7474

7575
let mut decode_body = Vec::new();
7676
let mut decode_result = Vec::new();
77-
let mut encode_body = Vec::new();
77+
let mut encoded_lengths = Vec::new();
78+
let mut encode_fields = Vec::new();
7879

7980
for field in &self.fields {
8081
decode_body.push(field.to_decode_tokens());
8182
decode_result.push(&field.ident);
82-
encode_body.push(field.to_encode_tokens());
83+
84+
let field = field.to_encode_tokens();
85+
encoded_lengths.push(quote!(#field.encoded_len()?));
86+
encode_fields.push(quote!(#field.encode(writer)?;));
8387
}
8488

8589
quote! {
@@ -100,16 +104,25 @@ impl DeriveSequence {
100104
}
101105
}
102106

103-
impl<#lifetime> ::der::Sequence<#lifetime> for #ident<#lt_params> {
104-
fn fields<F, T>(&self, f: F) -> ::der::Result<T>
105-
where
106-
F: FnOnce(&[&dyn der::Encode]) -> ::der::Result<T>,
107-
{
108-
f(&[
109-
#(#encode_body),*
110-
])
107+
impl<#lifetime> ::der::EncodeValue for #ident<#lt_params> {
108+
fn value_len(&self) -> ::der::Result<::der::Length> {
109+
use ::der::Encode as _;
110+
111+
[
112+
#(#encoded_lengths),*
113+
]
114+
.into_iter()
115+
.try_fold(::der::Length::ZERO, |acc, len| acc + len)
116+
}
117+
118+
fn encode_value(&self, writer: &mut impl ::der::Writer) -> ::der::Result<()> {
119+
use ::der::Encode as _;
120+
#(#encode_fields)*
121+
Ok(())
111122
}
112123
}
124+
125+
impl<#lifetime> ::der::Sequence<#lifetime> for #ident<#lt_params> {}
113126
}
114127
}
115128
}

der/derive/src/sequence/field.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,7 @@ impl LowerFieldEncoder {
167167

168168
/// the field encoder to tokens.
169169
fn into_tokens(self) -> TokenStream {
170-
let encoder = self.encoder;
171-
quote! { &#encoder }
170+
self.encoder
172171
}
173172

174173
/// Apply the ASN.1 type (if defined).
@@ -295,7 +294,7 @@ mod tests {
295294
assert_eq!(
296295
field.to_encode_tokens().to_string(),
297296
quote! {
298-
&self.example_field
297+
self.example_field
299298
}
300299
.to_string()
301300
);
@@ -346,7 +345,7 @@ mod tests {
346345
assert_eq!(
347346
field.to_encode_tokens().to_string(),
348347
quote! {
349-
&::der::asn1::ContextSpecificRef {
348+
::der::asn1::ContextSpecificRef {
350349
tag_number: ::der::TagNumber::N0,
351350
tag_mode: ::der::TagMode::Implicit,
352351
value: &self.implicit_field,

der/src/asn1/any.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
use core::cmp::Ordering;
99

1010
#[cfg(feature = "alloc")]
11-
use crate::BytesOwned;
11+
use {crate::BytesOwned, alloc::boxed::Box};
1212

1313
#[cfg(feature = "oid")]
1414
use crate::asn1::ObjectIdentifier;
@@ -147,7 +147,12 @@ impl<'a> Choice<'a> for AnyRef<'a> {
147147
impl<'a> Decode<'a> for AnyRef<'a> {
148148
fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
149149
let header = Header::decode(reader)?;
150+
Self::decode_value(reader, header)
151+
}
152+
}
150153

154+
impl<'a> DecodeValue<'a> for AnyRef<'a> {
155+
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
151156
Ok(Self {
152157
tag: header.tag,
153158
value: BytesRef::decode_value(reader, header)?,
@@ -160,7 +165,7 @@ impl EncodeValue for AnyRef<'_> {
160165
Ok(self.value.len())
161166
}
162167

163-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
168+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
164169
writer.write(self.value())
165170
}
166171
}
@@ -217,7 +222,7 @@ pub struct Any {
217222
#[cfg(feature = "alloc")]
218223
impl Any {
219224
/// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
220-
pub fn new(tag: Tag, bytes: &[u8]) -> Result<Self> {
225+
pub fn new(tag: Tag, bytes: impl Into<Box<[u8]>>) -> Result<Self> {
221226
let value = BytesOwned::new(bytes)?;
222227

223228
// Ensure the tag and value are a valid `AnyRef`.
@@ -253,8 +258,15 @@ impl Choice<'_> for Any {
253258
impl<'a> Decode<'a> for Any {
254259
fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
255260
let header = Header::decode(reader)?;
261+
Self::decode_value(reader, header)
262+
}
263+
}
264+
265+
#[cfg(feature = "alloc")]
266+
impl<'a> DecodeValue<'a> for Any {
267+
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
256268
let value = reader.read_vec(header.length)?;
257-
Self::new(header.tag, &value)
269+
Self::new(header.tag, value)
258270
}
259271
}
260272

@@ -264,7 +276,7 @@ impl EncodeValue for Any {
264276
Ok(self.value.len())
265277
}
266278

267-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
279+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
268280
writer.write(self.value.as_slice())
269281
}
270282
}

der/src/asn1/bit_string.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl EncodeValue for BitStringRef<'_> {
138138
self.byte_len() + Length::ONE
139139
}
140140

141-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
141+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
142142
writer.write_byte(self.unused_bits)?;
143143
writer.write(self.raw_bytes())
144144
}
@@ -325,7 +325,7 @@ impl EncodeValue for BitString {
325325
Length::ONE + Length::try_from(self.inner.len())?
326326
}
327327

328-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
328+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
329329
writer.write_byte(self.unused_bits)?;
330330
writer.write(&self.inner)
331331
}
@@ -504,7 +504,7 @@ where
504504
BitStringRef::new((lead % 8) as u8, buff)?.value_len()
505505
}
506506

507-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
507+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
508508
let (lead, buff) = encode_flagset(self);
509509
let buff = &buff[..buff.len() - lead / 8];
510510
BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)

der/src/asn1/boolean.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl EncodeValue for bool {
3333
Ok(Length::ONE)
3434
}
3535

36-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
36+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
3737
writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
3838
}
3939
}

der/src/asn1/context_specific.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ where
145145
}
146146
}
147147

148-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
148+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
149149
match self.tag_mode {
150150
TagMode::Explicit => self.value.encode(writer),
151151
TagMode::Implicit => self.value.encode_value(writer),
@@ -239,7 +239,7 @@ where
239239
self.encoder().value_len()
240240
}
241241

242-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
242+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
243243
self.encoder().encode_value(writer)
244244
}
245245
}

der/src/asn1/generalized_time.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl EncodeValue for GeneralizedTime {
113113
Self::LENGTH.try_into()
114114
}
115115

116-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
116+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
117117
let year_hi = u8::try_from(self.0.year() / 100)?;
118118
let year_lo = u8::try_from(self.0.year() % 100)?;
119119

@@ -183,7 +183,7 @@ impl EncodeValue for DateTime {
183183
GeneralizedTime::from(self).value_len()
184184
}
185185

186-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
186+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
187187
GeneralizedTime::from(self).encode_value(writer)
188188
}
189189
}
@@ -209,7 +209,7 @@ impl EncodeValue for SystemTime {
209209
GeneralizedTime::try_from(self)?.value_len()
210210
}
211211

212-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
212+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
213213
GeneralizedTime::try_from(self)?.encode_value(writer)
214214
}
215215
}
@@ -285,7 +285,7 @@ impl EncodeValue for PrimitiveDateTime {
285285
GeneralizedTime::try_from(self)?.value_len()
286286
}
287287

288-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
288+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
289289
GeneralizedTime::try_from(self)?.encode_value(writer)
290290
}
291291
}

der/src/asn1/integer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ macro_rules! impl_int_encoding {
4242
}
4343
}
4444

45-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
45+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
4646
if *self < 0 {
4747
int::encode_bytes(writer, &(*self as $uint).to_be_bytes())
4848
} else {
@@ -94,7 +94,7 @@ macro_rules! impl_uint_encoding {
9494
uint::encoded_len(&self.to_be_bytes())
9595
}
9696

97-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
97+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
9898
uint::encode_bytes(writer, &self.to_be_bytes())
9999
}
100100
}

der/src/asn1/integer/bigint.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<'a> EncodeValue for IntRef<'a> {
6464
int::encoded_len(self.inner.as_slice())
6565
}
6666

67-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
67+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
6868
writer.write(self.as_bytes())
6969
}
7070
}
@@ -147,7 +147,7 @@ impl<'a> EncodeValue for UintRef<'a> {
147147
uint::encoded_len(self.inner.as_slice())
148148
}
149149

150-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
150+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
151151
// Add leading `0x00` byte if required
152152
if self.value_len()? > self.len() {
153153
writer.write_byte(0)?;
@@ -249,7 +249,7 @@ mod allocating {
249249
int::encoded_len(self.inner.as_slice())
250250
}
251251

252-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
252+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
253253
writer.write(self.as_bytes())
254254
}
255255
}
@@ -351,7 +351,7 @@ mod allocating {
351351
uint::encoded_len(self.inner.as_slice())
352352
}
353353

354-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
354+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
355355
// Add leading `0x00` byte if required
356356
if self.value_len()? > self.len() {
357357
writer.write_byte(0)?;

der/src/asn1/internal_macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ macro_rules! impl_string_type {
3535
self.inner.value_len()
3636
}
3737

38-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
38+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
3939
self.inner.encode_value(writer)
4040
}
4141
}

der/src/asn1/null.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl EncodeValue for Null {
2424
Ok(Length::ZERO)
2525
}
2626

27-
fn encode_value(&self, _writer: &mut dyn Writer) -> Result<()> {
27+
fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
2828
Ok(())
2929
}
3030
}
@@ -75,7 +75,7 @@ impl EncodeValue for () {
7575
Ok(Length::ZERO)
7676
}
7777

78-
fn encode_value(&self, _writer: &mut dyn Writer) -> Result<()> {
78+
fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
7979
Ok(())
8080
}
8181
}

der/src/asn1/octet_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl EncodeValue for OctetStringRef<'_> {
6666
self.inner.value_len()
6767
}
6868

69-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
69+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
7070
self.inner.encode_value(writer)
7171
}
7272
}
@@ -165,7 +165,7 @@ impl EncodeValue for OctetString {
165165
self.inner.len().try_into()
166166
}
167167

168-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
168+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
169169
writer.write(&self.inner)
170170
}
171171
}

der/src/asn1/oid.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl EncodeValue for ObjectIdentifier {
2424
Length::try_from(self.as_bytes().len())
2525
}
2626

27-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
27+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
2828
writer.write(self.as_bytes())
2929
}
3030
}

der/src/asn1/optional.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ where
4141
(&self).encoded_len()
4242
}
4343

44-
fn encode(&self, writer: &mut dyn Writer) -> Result<()> {
44+
fn encode(&self, writer: &mut impl Writer) -> Result<()> {
4545
(&self).encode(writer)
4646
}
4747
}
@@ -57,7 +57,7 @@ where
5757
}
5858
}
5959

60-
fn encode(&self, encoder: &mut dyn Writer) -> Result<()> {
60+
fn encode(&self, encoder: &mut impl Writer) -> Result<()> {
6161
match self {
6262
Some(encodable) => encodable.encode(encoder),
6363
None => Ok(()),

der/src/asn1/real.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl EncodeValue for f64 {
120120
}
121121
}
122122

123-
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
123+
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
124124
// Check if special value
125125
// Encode zero first, if it's zero
126126
// Special value from section 8.5.9 if non zero

0 commit comments

Comments
 (0)