Skip to content

Commit 8db9d69

Browse files
authored
Merge pull request #455 from tox-rs/asymmetric
Pure rust asymmetric crypto
2 parents 3e4b8df + cb7edf1 commit 8db9d69

File tree

122 files changed

+4227
-4118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+4227
-4118
lines changed

examples/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ publish = false
55
edition = "2018"
66

77
[dev-dependencies]
8-
tox_binary_io = { version = "0.1.1", path = "../tox_binary_io", features = ["sodium"] }
8+
tox_binary_io = { version = "0.1.1", path = "../tox_binary_io", features = ["crypto"] }
99
tox_crypto = { version = "0.1.1", path = "../tox_crypto" }
1010
tox_packet = { version = "0.1.1", path = "../tox_packet" }
1111
tox_core = { version = "0.1.1", path = "../tox_core" }

examples/dht_server.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extern crate log;
88
use futures::future::FutureExt;
99
use futures::channel::mpsc;
1010
use failure::Error;
11+
use rand::thread_rng;
1112

1213
use std::net::SocketAddr;
1314

@@ -23,21 +24,19 @@ mod common;
2324

2425
fn as_packed_node(pk: &str, saddr: &str) -> PackedNode {
2526
let pk_bytes: [u8; 32] = hex::FromHex::from_hex(pk).unwrap();
26-
let pk = PublicKey::from_slice(&pk_bytes).unwrap();
27+
let pk = PublicKey::from(pk_bytes);
2728
let saddr: SocketAddr = saddr.parse().unwrap();
2829

29-
PackedNode::new(saddr, &pk)
30+
PackedNode::new(saddr, pk)
3031
}
3132

3233
#[tokio::main]
3334
async fn main() -> Result<(), Error> {
3435
env_logger::init();
3536

36-
if crypto_init().is_err() {
37-
panic!("Crypto initialization failed.");
38-
}
39-
40-
let (server_pk, server_sk) = gen_keypair();
37+
let mut rng = thread_rng();
38+
let server_sk = SecretKey::generate(&mut rng);
39+
let server_pk = server_sk.public_key();
4140

4241
// Create a channel for server to communicate with network
4342
let (tx, rx) = mpsc::channel(32);
@@ -48,7 +47,7 @@ async fn main() -> Result<(), Error> {
4847
let stats = Stats::new();
4948

5049
let mut lan_discovery_sender =
51-
LanDiscoverySender::new(tx.clone(), server_pk, local_addr.is_ipv6());
50+
LanDiscoverySender::new(tx.clone(), server_pk.clone(), local_addr.is_ipv6());
5251

5352
let mut dht_server = DhtServer::new(tx, server_pk, server_sk);
5453
dht_server.set_bootstrap_info(3_000_000_000, Box::new(|_| b"This is tox-rs".to_vec()));

examples/echo.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ async fn main() -> Result<(), Error> {
5252

5353
let mut rng = thread_rng();
5454

55-
let (dht_pk, dht_sk) = gen_keypair();
55+
let dht_sk = SecretKey::generate(&mut rng);
56+
let dht_pk = dht_sk.public_key();
5657

5758
// create random tox id and print it
58-
let (real_pk, real_sk) = gen_keypair();
59-
let id = ToxId::new(&mut rng, real_pk);
59+
let real_sk = SecretKey::generate(&mut rng);
60+
let real_pk = real_sk.public_key();
61+
let id = ToxId::new(&mut rng, real_pk.clone());
6062
println!("your tox id is: {:X}",id);
6163

6264
// Create a channel for server to communicate with network
@@ -70,16 +72,16 @@ async fn main() -> Result<(), Error> {
7072
let socket = common::bind_socket(local_addr).await;
7173
let stats = Stats::new();
7274

73-
let mut lan_discovery_sender = LanDiscoverySender::new(tx.clone(), dht_pk, local_addr.is_ipv6());
75+
let mut lan_discovery_sender = LanDiscoverySender::new(tx.clone(), dht_pk.clone(), local_addr.is_ipv6());
7476

7577
let (tcp_incoming_tx, mut tcp_incoming_rx) = mpsc::unbounded();
7678

77-
let mut dht_server = DhtServer::new(tx.clone(), dht_pk, dht_sk.clone());
79+
let mut dht_server = DhtServer::new(tx.clone(), dht_pk.clone(), dht_sk.clone());
7880
dht_server.enable_lan_discovery(true);
7981
dht_server.enable_ipv6_mode(local_addr.is_ipv6());
8082

81-
let tcp_connections = Connections::new(dht_pk, dht_sk.clone(), tcp_incoming_tx);
82-
let onion_client = OnionClient::new(dht_server.clone(), tcp_connections.clone(), real_sk.clone(), real_pk);
83+
let tcp_connections = Connections::new(dht_pk.clone(), dht_sk.clone(), tcp_incoming_tx);
84+
let onion_client = OnionClient::new(dht_server.clone(), tcp_connections.clone(), real_sk.clone(), real_pk.clone());
8385

8486
let (lossless_tx, mut lossless_rx) = mpsc::unbounded();
8587
let (lossy_tx, mut lossy_rx) = mpsc::unbounded();
@@ -93,7 +95,7 @@ async fn main() -> Result<(), Error> {
9395
lossy_tx,
9496
dht_pk,
9597
dht_sk,
96-
real_pk,
98+
real_pk: real_pk.clone(),
9799
real_sk: real_sk.clone(),
98100
precomputed_keys: dht_server.get_precomputed_keys(),
99101
});
@@ -115,11 +117,11 @@ async fn main() -> Result<(), Error> {
115117
// get PK bytes of the bootstrap node
116118
let bootstrap_pk_bytes: [u8; 32] = FromHex::from_hex(pk).unwrap();
117119
// create PK from bytes
118-
let bootstrap_pk = PublicKey::from_slice(&bootstrap_pk_bytes).unwrap();
120+
let bootstrap_pk = PublicKey::from(bootstrap_pk_bytes);
119121

120-
let node = PackedNode::new(saddr.parse().unwrap(), &bootstrap_pk);
122+
let node = PackedNode::new(saddr.parse().unwrap(), bootstrap_pk);
121123

122-
dht_server.add_initial_bootstrap(node);
124+
dht_server.add_initial_bootstrap(node.clone());
123125
onion_client.add_path_node(node).await;
124126
}
125127

@@ -176,8 +178,8 @@ async fn main() -> Result<(), Error> {
176178
}
177179
},
178180
0x18 => { // PACKET_ID_ONLINE
179-
net_crypto_c.send_lossless(pk, vec![0x18]).map_err(Error::from).await?;
180-
net_crypto_c.send_lossless(pk, vec![0x32, 0x00]).map_err(Error::from).await?; // PACKET_ID_USERSTATUS
181+
net_crypto_c.send_lossless(pk.clone(), vec![0x18]).map_err(Error::from).await?;
182+
net_crypto_c.send_lossless(pk.clone(), vec![0x32, 0x00]).map_err(Error::from).await?; // PACKET_ID_USERSTATUS
181183
net_crypto_c.send_lossless(pk, b"\x30tox-rs".to_vec()).map_err(Error::from).await?;
182184
},
183185
0x40 => { // PACKET_ID_CHAT_MESSAGE
@@ -210,7 +212,7 @@ async fn main() -> Result<(), Error> {
210212
// get PK bytes of the relay
211213
let relay_pk_bytes: [u8; 32] = FromHex::from_hex(pk).unwrap();
212214
// create PK from bytes
213-
let relay_pk = PublicKey::from_slice(&relay_pk_bytes).unwrap();
215+
let relay_pk = PublicKey::from(relay_pk_bytes);
214216

215217
tcp_connections.add_relay_global(saddr.parse().unwrap(), relay_pk).await.map_err(Error::from)?;
216218
}

examples/onion_client.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use futures::future::FutureExt;
88
use futures::stream::StreamExt;
99
use futures::sink::SinkExt;
1010
use futures::channel::mpsc;
11+
use rand::thread_rng;
1112
use tokio_util::udp::UdpFramed;
1213

1314
use tox_crypto::*;
@@ -27,17 +28,17 @@ const FRIEND_PK: &str = "3E6A06DA48D1AB98549AD76890770B704AE9116D8654FBCD35C9BF2
2728

2829
fn as_packed_node(pk: &str, saddr: &str) -> PackedNode {
2930
let pk_bytes: [u8; 32] = hex::FromHex::from_hex(pk).unwrap();
30-
let pk = PublicKey::from_slice(&pk_bytes).unwrap();
31+
let pk = PublicKey::from(pk_bytes);
3132
let saddr: SocketAddr = saddr.parse().unwrap();
3233

33-
PackedNode::new(saddr, &pk)
34+
PackedNode::new(saddr, pk)
3435
}
3536

3637
fn load_keypair() -> (PublicKey, SecretKey) {
3738
use hex::FromHex;
3839

3940
let real_sk_bytes: [u8; 32] = FromHex::from_hex(SELF_SK).unwrap();
40-
let real_sk = SecretKey::from_slice(&real_sk_bytes).unwrap();
41+
let real_sk = SecretKey::from(real_sk_bytes);
4142
let real_pk = real_sk.public_key();
4243

4344
(real_pk, real_sk)
@@ -47,7 +48,9 @@ fn load_keypair() -> (PublicKey, SecretKey) {
4748
async fn main() -> Result<(), Error> {
4849
env_logger::init();
4950

50-
let (dht_pk, dht_sk) = gen_keypair();
51+
let mut rng = thread_rng();
52+
let dht_sk = SecretKey::generate(&mut rng);
53+
let dht_pk = dht_sk.public_key();
5154
let (real_pk, real_sk) = load_keypair();
5255

5356
// Create a channel for server to communicate with network
@@ -61,7 +64,7 @@ async fn main() -> Result<(), Error> {
6164
let (dht_pk_tx, dht_pk_rx) = mpsc::unbounded();
6265
let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded();
6366

64-
let dht_server = Server::new(tx, dht_pk, dht_sk.clone());
67+
let dht_server = Server::new(tx, dht_pk.clone(), dht_sk.clone());
6568
let tcp_connections = Connections::new(dht_pk, dht_sk, tcp_incoming_tx);
6669
let onion_client = OnionClient::new(dht_server, tcp_connections, real_sk, real_pk);
6770

@@ -74,7 +77,7 @@ async fn main() -> Result<(), Error> {
7477
}
7578

7679
let friend_pk_bytes: [u8; 32] = hex::FromHex::from_hex(FRIEND_PK).unwrap();
77-
let friend_pk = PublicKey::from_slice(&friend_pk_bytes).unwrap();
80+
let friend_pk = PublicKey::from(friend_pk_bytes);
7881

7982
onion_client.add_friend(friend_pk).await;
8083

examples/tcp_client.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,38 @@ use tokio::net::TcpStream;
2424
// Since we pass a copy of tx as arg (to send PongResponses), the client will live untill IO error
2525
// Comment out pong responser and client will be destroyed when there will be no messages to send
2626
async fn create_client(mut rx: mpsc::Receiver<Packet>, tx: mpsc::Sender<Packet>) -> Result<(), Error> {
27-
// Use `gen_keypair` to generate random keys
2827
// Client constant keypair for examples/tests
29-
let client_pk = PublicKey([252, 72, 40, 127, 213, 13, 0, 95,
30-
13, 230, 176, 49, 69, 252, 220, 132,
31-
48, 73, 227, 58, 218, 154, 215, 245,
32-
23, 189, 223, 216, 153, 237, 130, 88]);
33-
let client_sk = SecretKey([157, 128, 29, 197, 1, 72, 47, 56,
34-
65, 81, 191, 67, 220, 225, 108, 193,
35-
46, 163, 145, 242, 139, 125, 159,
36-
137, 174, 14, 225, 7, 138, 120, 185, 153]);
28+
let client_pk = PublicKey::from([252, 72, 40, 127, 213, 13, 0, 95,
29+
13, 230, 176, 49, 69, 252, 220, 132,
30+
48, 73, 227, 58, 218, 154, 215, 245,
31+
23, 189, 223, 216, 153, 237, 130, 88]);
32+
let client_sk = SecretKey::from([157, 128, 29, 197, 1, 72, 47, 56,
33+
65, 81, 191, 67, 220, 225, 108, 193,
34+
46, 163, 145, 242, 139, 125, 159,
35+
137, 174, 14, 225, 7, 138, 120, 185, 153]);
3736

3837
let (addr, server_pk) = match 1 {
3938
1 => {
4039
// local tcp relay server from example
4140
let addr: std::net::SocketAddr = "0.0.0.0:12345".parse().unwrap();
4241
// Server constant PK for examples/tests
43-
let server_pk = PublicKey([177, 185, 54, 250, 10, 168, 174,
44-
148, 0, 93, 99, 13, 131, 131, 239,
45-
193, 129, 141, 80, 158, 50, 133, 100,
46-
182, 179, 183, 234, 116, 142, 102, 53, 38]);
42+
let server_pk = PublicKey::from([177, 185, 54, 250, 10, 168, 174,
43+
148, 0, 93, 99, 13, 131, 131, 239,
44+
193, 129, 141, 80, 158, 50, 133, 100,
45+
182, 179, 183, 234, 116, 142, 102, 53, 38]);
4746
(addr, server_pk)
4847
},
4948
2 => {
5049
// remote tcp relay server
5150
let server_pk_bytes: [u8; 32] = FromHex::from_hex("461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F").unwrap();
52-
let server_pk = PublicKey::from_slice(&server_pk_bytes).unwrap();
51+
let server_pk = PublicKey::from(server_pk_bytes);
5352
let addr = "130.133.110.14:33445".parse().unwrap();
5453
(addr, server_pk)
5554
},
5655
3 => {
5756
// local C DHT node, TODO remove this case
5857
let server_pk_bytes: [u8; 32] = FromHex::from_hex("C4B8D288C391704E3C8840A8A7C19B21D0B76CAF3B55341D37C5A9732887F879").unwrap();
59-
let server_pk = PublicKey::from_slice(&server_pk_bytes).unwrap();
58+
let server_pk = PublicKey::from(server_pk_bytes);
6059
let addr = "0.0.0.0:33445".parse().unwrap();
6160
(addr, server_pk)
6261
}
@@ -120,10 +119,10 @@ async fn main() -> Result<(), Error> {
120119
i += 1;
121120
if i == 1 {
122121
// Client friend constant PK for examples/tests
123-
let friend_pk = PublicKey([15, 107, 126, 130, 81, 55, 154, 157,
124-
192, 117, 0, 225, 119, 43, 48, 117,
125-
84, 109, 112, 57, 243, 216, 4, 171,
126-
185, 111, 33, 146, 221, 31, 77, 118]);
122+
let friend_pk = PublicKey::from([15, 107, 126, 130, 81, 55, 154, 157,
123+
192, 117, 0, 225, 119, 43, 48, 117,
124+
84, 109, 112, 57, 243, 216, 4, 171,
125+
185, 111, 33, 146, 221, 31, 77, 118]);
127126
tx.send(Packet::RouteRequest(RouteRequest { pk: friend_pk } )).await?;
128127
} else {
129128
tx.send(Packet::Data(Data {

examples/tcp_server.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ const TCP_CONNECTIONS_LIMIT: usize = 1024;
1414
async fn main() -> Result<(), Error> {
1515
env_logger::init();
1616
// Server constant PK for examples/tests
17-
// Use `gen_keypair` to generate random keys
18-
let server_pk = PublicKey([
17+
let server_pk = PublicKey::from([
1918
177, 185, 54, 250, 10, 168, 174,
2019
148, 0, 93, 99, 13, 131, 131, 239,
2120
193, 129, 141, 80, 158, 50, 133, 100,
2221
182, 179, 183, 234, 116, 142, 102, 53, 38
2322
]);
24-
let server_sk = SecretKey([
23+
let server_sk = SecretKey::from([
2524
74, 163, 57, 111, 32, 145, 19, 40,
2625
44, 145, 233, 210, 173, 67, 88, 217,
2726
140, 147, 14, 176, 106, 255, 54, 249,

tox_binary_io/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ edition = "2018"
1717
[dependencies]
1818
nom = "5.1"
1919
cookie-factory = "0.3"
20-
sodiumoxide = { version = "0.2.5", optional = true }
20+
crypto_box = { version = "0.6", optional = true }
2121

2222
[features]
2323
default = []
24-
sodium = ["sodiumoxide"]
24+
crypto = ["crypto_box"]

tox_binary_io/src/crypto.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use std::convert::TryInto;
2+
3+
use nom::{map, map_opt, named, take};
4+
5+
use crypto_box::{PublicKey, SecretKey, KEY_SIZE};
6+
7+
use super::FromBytes;
8+
9+
10+
impl FromBytes for PublicKey {
11+
// TODO: use map_from with new nom version
12+
named!(from_bytes<PublicKey>, map!(map_opt!(take!(KEY_SIZE), |pk: &[u8]| pk.try_into().ok()), |pk: [u8; KEY_SIZE]| pk.into()));
13+
}
14+
15+
/* TODO
16+
Use the following implementation when https://github.com/TokTok/c-toxcore/issues/1169 is fixed.
17+
And when most of tox network will send valid PK for fake friends.
18+
19+
impl FromBytes for PublicKey {
20+
named!(from_bytes<PublicKey>, verify!(
21+
// TODO: use map_from with new nom version
22+
map!(map_opt!(take!(KEY_SIZE), |pk: &[u8]| pk.try_into().ok()), |pk: [u8; KEY_SIZE]| pk.into()),
23+
|pk| public_key_valid(&pk)
24+
));
25+
}
26+
*/
27+
28+
impl FromBytes for SecretKey {
29+
// TODO: use map_from with new nom version
30+
named!(from_bytes<SecretKey>, map!(map_opt!(take!(KEY_SIZE), |sk: &[u8]| sk.try_into().ok()), |sk: [u8; KEY_SIZE]| sk.into()));
31+
}
32+
33+
#[cfg(test)]
34+
mod tests {
35+
use super::*;
36+
37+
#[test]
38+
fn public_key_parse_bytes_test() {
39+
let bytes = [42; KEY_SIZE];
40+
let (_rest, pk) = PublicKey::from_bytes(&bytes).unwrap();
41+
42+
assert_eq!(pk.as_bytes(), &bytes as &[u8]);
43+
}
44+
45+
#[test]
46+
fn secret_key_parse_bytes_test() {
47+
let bytes = [42; KEY_SIZE];
48+
let (_rest, sk) = SecretKey::from_bytes(&bytes).unwrap();
49+
50+
assert_eq!(&sk.to_bytes()[..], &bytes as &[u8]);
51+
}
52+
}

tox_binary_io/src/lib.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use std::{convert::TryInto, net::{
1111
Ipv6Addr,
1212
}};
1313

14-
#[cfg(feature = "sodiumoxide")]
15-
pub use sodium::*;
16-
#[cfg(feature = "sodiumoxide")]
17-
mod sodium;
14+
#[cfg(feature = "crypto")]
15+
pub use crypto::*;
16+
#[cfg(feature = "crypto")]
17+
mod crypto;
1818

1919
/// The trait provides method to deserialize struct from raw bytes
2020
pub trait FromBytes: Sized {
@@ -108,11 +108,9 @@ equals original value. Type of this value should implement `ToBytes`,
108108
*/
109109
#[macro_export]
110110
macro_rules! encode_decode_test (
111-
($init:expr, $test:ident, $value:expr) => (
111+
($test:ident, $value:expr) => (
112112
#[test]
113113
fn $test() {
114-
$init;
115-
116114
let value = $value;
117115
let mut buf = [0; 1024 * 1024];
118116
let (_, size) = value.to_bytes((&mut buf, 0)).unwrap();
@@ -140,13 +138,13 @@ macro_rules! unpack {
140138
($variable:expr, $variant:path [ $($inner:ident),* ]) => (
141139
match $variable {
142140
$variant( $($inner),* ) => ( $($inner),* ),
143-
other => panic!("Expected {} but got {:?}", stringify!($variant), other),
141+
other => panic!("Expected {}", stringify!($variant)),
144142
}
145143
);
146144
($variable:expr, $variant:path { $($inner:ident),* }) => (
147145
match $variable {
148146
$variant { $($inner,)* .. } => ( $($inner),* ),
149-
other => panic!("Expected {} but got {:?}", stringify!($variant), other),
147+
other => panic!("Expected {}", stringify!($variant)),
150148
}
151149
);
152150
}

0 commit comments

Comments
 (0)