Commit abb40764 authored by Thomas Gatzweiler's avatar Thomas Gatzweiler
Browse files

Add public/private key traits

parent 8f19dadc
......@@ -5,8 +5,10 @@ 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)",
"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)",
"redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -15,6 +17,25 @@ name = "byteorder"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "coco"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.51"
......@@ -29,6 +50,11 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.26"
......@@ -63,6 +89,14 @@ name = "num-traits"
version = "0.1.39"
source = "git+https://github.com/rust-num/num#d159ed63be98c8ff01b62cbbf912d721e2b0eb41"
[[package]]
name = "num_cpus"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.15"
......@@ -71,11 +105,44 @@ dependencies = [
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ring"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-crypto"
version = "0.2.36"
......@@ -93,6 +160,11 @@ name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "time"
version = "0.1.38"
......@@ -104,6 +176,11 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "untrusted"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
......@@ -116,17 +193,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a"
"checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
"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 num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
"checksum redox_syscall 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "9df6a71a1e67be2104410736b2389fb8e383c1d7e9e792d629ff13c02867147a"
"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
"checksum untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b65243989ef6aacd9c0d6bd2b822765c3361d8ed352185a6f3a41f3a718c673"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
......@@ -10,10 +10,17 @@ path = "src/lib.rs"
[[bin]]
name = "ssh"
path = "src/bin/ssh.rs"
doc = false
[[bin]]
name = "sshd"
path = "src/bin/sshd.rs"
doc = false
[[bin]]
name = "ssh-keygen"
path = "src/bin/ssh-keygen.rs"
doc = false
[dependencies]
byteorder = "^1.0"
......@@ -21,6 +28,11 @@ log = "^0.3"
rust-crypto = "^0.2"
rand = "^0.3"
num-bigint = { git = "https://github.com/rust-num/num" }
num-traits = { git = "https://github.com/rust-num/num" }
[dependencies.ring]
version = "^0.11.0"
features = ["rsa_signing"]
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"
......
# redox-ssh
A ssh client and server written entirely on rust, primarily targeted at (http://redox-os.org).
A ssh client and server written entirely on rust, primarily targeted at [Redox OS](http://redox-os.org).
## Features
Currently implemented features, ordered by priority:
[ ] SSH Server
[ ] SSH Client
[ ] Encryption
[ ] Public key authentication
[ ] Port forwarding
[ ] SCP File Transfers
- [ ] SSH Server
- [ ] SSH Client
- [ ] Key Exchange algorithms
- [ ] `diffie-hellman-group-exchange-sha1`
- [ ] `curve25519-sha256`
- [ ] Public Key algorithms
- [ ] `ssh-rsa`
- [ ] `ssh-ed25519`
- [ ] Encryption algorithms
- [ ] `aes256-ctr`
- [ ] `aes256-gcm`
- [ ] Port forwarding
- [ ] SCP File Transfers
## License
......
extern crate ssh;
use std::io::prelude::*;
use std::fs::File;
pub fn main() {
let keys = (ssh::key::RSA.generate_key_pair)(1024);
let mut buffer = File::create("key.pub").unwrap();
keys.0.write(&mut buffer);
}
extern crate ssh;
pub fn main() {
println!("Hello from ssh!");
}
use std::io::{Result, Read, Write};
mod rsa;
pub use self::rsa::RSA;
pub trait Key {
fn system(&self) -> &'static CryptoSystem;
fn read(&self, r: &mut Read) -> Result<Box<Self>>
where
Self: Sized;
fn import(&self, r: &mut Read) -> Result<Box<Self>>
where
Self: Sized,
{
self.read(r)
}
fn write(&self, w: &mut Write) -> Result<()>;
fn export(&self, w: &mut Write) -> Result<()> {
self.write(w)
}
}
pub trait PublicKey: Key {
fn encrypt(&self, data: &[u8]) -> Vec<u8>;
}
pub trait PrivateKey: Key {
fn sign(&self, data: &[u8]) -> Vec<u8>;
}
type KeyPair = (Box<PublicKey>, Box<PrivateKey>);
pub struct CryptoSystem {
pub id: &'static str,
pub generate_key_pair: fn(bits: u32) -> KeyPair
}
use key::{Key, PublicKey, PrivateKey, KeyPair, CryptoSystem};
use std::io::{Read, Write, Result};
pub static RSA: CryptoSystem = CryptoSystem {
id: "ssh-rsa",
generate_key_pair: generate_key_pair,
};
pub fn generate_key_pair(size: u32) -> KeyPair {
let public = Box::new(RsaPublicKey::new());
let private = Box::new(RsaPrivateKey::new());
(public, private)
}
pub struct RsaPublicKey {}
impl RsaPublicKey {
pub fn new() -> RsaPublicKey {
RsaPublicKey {}
}
}
impl Key for RsaPublicKey {
fn system(&self) -> &'static CryptoSystem {
&RSA
}
fn read(&self, r: &mut Read) -> Result<Box<Self>> {
Err(::std::io::Error::new(::std::io::ErrorKind::Other, ""))
}
fn write(&self, w: &mut Write) -> Result<()> {
Ok(())
}
}
impl PublicKey for RsaPublicKey {
fn encrypt(&self, data: &[u8]) -> Vec<u8> {
Vec::new()
}
}
pub struct RsaPrivateKey {
}
impl RsaPrivateKey {
pub fn new() -> RsaPrivateKey {
RsaPrivateKey { }
}
}
impl PrivateKey for RsaPrivateKey {
fn sign(&self, data: &[u8]) -> Vec<u8> {
Vec::new()
}
}
impl Key for RsaPrivateKey {
fn system(&self) -> &'static CryptoSystem {
&RSA
}
fn read(&self, r: &mut Read) -> Result<Box<Self>> {
Err(::std::io::Error::new(::std::io::ErrorKind::Other, ""))
}
fn write(&self, w: &mut Write) -> Result<()> {
Ok(())
}
}
......@@ -12,7 +12,7 @@ impl Curve25519 {
}
impl KeyExchange for Curve25519 {
fn process(&self, packet: &Packet) -> KeyExchangeResult {
fn process(&mut self, packet: &Packet) -> KeyExchangeResult {
KeyExchangeResult::Ok(None)
}
}
use key_exchange::{KeyExchange, KeyExchangeResult};
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 process(&mut self, packet: &Packet) -> KeyExchangeResult {
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());
});
self.g = Some(g);
self.p = Some(p);
KeyExchangeResult::Ok(Some(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");
});
self.e = Some(e);
KeyExchangeResult::Ok(Some(packet))
},
_ => {
debug!("Unhandled key exchange packet: {:?}", packet);
KeyExchangeResult::Error(None)
}
}
}
}
......@@ -14,5 +14,5 @@ pub enum KeyExchangeResult {
}
pub trait KeyExchange {
fn process(&self, packet: &Packet) -> KeyExchangeResult;
fn process(&mut self, packet: &Packet) -> KeyExchangeResult;
}
extern crate byteorder;
extern crate rand;
extern crate ring;
extern crate crypto;
extern crate num_bigint;
#[macro_use]
extern crate log;
pub mod algorithm;
pub mod protocol;
mod algorithm;
mod protocol;
mod packet;
mod message;
mod session;
mod key_exchange;
pub mod key;
pub mod server;
pub mod packet;
pub mod message;
pub mod session;
pub mod key_exchange;
pub use self::server::{Server, ServerConfig};
......@@ -88,6 +88,10 @@ pub trait ReadPacketExt: ReadBytesExt {
Ok(BigInt::from_signed_bytes_be(bytes.as_slice()))
}
fn read_uint32(&mut self) -> Result<u32> {
Ok(self.read_u32::<BigEndian>()?)
}
fn read_bytes(&mut self, len: usize) -> Result<Vec<u8>> {
let mut buffer = Vec::with_capacity(len);
self.take(len as u64).read_to_end(&mut buffer)?;
......@@ -136,7 +140,7 @@ pub trait WritePacketExt: WriteBytesExt {
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_u32::<BigEndian>(bytes.len() as u32)?;
self.write_bytes(bytes.as_slice())
}
......
......@@ -40,7 +40,7 @@ impl<W: Write> Session<W> {
self.kex_init(packet);
}
MessageType::KeyExchange(_) => {
if let Some(ref kex) = self.key_exchange {
if let Some(ref mut 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); },
......
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