55 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" ,
66 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
77) ]
8+ #![ allow( clippy:: len_without_is_empty) ]
89#![ forbid( unsafe_code) ]
910#![ warn(
1011 clippy:: integer_arithmetic,
@@ -24,6 +25,7 @@ extern crate std;
2425mod checked;
2526
2627mod arcs;
28+ mod buffer;
2729mod encoder;
2830mod error;
2931mod parser;
@@ -34,12 +36,18 @@ pub mod db;
3436
3537pub use crate :: {
3638 arcs:: { Arc , Arcs } ,
39+ buffer:: Buffer ,
3740 error:: { Error , Result } ,
3841} ;
3942
4043use crate :: encoder:: Encoder ;
4144use core:: { fmt, str:: FromStr } ;
4245
46+ /// Default maximum size.
47+ ///
48+ /// Makes `ObjectIdentifier` 40-bytes total w\ 1-byte length.
49+ const MAX_SIZE : usize = 39 ;
50+
4351/// A trait which associates an OID with a type.
4452pub trait AssociatedOid {
4553 /// The OID associated with this type.
@@ -78,18 +86,14 @@ impl<T: AssociatedOid> DynAssociatedOid for T {
7886/// - The BER/DER encoding of the OID MUST be shorter than
7987/// [`ObjectIdentifier::MAX_SIZE`]
8088#[ 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 ,
8792}
8893
89- #[ allow( clippy:: len_without_is_empty) ]
9094impl ObjectIdentifier {
9195 /// 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 ;
9397
9498 /// Parse an [`ObjectIdentifier`] from the dot-delimited string form,
9599 /// panicking on parse errors.
@@ -145,27 +149,60 @@ impl ObjectIdentifier {
145149 3 ..=Self :: MAX_SIZE => ( ) ,
146150 _ => return Err ( Error :: NotEnoughArcs ) ,
147151 }
152+
148153 let mut bytes = [ 0u8 ; Self :: MAX_SIZE ] ;
149154 bytes[ ..len] . copy_from_slice ( ber_bytes) ;
150155
151- let oid = Self {
156+ let bytes = Buffer {
152157 bytes,
153158 length : len as u8 ,
154159 } ;
155160
161+ let oid = Self { buffer : bytes } ;
162+
156163 // Ensure arcs are well-formed
157164 let mut arcs = oid. arcs ( ) ;
158165 while arcs. try_next ( ) ?. is_some ( ) { }
159166
160167 Ok ( oid)
161168 }
162169
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+ {
163200 /// Get the BER/DER serialization of this OID as bytes.
164201 ///
165202 /// Note that this encoding omits the tag/length, and only contains the
166203 /// value portion of the encoded OID.
167204 pub fn as_bytes ( & self ) -> & [ u8 ] {
168- & self . bytes [ .. self . length as usize ]
205+ self . buffer . as_ref ( )
169206 }
170207
171208 /// Return the arc with the given index, if it exists.
@@ -177,31 +214,19 @@ impl ObjectIdentifier {
177214 ///
178215 /// Returns [`Arcs`], an iterator over [`Arc`] values.
179216 pub fn arcs ( & self ) -> Arcs < ' _ > {
180- Arcs :: new ( self )
217+ Arcs :: new ( self . buffer . as_ref ( ) )
181218 }
182219
183220 /// Get the length of this [`ObjectIdentifier`] in arcs.
184221 pub fn len ( & self ) -> usize {
185222 self . arcs ( ) . count ( )
186223 }
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- }
202224}
203225
204- impl AsRef < [ u8 ] > for ObjectIdentifier {
226+ impl < B > AsRef < [ u8 ] > for ObjectIdentifier < B >
227+ where
228+ B : AsRef < [ u8 ] > ,
229+ {
205230 fn as_ref ( & self ) -> & [ u8 ] {
206231 self . as_bytes ( )
207232 }
@@ -223,12 +248,6 @@ impl TryFrom<&[u8]> for ObjectIdentifier {
223248 }
224249}
225250
226- impl From < & ObjectIdentifier > for ObjectIdentifier {
227- fn from ( oid : & ObjectIdentifier ) -> ObjectIdentifier {
228- * oid
229- }
230- }
231-
232251impl fmt:: Debug for ObjectIdentifier {
233252 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
234253 write ! ( f, "ObjectIdentifier({})" , self )
0 commit comments