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