Commit 8f19dadc authored by Thomas Gatzweiler's avatar Thomas Gatzweiler
Browse files

Add BigInt

parent 6dd79b78
......@@ -4,6 +4,7 @@ version = "0.1.0"
dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.1.39 (git+https://github.com/rust-num/num)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -38,6 +39,30 @@ name = "log"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-bigint"
version = "0.1.39"
source = "git+https://github.com/rust-num/num#d159ed63be98c8ff01b62cbbf912d721e2b0eb41"
dependencies = [
"num-integer 0.1.34 (git+https://github.com/rust-num/num)",
"num-traits 0.1.39 (git+https://github.com/rust-num/num)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.34"
source = "git+https://github.com/rust-num/num#d159ed63be98c8ff01b62cbbf912d721e2b0eb41"
dependencies = [
"num-traits 0.1.39 (git+https://github.com/rust-num/num)",
]
[[package]]
name = "num-traits"
version = "0.1.39"
source = "git+https://github.com/rust-num/num#d159ed63be98c8ff01b62cbbf912d721e2b0eb41"
[[package]]
name = "rand"
version = "0.3.15"
......@@ -95,6 +120,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum num-bigint 0.1.39 (git+https://github.com/rust-num/num)" = "<none>"
"checksum num-integer 0.1.34 (git+https://github.com/rust-num/num)" = "<none>"
"checksum num-traits 0.1.39 (git+https://github.com/rust-num/num)" = "<none>"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
"checksum redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "9df6a71a1e67be2104410736b2389fb8e383c1d7e9e792d629ff13c02867147a"
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
......
......@@ -20,6 +20,7 @@ byteorder = "^1.0"
log = "^0.3"
rust-crypto = "^0.2"
rand = "^0.3"
num-bigint = { git = "https://github.com/rust-num/num" }
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"
......
......@@ -3,29 +3,24 @@ use std::fmt;
/// Slice of implemented key exchange algorithms, ordered by preference
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] = &[
KeyExchangeAlgorithm::CURVE25519_SHA256
KeyExchangeAlgorithm::DH_GROUP_EXCHANGE_SHA1,
// KeyExchangeAlgorithm::CURVE25519_SHA256,
];
/// Slice of implemented host key algorithms, ordered by preference
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[
PublicKeyAlgorithm::SSH_ED25519
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[PublicKeyAlgorithm::SSH_RSA,
// PublicKeyAlgorithm::SSH_ED25519
];
/// Slice of implemented encryption algorithms, ordered by preference
pub static ENCRYPTION: &[EncryptionAlgorithm] = &[
EncryptionAlgorithm::AES256_CTR
];
pub static ENCRYPTION: &[EncryptionAlgorithm] = &[EncryptionAlgorithm::AES256_CTR];
/// Slice of implemented MAC algorithms, ordered by preference
pub static MAC: &[MacAlgorithm] = &[
MacAlgorithm::HMAC_SHA2_512
];
pub static MAC: &[MacAlgorithm] = &[MacAlgorithm::HMAC_SHA2_512];
/// Slice of implemented compression algorithms, ordered by preference
pub static COMPRESSION: &[CompressionAlgorithm] = &[
CompressionAlgorithm::None,
CompressionAlgorithm::Zlib
];
pub static COMPRESSION: &[CompressionAlgorithm] =
&[CompressionAlgorithm::None, CompressionAlgorithm::Zlib];
/// Find the best matching algorithm
pub fn negotiate<A: PartialEq + Copy>(server: &[A], client: &[A]) -> Option<A> {
......@@ -169,7 +164,7 @@ impl FromStr for EncryptionAlgorithm {
"aes256-cbc" => Ok(AES256_CBC),
"none" => Ok(EncryptionAlgorithm::None),
_ => {
println!("Unknown encryption algorithm: `{}`", s);
debug!("Unknown encryption algorithm: `{}`", s);
Err(())
}
}
......@@ -209,7 +204,7 @@ impl FromStr for MacAlgorithm {
"hmac-sha2-256" => Ok(MacAlgorithm::HMAC_SHA2_256),
"hmac-sha2-512" => Ok(MacAlgorithm::HMAC_SHA2_512),
_ => {
println!("Unknown mac algorithm: {}", s);
debug!("Unknown mac algorithm: {}", s);
Err(())
}
}
......@@ -223,7 +218,7 @@ impl fmt::Display for MacAlgorithm {
&HMAC_SHA1 => "hmac-sha1",
&HMAC_SHA2_256 => "hmac-sha2-256",
&HMAC_SHA2_512 => "hmac-sha2-512",
&MacAlgorithm::None => "none"
&MacAlgorithm::None => "none",
})
}
}
......@@ -241,7 +236,7 @@ impl FromStr for CompressionAlgorithm {
"zlib" => Ok(CompressionAlgorithm::Zlib),
"none" => Ok(CompressionAlgorithm::None),
_ => {
println!("Unknown compression algorithm: {}", s);
debug!("Unknown compression algorithm: {}", s);
Err(())
}
}
......@@ -252,7 +247,7 @@ impl fmt::Display for CompressionAlgorithm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
&CompressionAlgorithm::Zlib => "zlib",
&CompressionAlgorithm::None => "none"
&CompressionAlgorithm::None => "none",
})
}
}
use key_exchange::{KeyExchange, KeyExchangeResult};
use packet::Packet;
pub struct Curve25519 {
}
impl Curve25519 {
pub fn new() -> Curve25519 {
Curve25519 { }
}
}
impl KeyExchange for Curve25519 {
fn process(&self, packet: &Packet) -> KeyExchangeResult {
KeyExchangeResult::Ok(None)
}
}
mod curve25519;
mod dh_group_sha1;
pub use self::curve25519::Curve25519;
pub use self::dh_group_sha1::DhGroupSha1;
use session::Session;
use packet::Packet;
pub enum KeyExchangeResult {
Ok(Option<Packet>),
Done(Option<Packet>),
Error(Option<Packet>)
}
pub trait KeyExchange {
fn process(&self, packet: &Packet);
fn process(&self, packet: &Packet) -> KeyExchangeResult;
}
extern crate byteorder;
extern crate rand;
extern crate crypto;
extern crate num_bigint;
#[macro_use]
extern crate log;
......
......@@ -4,6 +4,7 @@ use std::string::ToString;
use std::io::{self, BufReader, Write, Read, Result};
use message::MessageType;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
use num_bigint::BigInt;
pub struct Packet {
payload: Vec<u8>
......@@ -62,7 +63,7 @@ impl Packet {
}
pub fn reader<'a>(&'a self) -> BufReader<&'a [u8]> {
BufReader::new(self.payload.as_slice())
BufReader::new(&self.payload.as_slice()[1..])
}
pub fn padding_len(&self) -> usize {
......@@ -76,18 +77,15 @@ impl Packet {
}
pub trait ReadPacketExt: ReadBytesExt {
fn read_msg_type(&mut self) -> Result<MessageType> {
Ok(self.read_u8()?.into())
}
fn read_string(&mut self) -> Result<Vec<u8>> {
let len = self.read_u32::<BigEndian>()?;
self.read_bytes(len as usize)
}
fn read_mpint(&mut self) -> Result<Vec<u8>> {
fn read_mpint(&mut self) -> Result<BigInt> {
let len = self.read_u32::<BigEndian>()?;
self.read_bytes(len as usize)
let bytes = self.read_bytes(len as usize)?;
Ok(BigInt::from_signed_bytes_be(bytes.as_slice()))
}
fn read_bytes(&mut self, len: usize) -> Result<Vec<u8>> {
......@@ -136,6 +134,12 @@ pub trait WritePacketExt: WriteBytesExt {
self.write_u8(if value { 1 } else { 0 })
}
fn write_mpint(&mut self, value: BigInt) -> Result<()> {
let bytes = value.to_signed_bytes_be();
self.write_u32::<BigEndian>(bytes.len() as u32 + 1)?;
self.write_bytes(bytes.as_slice())
}
fn write_list<T: ToString>(&mut self, list: &[T]) -> Result<()> {
let mut string = String::new();
let mut iter = list.iter();
......
......@@ -39,45 +39,17 @@ impl Server {
));
println!("Incoming connection from {}", addr);
protocol::send_identification(&mut stream)?;
let id = protocol::read_identification(&mut stream)?;
println!("{} identifies as {}", addr, id);
protocol::send_identification(&mut stream)?;
let mut session = Session::new(SessionType::Server, stream.try_clone().unwrap());
loop {
let packet = Packet::read_from(&mut stream).unwrap();
println!("packet: {:?}", packet);
session.process(&packet);
use rand::{OsRng, Rng};
let mut rng = OsRng::new()?;
/*
if message.msg_type() == MessageType::KexInit {
xs let cookie: Vec<u8> = rng.gen_iter::<u8>().take(16).collect();
let kex = message::kex::KeyExchangeInit {
cookie: cookie,
kex_algorithms: vec![message::kex::KeyExchangeAlgorithm::CURVE25519_SHA256],
server_host_key_algorithms: vec![message::kex::HostKeyAlgorithm::SSH_ED25519],
encryption_algorithms_client_to_server: vec![message::kex::EncryptionAlgorithm::AES256_CTR],
encryption_algorithms_server_to_client: vec![message::kex::EncryptionAlgorithm::AES256_CTR],
mac_algorithms_client_to_server: vec![message::kex::MacAlgorithm::HMAC_SHA2_512],
mac_algorithms_server_to_client: vec![message::kex::MacAlgorithm::HMAC_SHA2_512],
compression_algorithms_client_to_server: vec![message::kex::CompressionAlgorithm::None],
compression_algorithms_server_to_client: vec![message::kex::CompressionAlgorithm::None],
languages_client_to_server: vec![],
languages_server_to_client: vec![],
first_kex_packet_follows: false
};
protocol::write_message(&mut stream, &kex);
}
else {
println!("Unhandled Message Type");
}
*/
}
Ok(())
}
......
use key_exchange::KeyExchange;
use key_exchange::{self, KeyExchange, KeyExchangeResult};
use message::MessageType;
use packet::{Packet, ReadPacketExt, WritePacketExt};
use std::io::Write;
......@@ -7,29 +7,29 @@ use std::io::Write;
enum SessionState {
Initial,
KeyExchange,
Established
Established,
}
#[derive(PartialEq)]
pub enum SessionType {
Server,
Client
Client,
}
pub struct Session<'a, W: Write> {
pub struct Session<W: Write> {
stype: SessionType,
state: SessionState,
key_exchange: Option<&'a KeyExchange>,
stream: W
key_exchange: Option<Box<KeyExchange>>,
stream: W,
}
impl<'a, W: Write> Session<'a, W> {
pub fn new(stype: SessionType, stream: W) -> Session<'a, W> {
impl<W: Write> Session<W> {
pub fn new(stype: SessionType, stream: W) -> Session<W> {
Session {
stype: stype,
state: SessionState::Initial,
key_exchange: None,
stream: stream
stream: stream,
}
}
......@@ -39,6 +39,20 @@ impl<'a, W: Write> Session<'a, W> {
println!("Starting Key Exchange!");
self.kex_init(packet);
}
MessageType::KeyExchange(_) => {
if let Some(ref kex) = self.key_exchange {
match kex.process(packet) {
KeyExchangeResult::Ok(Some(packet)) => { packet.write_to(&mut self.stream); },
KeyExchangeResult::Error(Some(packet)) => { packet.write_to(&mut self.stream); },
KeyExchangeResult::Done(Some(packet)) => { packet.write_to(&mut self.stream); },
KeyExchangeResult::Ok(None) |
KeyExchangeResult::Error(None) |
KeyExchangeResult::Done(None) => {}
};
} else {
warn!("Received KeyExchange packet without KexInit");
}
}
_ => {
println!("Unhandled packet: {:?}", packet);
}
......@@ -49,7 +63,6 @@ impl<'a, W: Write> Session<'a, W> {
use algorithm::*;
let mut reader = packet.reader();
reader.read_msg_type();
let cookie = reader.read_bytes(16);
let kex_algos = reader.read_enum_list::<KeyExchangeAlgorithm>();
let srv_host_key_algos = reader.read_enum_list::<PublicKeyAlgorithm>();
......@@ -66,11 +79,11 @@ impl<'a, W: Write> Session<'a, W> {
let mac_algo = negotiate(MAC, mac_algos_s2c.unwrap().as_slice());
let comp_algo = negotiate(COMPRESSION, comp_algos_s2c.unwrap().as_slice());
println!("Negociated Kex Algorithm: {:?}", kex_algo);
println!("Negociated Host Key Algorithm: {:?}", srv_host_key_algo);
println!("Negociated Encryption Algorithm: {:?}", enc_algo);
println!("Negociated Mac Algorithm: {:?}", mac_algo);
println!("Negociated Comp Algorithm: {:?}", comp_algo);
println!("Negotiated Kex Algorithm: {:?}", kex_algo);
println!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
println!("Negotiated Encryption Algorithm: {:?}", enc_algo);
println!("Negotiated Mac Algorithm: {:?}", mac_algo);
println!("Negotiated Comp Algorithm: {:?}", comp_algo);
use rand::{OsRng, Rng};
let mut rng = OsRng::new().unwrap();
......@@ -94,6 +107,7 @@ impl<'a, W: Write> Session<'a, W> {
});
self.state = SessionState::KeyExchange;
self.key_exchange = Some(Box::new(key_exchange::DhGroupSha1::new()));
packet.write_to(&mut self.stream);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment