Skip to content

Commit 72ef39a

Browse files
authored
x509-cert: make name an owned type (#771)
Also adds `Bytes`, an owned alternative to `ByteSlice`
1 parent 01dd38c commit 72ef39a

25 files changed

+478
-165
lines changed

der/src/asn1/any.rs

+46-34
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
use core::cmp::Ordering;
88

99
#[cfg(feature = "alloc")]
10-
use alloc::vec::Vec;
10+
use crate::Bytes;
1111

1212
#[cfg(feature = "oid")]
1313
use crate::asn1::ObjectIdentifier;
@@ -94,11 +94,6 @@ impl<'a> AnyRef<'a> {
9494
self.try_into()
9595
}
9696

97-
/// Attempt to decode an ASN.1 `IA5String`.
98-
pub fn ia5_string(self) -> Result<Ia5StringRef<'a>> {
99-
self.try_into()
100-
}
101-
10297
/// Attempt to decode an ASN.1 `OCTET STRING`.
10398
pub fn octet_string(self) -> Result<OctetStringRef<'a>> {
10499
self.try_into()
@@ -123,21 +118,6 @@ impl<'a> AnyRef<'a> {
123118
}
124119
}
125120

126-
/// Attempt to decode an ASN.1 `PrintableString`.
127-
pub fn printable_string(self) -> Result<PrintableStringRef<'a>> {
128-
self.try_into()
129-
}
130-
131-
/// Attempt to decode an ASN.1 `TeletexString`.
132-
pub fn teletex_string(self) -> Result<TeletexStringRef<'a>> {
133-
self.try_into()
134-
}
135-
136-
/// Attempt to decode an ASN.1 `VideotexString`.
137-
pub fn videotex_string(self) -> Result<VideotexStringRef<'a>> {
138-
self.try_into()
139-
}
140-
141121
/// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
142122
/// nested reader and calling the provided argument with it.
143123
pub fn sequence<F, T>(self, f: F) -> Result<T>
@@ -154,11 +134,6 @@ impl<'a> AnyRef<'a> {
154134
pub fn utc_time(self) -> Result<UtcTime> {
155135
self.try_into()
156136
}
157-
158-
/// Attempt to decode an ASN.1 `UTF8String`.
159-
pub fn utf8_string(self) -> Result<Utf8StringRef<'a>> {
160-
self.try_into()
161-
}
162137
}
163138

164139
impl<'a> Choice<'a> for AnyRef<'a> {
@@ -194,6 +169,13 @@ impl Tagged for AnyRef<'_> {
194169
}
195170
}
196171

172+
#[cfg(feature = "alloc")]
173+
impl ValueOrd for Any {
174+
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
175+
self.value.der_cmp(&other.value)
176+
}
177+
}
178+
197179
impl ValueOrd for AnyRef<'_> {
198180
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
199181
self.value.der_cmp(&other.value)
@@ -226,19 +208,35 @@ pub struct Any {
226208
tag: Tag,
227209

228210
/// Inner value encoded as bytes.
229-
value: Vec<u8>,
211+
value: Bytes,
230212
}
231213

232214
#[cfg(feature = "alloc")]
233215
impl Any {
234216
/// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
235-
pub fn new(tag: Tag, bytes: impl Into<Vec<u8>>) -> Result<Self> {
236-
let value = bytes.into();
217+
pub fn new(tag: Tag, bytes: &[u8]) -> Result<Self> {
218+
let value = Bytes::new(bytes)?;
237219

238220
// Ensure the tag and value are a valid `AnyRef`.
239-
AnyRef::new(tag, &value)?;
221+
AnyRef::new(tag, value.as_slice())?;
240222
Ok(Self { tag, value })
241223
}
224+
225+
/// Attempt to decode this [`Any`] type into the inner value.
226+
pub fn decode_into<'a, T>(&'a self) -> Result<T>
227+
where
228+
T: DecodeValue<'a> + FixedTag,
229+
{
230+
self.tag.assert_eq(T::TAG)?;
231+
let header = Header {
232+
tag: self.tag,
233+
length: self.value.len(),
234+
};
235+
236+
let mut decoder = SliceReader::new(self.value.as_slice())?;
237+
let result = T::decode_value(&mut decoder, header)?;
238+
decoder.finish(result)
239+
}
242240
}
243241

244242
#[cfg(feature = "alloc")]
@@ -253,26 +251,26 @@ impl<'a> Decode<'a> for Any {
253251
fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
254252
let header = Header::decode(reader)?;
255253
let value = reader.read_vec(header.length)?;
256-
Self::new(header.tag, value)
254+
Self::new(header.tag, &value)
257255
}
258256
}
259257

260258
#[cfg(feature = "alloc")]
261259
impl EncodeValue for Any {
262260
fn value_len(&self) -> Result<Length> {
263-
self.value.len().try_into()
261+
Ok(self.value.len())
264262
}
265263

266264
fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
267-
writer.write(&self.value)
265+
writer.write(self.value.as_slice())
268266
}
269267
}
270268

271269
#[cfg(feature = "alloc")]
272270
impl<'a> From<&'a Any> for AnyRef<'a> {
273271
fn from(any: &'a Any) -> AnyRef<'a> {
274272
// Ensured to parse successfully in constructor
275-
AnyRef::new(any.tag, &any.value).expect("invalid ANY")
273+
AnyRef::new(any.tag, any.value.as_slice()).expect("invalid ANY")
276274
}
277275
}
278276

@@ -282,3 +280,17 @@ impl Tagged for Any {
282280
self.tag
283281
}
284282
}
283+
284+
#[cfg(feature = "alloc")]
285+
impl<'a, T> From<T> for Any
286+
where
287+
T: Into<AnyRef<'a>>,
288+
{
289+
fn from(input: T) -> Any {
290+
let anyref: AnyRef<'a> = input.into();
291+
Self {
292+
tag: anyref.tag(),
293+
value: Bytes::from(anyref.value),
294+
}
295+
}
296+
}

der/src/asn1/ia5_string.rs

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::{
66
};
77
use core::{fmt, ops::Deref, str};
88

9+
#[cfg(feature = "alloc")]
10+
use crate::asn1::Any;
11+
912
/// ASN.1 `IA5String` type.
1013
///
1114
/// Supports the [International Alphabet No. 5 (IA5)] character encoding, i.e.
@@ -99,6 +102,15 @@ impl<'a> TryFrom<AnyRef<'a>> for Ia5StringRef<'a> {
99102
}
100103
}
101104

105+
#[cfg(feature = "alloc")]
106+
impl<'a> TryFrom<&'a Any> for Ia5StringRef<'a> {
107+
type Error = Error;
108+
109+
fn try_from(any: &'a Any) -> Result<Ia5StringRef<'a>> {
110+
any.decode_into()
111+
}
112+
}
113+
102114
impl<'a> From<Ia5StringRef<'a>> for AnyRef<'a> {
103115
fn from(printable_string: Ia5StringRef<'a>) -> AnyRef<'a> {
104116
AnyRef::from_tag_and_value(Tag::Ia5String, printable_string.inner.into())

der/src/asn1/printable_string.rs

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::{
66
};
77
use core::{fmt, ops::Deref, str};
88

9+
#[cfg(feature = "alloc")]
10+
use crate::asn1::Any;
11+
912
/// ASN.1 `PrintableString` type.
1013
///
1114
/// Supports a subset the ASCII character set (described below).
@@ -133,6 +136,15 @@ impl<'a> TryFrom<AnyRef<'a>> for PrintableStringRef<'a> {
133136
}
134137
}
135138

139+
#[cfg(feature = "alloc")]
140+
impl<'a> TryFrom<&'a Any> for PrintableStringRef<'a> {
141+
type Error = Error;
142+
143+
fn try_from(any: &'a Any) -> Result<PrintableStringRef<'a>> {
144+
any.decode_into()
145+
}
146+
}
147+
136148
impl<'a> From<PrintableStringRef<'a>> for AnyRef<'a> {
137149
fn from(printable_string: PrintableStringRef<'a>) -> AnyRef<'a> {
138150
AnyRef::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())

der/src/asn1/teletex_string.rs

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::{
66
};
77
use core::{fmt, ops::Deref, str};
88

9+
#[cfg(feature = "alloc")]
10+
use crate::asn1::Any;
11+
912
/// ASN.1 `TeletexString` type.
1013
///
1114
/// Supports a subset the ASCII character set (described below).
@@ -103,6 +106,15 @@ impl<'a> TryFrom<AnyRef<'a>> for TeletexStringRef<'a> {
103106
}
104107
}
105108

109+
#[cfg(feature = "alloc")]
110+
impl<'a> TryFrom<&'a Any> for TeletexStringRef<'a> {
111+
type Error = Error;
112+
113+
fn try_from(any: &'a Any) -> Result<TeletexStringRef<'a>> {
114+
any.decode_into()
115+
}
116+
}
117+
106118
impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
107119
fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
108120
AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.into())

der/src/asn1/utf8_string.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use crate::{
77
use core::{fmt, ops::Deref, str};
88

99
#[cfg(feature = "alloc")]
10-
use alloc::{borrow::ToOwned, string::String};
10+
use {
11+
crate::asn1::Any,
12+
alloc::{borrow::ToOwned, string::String},
13+
};
1114

1215
/// ASN.1 `UTF8String` type.
1316
///
@@ -95,9 +98,18 @@ impl<'a> TryFrom<AnyRef<'a>> for Utf8StringRef<'a> {
9598
}
9699
}
97100

101+
#[cfg(feature = "alloc")]
102+
impl<'a> TryFrom<&'a Any> for Utf8StringRef<'a> {
103+
type Error = Error;
104+
105+
fn try_from(any: &'a Any) -> Result<Utf8StringRef<'a>> {
106+
any.decode_into()
107+
}
108+
}
109+
98110
impl<'a> From<Utf8StringRef<'a>> for AnyRef<'a> {
99-
fn from(printable_string: Utf8StringRef<'a>) -> AnyRef<'a> {
100-
AnyRef::from_tag_and_value(Tag::Utf8String, printable_string.inner.into())
111+
fn from(utf_string: Utf8StringRef<'a>) -> AnyRef<'a> {
112+
AnyRef::from_tag_and_value(Tag::Utf8String, utf_string.inner.into())
101113
}
102114
}
103115

der/src/asn1/videotex_string.rs

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::{
66
};
77
use core::{fmt, ops::Deref, str};
88

9+
#[cfg(feature = "alloc")]
10+
use crate::asn1::Any;
11+
912
/// ASN.1 `VideotexString` type.
1013
///
1114
/// Supports a subset the ASCII character set (described below).
@@ -102,6 +105,15 @@ impl<'a> TryFrom<AnyRef<'a>> for VideotexStringRef<'a> {
102105
}
103106
}
104107

108+
#[cfg(feature = "alloc")]
109+
impl<'a> TryFrom<&'a Any> for VideotexStringRef<'a> {
110+
type Error = Error;
111+
112+
fn try_from(any: &'a Any) -> Result<VideotexStringRef<'a>> {
113+
any.decode_into()
114+
}
115+
}
116+
105117
impl<'a> From<VideotexStringRef<'a>> for AnyRef<'a> {
106118
fn from(printable_string: VideotexStringRef<'a>) -> AnyRef<'a> {
107119
AnyRef::from_tag_and_value(Tag::VideotexString, printable_string.inner.into())

der/src/byte_slice.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use core::cmp::Ordering;
1111
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
1212
pub(crate) struct ByteSlice<'a> {
1313
/// Precomputed `Length` (avoids possible panicking conversions)
14-
length: Length,
14+
pub length: Length,
1515

1616
/// Inner value
17-
inner: &'a [u8],
17+
pub inner: &'a [u8],
1818
}
1919

2020
impl<'a> ByteSlice<'a> {

0 commit comments

Comments
 (0)