1use std::io::prelude::*;
2use crate::errors::*;
3
4pub mod armor;
5pub mod errors;
6mod encoding;
7pub mod packet;
8pub use packet::Tag;
9pub mod pubkey;
10pub mod signature;
11pub use signature::Signature;
12
13
14pub struct Parser<R: Read> {
15 r: R,
16 max_alloc: Option<usize>,
17}
18
19impl<R: Read> Parser<R> {
20 pub fn new(r: R) -> Parser<R> {
21 Parser {
22 r,
23 max_alloc: None,
24 }
25 }
26
27 pub fn with_max_alloc(r: R, max_alloc: usize) -> Parser<R> {
28 Parser {
29 r,
30 max_alloc: Some(max_alloc),
31 }
32 }
33
34 pub fn inner(&self) -> &R {
35 &self.r
36 }
37}
38
39impl<R: Read> Iterator for Parser<R> {
40 type Item = (Tag, Vec<u8>);
41
42 fn next(&mut self) -> Option<Self::Item> {
43 let mut packet_body = Vec::new();
44 let tag = packet::read(&mut self.r, &mut packet_body, &self.max_alloc);
45 debug!("Received tag: {:?}", tag);
46
47 match tag {
48 Ok(tag) => Some((tag, packet_body)),
49 _ => None,
50 }
51 }
52}
53
54
55#[cfg(test)]
56mod tests {
57 use armor::read_armored;
58 use std::io::BufReader;
59 use super::*;
60
61 #[test]
62 fn extract_userid_from_pubkey() {
63 let key = include_bytes!("../data/hans_acker.asc");
64 let key = read_armored(&mut BufReader::new(&key[..])).expect("read_armored");
65
66 for (tag, body) in Parser::new(key.as_slice()) {
67 println!("{:?}: {:?}", tag, body);
68 if tag == Tag::UserID {
69 let body = String::from_utf8(body).expect("invalid utf8");
70 println!("UserID: {:?}", body);
71 assert_eq!("Hans Acker (example comment) <hans.acker@example.com>", body);
72 return;
73 }
74 }
75
76 unreachable!("UserID wasn't found");
77 }
78
79 #[test]
80 fn extract_userid_from_pubkey_freebsd() {
81 let key = include_bytes!("../data/freebsd.asc");
82 let key = read_armored(&mut BufReader::new(&key[..])).expect("read_armored");
83
84 for (tag, body) in Parser::new(key.as_slice()) {
85 if tag == Tag::UserID {
87 let body = String::from_utf8(body).expect("invalid utf8");
88 println!("UserID: {:?}", body);
89 assert_eq!("FreeBSD Security Officer <security-officer@FreeBSD.org>", body);
90 return;
91 }
92 }
93
94 unreachable!("UserID wasn't found");
95 }
96
97 #[test]
98 fn extract_userid_from_pubkey_freebsd_with_alloc_limit() {
99 let key = include_bytes!("../data/freebsd.asc");
100 let key = read_armored(&mut BufReader::new(&key[..])).expect("read_armored");
101
102 for (tag, body) in Parser::with_max_alloc(key.as_slice(), 1024 * 1024) {
103 if tag == Tag::UserID {
105 let body = String::from_utf8(body).expect("invalid utf8");
106 println!("UserID: {:?}", body);
107 assert_eq!("FreeBSD Security Officer <security-officer@FreeBSD.org>", body);
108 return;
109 }
110 }
111
112 unreachable!("UserID wasn't found");
113 }
114
115 #[test]
116 fn extract_userid_from_pubkey_freebsd_with_tiny_alloc_limit() {
117 let key = include_bytes!("../data/freebsd.asc");
118 let key = read_armored(&mut BufReader::new(&key[..])).expect("read_armored");
119
120 for (_tag, _body) in Parser::with_max_alloc(key.as_slice(), 3) {
121 unreachable!("max alloc didn't work");
122 }
123 }
124}