5
5
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" ,
6
6
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
7
7
) ]
8
+ #![ allow( clippy:: len_without_is_empty) ]
8
9
#![ forbid( unsafe_code) ]
9
10
#![ warn(
10
11
clippy:: integer_arithmetic,
@@ -24,6 +25,7 @@ extern crate std;
24
25
mod checked;
25
26
26
27
mod arcs;
28
+ mod buffer;
27
29
mod encoder;
28
30
mod error;
29
31
mod parser;
@@ -34,12 +36,18 @@ pub mod db;
34
36
35
37
pub use crate :: {
36
38
arcs:: { Arc , Arcs } ,
39
+ buffer:: Buffer ,
37
40
error:: { Error , Result } ,
38
41
} ;
39
42
40
43
use crate :: encoder:: Encoder ;
41
44
use core:: { fmt, str:: FromStr } ;
42
45
46
+ /// Default maximum size.
47
+ ///
48
+ /// Makes `ObjectIdentifier` 40-bytes total w\ 1-byte length.
49
+ const MAX_SIZE : usize = 39 ;
50
+
43
51
/// A trait which associates an OID with a type.
44
52
pub trait AssociatedOid {
45
53
/// The OID associated with this type.
@@ -78,18 +86,14 @@ impl<T: AssociatedOid> DynAssociatedOid for T {
78
86
/// - The BER/DER encoding of the OID MUST be shorter than
79
87
/// [`ObjectIdentifier::MAX_SIZE`]
80
88
#[ derive( Copy , Clone , Eq , Hash , PartialEq , PartialOrd , Ord ) ]
81
- pub struct ObjectIdentifier {
82
- /// Length in bytes
83
- length : u8 ,
84
-
85
- /// Array containing BER/DER-serialized bytes (no header)
86
- bytes : [ u8 ; Self :: MAX_SIZE ] ,
89
+ pub struct ObjectIdentifier < B : AsRef < [ u8 ] > = Buffer < MAX_SIZE > > {
90
+ /// Buffer containing BER/DER-serialized bytes (sans ASN.1 tag/length)
91
+ buffer : B ,
87
92
}
88
93
89
- #[ allow( clippy:: len_without_is_empty) ]
90
94
impl ObjectIdentifier {
91
95
/// Maximum size of a BER/DER-encoded OID in bytes.
92
- pub const MAX_SIZE : usize = 39 ; // makes `ObjectIdentifier` 40-bytes total w\ 1-byte length
96
+ pub const MAX_SIZE : usize = MAX_SIZE ;
93
97
94
98
/// Parse an [`ObjectIdentifier`] from the dot-delimited string form,
95
99
/// panicking on parse errors.
@@ -145,27 +149,60 @@ impl ObjectIdentifier {
145
149
3 ..=Self :: MAX_SIZE => ( ) ,
146
150
_ => return Err ( Error :: NotEnoughArcs ) ,
147
151
}
152
+
148
153
let mut bytes = [ 0u8 ; Self :: MAX_SIZE ] ;
149
154
bytes[ ..len] . copy_from_slice ( ber_bytes) ;
150
155
151
- let oid = Self {
156
+ let bytes = Buffer {
152
157
bytes,
153
158
length : len as u8 ,
154
159
} ;
155
160
161
+ let oid = Self { buffer : bytes } ;
162
+
156
163
// Ensure arcs are well-formed
157
164
let mut arcs = oid. arcs ( ) ;
158
165
while arcs. try_next ( ) ?. is_some ( ) { }
159
166
160
167
Ok ( oid)
161
168
}
162
169
170
+ /// Get the parent OID of this one (if applicable).
171
+ pub fn parent ( & self ) -> Option < Self > {
172
+ let num_arcs = self . len ( ) . checked_sub ( 1 ) ?;
173
+ Self :: from_arcs ( self . arcs ( ) . take ( num_arcs) ) . ok ( )
174
+ }
175
+
176
+ /// Push an additional arc onto this OID, returning the child OID.
177
+ pub const fn push_arc ( self , arc : Arc ) -> Result < Self > {
178
+ // TODO(tarcieri): use `?` when stable in `const fn`
179
+ match Encoder :: extend ( self ) . arc ( arc) {
180
+ Ok ( encoder) => encoder. finish ( ) ,
181
+ Err ( err) => Err ( err) ,
182
+ }
183
+ }
184
+ }
185
+
186
+ impl < ' a > ObjectIdentifier < & ' a [ u8 ] > {
187
+ /// Initialize OID from a byte slice without validating that it contains
188
+ /// a well-formed BER-encoded OID.
189
+ ///
190
+ /// Use with care, e.g. to define compact constants.
191
+ pub const fn from_bytes_unchecked ( buffer : & ' a [ u8 ] ) -> Self {
192
+ Self { buffer }
193
+ }
194
+ }
195
+
196
+ impl < B > ObjectIdentifier < B >
197
+ where
198
+ B : AsRef < [ u8 ] > ,
199
+ {
163
200
/// Get the BER/DER serialization of this OID as bytes.
164
201
///
165
202
/// Note that this encoding omits the tag/length, and only contains the
166
203
/// value portion of the encoded OID.
167
204
pub fn as_bytes ( & self ) -> & [ u8 ] {
168
- & self . bytes [ .. self . length as usize ]
205
+ self . buffer . as_ref ( )
169
206
}
170
207
171
208
/// Return the arc with the given index, if it exists.
@@ -177,31 +214,19 @@ impl ObjectIdentifier {
177
214
///
178
215
/// Returns [`Arcs`], an iterator over [`Arc`] values.
179
216
pub fn arcs ( & self ) -> Arcs < ' _ > {
180
- Arcs :: new ( self )
217
+ Arcs :: new ( self . buffer . as_ref ( ) )
181
218
}
182
219
183
220
/// Get the length of this [`ObjectIdentifier`] in arcs.
184
221
pub fn len ( & self ) -> usize {
185
222
self . arcs ( ) . count ( )
186
223
}
187
-
188
- /// Get the parent OID of this one (if applicable).
189
- pub fn parent ( & self ) -> Option < Self > {
190
- let num_arcs = self . len ( ) . checked_sub ( 1 ) ?;
191
- Self :: from_arcs ( self . arcs ( ) . take ( num_arcs) ) . ok ( )
192
- }
193
-
194
- /// Push an additional arc onto this OID, returning the child OID.
195
- pub const fn push_arc ( self , arc : Arc ) -> Result < Self > {
196
- // TODO(tarcieri): use `?` when stable in `const fn`
197
- match Encoder :: extend ( self ) . arc ( arc) {
198
- Ok ( encoder) => encoder. finish ( ) ,
199
- Err ( err) => Err ( err) ,
200
- }
201
- }
202
224
}
203
225
204
- impl AsRef < [ u8 ] > for ObjectIdentifier {
226
+ impl < B > AsRef < [ u8 ] > for ObjectIdentifier < B >
227
+ where
228
+ B : AsRef < [ u8 ] > ,
229
+ {
205
230
fn as_ref ( & self ) -> & [ u8 ] {
206
231
self . as_bytes ( )
207
232
}
@@ -223,12 +248,6 @@ impl TryFrom<&[u8]> for ObjectIdentifier {
223
248
}
224
249
}
225
250
226
- impl From < & ObjectIdentifier > for ObjectIdentifier {
227
- fn from ( oid : & ObjectIdentifier ) -> ObjectIdentifier {
228
- * oid
229
- }
230
- }
231
-
232
251
impl fmt:: Debug for ObjectIdentifier {
233
252
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
234
253
write ! ( f, "ObjectIdentifier({})" , self )
0 commit comments