mirror of
https://gitlab.redox-os.org/CoffeeCode/redox-ssh.git
synced 2025-12-28 15:02:18 +01:00
Add BigInt
This commit is contained in:
parent
6dd79b785d
commit
8f19dadccc
9 changed files with 110 additions and 71 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
|
@ -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",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
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 trait KeyExchange {
|
||||
fn process(&self, packet: &Packet);
|
||||
pub enum KeyExchangeResult {
|
||||
Ok(Option<Packet>),
|
||||
Done(Option<Packet>),
|
||||
Error(Option<Packet>)
|
||||
}
|
||||
|
||||
pub trait KeyExchange {
|
||||
fn process(&self, packet: &Packet) -> KeyExchangeResult;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue