sloppy_rfc4880/
lib.rs

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            // println!("{:?}: {:?}", tag, body);
86            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            // println!("{:?}: {:?}", tag, body);
104            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}