1
0
Fork 0
mirror of https://gitlab.redox-os.org/CoffeeCode/redox-ssh.git synced 2025-12-28 20:42:18 +01:00

Implement server host key file

This commit is contained in:
Thomas Gatzweiler 2017-07-15 15:59:37 +02:00
parent 0a3c2cb325
commit 5d81f21f3f
9 changed files with 102 additions and 50 deletions

View file

@ -3,13 +3,14 @@ use std::fmt;
/// Slice of implemented key exchange algorithms, ordered by preference /// Slice of implemented key exchange algorithms, ordered by preference
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] = &[ pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] = &[
KeyExchangeAlgorithm::DH_GROUP_EXCHANGE_SHA1, KeyExchangeAlgorithm::CURVE25519_SHA256,
// KeyExchangeAlgorithm::CURVE25519_SHA256, // KeyExchangeAlgorithm::DH_GROUP_EXCHANGE_SHA1,
]; ];
/// Slice of implemented host key algorithms, ordered by preference /// Slice of implemented host key algorithms, ordered by preference
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[PublicKeyAlgorithm::SSH_RSA, pub static HOST_KEY: &[PublicKeyAlgorithm] = &[
// PublicKeyAlgorithm::SSH_ED25519 PublicKeyAlgorithm::SSH_ED25519,
// PublicKeyAlgorithm::SSH_RSA,
]; ];
/// Slice of implemented encryption algorithms, ordered by preference /// Slice of implemented encryption algorithms, ordered by preference

View file

@ -6,6 +6,6 @@ use ssh::public_key;
pub fn main() { pub fn main() {
let keypair = (public_key::ED25519.generate_key_pair)(None); let keypair = (public_key::ED25519.generate_key_pair)(None);
let mut buffer = File::create("key.pub").unwrap(); let mut buffer = File::create("server.key").unwrap();
keypair.export(&mut buffer); keypair.export(&mut buffer);
} }

View file

@ -1,25 +1,45 @@
extern crate ssh; extern crate ssh;
use std::io::{self, Write};
use std::str::FromStr;
use std::env; use std::env;
use std::fs::File;
use std::io::{self, Write};
use std::process; use std::process;
use std::str::FromStr;
use ssh::{Server, ServerConfig}; use ssh::{Server, ServerConfig};
use ssh::public_key::ED25519;
pub fn main() { pub fn main() {
let mut quiet = false; let mut quiet = false;
let mut config = ServerConfig::default(); let key_pair = File::open("server.key").and_then(
|mut f| (ED25519.import)(&mut f),
);
if let Some(ref err) = key_pair.as_ref().err() {
writeln!(io::stderr(), "sshd: failed to open server.key: {}", err)
.unwrap();
process::exit(1);
}
let mut config = ServerConfig {
host: String::from("0.0.0.0"),
port: 22,
key: key_pair.unwrap(),
};
let mut args = env::args().skip(1); let mut args = env::args().skip(1);
while let Some(arg) = args.next() { while let Some(arg) = args.next() {
match arg.as_ref() { match arg.as_ref()
{
"-q" => quiet = true, "-q" => quiet = true,
"-p" => { "-p" => {
config.port = u16::from_str(&args.next().expect("sshd: no argument to -p option")) config.port =
.expect("sshd: invalid port number to -p option"); u16::from_str(
&args.next().expect("sshd: no argument to -p option"),
).expect("sshd: invalid port number to -p option");
} }
_ => () _ => (),
} }
} }

View file

@ -1,18 +1,49 @@
use crypto::curve25519::curve25519;
use key_exchange::{KeyExchange, KeyExchangeResult}; use key_exchange::{KeyExchange, KeyExchangeResult};
use packet::Packet; use message::MessageType;
use packet::{Packet, ReadPacketExt, WritePacketExt};
use public_key::ED25519;
pub struct Curve25519 { const ECDH_KEX_INIT: u8 = 30;
const ECDH_KEX_REPLY: u8 = 31;
} pub struct Curve25519 {}
impl Curve25519 { impl Curve25519 {
pub fn new() -> Curve25519 { pub fn new() -> Curve25519 {
Curve25519 { } Curve25519 {}
} }
} }
impl KeyExchange for Curve25519 { impl KeyExchange for Curve25519 {
fn process(&mut self, packet: &Packet) -> KeyExchangeResult { fn process(&mut self, packet: &Packet) -> KeyExchangeResult {
KeyExchangeResult::Ok(None) match packet.msg_type()
{
MessageType::KeyExchange(ECDH_KEX_INIT) => {
let mut reader = packet.reader();
let qc = reader.read_string().unwrap();
let keypair = (ED25519.generate_key_pair)(None);
let mut public_key = Vec::new();
keypair.write_public(&mut public_key);
println!("Received qc: {:?}", qc);
let mut packet =
Packet::new(MessageType::KeyExchange(ECDH_KEX_REPLY));
packet.with_writer(&|w| {
w.write_bytes(public_key.as_slice())?;
w.write_bytes(qc.as_slice())?;
w.write_bytes(&[0; 256])?;
Ok(())
});
KeyExchangeResult::Ok(Some(packet))
}
_ => {
debug!("Unhandled key exchange packet: {:?}", packet);
KeyExchangeResult::Error(None)
}
}
} }
} }

View file

@ -54,8 +54,9 @@ impl KeyExchange for DhGroupSha1 {
let mut packet = Packet::new(MessageType::KeyExchange(DH_GEX_GROUP)); let mut packet = Packet::new(MessageType::KeyExchange(DH_GEX_GROUP));
packet.with_writer(&|w| { packet.with_writer(&|w| {
w.write_mpint(g.clone()); w.write_mpint(g.clone())?;
w.write_mpint(p.clone()); w.write_mpint(p.clone())?;
Ok(())
}); });
self.g = Some(g); self.g = Some(g);
@ -71,9 +72,10 @@ impl KeyExchange for DhGroupSha1 {
let mut packet = Packet::new(MessageType::KeyExchange(DH_GEX_REPLY)); let mut packet = Packet::new(MessageType::KeyExchange(DH_GEX_REPLY));
packet.with_writer(&|w| { packet.with_writer(&|w| {
w.write_string("HELLO WORLD"); w.write_string("HELLO WORLD")?;
w.write_mpint(e.clone()); w.write_mpint(e.clone())?;
w.write_string("HELLO WORLD"); w.write_string("HELLO WORLD")?;
Ok(())
}); });
self.e = Some(e); self.e = Some(e);

View file

@ -58,8 +58,8 @@ impl Packet {
&mut self.payload &mut self.payload
} }
pub fn with_writer(&mut self, f: &Fn(&mut Write) -> ()) { pub fn with_writer(&mut self, f: &Fn(&mut Write) -> Result<()>) -> Result<()> {
f(&mut self.payload); f(&mut self.payload)
} }
pub fn reader<'a>(&'a self) -> BufReader<&'a [u8]> { pub fn reader<'a>(&'a self) -> BufReader<&'a [u8]> {
@ -130,7 +130,7 @@ pub trait WritePacketExt: WriteBytesExt {
} }
fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> { fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
self.write_u32::<BigEndian>(bytes.len() as u32)?; self.write_uint32(bytes.len() as u32)?;
self.write_all(bytes) self.write_all(bytes)
} }
@ -147,6 +147,10 @@ pub trait WritePacketExt: WriteBytesExt {
self.write_bytes(bytes.as_slice()) self.write_bytes(bytes.as_slice())
} }
fn write_uint32(&mut self, value: u32) -> Result<()> {
self.write_u32::<BigEndian>(value as u32)
}
fn write_list<T: ToString>(&mut self, list: &[T]) -> Result<()> { fn write_list<T: ToString>(&mut self, list: &[T]) -> Result<()> {
let mut string = String::new(); let mut string = String::new();
let mut iter = list.iter(); let mut iter = list.iter();

View file

@ -3,20 +3,13 @@ use std::io::{self, Write};
use session::{Session, SessionType}; use session::{Session, SessionType};
use packet::Packet; use packet::Packet;
use public_key::KeyPair;
use protocol; use protocol;
pub struct ServerConfig { pub struct ServerConfig {
pub host: String, pub host: String,
pub port: u16, pub port: u16,
} pub key: Box<KeyPair>
impl Default for ServerConfig {
fn default() -> ServerConfig {
ServerConfig {
host: "0.0.0.0".to_owned(),
port: 22,
}
}
} }
pub struct Server { pub struct Server {

View file

@ -91,23 +91,24 @@ impl<W: Write> Session<W> {
let mut packet = Packet::new(MessageType::KexInit); let mut packet = Packet::new(MessageType::KexInit);
packet.with_writer(&|w| { packet.with_writer(&|w| {
w.write_raw_bytes(cookie.as_slice()); w.write_raw_bytes(cookie.as_slice())?;
w.write_list(KEY_EXCHANGE); w.write_list(KEY_EXCHANGE)?;
w.write_list(HOST_KEY); w.write_list(HOST_KEY)?;
w.write_list(ENCRYPTION); w.write_list(ENCRYPTION)?;
w.write_list(ENCRYPTION); w.write_list(ENCRYPTION)?;
w.write_list(MAC); w.write_list(MAC)?;
w.write_list(MAC); w.write_list(MAC)?;
w.write_list(COMPRESSION); w.write_list(COMPRESSION)?;
w.write_list(COMPRESSION); w.write_list(COMPRESSION)?;
w.write_string(""); w.write_string("")?;
w.write_string(""); w.write_string("")?;
w.write_bool(false); w.write_bool(false)?;
w.write_bytes(&[0, 0, 0, 0]); w.write_uint32(0)?;
Ok(())
}); });
self.state = SessionState::KeyExchange; self.state = SessionState::KeyExchange;
self.key_exchange = Some(Box::new(key_exchange::DhGroupSha1::new())); self.key_exchange = Some(Box::new(key_exchange::Curve25519::new()));
packet.write_to(&mut self.stream); packet.write_to(&mut self.stream);
} }
} }

View file

@ -3,7 +3,7 @@ extern crate rand;
use rand::Rng; use rand::Rng;
use std::io::Cursor; use std::io::Cursor;
use ssh::key::{self, CryptoSystem, KeyPair}; use ssh::public_key::{self, CryptoSystem, KeyPair};
fn test_export_import(keypair: &Box<KeyPair>) -> Box<KeyPair> { fn test_export_import(keypair: &Box<KeyPair>) -> Box<KeyPair> {
// Export the keypair to a vector and import it again // Export the keypair to a vector and import it again
@ -36,4 +36,4 @@ fn test_crypto_system(system: &CryptoSystem, key_size: Option<u32>) {
} }
#[test] #[test]
fn test_ed25519() { test_crypto_system(&key::ED25519, None); } fn test_ed25519() { test_crypto_system(&public_key::ED25519, None); }