1#![allow(dead_code)]
2
3use std::io::Cursor;
4use std::io::Read;
5use std::io::Result;
6
7use byteorder::ReadBytesExt;
8use byteorder::WriteBytesExt;
9
10#[derive(Debug, Clone)]
11pub enum Class {
12 Universal,
13 Application,
14 ContextSpecific,
15 Private,
16}
17
18#[derive(Debug, Clone)]
19pub struct TagSpec {
20 class: Class,
21 constructed: bool,
22 tag: u16,
23}
24
25pub fn read_tag(cursor: &mut Cursor<&[u8]>) -> Result<u8> {
26 cursor.read_u8()
27}
28
29pub fn read_tag_s(cursor: &mut Cursor<&[u8]>) -> Result<TagSpec> {
30 let first = cursor.read_u8()?;
31 let class = {
32 match first & 0xc0 {
33 0 => Class::Universal,
34 0x40 => Class::Application,
35 0x80 => Class::ContextSpecific,
36 0xc0 => Class::Private,
37 _ => Class::Universal,
38 }
39 };
40 let constructed = (first & 0x20) == 0x20;
41 if (first & 0x1f) != 0x1f {
42 Ok(TagSpec {
43 class,
44 constructed,
45 tag: (first & 0x1f) as u16,
46 })
47 } else {
48 let mut tag: u16 = 0;
49 loop {
50 let next = cursor.read_u8()?;
51 tag <<= 7;
52 tag |= (next & 0x7f) as u16;
53 if next & 0x80 == 0 {
54 break Ok(TagSpec {
55 class,
56 constructed,
57 tag,
58 });
59 }
60 }
61 }
62}
63
64pub fn read_size(cursor: &mut Cursor<&[u8]>) -> Result<usize> {
65 let b1 = cursor.read_u8()? as usize;
66 if b1 & 0x80 == 0 {
67 return Ok(b1);
68 }
69 let size = b1 & 0x7f;
70 let mut out = 0;
71 for _ in 0..size {
72 let c = cursor.read_u8()? as usize;
73 out = (out << 8) + c;
74 }
75 Ok(out)
76}
77
78pub fn read_uint(cursor: &mut Cursor<&[u8]>) -> Result<u32> {
79 read_tag(cursor)?;
80 let size = read_size(cursor)?;
81 let mut out = 0;
82 for _ in 0..size {
83 let c = cursor.read_u8()? as u32;
84 out <<= 8;
85 out |= c;
86 }
87 Ok(out)
88}
89
90pub fn read_string(cursor: &mut Cursor<&[u8]>) -> Result<String> {
91 read_tag(cursor)?;
92 let size = read_size(cursor)?;
93 let mut buf = vec![0; size];
94 cursor.read_exact(&mut buf)?;
95 match std::str::from_utf8(&buf) {
96 Ok(s) => Ok(s.to_owned()),
97 Err(e) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
98 }
99}
100
101pub fn write_tag(buf: &mut Vec<u8>, tag: u8) -> Result<()> {
102 buf.write_u8(tag)
103}
104
105pub fn write_tag_s(buf: &mut Vec<u8>, class: u8, contructed: bool, tag: u16) -> Result<()> {
106 let mut first = class;
107 if contructed {
108 first |= 0x20
109 }
110 if tag <= 30 {
111 first |= tag as u8;
112 buf.write_u8(first)
113 } else {
114 first |= 0x1f;
115 buf.write_u8(first)?;
116 let mut tmp = tag;
117 while tmp > 0 {
118 if tmp > 0x7f {
119 buf.write_u8((tmp & 0x7f) as u8)?;
120 tmp >>= 7;
121 } else {
122 buf.write_u8(tmp as u8)?;
123 break;
124 }
125 }
126 Ok(())
127 }
128}
129pub fn write_tag_s2(buf: &mut Vec<u8>, ctag: &TagSpec) -> Result<()> {
130 let class = {
131 match ctag.class {
132 Class::Universal => 0,
133 Class::Application => 0x40,
134 Class::ContextSpecific => 0x80,
135 Class::Private => 0xc0,
136 }
137 };
138 write_tag_s(buf, class, ctag.constructed, ctag.tag)
139}
140
141pub fn write_len(buf: &mut Vec<u8>, len: u8) -> Result<()> {
142 buf.write_u8(len)
143}
144
145pub fn write_enum(buf: &mut Vec<u8>, val: u8) -> Result<()> {
146 write_tag(buf, 0xa)?;
147 write_len(buf, 1)?;
148 buf.write_u8(val)
149}
150fn write_octet_string(buf: &mut Vec<u8>, val: &[u8]) -> Result<()> {
151 write_tag(buf, 0x4)?;
152 write_len(buf, val.len() as u8)?;
153 buf.extend_from_slice(val);
154 Ok(())
155}
156fn write_string(buf: &mut Vec<u8>, val: &str) -> Result<()> {
157 write_tag(buf, 0xc)?;
158 let bytes = val.as_bytes();
159 write_len(buf, bytes.len() as u8)?;
160 buf.extend_from_slice(bytes);
161 Ok(())
162}
163fn write_string_with_tag(buf: &mut Vec<u8>, tag: u8, val: &str) -> Result<()> {
164 write_tag(buf, tag)?;
165 let bytes = val.as_bytes();
166 write_len(buf, bytes.len() as u8)?;
167 buf.extend_from_slice(bytes);
168 Ok(())
169}
170fn write_bool(buf: &mut Vec<u8>, val: bool) -> Result<()> {
171 write_tag(buf, 0x1)?;
172 write_len(buf, 1)?;
173 if val {
174 buf.write_u8(0xff)?;
175 } else {
176 buf.write_u8(0)?;
177 }
178 Ok(())
179}
180
181fn write_octet_string_with_tag(buf: &mut Vec<u8>, tag: u8, val: &[u8]) -> Result<()> {
182 write_tag(buf, tag)?;
183 write_len(buf, val.len() as u8)?;
184 buf.extend_from_slice(val);
185 Ok(())
186}
187
188pub fn write_int(buf: &mut Vec<u8>, val: u32) -> Result<()> {
189 write_tag(buf, 0x2)?;
190 if val < 0x80 {
191 write_len(buf, 1)?;
192 buf.write_u8(val as u8)
193 } else if val < 0x8000 {
194 write_len(buf, 2)?;
195 buf.write_u8((val >> 8) as u8)?;
196 buf.write_u8(val as u8)
197 } else if val < 0x800000 {
198 write_len(buf, 3)?;
199 buf.write_u8((val >> 16) as u8)?;
200 buf.write_u8((val >> 8) as u8)?;
201 buf.write_u8(val as u8)
202 } else {
203 Err(std::io::Error::from(std::io::ErrorKind::Unsupported))
204 }
205}
206
207#[derive(Debug, Clone)]
208struct Asn1EncoderStackEntry {
209 pos: usize,
210}
211
212#[derive(Debug, Clone)]
213pub struct Encoder {
214 buffer: Vec<u8>,
215 stack: Vec<Asn1EncoderStackEntry>,
216}
217
218impl Encoder {
219 pub fn new() -> Self {
220 Self {
221 buffer: Vec::new(),
222 stack: Vec::new(),
223 }
224 }
225 pub fn start_seq(&mut self, tag: u8) -> Result<()> {
226 write_tag(&mut self.buffer, tag)?;
227 self.stack.push(Asn1EncoderStackEntry {
228 pos: self.buffer.len() - 1,
229 });
230 write_len(&mut self.buffer, 0)
231 }
232 pub fn fix(&mut self) {
233 while !self.stack.is_empty() {
234 self.end_seq()
235 }
236 }
237 pub fn end_seq(&mut self) {
238 let i = self.stack.pop();
239 if let Some(a) = i {
240 let s = self.buffer.len() - a.pos - 2;
241 if s < 0x80 {
243 self.buffer[a.pos + 1] = s as u8;
244 } else if s <= 0xff {
245 self.buffer[a.pos + 1] = 0x81;
246 self.buffer.insert(a.pos + 2, s as u8);
247 } else {
248 self.buffer[a.pos + 1] = 0x82;
249 self.buffer.insert(a.pos + 2, (s >> 8) as u8);
250 self.buffer.insert(a.pos + 3, s as u8);
251 }
252 }
253 }
254 pub fn write_octet_string(&mut self, val: &[u8]) -> Result<()> {
255 write_octet_string(&mut self.buffer, val)
256 }
257 pub fn write_string(&mut self, val: &str) -> Result<()> {
258 write_string(&mut self.buffer, val)
259 }
260 pub fn write_string_with_tag(&mut self, tag: u8, val: &str) -> Result<()> {
261 write_string_with_tag(&mut self.buffer, tag, val)
262 }
263 pub fn write_octet_string_with_tag(&mut self, tag: u8, val: &[u8]) -> Result<()> {
264 write_octet_string_with_tag(&mut self.buffer, tag, val)
265 }
266 pub fn write_enum(&mut self, val: u8) -> Result<()> {
267 write_enum(&mut self.buffer, val)
268 }
269 pub fn write_int(&mut self, val: u32) -> Result<()> {
270 write_int(&mut self.buffer, val)
271 }
272 pub fn write_bool(&mut self, val: bool) -> Result<()> {
273 write_bool(&mut self.buffer, val)
274 }
275 pub fn write_raw(&mut self, data: &[u8]) {
276 self.buffer.extend_from_slice(data);
277 }
278 pub fn write_oid(&mut self, val: &str) -> Result<()> {
279 match const_oid::ObjectIdentifier::new(val) {
280 Ok(o) => self.write_octet_string_with_tag(0x6, o.as_bytes()),
281 Err(e) => Err(std::io::Error::new(
282 std::io::ErrorKind::InvalidData,
283 format!("can't parse oid {:?}", e),
284 )),
285 }
286 }
287
288 pub fn encode(mut self) -> Vec<u8> {
289 self.fix();
290 self.buffer
291 }
292}
293
294impl Default for Encoder {
295 fn default() -> Self {
296 Self::new()
297 }
298}
299
300#[test]
301fn a_test() {
302 assert_eq!(
303 read_size(&mut std::io::Cursor::new(&[0x82, 0x27, 0x32])).unwrap(),
304 10034
305 );
306 assert_eq!(read_size(&mut std::io::Cursor::new(&[0x08])).unwrap(), 8);
307 let mut buf = Vec::new();
308 write_int(&mut buf, 127).unwrap();
309 assert_eq!(buf, vec![0x02, 0x01, 0x7f]);
310
311 let mut buf = Vec::new();
312 write_int(&mut buf, 128).unwrap();
313 assert_eq!(buf, vec![0x02, 0x02, 0x0, 0x80]);
314
315 let mut buf = Vec::new();
316 write_int(&mut buf, 256).unwrap();
317 assert_eq!(buf, vec![0x02, 0x02, 0x1, 0x0]);
318
319 let mut buf = Vec::new();
320 write_bool(&mut buf, true).unwrap();
321 assert_eq!(buf, vec![0x01, 0x01, 0xff]);
322}
323
324#[test]
325fn tag_test() {
326 let mut buf = Vec::new();
327 write_tag_s(&mut buf, 0xc0, false, 10).unwrap();
328 write_len(&mut buf, 3).unwrap();
329 std::io::Write::write_all(&mut buf, "abc".as_bytes()).unwrap();
330 let mut cursor = Cursor::new(buf.as_ref());
331 println!(
332 "{:?} {:?}",
333 hex::encode(&buf),
334 read_tag_s(&mut cursor).unwrap()
335 );
336
337 let mut buf = Vec::new();
338 write_tag_s(&mut buf, 0xc0, false, 31).unwrap();
339 write_len(&mut buf, 3).unwrap();
340 std::io::Write::write_all(&mut buf, "abc".as_bytes()).unwrap();
341 let mut cursor = Cursor::new(buf.as_ref());
342 println!(
343 "{:?} {:?}",
344 hex::encode(&buf),
345 read_tag_s(&mut cursor).unwrap()
346 );
347
348 let mut buf = Vec::new();
349 write_tag_s(&mut buf, 0xc0, false, 100).unwrap();
350 write_len(&mut buf, 3).unwrap();
351 std::io::Write::write_all(&mut buf, "abc".as_bytes()).unwrap();
352 let mut cursor = Cursor::new(buf.as_ref());
353 println!(
354 "{:?} {:?}",
355 hex::encode(&buf),
356 read_tag_s(&mut cursor).unwrap()
357 );
358}