1use super::*;
8
9impl Writer for Vec<u8> {
13 fn write_all(&mut self, bytes: &[u8]) {
14 self.extend_from_slice(bytes);
15 }
16 fn write_u8(&mut self, byte: u8) {
17 self.push(byte);
19 }
20 fn write_zeros(&mut self, n: usize) {
21 let new_len = self.len().saturating_add(n);
23 self.resize(new_len, 0);
24 }
25}
26
27impl Writer for bytes::BytesMut {
28 fn write_all(&mut self, bytes: &[u8]) {
29 self.extend_from_slice(bytes);
30 }
31}
32
33impl Writeable for [u8] {
36 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
37 b.write_all(self);
38 Ok(())
39 }
40}
41
42impl Writeable for Vec<u8> {
43 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
44 b.write_all(&self[..]);
45 Ok(())
46 }
47}
48
49impl<N> Readable for digest::generic_array::GenericArray<u8, N>
52where
53 N: digest::generic_array::ArrayLength<u8>,
54{
55 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
56 Ok(Self::clone_from_slice(b.take(N::to_usize())?))
58 }
59}
60
61impl<N> Writeable for digest::generic_array::GenericArray<u8, N>
62where
63 N: digest::generic_array::ArrayLength<u8>,
64{
65 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
66 b.write_all(self.as_slice());
67 Ok(())
68 }
69}
70
71macro_rules! impl_u {
107 ( $t:ty, $wrfn:ident, $rdfn:ident ) => {
108 impl Writeable for $t {
109 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
110 b.$wrfn(*self);
111 Ok(())
112 }
113 }
114 impl Readable for $t {
115 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
116 b.$rdfn()
117 }
118 }
119 };
120}
121
122impl_u!(u8, write_u8, take_u8);
123impl_u!(u16, write_u16, take_u16);
124impl_u!(u32, write_u32, take_u32);
125impl_u!(u64, write_u64, take_u64);
126impl_u!(u128, write_u128, take_u128);
127
128mod net_impls {
134 use super::*;
135 use std::net::{Ipv4Addr, Ipv6Addr};
136
137 impl Writeable for Ipv4Addr {
138 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
139 b.write_all(&self.octets()[..]);
140 Ok(())
141 }
142 }
143
144 impl Readable for Ipv4Addr {
145 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
146 Ok(b.take_u32()?.into())
147 }
148 }
149
150 impl Writeable for Ipv6Addr {
151 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
152 b.write_all(&self.octets()[..]);
153 Ok(())
154 }
155 }
156 impl Readable for Ipv6Addr {
157 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
158 Ok(b.take_u128()?.into())
159 }
160 }
161}
162
163#[cfg(feature = "tor-llcrypto")]
165mod ed25519_impls {
166 use super::*;
167 use tor_llcrypto::pk::ed25519;
168
169 impl Writeable for ed25519::PublicKey {
170 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
171 b.write_all(self.as_bytes());
172 Ok(())
173 }
174 }
175 impl Readable for ed25519::PublicKey {
176 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
177 let bytes: [u8; 32] = b.extract()?;
178 Self::from_bytes(&bytes)
179 .map_err(|_| Error::InvalidMessage("Couldn't decode Ed25519 public key".into()))
180 }
181 }
182
183 impl Writeable for ed25519::Ed25519Identity {
184 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
185 b.write_all(self.as_bytes());
186 Ok(())
187 }
188 }
189 impl Readable for ed25519::Ed25519Identity {
190 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
191 let bytes: [u8; 32] = b.extract()?;
192 Ok(Self::new(bytes))
193 }
194 }
195 impl Writeable for ed25519::Signature {
196 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
197 b.write_all(&self.to_bytes()[..]);
198 Ok(())
199 }
200 }
201 impl Readable for ed25519::Signature {
202 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
203 let bytes: [u8; 64] = b.extract()?;
204 Ok(Self::from_bytes(&bytes))
205 }
206 }
207}
208
209#[cfg(feature = "tor-llcrypto")]
211mod curve25519_impls {
212 use super::*;
213 use tor_llcrypto::pk::curve25519::{PublicKey, SharedSecret};
214
215 impl Writeable for PublicKey {
216 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
217 b.write_all(self.as_bytes());
218 Ok(())
219 }
220 }
221 impl Readable for PublicKey {
222 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
223 let bytes: [u8; 32] = b.extract()?;
224 Ok(bytes.into())
225 }
226 }
227 impl Writeable for SharedSecret {
228 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
229 b.write_all(self.as_bytes());
230 Ok(())
231 }
232 }
233}
234
235#[cfg(feature = "tor-llcrypto")]
237mod rsa_impls {
238 use super::*;
239 use tor_llcrypto::pk::rsa::*;
240
241 impl Writeable for RsaIdentity {
242 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
243 b.write_all(self.as_bytes());
244 Ok(())
245 }
246 }
247 impl Readable for RsaIdentity {
248 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
249 let m = b.take(RSA_ID_LEN)?;
250 RsaIdentity::from_bytes(m)
251 .ok_or_else(|| tor_error::internal!("wrong number of bytes from take").into())
252 }
253 }
254}
255
256mod digest_impls {
258 use super::*;
259 use digest::{CtOutput, OutputSizeUser};
260 impl<T: OutputSizeUser> WriteableOnce for CtOutput<T> {
261 fn write_into<B: Writer + ?Sized>(self, b: &mut B) -> EncodeResult<()> {
262 let code = self.into_bytes();
263 b.write_all(&code[..]);
264 Ok(())
265 }
266 }
267 impl<T: OutputSizeUser> Readable for CtOutput<T> {
268 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
269 let array = digest::generic_array::GenericArray::take_from(b)?;
270 Ok(CtOutput::new(array))
271 }
272 }
273}
274
275mod u8_array_impls {
277 use super::*;
278 impl<const N: usize> Writeable for [u8; N] {
279 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
280 b.write_all(&self[..]);
281 Ok(())
282 }
283 }
284
285 impl<const N: usize> Readable for [u8; N] {
286 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
287 let mut array = [0_u8; N];
290 b.take_into(&mut array[..])?;
291 Ok(array)
292 }
293 }
294}
295
296#[cfg(feature = "tor-llcrypto")]
298mod ctbytearray_impls {
299 use super::*;
300 use tor_llcrypto::util::ct::CtByteArray;
301 impl<const N: usize> Writeable for CtByteArray<N> {
302 fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
303 b.write_all(&self.as_ref()[..]);
304 Ok(())
305 }
306 }
307
308 impl<const N: usize> Readable for CtByteArray<N> {
309 fn take_from(b: &mut Reader<'_>) -> Result<Self> {
310 Ok(CtByteArray::from(b.extract::<[u8; N]>()?))
311 }
312 }
313}
314
315#[cfg(test)]
316mod tests {
317 #![allow(clippy::unwrap_used)]
318 use crate::{Reader, Writer};
319 #[cfg(feature = "tor-llcrypto")]
320 use hex_literal::hex;
321
322 macro_rules! check_encode {
323 ($e:expr, $e2:expr) => {
324 let mut w = Vec::new();
325 w.write(&$e).expect("encoding failed");
326 assert_eq!(&w[..], &$e2[..]);
327 };
328 }
329 macro_rules! check_decode {
330 ($t:ty, $e:expr, $e2:expr) => {
331 let mut b = Reader::from_slice_for_test(&$e[..]);
332 let obj: $t = b.extract().unwrap();
333 assert_eq!(obj, $e2);
334 assert!(b.should_be_exhausted().is_ok());
335 };
336 }
337 macro_rules! check_roundtrip {
338 ($t:ty, $e:expr, $e2:expr) => {
339 check_encode!($e, $e2);
340 check_decode!($t, $e2, $e);
341 };
342 }
343 #[cfg(feature = "tor-llcrypto")]
344 macro_rules! check_bad {
345 ($t:ty, $e:expr) => {
346 let mut b = Reader::from_slice_for_test(&$e[..]);
347 let len_orig = b.remaining();
348 let res: Result<$t, _> = b.extract();
349 assert!(res.is_err());
350 assert_eq!(b.remaining(), len_orig);
351 };
352 }
353 #[test]
354 fn vec_u8() {
355 let v: Vec<u8> = vec![1, 2, 3, 4];
356 check_encode!(v, b"\x01\x02\x03\x04");
357 }
358
359 #[test]
360 fn genarray() {
361 use digest::generic_array as ga;
362 let a: ga::GenericArray<u8, ga::typenum::U7> = [4, 5, 6, 7, 8, 9, 10].into();
363 check_roundtrip!(ga::GenericArray<u8, ga::typenum::U7>,
364 a,
365 [4, 5, 6, 7, 8, 9, 10]);
366 }
367
368 #[test]
369 fn roundtrip_u64() {
370 check_roundtrip!(u64, 0x4040111_u64, [0, 0, 0, 0, 4, 4, 1, 17]);
371 }
372
373 #[test]
374 fn u8_array() {
375 check_roundtrip!(
376 [u8; 16],
377 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
378 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
379 );
380 }
381
382 #[test]
383 fn ipv4addr() {
384 use std::net::Ipv4Addr;
385 check_roundtrip!(Ipv4Addr, Ipv4Addr::new(192, 168, 0, 1), [192, 168, 0, 1]);
386 }
387
388 #[test]
389 fn ipv6addr() {
390 use std::net::Ipv6Addr;
391 check_roundtrip!(
392 Ipv6Addr,
393 Ipv6Addr::new(65535, 77, 1, 1, 1, 0, 0, 0),
394 [255, 255, 0, 77, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
395 );
396 }
397
398 #[cfg(feature = "tor-llcrypto")]
399 #[test]
400 fn ed25519() {
401 use tor_llcrypto::pk::ed25519;
402 let b = &hex!(
403 "68a6cee11d2883661f5876f7aac748992cd140f
404 cfc36923aa957d04b5f8967ff"
405 );
406 check_roundtrip!(
407 ed25519::PublicKey,
408 ed25519::PublicKey::from_bytes(b).unwrap(),
409 b
410 );
411 let b = &hex!(
412 "68a6cee11d2883661f5876f7aac748992cd140f
413 cfc36923aa957d04b5f8967"
414 ); check_bad!(ed25519::PublicKey, b);
416 let b = &hex!(
417 "68a6cee11d2883661f5876f7aac748992cd140f
418 cfc36923aa957d04b5f896700"
419 ); check_bad!(ed25519::PublicKey, b);
421
422 let sig = &hex!(
423 "b8842c083a56076fc27c8af21211f9fe57d1c32d9d
424 c804f76a8fa858b9ab43622b9e8335993c422eab15
425 6ebb5a047033f35256333a47a508b02699314d22550e"
426 );
427 check_roundtrip!(ed25519::Signature, ed25519::Signature::from_bytes(sig), sig);
428
429 }
439
440 #[cfg(feature = "tor-llcrypto")]
441 #[test]
442 fn curve25519() {
443 use tor_llcrypto::pk::curve25519;
444 let b = &hex!("5f6df7a2fe3bcf1c9323e9755250efd79b9db4ed8f3fd21c7515398b6662a365");
445 let pk: curve25519::PublicKey = (*b).into();
446 check_roundtrip!(curve25519::PublicKey, pk, b);
447 }
448
449 #[cfg(feature = "tor-llcrypto")]
450 #[test]
451 fn rsa_id() {
452 use tor_llcrypto::pk::rsa::RsaIdentity;
453 let b = &hex!("9432D4CEA2621ED09F5A8088BE0E31E0D271435C");
454 check_roundtrip!(RsaIdentity, RsaIdentity::from_bytes(b).unwrap(), b);
455 }
456}