1
//! Implementations of Writeable and Readable for several items that
2
//! we use in Tor.
3
//!
4
//! These don't need to be in a separate module, but for convenience
5
//! this is where I'm putting them.
6

            
7
use super::*;
8
use generic_array::GenericArray;
9

            
10
// ----------------------------------------------------------------------
11

            
12
/// Vec<u8> is the main type that implements Writer.
13
impl Writer for Vec<u8> {
14
263080
    fn write_all(&mut self, bytes: &[u8]) {
15
263080
        self.extend_from_slice(bytes);
16
263080
    }
17
67162
    fn write_u8(&mut self, byte: u8) {
18
67162
        // specialize for performance
19
67162
        self.push(byte);
20
67162
    }
21
97
    fn write_zeros(&mut self, n: usize) {
22
97
        // specialize for performance
23
97
        let new_len = self.len() + n;
24
97
        self.resize(new_len, 0);
25
97
    }
26
}
27

            
28
impl Writer for bytes::BytesMut {
29
1545
    fn write_all(&mut self, bytes: &[u8]) {
30
1545
        self.extend_from_slice(bytes);
31
1545
    }
32
}
33

            
34
// ----------------------------------------------------------------------
35

            
36
impl<'a> Writeable for [u8] {
37
181
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
38
181
        b.write_all(self);
39
181
    }
40
}
41

            
42
impl Writeable for Vec<u8> {
43
8
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
44
8
        b.write_all(&self[..]);
45
8
    }
46
}
47

            
48
// The GenericArray type is defined to work around a limitation in Rust's
49
// type system.  Ideally we can get rid of GenericArray entirely at some
50
// point down the line.
51
//
52
// For now, we only use GenericArray<u8>, so that's all we'll declare, since
53
// it permits a faster implementation.
54
impl<N> Readable for GenericArray<u8, N>
55
where
56
    N: generic_array::ArrayLength<u8>,
57
{
58
16
    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
59
16
        // safety -- "take" returns the requested bytes or error.
60
16
        Ok(Self::clone_from_slice(b.take(N::to_usize())?))
61
16
    }
62
}
63

            
64
impl<N> Writeable for GenericArray<u8, N>
65
where
66
    N: generic_array::ArrayLength<u8>,
67
{
68
1
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
69
1
        b.write_all(self.as_slice());
70
1
    }
71
}
72

            
73
/*
74
// We could add these as well as our implementations over GenericArray<u8>,
75
// except that we don't actually need them, and Rust doesn't support
76
// specialization.
77

            
78
impl<T, N> Readable for GenericArray<T, N>
79
where
80
    T: Readable + Clone,
81
    N: generic_array::ArrayLength<T>,
82
{
83
    fn take_from(b: &mut Reader<'_>) -> Result<Self> {
84
        let mut v: Vec<T> = Vec::new();
85
        for _ in 0..N::to_usize() {
86
            v.push(T::take_from(b)?);
87
        }
88
        // TODO(nickm) I wish I didn't have to clone this.
89
        Ok(Self::from_slice(v.as_slice()).clone())
90
    }
91
}
92

            
93
impl<T, N> Writeable for GenericArray<T, N>
94
where
95
    T: Writeable,
96
    N: generic_array::ArrayLength<T>,
97
{
98
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
99
        for item in self {
100
            item.write_onto(b)
101
        }
102
    }
103
}
104
*/
105

            
106
/// Make Readable and Writeable implementations for a provided
107
/// unsigned type, delegating to the `read_uNN` and `write_uNN` functions.
108
macro_rules! impl_u {
109
    ( $t:ty, $wrfn:ident, $rdfn:ident ) => {
110
        impl Writeable for $t {
111
1
            fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
112
1
                b.$wrfn(*self)
113
1
            }
114
        }
115
        impl Readable for $t {
116
1
            fn take_from(b: &mut Reader<'_>) -> Result<Self> {
117
1
                b.$rdfn()
118
1
            }
119
        }
120
    };
121
}
122

            
123
impl_u!(u8, write_u8, take_u8);
124
impl_u!(u16, write_u16, take_u16);
125
impl_u!(u32, write_u32, take_u32);
126
impl_u!(u64, write_u64, take_u64);
127
impl_u!(u128, write_u128, take_u128);
128

            
129
// ----------------------------------------------------------------------
130

            
131
/// Implement Readable and Writeable for IPv4 and IPv6 addresses.
132
///
133
/// These are encoded as a sequence of octets, not as strings.
134
mod net_impls {
135
    use super::*;
136
    use std::net::{Ipv4Addr, Ipv6Addr};
137

            
138
    impl Writeable for Ipv4Addr {
139
312
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
140
312
            b.write_all(&self.octets()[..]);
141
312
        }
142
    }
143

            
144
    impl Readable for Ipv4Addr {
145
261
        fn take_from(r: &mut Reader<'_>) -> Result<Self> {
146
261
            Ok(r.take_u32()?.into())
147
261
        }
148
    }
149

            
150
    impl Writeable for Ipv6Addr {
151
135
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
152
135
            b.write_all(&self.octets()[..]);
153
135
        }
154
    }
155
    impl Readable for Ipv6Addr {
156
157
        fn take_from(r: &mut Reader<'_>) -> Result<Self> {
157
157
            Ok(r.take_u128()?.into())
158
157
        }
159
    }
160
}
161

            
162
/// Implement Readable and Writeable for Ed25519 types.
163
mod ed25519_impls {
164
    use super::*;
165
    #[allow(unused_imports)] // This `use` is needed with ed25519 < 1.3.0
166
    use signature::Signature;
167
    use tor_llcrypto::pk::ed25519;
168

            
169
    impl Writeable for ed25519::PublicKey {
170
7
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
171
7
            b.write_all(self.as_bytes());
172
7
        }
173
    }
174
    impl Readable for ed25519::PublicKey {
175
921
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
176
921
            let bytes = b.take(32)?;
177
920
            Self::from_bytes(array_ref![bytes, 0, 32])
178
920
                .map_err(|_| Error::BadMessage("Couldn't decode Ed25519 public key"))
179
921
        }
180
    }
181

            
182
    impl Writeable for ed25519::Ed25519Identity {
183
585
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
184
585
            b.write_all(self.as_bytes());
185
585
        }
186
    }
187
    impl Readable for ed25519::Ed25519Identity {
188
161
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
189
161
            let bytes = b.take(32)?;
190
161
            Ok(Self::new(*array_ref![bytes, 0, 32]))
191
161
        }
192
    }
193
    impl Writeable for ed25519::Signature {
194
1
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
195
1
            b.write_all(&self.to_bytes()[..]);
196
1
        }
197
    }
198
    impl Readable for ed25519::Signature {
199
938
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
200
938
            let bytes = b.take(64)?;
201
938
            Self::from_bytes(array_ref![bytes, 0, 64])
202
938
                .map_err(|_| Error::BadMessage("Couldn't decode Ed25519 signature."))
203
938
        }
204
    }
205
}
206

            
207
/// Implement Readable and Writeable for Curve25519 types.
208
mod curve25519_impls {
209
    use super::*;
210
    use tor_llcrypto::pk::curve25519::{PublicKey, SharedSecret};
211

            
212
    impl Writeable for PublicKey {
213
290
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
214
290
            b.write_all(self.as_bytes());
215
290
        }
216
    }
217
    impl Readable for PublicKey {
218
883
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
219
883
            let bytes = b.take(32)?;
220
883
            Ok((*array_ref![bytes, 0, 32]).into())
221
883
        }
222
    }
223
    impl Writeable for SharedSecret {
224
70
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
225
70
            b.write_all(self.as_bytes());
226
70
        }
227
    }
228
}
229

            
230
/// Implement readable and writeable for the the RsaIdentity type.
231
mod rsa_impls {
232
    use super::*;
233
    use tor_llcrypto::pk::rsa::*;
234

            
235
    impl Writeable for RsaIdentity {
236
2312
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
237
2312
            b.write_all(self.as_bytes());
238
2312
        }
239
    }
240
    impl Readable for RsaIdentity {
241
484
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
242
484
            let m = b.take(RSA_ID_LEN)?;
243
484
            RsaIdentity::from_bytes(m)
244
484
                .ok_or_else(|| tor_error::internal!("wrong number of bytes from take").into())
245
484
        }
246
    }
247
}
248

            
249
/// Implement readable and writeable for the digest::CtOutput type.
250
mod digest_impls {
251
    use super::*;
252
    use digest::{CtOutput, OutputSizeUser};
253
    impl<T: OutputSizeUser> WriteableOnce for CtOutput<T> {
254
37
        fn write_into<B: Writer + ?Sized>(self, b: &mut B) {
255
37
            let code = self.into_bytes();
256
37
            b.write(&code[..]);
257
37
        }
258
    }
259
    impl<T: OutputSizeUser> Readable for CtOutput<T> {
260
15
        fn take_from(b: &mut Reader<'_>) -> Result<Self> {
261
15
            let array = GenericArray::take_from(b)?;
262
15
            Ok(CtOutput::new(array))
263
15
        }
264
    }
265
}
266

            
267
/// Implement readable and writeable for u8 arrays.
268
mod u8_array_impls {
269
    use super::*;
270
    impl<const N: usize> Writeable for [u8; N] {
271
25
        fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) {
272
25
            b.write_all(&self[..]);
273
25
        }
274
    }
275

            
276
    impl<const N: usize> Readable for [u8; N] {
277
523
        fn take_from(r: &mut Reader<'_>) -> Result<Self> {
278
523
            // note: Conceivably this should use MaybeUninit, but let's
279
523
            // avoid that unless there is some measurable benefit.
280
523
            let mut array = [0_u8; N];
281
523
            r.take_into(&mut array[..])?;
282
523
            Ok(array)
283
523
        }
284
    }
285
}
286

            
287
#[cfg(test)]
288
mod tests {
289
    #![allow(clippy::unwrap_used)]
290
    use crate::{Reader, Writer};
291
    use hex_literal::hex;
292
    macro_rules! check_encode {
293
        ($e:expr, $e2:expr) => {
294
            let mut w = Vec::new();
295
            w.write(&$e);
296
            assert_eq!(&w[..], &$e2[..]);
297
        };
298
    }
299
    macro_rules! check_decode {
300
        ($t:ty, $e:expr, $e2:expr) => {
301
            let mut r = Reader::from_slice(&$e[..]);
302
            let obj: $t = r.extract().unwrap();
303
            assert_eq!(obj, $e2);
304
            assert!(r.should_be_exhausted().is_ok());
305
        };
306
    }
307
    macro_rules! check_roundtrip {
308
        ($t:ty, $e:expr, $e2:expr) => {
309
            check_encode!($e, $e2);
310
            check_decode!($t, $e2, $e);
311
        };
312
    }
313
    macro_rules! check_bad {
314
        ($t:ty, $e:expr) => {
315
            let mut r = Reader::from_slice(&$e[..]);
316
            let len_orig = r.remaining();
317
            let res: Result<$t, _> = r.extract();
318
            assert!(res.is_err());
319
            assert_eq!(r.remaining(), len_orig);
320
        };
321
    }
322
    #[test]
323
    fn vec_u8() {
324
        let v: Vec<u8> = vec![1, 2, 3, 4];
325
        check_encode!(v, b"\x01\x02\x03\x04");
326
    }
327

            
328
    #[test]
329
    fn genarray() {
330
        use generic_array as ga;
331
        let a: ga::GenericArray<u8, ga::typenum::U7> = [4, 5, 6, 7, 8, 9, 10].into();
332
        check_roundtrip!(ga::GenericArray<u8, ga::typenum::U7>,
333
                         a,
334
                         [4, 5, 6, 7, 8, 9, 10]);
335
    }
336

            
337
    #[test]
338
    fn roundtrip_u64() {
339
        check_roundtrip!(u64, 0x4040111_u64, [0, 0, 0, 0, 4, 4, 1, 17]);
340
    }
341

            
342
    #[test]
343
    fn u8_array() {
344
        check_roundtrip!(
345
            [u8; 16],
346
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
347
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
348
        );
349
    }
350

            
351
    #[test]
352
    fn ipv4addr() {
353
        use std::net::Ipv4Addr;
354
        check_roundtrip!(Ipv4Addr, Ipv4Addr::new(192, 168, 0, 1), [192, 168, 0, 1]);
355
    }
356

            
357
    #[test]
358
    fn ipv6addr() {
359
        use std::net::Ipv6Addr;
360
        check_roundtrip!(
361
            Ipv6Addr,
362
            Ipv6Addr::new(65535, 77, 1, 1, 1, 0, 0, 0),
363
            [255, 255, 0, 77, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
364
        );
365
    }
366

            
367
    #[test]
368
    fn ed25519() {
369
        #[allow(unused_imports)] // This `use` is needed with ed25519 < 1.3.0
370
        use signature::Signature;
371
        use tor_llcrypto::pk::ed25519;
372
        let b = &hex!(
373
            "68a6cee11d2883661f5876f7aac748992cd140f
374
             cfc36923aa957d04b5f8967ff"
375
        );
376
        check_roundtrip!(
377
            ed25519::PublicKey,
378
            ed25519::PublicKey::from_bytes(b).unwrap(),
379
            b
380
        );
381
        let b = &hex!(
382
            "68a6cee11d2883661f5876f7aac748992cd140f
383
             cfc36923aa957d04b5f8967"
384
        ); // too short
385
        check_bad!(ed25519::PublicKey, b);
386
        let b = &hex!(
387
            "68a6cee11d2883661f5876f7aac748992cd140f
388
             cfc36923aa957d04b5f896700"
389
        ); // not a valid compressed Y
390
        check_bad!(ed25519::PublicKey, b);
391

            
392
        let sig = &hex!(
393
            "b8842c083a56076fc27c8af21211f9fe57d1c32d9d
394
             c804f76a8fa858b9ab43622b9e8335993c422eab15
395
             6ebb5a047033f35256333a47a508b02699314d22550e"
396
        );
397
        check_roundtrip!(
398
            ed25519::Signature,
399
            ed25519::Signature::from_bytes(sig).unwrap(),
400
            sig
401
        );
402
        let sig = &hex!(
403
            "b8842c083a56076fc27c8af21211f9fe57d1c32d9d
404
             c804f76a8fa858b9ab43622b9e8335993c422eab15
405
             6ebb5a047033f35256333a47a508b02699314d2255ff"
406
        );
407
        check_bad!(ed25519::Signature, sig);
408
    }
409

            
410
    #[test]
411
    fn curve25519() {
412
        use tor_llcrypto::pk::curve25519;
413
        let b = &hex!("5f6df7a2fe3bcf1c9323e9755250efd79b9db4ed8f3fd21c7515398b6662a365");
414
        let pk: curve25519::PublicKey = (*b).into();
415
        check_roundtrip!(curve25519::PublicKey, pk, b);
416
    }
417

            
418
    #[test]
419
    fn rsa_id() {
420
        use tor_llcrypto::pk::rsa::RsaIdentity;
421
        let b = &hex!("9432D4CEA2621ED09F5A8088BE0E31E0D271435C");
422
        check_roundtrip!(RsaIdentity, RsaIdentity::from_bytes(b).unwrap(), b);
423
    }
424
}