1
//! Implementations for the channel handshake
2

            
3
use arrayref::array_ref;
4
use asynchronous_codec as futures_codec;
5
use futures::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
6
use futures::sink::SinkExt;
7
use futures::stream::StreamExt;
8
use tor_error::internal;
9

            
10
use crate::channel::codec::{ChannelCodec, CodecError};
11
use crate::channel::UniqId;
12
use crate::{Error, Result};
13
use tor_cell::chancell::{msg, ChanCmd};
14

            
15
use std::net::SocketAddr;
16
use std::sync::Arc;
17

            
18
use tor_bytes::Reader;
19
use tor_linkspec::ChanTarget;
20
use tor_llcrypto as ll;
21
use tor_llcrypto::pk::ed25519::Ed25519Identity;
22
use tor_llcrypto::pk::rsa::RsaIdentity;
23

            
24
use digest::Digest;
25

            
26
use super::CellFrame;
27

            
28
use tracing::{debug, trace};
29

            
30
/// A list of the link protocols that we support.
31
// We only support version 4 for now, since we don't do padding right.
32
static LINK_PROTOCOLS: &[u16] = &[4];
33

            
34
/// A raw client channel on which nothing has been done.
35
pub struct OutboundClientHandshake<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> {
36
    /// Underlying TLS stream.
37
    ///
38
    /// (We don't enforce that this is actually TLS, but if it isn't, the
39
    /// connection won't be secure.)
40
    tls: T,
41

            
42
    /// Declared target for this stream, if any.
43
    target_addr: Option<SocketAddr>,
44

            
45
    /// Logging identifier for this stream.  (Used for logging only.)
46
    unique_id: UniqId,
47
}
48

            
49
/// A client channel on which versions have been negotiated and the
50
/// relay's handshake has been read, but where the certs have not
51
/// been checked.
52
pub struct UnverifiedChannel<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> {
53
    /// The negotiated link protocol.  Must be a member of LINK_PROTOCOLS
54
    link_protocol: u16,
55
    /// The Source+Sink on which we're reading and writing cells.
56
    tls: CellFrame<T>,
57
    /// The certs cell that we got from the relay.
58
    certs_cell: msg::Certs,
59
    /// Declared target for this stream, if any.
60
    target_addr: Option<SocketAddr>,
61
    /// The netinfo cell that we got from the relay.
62
    #[allow(dead_code)] // Relays will need this.
63
    netinfo_cell: msg::Netinfo,
64
    /// Logging identifier for this stream.  (Used for logging only.)
65
    unique_id: UniqId,
66
}
67

            
68
/// A client channel on which versions have been negotiated,
69
/// relay's handshake has been read, but the client has not yet
70
/// finished the handshake.
71
///
72
/// This type is separate from UnverifiedChannel, since finishing the
73
/// handshake requires a bunch of CPU, and you might want to do it as
74
/// a separate task or after a yield.
75
pub struct VerifiedChannel<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> {
76
    /// The negotiated link protocol.
77
    link_protocol: u16,
78
    /// The Source+Sink on which we're reading and writing cells.
79
    tls: CellFrame<T>,
80
    /// Declared target for this stream, if any.
81
    target_addr: Option<SocketAddr>,
82
    /// Logging identifier for this stream.  (Used for logging only.)
83
    unique_id: UniqId,
84
    /// Validated Ed25519 identity for this peer.
85
    ed25519_id: Ed25519Identity,
86
    /// Validated RSA identity for this peer.
87
    rsa_id: RsaIdentity,
88
}
89

            
90
/// Convert a CodecError to an Error, under the context that it occurs while
91
/// doing a channel handshake.
92
1
fn codec_err_to_handshake(err: CodecError) -> Error {
93
1
    match err {
94
        CodecError::Io(e) => Error::HandshakeIoErr(Arc::new(e)),
95
1
        CodecError::Cell(e) => Error::HandshakeProto(format!("Invalid cell on handshake: {}", e)),
96
    }
97
1
}
98

            
99
impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> OutboundClientHandshake<T> {
100
    /// Construct a new OutboundClientHandshake.
101
11
    pub(crate) fn new(tls: T, target_addr: Option<SocketAddr>) -> Self {
102
11
        Self {
103
11
            tls,
104
11
            target_addr,
105
11
            unique_id: UniqId::new(),
106
11
        }
107
11
    }
108

            
109
    /// Negotiate a link protocol version with the relay, and read
110
    /// the relay's handshake information.
111
10
    pub async fn connect(mut self) -> Result<UnverifiedChannel<T>> {
112
10
        /// Helper: wrap an IoError as a HandshakeIoErr.
113
10
        fn io_err_to_handshake(err: std::io::Error) -> Error {
114
            Error::HandshakeIoErr(Arc::new(err))
115
        }
116
10

            
117
10
        match self.target_addr {
118
1
            Some(addr) => debug!("{}: starting Tor handshake with {}", self.unique_id, addr),
119
            None => debug!("{}: starting Tor handshake", self.unique_id),
120
        }
121
        trace!("{}: sending versions", self.unique_id);
122
        // Send versions cell
123
        {
124
10
            let my_versions = msg::Versions::new(LINK_PROTOCOLS)?;
125
10
            self.tls
126
10
                .write_all(&my_versions.encode_for_handshake())
127
                .await
128
10
                .map_err(io_err_to_handshake)?;
129
10
            self.tls.flush().await.map_err(io_err_to_handshake)?;
130
        }
131

            
132
        // Get versions cell.
133
        trace!("{}: waiting for versions", self.unique_id);
134
9
        let their_versions: msg::Versions = {
135
            // TODO: this could be turned into another function, I suppose.
136
10
            let mut hdr = [0_u8; 5];
137
10
            let not_relay = || {
138
1
                Err(Error::HandshakeProto(
139
1
                    "Doesn't seem to be a tor relay".into(),
140
1
                ))
141
1
            };
142
10
            match self.tls.read_exact(&mut hdr).await {
143
                Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return not_relay(),
144
9
                otherwise => otherwise,
145
9
            }
146
9
            .map_err(io_err_to_handshake)?;
147
9
            if hdr[0..3] != [0, 0, ChanCmd::VERSIONS.into()] {
148
1
                return not_relay();
149
8
            }
150
8
            let msglen = u16::from_be_bytes(*array_ref![hdr, 3, 2]);
151
8
            let mut msg = vec![0; msglen as usize];
152
8
            self.tls
153
8
                .read_exact(&mut msg)
154
                .await
155
9
                .map_err(io_err_to_handshake)?;
156
9
            let mut reader = Reader::from_slice(&msg);
157
9
            reader.extract()?
158
        };
159
        trace!("{}: received {:?}", self.unique_id, their_versions);
160

            
161
        // Determine which link protocol we negotiated.
162
8
        let link_protocol = their_versions
163
8
            .best_shared_link_protocol(LINK_PROTOCOLS)
164
8
            .ok_or_else(|| Error::HandshakeProto("No shared link protocols".into()))?;
165
        trace!("{}: negotiated version {}", self.unique_id, link_protocol);
166

            
167
        // Now we can switch to using a "Framed". We can ignore the
168
        // AsyncRead/AsyncWrite aspects of the tls, and just treat it
169
        // as a stream and a sink for cells.
170
7
        let codec = ChannelCodec::new(link_protocol);
171
7
        let mut tls = futures_codec::Framed::new(self.tls, codec);
172
7

            
173
7
        // Read until we have the netinfo cells.
174
7
        let mut certs: Option<msg::Certs> = None;
175
7
        let mut netinfo: Option<msg::Netinfo> = None;
176
7
        let mut seen_authchallenge = false;
177

            
178
        // Loop: reject duplicate and unexpected cells
179
        trace!("{}: waiting for rest of handshake.", self.unique_id);
180
17
        while let Some(m) = tls.next().await {
181
            use msg::ChanMsg::*;
182
17
            let (_, m) = m.map_err(codec_err_to_handshake)?.into_circid_and_msg();
183
            trace!("{}: received a {} cell.", self.unique_id, m.cmd());
184
16
            match m {
185
                // Are these technically allowed?
186
2
                Padding(_) | VPadding(_) => (),
187
                // Unrecognized cells get ignored.
188
                Unrecognized(_) => (),
189
                // Clients don't care about AuthChallenge
190
                AuthChallenge(_) => {
191
3
                    if seen_authchallenge {
192
1
                        return Err(Error::HandshakeProto("Duplicate authchallenge cell".into()));
193
2
                    }
194
2
                    seen_authchallenge = true;
195
                }
196
6
                Certs(c) => {
197
6
                    if certs.is_some() {
198
1
                        return Err(Error::HandshakeProto("Duplicate certs cell".into()));
199
5
                    }
200
5
                    certs = Some(c);
201
                }
202
4
                Netinfo(n) => {
203
4
                    if netinfo.is_some() {
204
                        // This should be impossible, since we would
205
                        // exit this loop on the first netinfo cell.
206
                        return Err(Error::from(internal!(
207
                            "Somehow tried to record a duplicate NETINFO cell"
208
                        )));
209
4
                    }
210
4
                    netinfo = Some(n);
211
4
                    break;
212
                }
213
                // No other cell types are allowed.
214
1
                m => {
215
1
                    return Err(Error::HandshakeProto(format!(
216
1
                        "Unexpected cell type {}",
217
1
                        m.cmd()
218
1
                    )))
219
                }
220
            }
221
        }
222

            
223
        // If we have certs and netinfo, we can finish authenticating.
224
4
        match (certs, netinfo) {
225
            (Some(_), None) => Err(Error::HandshakeProto(
226
                "Missing netinfo or closed stream".into(),
227
            )),
228
1
            (None, _) => Err(Error::HandshakeProto("Missing certs cell".into())),
229
3
            (Some(certs_cell), Some(netinfo_cell)) => {
230
                trace!("{}: received handshake, ready to verify.", self.unique_id);
231
3
                Ok(UnverifiedChannel {
232
3
                    link_protocol,
233
3
                    tls,
234
3
                    certs_cell,
235
3
                    netinfo_cell,
236
3
                    target_addr: self.target_addr,
237
3
                    unique_id: self.unique_id,
238
3
                })
239
            }
240
        }
241
10
    }
242
}
243

            
244
impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> UnverifiedChannel<T> {
245
    /// Validate the certificates and keys in the relay's handshake.
246
    ///
247
    /// 'peer' is the peer that we want to make sure we're connecting to.
248
    ///
249
    /// 'peer_cert' is the x.509 certificate that the peer presented during
250
    /// its handshake.
251
    ///
252
    /// 'now' is the time at which to check that certificates are
253
    /// valid.  `None` means to use the current time. It can be used
254
    /// for testing to override the current view of the time.
255
    ///
256
    /// This is a separate function because it's likely to be somewhat
257
    /// CPU-intensive.
258
1
    pub fn check<U: ChanTarget + ?Sized>(
259
1
        self,
260
1
        peer: &U,
261
1
        peer_cert: &[u8],
262
1
        now: Option<std::time::SystemTime>,
263
1
    ) -> Result<VerifiedChannel<T>> {
264
1
        let peer_cert_sha256 = ll::d::Sha256::digest(peer_cert);
265
1
        self.check_internal(peer, &peer_cert_sha256[..], now)
266
1
    }
267

            
268
    /// Same as `check`, but takes the SHA256 hash of the peer certificate,
269
    /// since that is all we use.
270
12
    fn check_internal<U: ChanTarget + ?Sized>(
271
12
        self,
272
12
        peer: &U,
273
12
        peer_cert_sha256: &[u8],
274
12
        now: Option<std::time::SystemTime>,
275
12
    ) -> Result<VerifiedChannel<T>> {
276
12
        use tor_cert::CertType;
277
12
        use tor_checkable::*;
278
12
        // We need to check the following lines of authentication:
279
12
        //
280
12
        // First, to bind the ed identity to the channel.
281
12
        //    peer.ed_identity() matches the key in...
282
12
        //    IDENTITY_V_SIGNING cert, which signs...
283
12
        //    SIGNING_V_TLS_CERT cert, which signs peer_cert.
284
12
        //
285
12
        // Second, to bind the rsa identity to the ed identity:
286
12
        //    peer.rsa_identity() matches the key in...
287
12
        //    the x.509 RSA identity certificate (type 2), which signs...
288
12
        //    the RSA->Ed25519 crosscert (type 7), which signs...
289
12
        //    peer.ed_identity().
290
12

            
291
12
        let c = &self.certs_cell;
292
        /// Helper: get a cert from a Certs cell, and convert errors appropriately.
293
        fn get_cert(
294
            certs: &tor_cell::chancell::msg::Certs,
295
            tp: CertType,
296
        ) -> Result<tor_cert::KeyUnknownCert> {
297
43
            match certs.parse_ed_cert(tp) {
298
40
                Ok(c) => Ok(c),
299
3
                Err(tor_cell::Error::ChanProto(e)) => Err(Error::HandshakeProto(e)),
300
                Err(e) => Err(Error::HandshakeProto(e.to_string())),
301
            }
302
43
        }
303

            
304
12
        let id_sk = get_cert(c, CertType::IDENTITY_V_SIGNING)?;
305
10
        let sk_tls = get_cert(c, CertType::SIGNING_V_TLS_CERT)?;
306

            
307
9
        let mut sigs = Vec::new();
308

            
309
        // Part 1: validate ed25519 stuff.
310

            
311
        // Check the identity->signing cert
312
9
        let (id_sk, id_sk_sig) = id_sk.check_key(&None)?.dangerously_split()?;
313
9
        sigs.push(&id_sk_sig);
314
9
        let id_sk = id_sk
315
9
            .check_valid_at_opt(now)
316
9
            .map_err(|_| Error::HandshakeProto("Certificate expired or not yet valid".into()))?;
317

            
318
        // Take the identity key from the identity->signing cert
319
9
        let identity_key = id_sk.signing_key().ok_or_else(|| {
320
            Error::HandshakeProto("Missing identity key in identity->signing cert".into())
321
9
        })?;
322

            
323
        // Take the signing key from the identity->signing cert
324
9
        let signing_key = id_sk.subject_key().as_ed25519().ok_or_else(|| {
325
            Error::HandshakeProto("Bad key type in identity->signing cert".into())
326
9
        })?;
327

            
328
        // Now look at the signing->TLS cert and check it against the
329
        // peer certificate.
330
9
        let (sk_tls, sk_tls_sig) = sk_tls
331
9
            .check_key(&Some(*signing_key))? // TODO(nickm): this is a bad interface
332
9
            .dangerously_split()?;
333
9
        sigs.push(&sk_tls_sig);
334
9
        let sk_tls = sk_tls
335
9
            .check_valid_at_opt(now)
336
9
            .map_err(|_| Error::HandshakeProto("Certificate expired or not yet valid".into()))?;
337

            
338
9
        if peer_cert_sha256 != sk_tls.subject_key().as_bytes() {
339
1
            return Err(Error::HandshakeProto(
340
1
                "Peer cert did not authenticate TLS cert".into(),
341
1
            ));
342
8
        }
343
8

            
344
8
        // Batch-verify the ed25519 certificates in this handshake.
345
8
        //
346
8
        // In theory we could build a list of _all_ the certificates here
347
8
        // and call pk::validate_all_sigs() instead, but that doesn't gain
348
8
        // any performance.
349
8
        if !ll::pk::ed25519::validate_batch(&sigs[..]) {
350
1
            return Err(Error::HandshakeProto(
351
1
                "Invalid ed25519 signature in handshake".into(),
352
1
            ));
353
7
        }
354
7

            
355
7
        let ed25519_id: Ed25519Identity = identity_key.into();
356

            
357
        // Part 2: validate rsa stuff.
358

            
359
        // What is the RSA identity key, according to the X.509 certificate
360
        // in which it is self-signed?
361
        //
362
        // (We don't actually check this self-signed certificate, and we use
363
        // a kludge to extract the RSA key)
364
7
        let pkrsa = c
365
7
            .cert_body(CertType::RSA_ID_X509)
366
7
            .and_then(ll::util::x509_extract_rsa_subject_kludge)
367
7
            .ok_or_else(|| Error::HandshakeProto("Couldn't find RSA identity key".into()))?;
368

            
369
        // Now verify the RSA identity -> Ed Identity crosscert.
370
        //
371
        // This proves that the RSA key vouches for the Ed key.  Note that
372
        // the Ed key does not vouch for the RSA key: The RSA key is too
373
        // weak.
374
6
        let rsa_cert = c
375
6
            .cert_body(CertType::RSA_ID_V_IDENTITY)
376
6
            .ok_or_else(|| Error::HandshakeProto("No RSA->Ed crosscert".into()))?;
377
5
        let rsa_cert = tor_cert::rsa::RsaCrosscert::decode(rsa_cert)?
378
5
            .check_signature(&pkrsa)
379
5
            .map_err(|_| Error::HandshakeProto("Bad RSA->Ed crosscert signature".into()))?
380
4
            .check_valid_at_opt(now)
381
4
            .map_err(|_| Error::HandshakeProto("RSA->Ed crosscert expired or invalid".into()))?;
382

            
383
4
        if !rsa_cert.subject_key_matches(identity_key) {
384
            return Err(Error::HandshakeProto(
385
                "RSA->Ed crosscert certifies incorrect key".into(),
386
            ));
387
4
        }
388
4

            
389
4
        let rsa_id = pkrsa.to_rsa_identity();
390
4

            
391
4
        trace!(
392
            "{}: Validated identity as {} [{}]",
393
            self.unique_id,
394
            ed25519_id,
395
            rsa_id
396
        );
397

            
398
        // Now that we've done all the verification steps on the
399
        // certificates, we know who we are talking to.  It's time to
400
        // make sure that the peer we are talking to is the peer we
401
        // actually wanted.
402
        //
403
        // We do this _last_, since "this is the wrong peer" is
404
        // usually a different situation than "this peer couldn't even
405
        // identify itself right."
406
4
        if *peer.ed_identity() != ed25519_id {
407
1
            return Err(Error::HandshakeProto(
408
1
                "Peer ed25519 id not as expected".into(),
409
1
            ));
410
3
        }
411
3

            
412
3
        if *peer.rsa_identity() != rsa_id {
413
1
            return Err(Error::HandshakeProto("Peer RSA id not as expected".into()));
414
2
        }
415
2

            
416
2
        Ok(VerifiedChannel {
417
2
            link_protocol: self.link_protocol,
418
2
            tls: self.tls,
419
2
            unique_id: self.unique_id,
420
2
            target_addr: self.target_addr,
421
2
            ed25519_id,
422
2
            rsa_id,
423
2
        })
424
12
    }
425
}
426

            
427
impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> VerifiedChannel<T> {
428
    /// Send a 'Netinfo' message to the relay to finish the handshake,
429
    /// and create an open channel and reactor.
430
    ///
431
    /// The channel is used to send cells, and to create outgoing circuits.
432
    /// The reactor is used to route incoming messages to their appropriate
433
    /// circuit.
434
2
    pub async fn finish(mut self) -> Result<(super::Channel, super::reactor::Reactor)> {
435
2
        // We treat a completed channel -- that is to say, one where the
436
2
        // authentication is finished -- as incoming traffic.
437
2
        //
438
2
        // TODO: conceivably we should remember the time when we _got_ the
439
2
        // final cell on the handshake, and update the channel completion
440
2
        // time to be no earlier than _that_ timestamp.
441
2
        crate::note_incoming_traffic();
442
        trace!("{}: Sending netinfo cell.", self.unique_id);
443
2
        let netinfo = msg::Netinfo::for_client(self.target_addr.as_ref().map(SocketAddr::ip));
444
2
        self.tls
445
2
            .send(netinfo.into())
446
            .await
447
2
            .map_err(codec_err_to_handshake)?;
448

            
449
        debug!(
450
            "{}: Completed handshake with {} [{}]",
451
            self.unique_id, self.ed25519_id, self.rsa_id
452
        );
453

            
454
2
        let (tls_sink, tls_stream) = self.tls.split();
455
2

            
456
2
        Ok(super::Channel::new(
457
2
            self.link_protocol,
458
2
            Box::new(tls_sink),
459
2
            Box::new(tls_stream),
460
2
            self.unique_id,
461
2
            self.ed25519_id,
462
2
            self.rsa_id,
463
2
        ))
464
2
    }
465
}
466

            
467
#[cfg(test)]
468
pub(super) mod test {
469
    #![allow(clippy::unwrap_used)]
470
    use hex_literal::hex;
471
    use std::time::{Duration, SystemTime};
472

            
473
    use super::*;
474
    use crate::channel::codec::test::MsgBuf;
475
    use crate::Result;
476
    use tor_cell::chancell::msg;
477

            
478
    const VERSIONS: &[u8] = &hex!("0000 07 0006 0003 0004 0005");
479
    // no certificates in this cell, but connect() doesn't care.
480
    const NOCERTS: &[u8] = &hex!("00000000 81 0001 00");
481
    const NETINFO_PREFIX: &[u8] = &hex!(
482
        "00000000 08 085F9067F7
483
         04 04 7f 00 00 02
484
         01
485
         04 04 7f 00 00 03"
486
    );
487
    const AUTHCHALLENGE: &[u8] = &hex!(
488
        "00000000 82 0026
489
         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
490
         FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
491
         0002 0003 00ff"
492
    );
493

            
494
    const VPADDING: &[u8] = &hex!("00000000 80 0003 FF FF FF");
495

            
496
6
    fn add_padded(buf: &mut Vec<u8>, cell: &[u8]) {
497
6
        let len_prev = buf.len();
498
6
        buf.extend_from_slice(cell);
499
6
        buf.resize(len_prev + 514, 0);
500
6
    }
501
5
    fn add_netinfo(buf: &mut Vec<u8>) {
502
5
        add_padded(buf, NETINFO_PREFIX);
503
5
    }
504

            
505
1
    #[test]
506
1
    fn connect_ok() -> Result<()> {
507
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
508
1
            let mut buf = Vec::new();
509
1
            // versions cell
510
1
            buf.extend_from_slice(VERSIONS);
511
1
            // certs cell -- no certs in it, but this function doesn't care.
512
1
            buf.extend_from_slice(NOCERTS);
513
1
            // netinfo cell -- quite minimal.
514
1
            add_netinfo(&mut buf);
515
1
            let mb = MsgBuf::new(&buf[..]);
516
1
            let handshake = OutboundClientHandshake::new(mb, None);
517
1
            let unverified = handshake.connect().await?;
518

            
519
1
            assert_eq!(unverified.link_protocol, 4);
520

            
521
            // Try again with an authchallenge cell and some padding.
522
1
            let mut buf = Vec::new();
523
1
            buf.extend_from_slice(VERSIONS);
524
1
            buf.extend_from_slice(NOCERTS);
525
1
            buf.extend_from_slice(VPADDING);
526
1
            buf.extend_from_slice(AUTHCHALLENGE);
527
1
            buf.extend_from_slice(VPADDING);
528
1
            add_netinfo(&mut buf);
529
1
            let mb = MsgBuf::new(&buf[..]);
530
1
            let handshake = OutboundClientHandshake::new(mb, None);
531
1
            let _unverified = handshake.connect().await?;
532

            
533
1
            Ok(())
534
1
        })
535
1
    }
536

            
537
7
    async fn connect_err<T: Into<Vec<u8>>>(input: T) -> Error {
538
7
        let mb = MsgBuf::new(input);
539
7
        let handshake = OutboundClientHandshake::new(mb, None);
540
7
        handshake.connect().await.err().unwrap()
541
7
    }
542

            
543
1
    #[test]
544
1
    fn connect_badver() {
545
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
546
1
            let err = connect_err(&b"HTTP://"[..]).await;
547
1
            assert!(matches!(err, Error::HandshakeProto(_)));
548
1
            assert_eq!(
549
1
                format!("{}", err),
550
1
                "handshake protocol violation: Doesn't seem to be a tor relay"
551
1
            );
552

            
553
1
            let err = connect_err(&hex!("0000 07 0004 1234 ffff")[..]).await;
554
1
            assert!(matches!(err, Error::HandshakeProto(_)));
555
1
            assert_eq!(
556
1
                format!("{}", err),
557
1
                "handshake protocol violation: No shared link protocols"
558
1
            );
559
1
        });
560
1
    }
561

            
562
1
    #[test]
563
1
    fn connect_cellparse() {
564
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
565
1
            let mut buf = Vec::new();
566
1
            buf.extend_from_slice(VERSIONS);
567
1
            // Here's a certs cell that will fail.
568
1
            buf.extend_from_slice(&hex!("00000000 81 0001 01")[..]);
569
1
            let err = connect_err(buf).await;
570
1
            assert!(matches!(err, Error::HandshakeProto(_)));
571
1
        });
572
1
    }
573

            
574
1
    #[test]
575
1
    fn connect_duplicates() {
576
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
577
1
            let mut buf = Vec::new();
578
1
            buf.extend_from_slice(VERSIONS);
579
1
            buf.extend_from_slice(NOCERTS);
580
1
            buf.extend_from_slice(NOCERTS);
581
1
            add_netinfo(&mut buf);
582
1
            let err = connect_err(buf).await;
583
1
            assert!(matches!(err, Error::HandshakeProto(_)));
584
1
            assert_eq!(
585
1
                format!("{}", err),
586
1
                "handshake protocol violation: Duplicate certs cell"
587
1
            );
588

            
589
1
            let mut buf = Vec::new();
590
1
            buf.extend_from_slice(VERSIONS);
591
1
            buf.extend_from_slice(NOCERTS);
592
1
            buf.extend_from_slice(AUTHCHALLENGE);
593
1
            buf.extend_from_slice(AUTHCHALLENGE);
594
1
            add_netinfo(&mut buf);
595
1
            let err = connect_err(buf).await;
596
1
            assert!(matches!(err, Error::HandshakeProto(_)));
597
1
            assert_eq!(
598
1
                format!("{}", err),
599
1
                "handshake protocol violation: Duplicate authchallenge cell"
600
1
            );
601
1
        });
602
1
    }
603

            
604
1
    #[test]
605
1
    fn connect_missing_certs() {
606
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
607
1
            let mut buf = Vec::new();
608
1
            buf.extend_from_slice(VERSIONS);
609
1
            add_netinfo(&mut buf);
610
1
            let err = connect_err(buf).await;
611
1
            assert!(matches!(err, Error::HandshakeProto(_)));
612
1
            assert_eq!(
613
1
                format!("{}", err),
614
1
                "handshake protocol violation: Missing certs cell"
615
1
            );
616
1
        });
617
1
    }
618

            
619
1
    #[test]
620
1
    fn connect_misplaced_cell() {
621
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
622
1
            let mut buf = Vec::new();
623
1
            buf.extend_from_slice(VERSIONS);
624
1
            // here's a create cell.
625
1
            add_padded(&mut buf, &hex!("00000001 01")[..]);
626
1
            let err = connect_err(buf).await;
627
1
            assert!(matches!(err, Error::HandshakeProto(_)));
628
1
            assert_eq!(
629
1
                format!("{}", err),
630
1
                "handshake protocol violation: Unexpected cell type CREATE"
631
1
            );
632
1
        });
633
1
    }
634

            
635
11
    fn make_unverified(certs: msg::Certs) -> UnverifiedChannel<MsgBuf> {
636
11
        let localhost = std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST);
637
11
        let netinfo_cell = msg::Netinfo::for_client(Some(localhost));
638
11
        UnverifiedChannel {
639
11
            link_protocol: 4,
640
11
            tls: futures_codec::Framed::new(MsgBuf::new(&b""[..]), ChannelCodec::new(4)),
641
11
            certs_cell: certs,
642
11
            netinfo_cell,
643
11
            target_addr: None,
644
11
            unique_id: UniqId::new(),
645
11
        }
646
11
    }
647

            
648
    struct DummyChanTarget {
649
        ed: Ed25519Identity,
650
        rsa: RsaIdentity,
651
    }
652
    impl ChanTarget for DummyChanTarget {
653
        fn addrs(&self) -> &[SocketAddr] {
654
            &[]
655
        }
656
3
        fn ed_identity(&self) -> &Ed25519Identity {
657
3
            &self.ed
658
3
        }
659
2
        fn rsa_identity(&self) -> &RsaIdentity {
660
2
            &self.rsa
661
2
        }
662
    }
663

            
664
    // Timestamp when the example certificates were all valid.
665
10
    fn cert_timestamp() -> SystemTime {
666
10
        SystemTime::UNIX_EPOCH + Duration::new(1601143280, 0)
667
10
    }
668

            
669
11
    fn certs_test(
670
11
        certs: msg::Certs,
671
11
        when: Option<SystemTime>,
672
11
        peer_ed: &[u8],
673
11
        peer_rsa: &[u8],
674
11
        peer_cert_sha256: &[u8],
675
11
    ) -> Result<VerifiedChannel<MsgBuf>> {
676
11
        let unver = make_unverified(certs);
677
11
        let ed = Ed25519Identity::from_bytes(peer_ed).unwrap();
678
11
        let rsa = RsaIdentity::from_bytes(peer_rsa).unwrap();
679
11
        let chan = DummyChanTarget { ed, rsa };
680
11
        unver.check_internal(&chan, peer_cert_sha256, when)
681
11
    }
682

            
683
    // no certs at all!
684
1
    #[test]
685
1
    fn certs_none() {
686
1
        let err = certs_test(
687
1
            msg::Certs::new_empty(),
688
1
            None,
689
1
            &[0_u8; 32],
690
1
            &[0_u8; 20],
691
1
            &[0_u8; 128],
692
1
        )
693
1
        .err()
694
1
        .unwrap();
695
1
        assert_eq!(
696
1
            format!("{}", err),
697
1
            "handshake protocol violation: Missing IDENTITY_V_SIGNING certificate"
698
1
        );
699
1
    }
700

            
701
1
    #[test]
702
1
    fn certs_good() {
703
1
        let mut certs = msg::Certs::new_empty();
704
1

            
705
1
        certs.push_cert_body(2.into(), certs::CERT_T2);
706
1
        certs.push_cert_body(5.into(), certs::CERT_T5);
707
1
        certs.push_cert_body(7.into(), certs::CERT_T7);
708
1
        certs.push_cert_body(4.into(), certs::CERT_T4);
709
1
        let res = certs_test(
710
1
            certs,
711
1
            Some(cert_timestamp()),
712
1
            certs::PEER_ED,
713
1
            certs::PEER_RSA,
714
1
            certs::PEER_CERT_DIGEST,
715
1
        );
716
1
        let _ = res.unwrap();
717
1
    }
718

            
719
1
    #[test]
720
1
    fn certs_missing() {
721
1
        let all_certs = [
722
1
            (2, certs::CERT_T2, "Couldn't find RSA identity key"),
723
1
            (7, certs::CERT_T7, "No RSA->Ed crosscert"),
724
1
            (4, certs::CERT_T4, "Missing IDENTITY_V_SIGNING certificate"),
725
1
            (5, certs::CERT_T5, "Missing SIGNING_V_TLS_CERT certificate"),
726
1
        ];
727

            
728
5
        for omit_idx in 0..4 {
729
            // build a certs cell with all but one certificate
730
4
            let mut certs = msg::Certs::new_empty();
731
4
            let mut expect_err = None;
732
16
            for (idx, (ctype, cert, err)) in all_certs.iter().enumerate() {
733
16
                if idx == omit_idx {
734
4
                    expect_err = Some(err);
735
4
                    continue;
736
12
                }
737
12

            
738
12
                certs.push_cert_body((*ctype).into(), &cert[..]);
739
            }
740
4
            let res = certs_test(
741
4
                certs,
742
4
                Some(cert_timestamp()),
743
4
                certs::PEER_ED,
744
4
                certs::PEER_RSA,
745
4
                certs::PEER_CERT_DIGEST,
746
4
            )
747
4
            .err()
748
4
            .unwrap();
749
4

            
750
4
            assert_eq!(
751
4
                format!("{}", res),
752
4
                format!("handshake protocol violation: {}", expect_err.unwrap())
753
4
            );
754
        }
755
1
    }
756

            
757
1
    #[test]
758
1
    fn certs_wrongtarget() {
759
1
        let mut certs = msg::Certs::new_empty();
760
1
        certs.push_cert_body(2.into(), certs::CERT_T2);
761
1
        certs.push_cert_body(5.into(), certs::CERT_T5);
762
1
        certs.push_cert_body(7.into(), certs::CERT_T7);
763
1
        certs.push_cert_body(4.into(), certs::CERT_T4);
764
1
        let err = certs_test(
765
1
            certs.clone(),
766
1
            Some(cert_timestamp()),
767
1
            &[0x10; 32],
768
1
            certs::PEER_RSA,
769
1
            certs::PEER_CERT_DIGEST,
770
1
        )
771
1
        .err()
772
1
        .unwrap();
773
1

            
774
1
        assert_eq!(
775
1
            format!("{}", err),
776
1
            "handshake protocol violation: Peer ed25519 id not as expected"
777
1
        );
778

            
779
1
        let err = certs_test(
780
1
            certs.clone(),
781
1
            Some(cert_timestamp()),
782
1
            certs::PEER_ED,
783
1
            &[0x99; 20],
784
1
            certs::PEER_CERT_DIGEST,
785
1
        )
786
1
        .err()
787
1
        .unwrap();
788
1

            
789
1
        assert_eq!(
790
1
            format!("{}", err),
791
1
            "handshake protocol violation: Peer RSA id not as expected"
792
1
        );
793

            
794
1
        let err = certs_test(
795
1
            certs,
796
1
            Some(cert_timestamp()),
797
1
            certs::PEER_ED,
798
1
            certs::PEER_RSA,
799
1
            &[0; 32],
800
1
        )
801
1
        .err()
802
1
        .unwrap();
803
1

            
804
1
        assert_eq!(
805
1
            format!("{}", err),
806
1
            "handshake protocol violation: Peer cert did not authenticate TLS cert"
807
1
        );
808
1
    }
809

            
810
1
    #[test]
811
1
    fn certs_badsig() {
812
2
        fn munge(inp: &[u8]) -> Vec<u8> {
813
2
            let mut v: Vec<u8> = inp.into();
814
2
            v[inp.len() - 1] ^= 0x10;
815
2
            v
816
2
        }
817
1
        let mut certs = msg::Certs::new_empty();
818
1
        certs.push_cert_body(2.into(), certs::CERT_T2);
819
1
        certs.push_cert_body(5.into(), munge(certs::CERT_T5)); // munge an ed signature
820
1
        certs.push_cert_body(7.into(), certs::CERT_T7);
821
1
        certs.push_cert_body(4.into(), certs::CERT_T4);
822
1
        let res = certs_test(
823
1
            certs,
824
1
            Some(cert_timestamp()),
825
1
            certs::PEER_ED,
826
1
            certs::PEER_RSA,
827
1
            certs::PEER_CERT_DIGEST,
828
1
        )
829
1
        .err()
830
1
        .unwrap();
831
1

            
832
1
        assert_eq!(
833
1
            format!("{}", res),
834
1
            "handshake protocol violation: Invalid ed25519 signature in handshake"
835
1
        );
836

            
837
1
        let mut certs = msg::Certs::new_empty();
838
1
        certs.push_cert_body(2.into(), certs::CERT_T2);
839
1
        certs.push_cert_body(5.into(), certs::CERT_T5);
840
1
        certs.push_cert_body(7.into(), munge(certs::CERT_T7)); // munge an RSA signature
841
1
        certs.push_cert_body(4.into(), certs::CERT_T4);
842
1
        let res = certs_test(
843
1
            certs,
844
1
            Some(cert_timestamp()),
845
1
            certs::PEER_ED,
846
1
            certs::PEER_RSA,
847
1
            certs::PEER_CERT_DIGEST,
848
1
        )
849
1
        .err()
850
1
        .unwrap();
851
1

            
852
1
        assert_eq!(
853
1
            format!("{}", res),
854
1
            "handshake protocol violation: Bad RSA->Ed crosscert signature"
855
1
        );
856
1
    }
857

            
858
    /// This module has a few certificates to play with. They're taken
859
    /// from a chutney network. They match those used in the CERTS
860
    /// cell test vector in the tor-cell crate.
861
    ///
862
    /// The names are taken from the type of the certificate.
863
    mod certs {
864
        use hex_literal::hex;
865

            
866
        pub(crate) const CERT_T2: &[u8] = &hex!("308201B930820122A0030201020208607C28BE6C390943300D06092A864886F70D01010B0500301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D301E170D3230303831303030303030305A170D3231303831303030303030305A301F311D301B06035504030C147777772E74636A76356B766A646472322E636F6D30819F300D06092A864886F70D010101050003818D0030818902818100D38B1E6CEB946E0DB0751F4CBACE3DCB9688B6C25304227B4710C35AFB73627E50500F5913E158B621802612D1C75827003703338375237552EB3CD3C12F6AB3604E60C1A2D26BB1FBAD206FF023969A90909D6A65A5458A5312C26EBD3A3DAD30302D4515CDCD264146AC18E6FC60A04BD3EC327F04294D96BA5AA25B464C3F0203010001300D06092A864886F70D01010B0500038181003BCE561EA7F95CC00B78AAB5D69573FF301C282A751D4A651921D042F1BECDBA24D918A6D8A5E138DC07BBA0B335478AE37ABD2C93A93932442AE9084329E846170FE0FC4A50AAFC804F311CC3CA4F41D845A7BA5901CBBC3E021E9794AAC70CE1F37B0A951592DB1B64F2B4AFB81AE52DBD9B6FEDE96A5FB8125EB6251EE50A");
867

            
868
        pub(crate) const CERT_T4: &[u8] = &hex!("01040006CC2A01F82294B866A31F01FC5D0DA8572850A9B929545C3266558D7D2316E3B74172B00100200400DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E9FF1A5203FA27F86EF7528D89A0845D2520166E340754FFEA2AAE0F612B7CE5DA094A0236CDAC45034B0B6842C18E7F6B51B93A3CF7E60663B8AD061C30A62602");
869
        pub(crate) const CERT_T5: &[u8] = &hex!("01050006C98A03B4FD606B64E4CBD466B8D76CB131069BAE6F3AA1878857C9F624E31D77A799B8007173E5F8068431D0D3F5EE16B4C9FFD59DF373E152A87281BAE744AA5FCF72171BF4B27C4E8FC1C6A9FC5CA11058BC49647063D7903CFD9F512F89099B27BC0C");
870

            
871
        pub(crate) const CERT_T7: &[u8] = &hex!("DCB604DB2034B00FD16986D4ADB9D16B21CB4E4457A33DEC0F538903683E96E90006DA3A805CF6006F9179066534DE6B45AD47A5C469063EE462762723396DC9F25452A0A52DA3F5087DD239F2A311F6B0D4DFEFF4ABD089DC3D0237A0ABAB19EB2045B91CDCAF04BE0A72D548A27BF2E77BD876ECFE5E1BE622350DA6BF31F6E306ED896488DD5B39409B23FC3EB7B2C9F7328EB18DA36D54D80575899EA6507CCBFCDF1F");
872

            
873
        pub(crate) const PEER_CERT_DIGEST: &[u8] =
874
            &hex!("b4fd606b64e4cbd466b8d76cb131069bae6f3aa1878857c9f624e31d77a799b8");
875

            
876
        pub(crate) const PEER_ED: &[u8] =
877
            &hex!("dcb604db2034b00fd16986d4adb9d16b21cb4e4457a33dec0f538903683e96e9");
878
        pub(crate) const PEER_RSA: &[u8] = &hex!("2f1fb49bb332a9eec617e41e911c33fb3890aef3");
879
    }
880

            
881
1
    #[test]
882
1
    fn test_finish() {
883
1
        tor_rtcompat::test_with_one_runtime!(|_rt| async move {
884
1
            let ed25519_id = [3_u8; 32].into();
885
1
            let rsa_id = [4_u8; 20].into();
886
1
            let peer_addr = "127.1.1.2:443".parse().unwrap();
887
1
            let ver = VerifiedChannel {
888
1
                link_protocol: 4,
889
1
                tls: futures_codec::Framed::new(MsgBuf::new(&b""[..]), ChannelCodec::new(4)),
890
1
                unique_id: UniqId::new(),
891
1
                target_addr: Some(peer_addr),
892
1
                ed25519_id,
893
1
                rsa_id,
894
1
            };
895

            
896
1
            let (_chan, _reactor) = ver.finish().await.unwrap();
897
1

            
898
1
            // TODO: check contents of netinfo cell
899
1
        });
900
1
    }
901
}