mirror of
https://gitlab.redox-os.org/CoffeeCode/redox-ssh.git
synced 2025-12-28 18:42:18 +01:00
Implement server host key file
This commit is contained in:
parent
0a3c2cb325
commit
5d81f21f3f
9 changed files with 102 additions and 50 deletions
|
|
@ -3,13 +3,14 @@ use std::fmt;
|
|||
|
||||
/// Slice of implemented key exchange algorithms, ordered by preference
|
||||
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
|
||||
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[PublicKeyAlgorithm::SSH_RSA,
|
||||
// PublicKeyAlgorithm::SSH_ED25519
|
||||
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[
|
||||
PublicKeyAlgorithm::SSH_ED25519,
|
||||
// PublicKeyAlgorithm::SSH_RSA,
|
||||
];
|
||||
|
||||
/// Slice of implemented encryption algorithms, ordered by preference
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ use ssh::public_key;
|
|||
|
||||
pub fn main() {
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,45 @@
|
|||
extern crate ssh;
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::str::FromStr;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::process;
|
||||
use std::str::FromStr;
|
||||
|
||||
use ssh::{Server, ServerConfig};
|
||||
use ssh::public_key::ED25519;
|
||||
|
||||
pub fn main() {
|
||||
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);
|
||||
while let Some(arg) = args.next() {
|
||||
match arg.as_ref() {
|
||||
match arg.as_ref()
|
||||
{
|
||||
"-q" => quiet = true,
|
||||
"-p" => {
|
||||
config.port = u16::from_str(&args.next().expect("sshd: no argument to -p option"))
|
||||
.expect("sshd: invalid port number to -p option");
|
||||
config.port =
|
||||
u16::from_str(
|
||||
&args.next().expect("sshd: no argument to -p option"),
|
||||
).expect("sshd: invalid port number to -p option");
|
||||
}
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,49 @@
|
|||
use crypto::curve25519::curve25519;
|
||||
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 {
|
||||
pub fn new() -> Curve25519 {
|
||||
Curve25519 { }
|
||||
Curve25519 {}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyExchange for Curve25519 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,9 @@ impl KeyExchange for DhGroupSha1 {
|
|||
|
||||
let mut packet = Packet::new(MessageType::KeyExchange(DH_GEX_GROUP));
|
||||
packet.with_writer(&|w| {
|
||||
w.write_mpint(g.clone());
|
||||
w.write_mpint(p.clone());
|
||||
w.write_mpint(g.clone())?;
|
||||
w.write_mpint(p.clone())?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.g = Some(g);
|
||||
|
|
@ -71,9 +72,10 @@ impl KeyExchange for DhGroupSha1 {
|
|||
|
||||
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");
|
||||
w.write_string("HELLO WORLD")?;
|
||||
w.write_mpint(e.clone())?;
|
||||
w.write_string("HELLO WORLD")?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
self.e = Some(e);
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ impl Packet {
|
|||
&mut self.payload
|
||||
}
|
||||
|
||||
pub fn with_writer(&mut self, f: &Fn(&mut Write) -> ()) {
|
||||
f(&mut self.payload);
|
||||
pub fn with_writer(&mut self, f: &Fn(&mut Write) -> Result<()>) -> Result<()> {
|
||||
f(&mut self.payload)
|
||||
}
|
||||
|
||||
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<()> {
|
||||
self.write_u32::<BigEndian>(bytes.len() as u32)?;
|
||||
self.write_uint32(bytes.len() as u32)?;
|
||||
self.write_all(bytes)
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +147,10 @@ pub trait WritePacketExt: WriteBytesExt {
|
|||
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<()> {
|
||||
let mut string = String::new();
|
||||
let mut iter = list.iter();
|
||||
|
|
|
|||
|
|
@ -3,20 +3,13 @@ use std::io::{self, Write};
|
|||
|
||||
use session::{Session, SessionType};
|
||||
use packet::Packet;
|
||||
use public_key::KeyPair;
|
||||
use protocol;
|
||||
|
||||
pub struct ServerConfig {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> ServerConfig {
|
||||
ServerConfig {
|
||||
host: "0.0.0.0".to_owned(),
|
||||
port: 22,
|
||||
}
|
||||
}
|
||||
pub key: Box<KeyPair>
|
||||
}
|
||||
|
||||
pub struct Server {
|
||||
|
|
|
|||
|
|
@ -91,23 +91,24 @@ impl<W: Write> Session<W> {
|
|||
|
||||
let mut packet = Packet::new(MessageType::KexInit);
|
||||
packet.with_writer(&|w| {
|
||||
w.write_raw_bytes(cookie.as_slice());
|
||||
w.write_list(KEY_EXCHANGE);
|
||||
w.write_list(HOST_KEY);
|
||||
w.write_list(ENCRYPTION);
|
||||
w.write_list(ENCRYPTION);
|
||||
w.write_list(MAC);
|
||||
w.write_list(MAC);
|
||||
w.write_list(COMPRESSION);
|
||||
w.write_list(COMPRESSION);
|
||||
w.write_string("");
|
||||
w.write_string("");
|
||||
w.write_bool(false);
|
||||
w.write_bytes(&[0, 0, 0, 0]);
|
||||
w.write_raw_bytes(cookie.as_slice())?;
|
||||
w.write_list(KEY_EXCHANGE)?;
|
||||
w.write_list(HOST_KEY)?;
|
||||
w.write_list(ENCRYPTION)?;
|
||||
w.write_list(ENCRYPTION)?;
|
||||
w.write_list(MAC)?;
|
||||
w.write_list(MAC)?;
|
||||
w.write_list(COMPRESSION)?;
|
||||
w.write_list(COMPRESSION)?;
|
||||
w.write_string("")?;
|
||||
w.write_string("")?;
|
||||
w.write_bool(false)?;
|
||||
w.write_uint32(0)?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ extern crate rand;
|
|||
|
||||
use rand::Rng;
|
||||
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> {
|
||||
// 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]
|
||||
fn test_ed25519() { test_crypto_system(&key::ED25519, None); }
|
||||
fn test_ed25519() { test_crypto_system(&public_key::ED25519, None); }
|
||||
|
|
|
|||
Loading…
Reference in a new issue