1 /// Internal parser, do not use directly
2 #[doc(hidden)]
3 #[macro_export]
4 macro_rules! fold_der_defined_m(
5     (__impl $i:expr, $acc:ident, $f:ident) => ( {
6         match $f($i) {
7             Ok((rem,res)) => { $acc.push(res); Ok((rem,$acc)) },
8             Err(e)        => Err(e)
9         }
10     });
11     (__impl $i:expr, $acc:ident, $submac:ident!( $($args:tt)* ) ) => ( {
12         match $submac!($i, $($args)*) {
13             Ok((rem,res)) => { $acc.push(res); Ok((rem,$acc)) },
14             Err(e)        => Err(e)
15         }
16     });
17     (__impl $i:expr, $acc:ident, $f:ident >> $($rest:tt)*) => (
18         {
19             match $f($i) {
20                 Ok((rem,res)) => {
21                     $acc.push(res);
22                     fold_der_defined_m!(__impl rem, $acc, $($rest)* )
23                 },
24                 Err(e)        => Err(e)
25             }
26         }
27     );
28     (__impl $i:expr, $acc:ident, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => (
29         {
30             match $submac!($i, $($args)*) {
31                 Ok((rem,res)) => {
32                     $acc.push(res);
33                     fold_der_defined_m!(__impl rem, $acc, $($rest)* )
34                 },
35                 Err(e)        => Err(e)
36             }
37         }
38     );
39 
40     ($i:expr, $($rest:tt)* ) => (
41         {
42             let mut v = Vec::new();
43             fold_der_defined_m!(__impl $i, v, $($rest)*)
44         }
45     );
46 );
47 
48 /// Internal parser, do not use directly
49 #[doc(hidden)]
50 #[macro_export]
51 macro_rules! parse_ber_defined_m(
52     ($i:expr, $tag:expr, $($args:tt)*) => (
53         {
54             use $crate::ber::ber_read_element_header;
55             use $crate::fold_der_defined_m;
56             do_parse!(
57                 $i,
58                 hdr:     ber_read_element_header >>
59                          custom_check!(hdr.class != 0b00, $crate::error::BerError::InvalidClass) >>
60                          custom_check!(hdr.structured != 0b1, $crate::error::BerError::ConstructExpected) >>
61                          custom_check!(hdr.tag != $tag, $crate::error::BerError::InvalidTag) >>
62                 content: flat_take!(hdr.len as usize, fold_der_defined_m!( $($args)* )) >>
63                 (hdr,content)
64             )
65         }
66     );
67 );
68 
69 /// Parse a defined sequence of DER elements (macro version)
70 ///
71 /// Given a list of expected parsers, apply them to build a DER sequence.
72 ///
73 /// ```rust
74 /// # #[macro_use] extern crate der_parser;
75 /// # use der_parser::ber::{parse_ber_integer, BerObject};
76 /// # use der_parser::error::BerResult;
77 /// #
78 /// # fn main() {
79 /// fn localparse_seq(i:&[u8]) -> BerResult {
80 ///     parse_der_sequence_defined_m!(i,
81 ///         parse_ber_integer >>
82 ///         // macros can also be called
83 ///         call!(parse_ber_integer)
84 ///     )
85 /// }
86 ///
87 /// let empty = &b""[..];
88 /// let bytes = [ 0x30, 0x0a,
89 ///               0x02, 0x03, 0x01, 0x00, 0x01,
90 ///               0x02, 0x03, 0x01, 0x00, 0x00,
91 /// ];
92 /// let expected  = BerObject::from_seq(vec![
93 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
94 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
95 /// ]);
96 /// assert_eq!(localparse_seq(&bytes), Ok((empty, expected)));
97 /// # }
98 /// ```
99 #[macro_export]
100 #[deprecated(since = "3.0.0", note = "Use parse_der_sequence_defined")]
101 macro_rules! parse_der_sequence_defined_m(
102     ($i:expr, $($args:tt)*) => ({
103         map!(
104             $i,
105             parse_ber_defined_m!($crate::ber::BerTag::Sequence, $($args)*),
106             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Sequence(o))
107         )
108     });
109 );
110 
111 /// Parse a defined set of DER elements
112 ///
113 /// Given a list of expected parsers, apply them to build a DER set.
114 ///
115 /// ```rust
116 /// # #[macro_use] extern crate der_parser;
117 /// # use der_parser::ber::{parse_ber_integer, BerObject};
118 /// # use der_parser::error::BerResult;
119 /// #
120 /// # fn main() {
121 /// fn localparse_set(i:&[u8]) -> BerResult {
122 ///     parse_der_set_defined_m!(i,
123 ///         parse_ber_integer >>
124 ///         // macros can also be called
125 ///         call!(parse_ber_integer)
126 ///     )
127 /// }
128 ///
129 /// let empty = &b""[..];
130 /// let bytes = [ 0x31, 0x0a,
131 ///               0x02, 0x03, 0x01, 0x00, 0x01,
132 ///               0x02, 0x03, 0x01, 0x00, 0x00,
133 /// ];
134 /// let expected  = BerObject::from_set(vec![
135 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
136 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
137 /// ]);
138 /// assert_eq!(localparse_set(&bytes), Ok((empty, expected)));
139 /// # }
140 /// ```
141 #[macro_export]
142 #[deprecated(since = "3.0.0", note = "Use parse_der_set_defined")]
143 macro_rules! parse_der_set_defined_m(
144     ($i:expr, $($args:tt)*) => ({
145         map!(
146             $i,
147             parse_ber_defined_m!($crate::ber::BerTag::Set, $($args)*),
148             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Set(o))
149         )
150     });
151 );
152 
153 /// Internal parser, do not use directly
154 #[doc(hidden)]
155 #[macro_export]
156 macro_rules! fold_parsers(
157     ($i:expr, $($args:tt)*) => (
158         {
159             let parsers = [ $($args)* ];
160             parsers.iter().fold(
161                 (Ok(($i,vec![]))),
162                 |r, f| {
163                     match r {
164                         Ok((rem,mut v)) => {
165                             map!(rem, f, |x| { v.push(x); v })
166                         }
167                         Err(e)          => Err(e)
168                     }
169                 }
170                 )
171         }
172     );
173 );
174 
175 /// Internal parser, do not use directly
176 #[doc(hidden)]
177 #[macro_export]
178 macro_rules! parse_der_defined(
179     ($i:expr, $tag:expr, $($args:tt)*) => (
180         {
181             use $crate::ber::ber_read_element_header;
182             let res =
183             do_parse!(
184                 $i,
185                 hdr:     ber_read_element_header >>
186                          custom_check!(hdr.class != 0b00, $crate::error::BerError::InvalidClass) >>
187                          custom_check!(hdr.structured != 0b1, $crate::error::BerError::ConstructExpected) >>
188                          custom_check!(hdr.tag != $tag, $crate::error::BerError::InvalidTag) >>
189                 content: take!(hdr.len) >>
190                 (hdr,content)
191             );
192             match res {
193                 Ok((_rem,o)) => {
194                     match fold_parsers!(o.1, $($args)* ) {
195                         Ok((rem,v)) => {
196                             if rem.len() != 0 { Err(::nom::Err::Error($crate::error::BerError::ObjectTooShort)) }
197                             else { Ok((_rem,(o.0,v))) }
198                         },
199                         Err(e)      => Err(e)
200                     }
201                 },
202                 Err(e)       => Err(e)
203             }
204         }
205     );
206 );
207 
208 /// Parse a defined sequence of DER elements
209 ///
210 /// Given a list of expected parsers, apply them to build a DER sequence.
211 ///
212 /// ```rust
213 /// # #[macro_use] extern crate der_parser;
214 /// # use der_parser::ber::{parse_ber_integer, BerObject};
215 /// # use der_parser::error::BerResult;
216 /// #
217 /// # fn main() {
218 /// fn localparse_seq(i:&[u8]) -> BerResult {
219 ///     parse_der_sequence_defined!(i,
220 ///         parse_ber_integer >>
221 ///         parse_ber_integer
222 ///     )
223 /// }
224 ///
225 /// let empty = &b""[..];
226 /// let bytes = [ 0x30, 0x0a,
227 ///               0x02, 0x03, 0x01, 0x00, 0x01,
228 ///               0x02, 0x03, 0x01, 0x00, 0x00,
229 /// ];
230 /// let expected  = BerObject::from_seq(vec![
231 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
232 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
233 /// ]);
234 /// assert_eq!(localparse_seq(&bytes), Ok((empty, expected)));
235 /// # }
236 /// ```
237 #[macro_export]
238 macro_rules! parse_der_sequence_defined(
239     ($i:expr, $($args:tt)*) => ({
240         map!(
241             $i,
242             parse_ber_defined_m!($crate::ber::BerTag::Sequence, $($args)*),
243             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Sequence(o))
244         )
245     });
246 );
247 // macro_rules! parse_der_sequence_defined(
248 //     ($i:expr, $($args:tt)*) => ({
249 //         map!(
250 //             $i,
251 //             parse_der_defined!($crate::ber::BerTag::Sequence, $($args)*),
252 //             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Sequence(o))
253 //         )
254 //     });
255 // );
256 
257 /// Parse a defined set of DER elements
258 ///
259 /// Given a list of expected parsers, apply them to build a DER set.
260 ///
261 /// ```rust
262 /// # #[macro_use] extern crate der_parser;
263 /// # use der_parser::ber::{parse_ber_integer, BerObject};
264 /// # use der_parser::error::BerResult;
265 /// #
266 /// # fn main() {
267 /// fn localparse_set(i:&[u8]) -> BerResult {
268 ///     parse_der_set_defined!(i,
269 ///         parse_ber_integer >>
270 ///         parse_ber_integer
271 ///     )
272 /// }
273 ///
274 /// let empty = &b""[..];
275 /// let bytes = [ 0x31, 0x0a,
276 ///               0x02, 0x03, 0x01, 0x00, 0x01,
277 ///               0x02, 0x03, 0x01, 0x00, 0x00,
278 /// ];
279 /// let expected  = BerObject::from_set(vec![
280 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
281 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
282 /// ]);
283 /// assert_eq!(localparse_set(&bytes), Ok((empty, expected)));
284 /// # }
285 /// ```
286 #[macro_export]
287 macro_rules! parse_der_set_defined(
288     ($i:expr, $($args:tt)*) => ({
289         map!(
290             $i,
291             parse_ber_defined_m!($crate::ber::BerTag::Set, $($args)*),
292             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Set(o))
293         )
294     });
295 );
296 // #[macro_export]
297 // macro_rules! parse_der_set_defined(
298 //     ($i:expr, $($args:tt)*) => (
299 //         map!(
300 //             $i,
301 //             parse_der_defined!($crate::ber::BerTag::Set, $($args)*),
302 //             |(hdr,o)| $crate::ber::BerObject::from_header_and_content(hdr,$crate::ber::BerObjectContent::Set(o))
303 //         )
304 //     );
305 // );
306 
307 /// Parse a sequence of identical DER elements
308 ///
309 /// Given a subparser for a DER type, parse a sequence of identical objects.
310 ///
311 /// ```rust
312 /// # #[macro_use] extern crate der_parser;
313 /// # use der_parser::ber::{parse_ber_integer, BerObject};
314 /// # use der_parser::error::BerResult;
315 /// #
316 /// # fn main() {
317 /// fn parser(i:&[u8]) -> BerResult {
318 ///     parse_der_sequence_of!(i, parse_ber_integer)
319 /// };
320 ///
321 /// let empty = &b""[..];
322 /// let bytes = [ 0x30, 0x0a,
323 ///               0x02, 0x03, 0x01, 0x00, 0x01,
324 ///               0x02, 0x03, 0x01, 0x00, 0x00,
325 /// ];
326 /// let expected  = BerObject::from_seq(vec![
327 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
328 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
329 /// ]);
330 /// assert_eq!(parser(&bytes), Ok((empty, expected)));
331 /// # }
332 /// ```
333 #[macro_export]
334 macro_rules! parse_der_sequence_of(
335     ($i:expr, $f:ident) => ({
336         use $crate::ber::ber_read_element_header;
337         do_parse!(
338             $i,
339             hdr:     ber_read_element_header >>
340                      custom_check!(hdr.tag != $crate::ber::BerTag::Sequence, $crate::error::BerError::InvalidTag) >>
341             content: flat_take!(hdr.len as usize,
342                 do_parse!(
343                     r: many0!(complete!($f)) >>
344                        eof!() >>
345                     ( r )
346                 )
347             ) >>
348             ( $crate::ber::BerObject::from_header_and_content(hdr, $crate::ber::BerObjectContent::Sequence(content)) )
349         )
350     })
351 );
352 
353 /// Parse a set of identical DER elements
354 ///
355 /// Given a subparser for a DER type, parse a set of identical objects.
356 ///
357 /// ```rust
358 /// # #[macro_use] extern crate der_parser;
359 /// # use der_parser::ber::{parse_ber_integer, BerObject};
360 /// # use der_parser::error::BerResult;
361 /// #
362 /// # fn main() {
363 /// fn parser(i:&[u8]) -> BerResult {
364 ///     parse_der_set_of!(i, parse_ber_integer)
365 /// };
366 ///
367 /// let empty = &b""[..];
368 /// let bytes = [ 0x31, 0x0a,
369 ///               0x02, 0x03, 0x01, 0x00, 0x01,
370 ///               0x02, 0x03, 0x01, 0x00, 0x00,
371 /// ];
372 /// let expected  = BerObject::from_set(vec![
373 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
374 ///     BerObject::from_int_slice(b"\x01\x00\x00"),
375 /// ]);
376 /// assert_eq!(parser(&bytes), Ok((empty, expected)));
377 /// # }
378 /// ```
379 #[macro_export]
380 macro_rules! parse_der_set_of(
381     ($i:expr, $f:ident) => ({
382         use $crate::ber::ber_read_element_header;
383         do_parse!(
384             $i,
385             hdr:     ber_read_element_header >>
386                      custom_check!(hdr.tag != $crate::ber::BerTag::Set, $crate::error::BerError::InvalidTag) >>
387             content: flat_take!(hdr.len as usize,
388                 do_parse!(
389                     r: many0!(complete!($f)) >>
390                        eof!() >>
391                     ( r )
392                 )
393             ) >>
394             ( $crate::ber::BerObject::from_header_and_content(hdr, $crate::ber::BerObjectContent::Set(content)) )
395         )
396     })
397 );
398 
399 /// Parse an optional DER element
400 ///
401 /// Try to parse an optional DER element, and return it as a `ContextSpecific` item with tag 0.
402 /// If the parsing failed, the `ContextSpecific` object has value `None`.
403 ///
404 /// ```rust
405 /// # #[macro_use] extern crate der_parser;
406 /// # use der_parser::ber::*;
407 /// # use der_parser::error::BerResult;
408 /// #
409 /// # fn main() {
410 /// let empty = &b""[..];
411 /// let bytes1 = [ 0x30, 0x0a,
412 ///                0x0a, 0x03, 0x00, 0x00, 0x01,
413 ///                0x02, 0x03, 0x01, 0x00, 0x01];
414 /// let bytes2 = [ 0x30, 0x05,
415 ///                0x02, 0x03, 0x01, 0x00, 0x01];
416 /// let expected1  = BerObject::from_seq(vec![
417 ///     BerObject::from_obj(
418 ///         BerObjectContent::ContextSpecific(BerTag(0),
419 ///             Some(Box::new(BerObject::from_obj(BerObjectContent::Enum(1)))))
420 ///     ),
421 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
422 /// ]);
423 /// let expected2  = BerObject::from_seq(vec![
424 ///     BerObject::from_obj(
425 ///         BerObjectContent::ContextSpecific(BerTag(0), None),
426 ///     ),
427 ///     BerObject::from_int_slice(b"\x01\x00\x01"),
428 /// ]);
429 ///
430 /// fn parse_optional_enum(i:&[u8]) -> BerResult {
431 ///     parse_der_optional!(i, parse_ber_enum)
432 /// }
433 /// fn parser(i:&[u8]) -> BerResult {
434 ///     parse_der_sequence_defined_m!(i,
435 ///         parse_optional_enum >>
436 ///         parse_ber_integer
437 ///     )
438 /// };
439 ///
440 /// assert_eq!(parser(&bytes1), Ok((empty, expected1)));
441 /// assert_eq!(parser(&bytes2), Ok((empty, expected2)));
442 /// # }
443 /// ```
444 #[macro_export]
445 macro_rules! parse_der_optional(
446     ($i:expr, $f:ident) => (
447         alt!(
448             $i,
449             complete!(do_parse!(
450                 content: call!($f) >>
451                 (
452                     $crate::ber::BerObject::from_obj(
453                         $crate::ber::BerObjectContent::ContextSpecific($crate::ber::BerTag(0) /* XXX */,Some(Box::new(content)))
454                     )
455                 )
456             )) |
457             complete!(call!($crate::ber::parse_ber_explicit_failed,$crate::ber::BerTag(0) /* XXX */))
458         )
459     )
460 );
461 
462 /// Parse a constructed DER element
463 ///
464 /// Read a constructed DER element (sequence or set, typically) using the provided functions.
465 /// This is generally used to build a struct from a DER sequence.
466 ///
467 /// The returned object is a tuple containing a [`BerObjectHeader`](struct.BerObjectHeader.html)
468 /// and the object returned by the subparser.
469 ///
470 /// To ensure the subparser consumes all bytes from the constructed object, add the `eof!()`
471 /// subparser as the last parsing item.
472 ///
473 /// To verify the tag of the constructed element, use the `TAG` version, for ex
474 /// `parse_der_struct!(i, TAG DerTag::Sequence, parse_der_integer)`
475 ///
476 /// Similar to [`parse_der_sequence_defined`](macro.parse_der_sequence_defined.html), but using the
477 /// `do_parse` macro from nom.
478 /// This allows declaring variables, and running code at the end.
479 ///
480 /// # Examples
481 ///
482 /// Basic struct parsing (ignoring tag):
483 ///
484 /// ```rust
485 /// # #[macro_use] extern crate der_parser;
486 /// # use der_parser::ber::*;
487 /// # use der_parser::error::BerResult;
488 /// #
489 /// # fn main() {
490 /// #[derive(Debug, PartialEq)]
491 /// struct MyStruct<'a>{
492 ///     a: BerObject<'a>,
493 ///     b: BerObject<'a>,
494 /// }
495 ///
496 /// fn parse_struct01(i: &[u8]) -> BerResult<(BerObjectHeader,MyStruct)> {
497 ///     parse_der_struct!(
498 ///         i,
499 ///         a: parse_ber_integer >>
500 ///         b: parse_ber_integer >>
501 ///            eof!() >>
502 ///         ( MyStruct{ a: a, b: b } )
503 ///     )
504 /// }
505 ///
506 /// let bytes = [ 0x30, 0x0a,
507 ///               0x02, 0x03, 0x01, 0x00, 0x01,
508 ///               0x02, 0x03, 0x01, 0x00, 0x00,
509 /// ];
510 /// let empty = &b""[..];
511 /// let expected = (
512 ///     BerObjectHeader{
513 ///         class: 0,
514 ///         structured: 1,
515 ///         tag: BerTag::Sequence,
516 ///         len: 0xa,
517 ///     },
518 ///     MyStruct {
519 ///         a: BerObject::from_int_slice(b"\x01\x00\x01"),
520 ///         b: BerObject::from_int_slice(b"\x01\x00\x00"),
521 ///     }
522 /// );
523 /// let res = parse_struct01(&bytes);
524 /// assert_eq!(res, Ok((empty, expected)));
525 /// # }
526 /// ```
527 ///
528 /// To check the expected tag, use the `TAG <tagname>` variant:
529 ///
530 /// ```rust
531 /// # #[macro_use] extern crate der_parser;
532 /// # use der_parser::ber::*;
533 /// # use der_parser::error::BerResult;
534 /// #
535 /// # fn main() {
536 /// struct MyStruct<'a>{
537 ///     a: BerObject<'a>,
538 ///     b: BerObject<'a>,
539 /// }
540 ///
541 /// fn parse_struct_with_tag(i: &[u8]) -> BerResult<(BerObjectHeader,MyStruct)> {
542 ///     parse_der_struct!(
543 ///         i,
544 ///         TAG BerTag::Sequence,
545 ///         a: parse_ber_integer >>
546 ///         b: parse_ber_integer >>
547 ///            eof!() >>
548 ///         ( MyStruct{ a: a, b: b } )
549 ///     )
550 /// }
551 /// # }
552 /// ```
553 #[macro_export]
554 macro_rules! parse_der_struct(
555     ($i:expr, TAG $tag:expr, $($rest:tt)*) => ({
556         use $crate::ber::{BerObjectHeader,ber_read_element_header};
557         do_parse!(
558             $i,
559             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader|
560                          hdr.structured == 1 && hdr.tag == $tag) >>
561             res: flat_take!(hdr.len as usize, do_parse!( $($rest)* )) >>
562             (hdr,res)
563         )
564     });
565     ($i:expr, $($rest:tt)*) => ({
566         use $crate::ber::{BerObjectHeader,ber_read_element_header};
567         do_parse!(
568             $i,
569             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader| hdr.structured == 1) >>
570             res: flat_take!(hdr.len as usize, do_parse!( $($rest)* )) >>
571             (hdr,res)
572         )
573     });
574 );
575 
576 /// Parse a tagged DER element
577 ///
578 /// Read a tagged DER element using the provided function.
579 ///
580 /// The returned object is either the object returned by the subparser, or a nom error.
581 /// Unlike [`parse_der_explicit`](fn.parse_der_explicit.html) or
582 /// [`parse_der_implicit`](fn.parse_der_implicit.html), the returned values are *not* encapsulated
583 /// in a `BerObject` (they are directly returned, without the tag).
584 ///
585 /// To specify the kind of tag, use the EXPLICIT or IMPLICIT keyword. If no keyword is specified,
586 /// the parsing is EXPLICIT by default.
587 ///
588 /// When parsing IMPLICIT values, the third argument is a [`DerTag`](enum.DerTag.html) defining the
589 /// subtype of the object.
590 ///
591 /// # Examples
592 ///
593 /// The following parses `[2] INTEGER`:
594 ///
595 /// ```rust
596 /// # #[macro_use] extern crate der_parser;
597 /// # use der_parser::ber::{parse_ber_integer, BerObject};
598 /// # use der_parser::error::BerResult;
599 /// #
600 /// # fn main() {
601 /// fn parse_int_explicit(i:&[u8]) -> BerResult<u32> {
602 ///     map_res!(
603 ///         i,
604 ///         parse_der_tagged!(EXPLICIT 2, parse_ber_integer),
605 ///         |x: BerObject| x.as_u32()
606 ///     )
607 /// }
608 ///
609 /// let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
610 /// let res = parse_int_explicit(bytes);
611 /// match res {
612 ///     Ok((rem,val)) => {
613 ///         assert!(rem.is_empty());
614 ///         assert_eq!(val, 0x10001);
615 ///     },
616 ///     _ => assert!(false)
617 /// }
618 /// # }
619 /// ```
620 ///
621 /// The following parses `[2] IMPLICIT INTEGER`:
622 ///
623 /// ```rust
624 /// # #[macro_use] extern crate der_parser;
625 /// # use der_parser::ber::{parse_ber_integer, BerObject, BerTag};
626 /// # use der_parser::error::BerResult;
627 /// #
628 /// # fn main() {
629 /// fn parse_int_implicit(i:&[u8]) -> BerResult<u32> {
630 ///     map_res!(
631 ///         i,
632 ///         parse_der_tagged!(IMPLICIT 2, BerTag::Integer),
633 ///         |x: BerObject| x.as_u32()
634 ///     )
635 /// }
636 ///
637 /// let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
638 /// let res = parse_int_implicit(bytes);
639 /// match res {
640 ///     Ok((rem,val)) => {
641 ///         assert!(rem.is_empty());
642 ///         assert_eq!(val, 0x10001);
643 ///     },
644 ///     _ => assert!(false)
645 /// }
646 /// # }
647 /// ```
648 #[macro_export]
649 macro_rules! parse_der_tagged(
650     ($i:expr, EXPLICIT $tag:expr, $f:ident) => ({
651         use $crate::ber::{BerObjectHeader,ber_read_element_header};
652         do_parse!(
653             $i,
654             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader| hdr.tag.0 == $tag) >>
655             res: flat_take!(hdr.len as usize, call!( $f )) >>
656             (res)
657         )
658     });
659     ($i:expr, EXPLICIT $tag:expr, $submac:ident!( $($args:tt)*)) => ({
660         use $crate::ber::{BerObjectHeader,ber_read_element_header};
661         do_parse!(
662             $i,
663             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader| hdr.tag.0 == $tag) >>
664             res: flat_take!(hdr.len as usize, $submac!( $($args)* )) >>
665             (res)
666         )
667     });
668     ($i:expr, IMPLICIT $tag:expr, $type:expr) => ({
669         use $crate::ber::{BerObjectHeader,ber_read_element_header,ber_read_element_content_as};
670         do_parse!(
671             $i,
672             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader| hdr.tag.0 == $tag) >>
673             res: call!(ber_read_element_content_as, $type, hdr.len as usize, hdr.is_constructed(), 0) >>
674             (BerObject::from_obj(res))
675         )
676     });
677     ($i:expr, $tag:expr, $f:ident) => ( parse_der_tagged!($i, EXPLICIT $tag, $f) );
678 );
679 
680 /// Parse an application DER element
681 ///
682 /// Read an application DER element using the provided functions.
683 /// This is generally used to build a struct from a DER sequence.
684 ///
685 /// The returned object is a tuple containing a [`BerObjectHeader`](struct.BerObjectHeader.html)
686 /// and the object returned by the subparser.
687 ///
688 /// To ensure the subparser consumes all bytes from the constructed object, add the `eof!()`
689 /// subparser as the last parsing item.
690 ///
691 /// # Examples
692 ///
693 /// The following parses `[APPLICATION 2] INTEGER`:
694 ///
695 /// ```rust
696 /// # #[macro_use] extern crate der_parser;
697 /// # use der_parser::ber::*;
698 /// # use der_parser::error::BerResult;
699 /// #
700 /// # fn main() {
701 /// #[derive(Debug, PartialEq)]
702 /// struct SimpleStruct {
703 ///     a: u32,
704 /// };
705 ///
706 /// fn parse_app01(i:&[u8]) -> BerResult<(BerObjectHeader,SimpleStruct)> {
707 ///     parse_der_application!(
708 ///         i,
709 ///         APPLICATION 2,
710 ///         a: map_res!(parse_ber_integer,|x: BerObject| x.as_u32()) >>
711 ///            eof!() >>
712 ///         ( SimpleStruct{ a:a } )
713 ///     )
714 /// }
715 ///
716 /// let bytes = &[0x62, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
717 /// let res = parse_app01(bytes);
718 /// match res {
719 ///     Ok((rem,(hdr,app))) => {
720 ///         assert!(rem.is_empty());
721 ///         assert_eq!(hdr.tag, BerTag::Integer);
722 ///         assert!(hdr.is_application());
723 ///         assert_eq!(hdr.structured, 1);
724 ///         assert_eq!(app, SimpleStruct{ a:0x10001 });
725 ///     },
726 ///     _ => assert!(false)
727 /// }
728 /// # }
729 /// ```
730 #[macro_export]
731 macro_rules! parse_der_application(
732     ($i:expr, APPLICATION $tag:expr, $($rest:tt)*) => ({
733         use $crate::ber::{BerObjectHeader,ber_read_element_header};
734         do_parse!(
735             $i,
736             hdr: verify!(ber_read_element_header, |hdr: &BerObjectHeader|
737                          hdr.class == 0b01 && hdr.tag.0 == $tag) >>
738             res: flat_take!(hdr.len as usize, do_parse!( $($rest)* )) >>
739             (hdr,res)
740         )
741     });
742     ($i:expr, $tag:expr, $($rest:tt)*) => ( parse_der_application!($i, $tag, $($rest)*) );
743 );
744