1use std::io::{self, Write, Read};
2use byteorder::{WriteBytesExt, BigEndian, ReadBytesExt};
3
4use super::*;
5
6pub trait DER: Sized {
42 fn der_universal_tag() -> UniversalTag;
44 fn der_content() -> ContentType;
46 fn der_encode_content(&self, w: &mut Write) -> io::Result<()>;
48 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self>;
50 fn der_intermediate(&self) -> io::Result<Intermediate> {
52 let mut buf = vec![];
53 try!(self.der_encode_content(&mut buf));
54 Ok(Intermediate::new(Class::Universal,
55 Self::der_content(),
56 Self::der_universal_tag() as u32)
57 .with_content(buf))
58 }
59 fn der_encode(&self, w: &mut Write) -> io::Result<()> {
61 try!(try!(self.der_intermediate()).encode(w));
62 Ok(())
63 }
64 fn der_bytes(&self) -> io::Result<Vec<u8>> {
66 let mut stream = Vec::new();
67 try!(self.der_encode(&mut stream));
68 Ok(stream)
69 }
70 fn der_from_intermediate(i: Intermediate) -> io::Result<Self> {
72 let length = i.content.len();
73 let mut stream = io::Cursor::new(i.content);
74 Self::der_decode_content(&mut stream, length)
75 }
76 fn der_decode(r: &mut Read) -> io::Result<Self> {
78 let i = try!(Intermediate::decode(r));
79 Self::der_from_intermediate(i)
80 }
81 fn der_from_bytes(bytes: Vec<u8>) -> io::Result<Self> {
83 let mut stream = io::Cursor::new(bytes);
84 Self::der_decode(&mut stream)
85 }
86}
87
88impl DER for bool {
90 fn der_universal_tag() -> UniversalTag {
91 UniversalTag::Boolean
92 }
93
94 fn der_content() -> ContentType {
95 ContentType::Primitive
96 }
97
98 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
99 match self {
100 &true => try!(w.write_u8(0xFF)),
101 &false => try!(w.write_u8(0x00)),
102 }
103 Ok(())
104 }
105
106 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
107 if length != 1 {
108 return Err(io::Error::new(io::ErrorKind::InvalidInput,
109 "boolean value longer that 1 octet"));
110 }
111 Ok(match try!(r.read_u8()) {
112 0x00 => false,
113 _ => true,
114 })
115 }
116}
117
118impl DER for i32 {
119 fn der_universal_tag() -> UniversalTag {
120 UniversalTag::Integer
121 }
122
123 fn der_content() -> ContentType {
124 ContentType::Primitive
125 }
126
127 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
128 let mut bytes = Vec::new();
129 try!(bytes.write_i32::<BigEndian>(self.clone()));
130 let i = 0;
131 loop {
132 if bytes[i] == 0 && i != (bytes.len() - 1) &&
133 (bytes[i + 1] == 0 || bytes[i + 1] & 0x80 == 0) {
134 bytes.remove(i);
135 } else if bytes[i] == 0xff && i != (bytes.len() - 1) &&
136 (bytes[i + 1] == 0xff || bytes[i + 1] & 0x80 == 0x80) {
137 bytes.remove(i);
138 } else {
139 break;
140 }
141 }
142 try!(w.write(&bytes));
143 Ok(())
144 }
145
146 #[allow(overflowing_literals)]
147 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
148 let mut encoded = r.take(length as u64);
149 let mut buffer = Vec::new();
150 try!(encoded.read_to_end(&mut buffer));
151 let mut value = 0;
152 let mut i = buffer.len();
153 if i == 0 { return Err(io::Error::new(io::ErrorKind::InvalidInput, "Integer with zero content octets"));
155 }
156 let fb = buffer[0];
157 if fb & 0x80 == 0x80 {
158 value = 0xffffffff;
159 }
160 for byte in buffer {
161 i -= 1;
162 if i > 3 {
163 return Err(io::Error::new(io::ErrorKind::InvalidInput,
165 "Trying to decode too big integer"));
166 }
167 if fb & 0x80 == 0x80 {
168 value = value & !(0xff << i * 8);
169 }
170 value = value | (byte as i32) << i * 8;
173 }
174 Ok(value)
179 }
180}
181
182impl DER for String {
183 fn der_universal_tag() -> UniversalTag {
184 UniversalTag::UTF8String
185 }
186
187 fn der_content() -> ContentType {
188 ContentType::Primitive
189 }
190
191 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
192 try!(w.write(self.as_bytes()));
193 Ok(())
194 }
195
196 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
197 let mut encoded = r.take(length as u64);
198 let mut buffer = String::new();
199 try!(encoded.read_to_string(&mut buffer));
200 Ok(buffer)
201 }
202}
203
204impl<'a> DER for &'a str {
205 fn der_universal_tag() -> UniversalTag {
206 UniversalTag::UTF8String
207 }
208
209 fn der_content() -> ContentType {
210 ContentType::Primitive
211 }
212
213 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
214 try!(w.write(self.as_bytes()));
215 Ok(())
216 }
217
218 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
219 let mut encoded = r.take(length as u64);
220 let mut buffer = String::new();
221 try!(encoded.read_to_string(&mut buffer));
222 Ok("not_implemented_yet")
223 }
224}
225
226impl<T: DER> DER for Vec<T> {
227 fn der_universal_tag() -> UniversalTag {
228 UniversalTag::Sequence
229 }
230
231 fn der_content() -> ContentType {
232 ContentType::Constructed
233 }
234
235 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
236 for item in self.iter() {
237 try!(item.der_encode(w));
238 }
239 Ok(())
240 }
241
242 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
243 let mut encoded = r.take(length as u64);
244 let mut vector = Vec::new();
245 while encoded.limit() > 0 {
246 vector.push(try!(T::der_decode(&mut encoded)));
247 }
248 Ok(vector)
249 }
250}
251
252impl DER for Vec<u8> {
253 fn der_universal_tag() -> UniversalTag {
254 UniversalTag::OctetString
255 }
256
257 fn der_content() -> ContentType {
258 ContentType::Primitive
259 }
260
261 fn der_encode_content(&self, w: &mut Write) -> io::Result<()> {
262 try!(w.write(self));
263 Ok(())
264 }
265
266 fn der_decode_content(r: &mut Read, length: usize) -> io::Result<Self> {
267 let mut buffer = Vec::new();
268 try!(r.take(length as u64).read_to_end(&mut buffer));
269 Ok(buffer)
270 }
271}