      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107

    use connection::Connection;
    use key_exchange::{KexResult, KeyExchange};
    use message::MessageType;
    use num_bigint::{BigInt, RandBigInt, ToBigInt};
    use packet::{Packet, ReadPacketExt, WritePacketExt};
    use rand;

    const DH_GEX_GROUP: u8 = 31;
    const DH_GEX_INIT: u8 = 32;
    const DH_GEX_REPLY: u8 = 33;
    const DH_GEX_REQUEST: u8 = 34;

    /// Second Oakley Group
    /// Source: https://tools.ietf.org/html/rfc2409#section-6.2
    #[cfg_attr(rustfmt, rustfmt_skip)]
    static OAKLEY_GROUP_2: &[u32] = &[
        0xFFFFFFFF, 0xFFFFFFFF, 0xC90FDAA2, 0x2168C234, 0xC4C6628B, 0x80DC1CD1,
        0x29024E08, 0x8A67CC74, 0x020BBEA6, 0x3B139B22, 0x514A0879, 0x8E3404DD,
        0xEF9519B3, 0xCD3A431B, 0x302B0A6D, 0xF25F1437, 0x4FE1356D, 0x6D51C245,
        0xE485B576, 0x625E7EC6, 0xF44C42E9, 0xA637ED6B, 0x0BFF5CB6, 0xF406B7ED,
        0xEE386BFB, 0x5A899FA5, 0xAE9F2411, 0x7C4B1FE6, 0x49286651, 0xECE65381,
        0xFFFFFFFF, 0xFFFFFFFF
    ];

    pub struct DhGroupSha1 {
        g: Option<BigInt>,
        p: Option<BigInt>,
        e: Option<BigInt>,
    }

    impl DhGroupSha1 {
        pub fn new() -> DhGroupSha1 {
            DhGroupSha1 {
                g: None,
                p: None,
                e: None,
            }
        }
    }

    impl KeyExchange for DhGroupSha1 {
        fn shared_secret<'a>(&'a self) -> Option<&'a [u8]> {
            Some(&[])
        }

        fn exchange_hash<'a>(&'a self) -> Option<&'a [u8]> {
            Some(&[])
        }

        fn hash(&self, data: &[&[u8]]) -> Vec<u8> {
            vec![]
        }

        fn process(&mut self, conn: &mut Connection, packet: Packet) -> KexResult {
            match packet.msg_type()
            {
                MessageType::KeyExchange(DH_GEX_REQUEST) => {
                    let mut reader = packet.reader();
                    let min = reader.read_uint32().unwrap();
                    let opt = reader.read_uint32().unwrap();
                    let max = reader.read_uint32().unwrap();

                    println!("Key Sizes: Min {}, Opt {}, Max {}", min, opt, max);

                    let mut rng = rand::thread_rng();
                    let g = rng.gen_biguint(opt as usize).to_bigint().unwrap();
                    let p = rng.gen_biguint(opt as usize).to_bigint().unwrap();

                    let mut packet =
                        Packet::new(MessageType::KeyExchange(DH_GEX_GROUP));
                    packet.with_writer(&|w| {
                        w.write_mpint(g.clone())?;
                        w.write_mpint(p.clone())?;
                        Ok(())
                    });

                    self.g = Some(g);
                    self.p = Some(p);

                    KexResult::Ok(packet)
                }
                MessageType::KeyExchange(DH_GEX_INIT) => {
                    let mut reader = packet.reader();
                    let e = reader.read_mpint().unwrap();

                    println!("Received e: {:?}", e);

                    let mut packet =
                        Packet::new(MessageType::KeyExchange(DH_GEX_REPLY));
                    packet.with_writer(&|w| {
                        w.write_string("HELLO WORLD")?;
                        w.write_mpint(e.clone())?;
                        w.write_string("HELLO WORLD")?;
                        Ok(())
                    });

                    self.e = Some(e);

                    KexResult::Done(packet)
                }
                _ => {
                    debug!("Unhandled key exchange packet: {:?}", packet);
                    KexResult::Error
                }
            }
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result
+
  Collapse/expand all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)