Skip to content

Commit 4e2266e

Browse files
authored
der: remove inherent AnyRef decoding methods (#829)
Also renames `decode_into` -> `decode_as` Removes almost all inherent methods for inherent ASN.1 types like `AnyRef::oid` and `AnyRef::octet_string`. `Any::sequence` is retained. Replaces them with `Any::decode_as<T>`. This simplifies the API by pushing things through the more flexible generic type-based API.
1 parent 4e2a5ee commit 4e2266e

20 files changed

+63
-94
lines changed

der/src/asn1/any.rs

+20-65
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
//! ASN.1 `ANY` type.
2+
23
#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
34

45
use crate::{
5-
asn1::*, BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind,
6-
FixedTag, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
6+
BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length,
7+
Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
78
};
89
use core::cmp::Ordering;
910

1011
#[cfg(feature = "alloc")]
1112
use {crate::BytesOwned, alloc::boxed::Box};
1213

13-
#[cfg(feature = "oid")]
14-
use crate::asn1::ObjectIdentifier;
15-
1614
/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
1715
///
1816
/// This is a zero-copy reference type which borrows from the input data.
@@ -58,11 +56,14 @@ impl<'a> AnyRef<'a> {
5856
}
5957

6058
/// Attempt to decode this [`AnyRef`] type into the inner value.
61-
pub fn decode_into<T>(self) -> Result<T>
59+
pub fn decode_as<T>(self) -> Result<T>
6260
where
63-
T: DecodeValue<'a> + FixedTag,
61+
T: Choice<'a> + DecodeValue<'a>,
6462
{
65-
self.tag.assert_eq(T::TAG)?;
63+
if !T::can_decode(self.tag) {
64+
return Err(self.tag.unexpected_error(None));
65+
}
66+
6667
let header = Header {
6768
tag: self.tag,
6869
length: self.value.len(),
@@ -78,48 +79,6 @@ impl<'a> AnyRef<'a> {
7879
self == Self::NULL
7980
}
8081

81-
/// Attempt to decode an ASN.1 `BIT STRING`.
82-
pub fn bit_string(self) -> Result<BitStringRef<'a>> {
83-
self.try_into()
84-
}
85-
86-
/// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field.
87-
pub fn context_specific<T>(self) -> Result<ContextSpecific<T>>
88-
where
89-
T: Decode<'a>,
90-
{
91-
self.try_into()
92-
}
93-
94-
/// Attempt to decode an ASN.1 `GeneralizedTime`.
95-
pub fn generalized_time(self) -> Result<GeneralizedTime> {
96-
self.try_into()
97-
}
98-
99-
/// Attempt to decode an ASN.1 `OCTET STRING`.
100-
pub fn octet_string(self) -> Result<OctetStringRef<'a>> {
101-
self.try_into()
102-
}
103-
104-
/// Attempt to decode an ASN.1 `OBJECT IDENTIFIER`.
105-
#[cfg(feature = "oid")]
106-
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
107-
pub fn oid(self) -> Result<ObjectIdentifier> {
108-
self.try_into()
109-
}
110-
111-
/// Attempt to decode an ASN.1 `OPTIONAL` value.
112-
pub fn optional<T>(self) -> Result<Option<T>>
113-
where
114-
T: Choice<'a> + TryFrom<Self, Error = Error>,
115-
{
116-
if T::can_decode(self.tag) {
117-
T::try_from(self).map(Some)
118-
} else {
119-
Ok(None)
120-
}
121-
}
122-
12382
/// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
12483
/// nested reader and calling the provided argument with it.
12584
pub fn sequence<F, T>(self, f: F) -> Result<T>
@@ -131,11 +90,6 @@ impl<'a> AnyRef<'a> {
13190
let result = f(&mut reader)?;
13291
reader.finish(result)
13392
}
134-
135-
/// Attempt to decode an ASN.1 `UTCTime`.
136-
pub fn utc_time(self) -> Result<UtcTime> {
137-
self.try_into()
138-
}
13993
}
14094

14195
impl<'a> Choice<'a> for AnyRef<'a> {
@@ -231,19 +185,20 @@ impl Any {
231185
}
232186

233187
/// Attempt to decode this [`Any`] type into the inner value.
234-
pub fn decode_into<'a, T>(&'a self) -> Result<T>
188+
pub fn decode_as<'a, T>(&'a self) -> Result<T>
235189
where
236-
T: DecodeValue<'a> + FixedTag,
190+
T: Choice<'a> + DecodeValue<'a>,
237191
{
238-
self.tag.assert_eq(T::TAG)?;
239-
let header = Header {
240-
tag: self.tag,
241-
length: self.value.len(),
242-
};
192+
AnyRef::from(self).decode_as()
193+
}
243194

244-
let mut decoder = SliceReader::new(self.value.as_slice())?;
245-
let result = T::decode_value(&mut decoder, header)?;
246-
decoder.finish(result)
195+
/// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
196+
/// nested reader and calling the provided argument with it.
197+
pub fn sequence<'a, F, T>(&'a self, f: F) -> Result<T>
198+
where
199+
F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
200+
{
201+
AnyRef::from(self).sequence(f)
247202
}
248203
}
249204

der/src/asn1/bit_string.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'a> TryFrom<AnyRef<'a>> for BitStringRef<'a> {
163163
type Error = Error;
164164

165165
fn try_from(any: AnyRef<'a>) -> Result<BitStringRef<'a>> {
166-
any.decode_into()
166+
any.decode_as()
167167
}
168168
}
169169

der/src/asn1/generalized_time.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl TryFrom<AnyRef<'_>> for GeneralizedTime {
168168
type Error = Error;
169169

170170
fn try_from(any: AnyRef<'_>) -> Result<GeneralizedTime> {
171-
any.decode_into()
171+
any.decode_as()
172172
}
173173
}
174174

der/src/asn1/integer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ macro_rules! impl_int_encoding {
6565
type Error = Error;
6666

6767
fn try_from(any: AnyRef<'_>) -> Result<Self> {
68-
any.decode_into()
68+
any.decode_as()
6969
}
7070
}
7171
)+
@@ -113,7 +113,7 @@ macro_rules! impl_uint_encoding {
113113
type Error = Error;
114114

115115
fn try_from(any: AnyRef<'_>) -> Result<Self> {
116-
any.decode_into()
116+
any.decode_as()
117117
}
118118
}
119119
)+

der/src/asn1/integer/bigint.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl<'a> TryFrom<AnyRef<'a>> for IntRef<'a> {
7979
type Error = Error;
8080

8181
fn try_from(any: AnyRef<'a>) -> Result<IntRef<'a>> {
82-
any.decode_into()
82+
any.decode_as()
8383
}
8484
}
8585

@@ -167,7 +167,7 @@ impl<'a> TryFrom<AnyRef<'a>> for UintRef<'a> {
167167
type Error = Error;
168168

169169
fn try_from(any: AnyRef<'a>) -> Result<UintRef<'a>> {
170-
any.decode_into()
170+
any.decode_as()
171171
}
172172
}
173173

@@ -265,7 +265,7 @@ mod allocating {
265265
type Error = Error;
266266

267267
fn try_from(any: AnyRef<'a>) -> Result<Int> {
268-
any.decode_into()
268+
any.decode_as()
269269
}
270270
}
271271

@@ -372,7 +372,7 @@ mod allocating {
372372
type Error = Error;
373373

374374
fn try_from(any: AnyRef<'a>) -> Result<Uint> {
375-
any.decode_into()
375+
any.decode_as()
376376
}
377377
}
378378

der/src/asn1/internal_macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ macro_rules! impl_string_type {
5353
type Error = Error;
5454

5555
fn try_from(any: &'__der Any) -> Result<$type> {
56-
any.decode_into()
56+
any.decode_as()
5757
}
5858
}
5959
}

der/src/asn1/null.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl TryFrom<AnyRef<'_>> for Null {
4545
type Error = Error;
4646

4747
fn try_from(any: AnyRef<'_>) -> Result<Null> {
48-
any.decode_into()
48+
any.decode_as()
4949
}
5050
}
5151

der/src/asn1/octet_string.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<'a> TryFrom<AnyRef<'a>> for OctetStringRef<'a> {
8787
type Error = Error;
8888

8989
fn try_from(any: AnyRef<'a>) -> Result<OctetStringRef<'a>> {
90-
any.decode_into()
90+
any.decode_as()
9191
}
9292
}
9393

der/src/asn1/printable_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'a> TryFrom<AnyRef<'a>> for PrintableStringRef<'a> {
112112
type Error = Error;
113113

114114
fn try_from(any: AnyRef<'a>) -> Result<PrintableStringRef<'a>> {
115-
any.decode_into()
115+
any.decode_as()
116116
}
117117
}
118118

@@ -206,7 +206,7 @@ mod allocation {
206206
type Error = Error;
207207

208208
fn try_from(any: &AnyRef<'a>) -> Result<PrintableString> {
209-
(*any).decode_into()
209+
(*any).decode_as()
210210
}
211211
}
212212

der/src/asn1/teletex_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl<'a> TryFrom<AnyRef<'a>> for TeletexStringRef<'a> {
8383
type Error = Error;
8484

8585
fn try_from(any: AnyRef<'a>) -> Result<TeletexStringRef<'a>> {
86-
any.decode_into()
86+
any.decode_as()
8787
}
8888
}
8989
impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
@@ -164,7 +164,7 @@ mod allocation {
164164
type Error = Error;
165165

166166
fn try_from(any: &AnyRef<'a>) -> Result<TeletexString> {
167-
(*any).decode_into()
167+
(*any).decode_as()
168168
}
169169
}
170170

der/src/asn1/utc_time.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl TryFrom<AnyRef<'_>> for UtcTime {
191191
type Error = Error;
192192

193193
fn try_from(any: AnyRef<'_>) -> Result<UtcTime> {
194-
any.decode_into()
194+
any.decode_as()
195195
}
196196
}
197197

der/src/asn1/utf8_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl<'a> TryFrom<AnyRef<'a>> for Utf8StringRef<'a> {
9494
type Error = Error;
9595

9696
fn try_from(any: AnyRef<'a>) -> Result<Utf8StringRef<'a>> {
97-
any.decode_into()
97+
any.decode_as()
9898
}
9999
}
100100

@@ -103,7 +103,7 @@ impl<'a> TryFrom<&'a Any> for Utf8StringRef<'a> {
103103
type Error = Error;
104104

105105
fn try_from(any: &'a Any) -> Result<Utf8StringRef<'a>> {
106-
any.decode_into()
106+
any.decode_as()
107107
}
108108
}
109109

der/src/asn1/videotex_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<'a> TryFrom<AnyRef<'a>> for VideotexStringRef<'a> {
101101
type Error = Error;
102102

103103
fn try_from(any: AnyRef<'a>) -> Result<VideotexStringRef<'a>> {
104-
any.decode_into()
104+
any.decode_as()
105105
}
106106
}
107107

@@ -110,7 +110,7 @@ impl<'a> TryFrom<&'a Any> for VideotexStringRef<'a> {
110110
type Error = Error;
111111

112112
fn try_from(any: &'a Any) -> Result<VideotexStringRef<'a>> {
113-
any.decode_into()
113+
any.decode_as()
114114
}
115115
}
116116

pkcs1/tests/params.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ fn decode_oaep_param() {
105105
.assert_algorithm_oid(db::rfc5912::ID_P_SPECIFIED)
106106
.is_ok());
107107
assert_eq!(
108-
param.p_source.parameters_any().unwrap().octet_string(),
108+
param
109+
.p_source
110+
.parameters_any()
111+
.unwrap()
112+
.decode_as::<OctetStringRef<'_>>(),
109113
OctetStringRef::new(&[0xab, 0xcd, 0xef])
110114
);
111115
}
@@ -147,7 +151,7 @@ fn decode_oaep_param_default() {
147151
.p_source
148152
.parameters_any()
149153
.unwrap()
150-
.octet_string()
154+
.decode_as::<OctetStringRef<'_>>()
151155
.unwrap()
152156
.is_empty(),);
153157
assert_eq!(param, Default::default())

pkcs5/src/pbes2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
320320
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
321321
// TODO(tarcieri): support for non-AES algorithms?
322322
let iv = match alg.parameters {
323-
Some(params) => params.octet_string()?.as_bytes(),
323+
Some(params) => params.decode_as::<OctetStringRef<'a>>()?.as_bytes(),
324324
None => return Err(Tag::OctetString.value_error()),
325325
};
326326

pkcs7/tests/content_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn decode_signed_mdm_example() {
104104
signer_infos: _,
105105
})) => {
106106
let _content = content
107-
.decode_into::<SequenceRef>()
107+
.decode_as::<SequenceRef>()
108108
.expect("Content should be in the correct format: SequenceRef");
109109
}
110110
_ => panic!("expected ContentInfo::SignedData(Some(_))"),
@@ -132,7 +132,7 @@ fn decode_signed_scep_example() {
132132
signer_infos: _,
133133
})) => {
134134
let _content = content
135-
.decode_into::<OctetStringRef>()
135+
.decode_as::<OctetStringRef>()
136136
.expect("Content should be in the correct format: OctetStringRef");
137137

138138
assert_eq!(ver, CmsVersion::V1)

pkcs8/tests/private_key.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! PKCS#8 private key tests
22
3+
use der::asn1::ObjectIdentifier;
34
use hex_literal::hex;
45
use pkcs8::{PrivateKeyInfo, Version};
56

@@ -48,7 +49,11 @@ fn decode_ec_p256_der() {
4849
assert_eq!(pk.algorithm.oid, "1.2.840.10045.2.1".parse().unwrap());
4950

5051
assert_eq!(
51-
pk.algorithm.parameters.unwrap().oid().unwrap(),
52+
pk.algorithm
53+
.parameters
54+
.unwrap()
55+
.decode_as::<ObjectIdentifier>()
56+
.unwrap(),
5257
"1.2.840.10045.3.1.7".parse().unwrap()
5358
);
5459

spki/src/algorithm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl<'a> AlgorithmIdentifierRef<'a> {
157157
None => None,
158158
Some(p) => match p {
159159
AnyRef::NULL => None,
160-
_ => Some(p.oid()?),
160+
_ => Some(p.decode_as::<ObjectIdentifier>()?),
161161
},
162162
},
163163
))

0 commit comments

Comments
 (0)