Compare commits

...

2 Commits

Author SHA1 Message Date
occheung 0c6807f593 fix: subtle version
Both "RSA" and "curve25519_dalek" depend on "subtle".
"curve25519_dalek" depends on any "subtle" version after "2.2.1"
Before commit "f6b445b" on the "RSA" crate, any version of "subtle" that is at least 2.0.0 can support the "RSA" crate.
Commit "f6b445b" of "RSA" broke "subtle" by mandating the use of version "2.1.1" of "subtle".

This commit fixes the dependency conflict by changing the source of "RSA" code to commit "c879eb2", which reverts the "subtle" dependency change.
2020-12-07 11:27:04 +08:00
occheung 370766aa1b deadcode: recuce 2020-12-07 11:26:49 +08:00
9 changed files with 45 additions and 190 deletions

View File

@ -58,6 +58,7 @@ features = [ "u64_backend" ]
# Fetch from master, for "no_std" + "alloc" combination # Fetch from master, for "no_std" + "alloc" combination
[dependencies.rsa] [dependencies.rsa]
git = "https://github.com/RustCrypto/RSA.git" git = "https://github.com/RustCrypto/RSA.git"
rev = "c879eb2"
default-features = false default-features = false
features = [ "alloc" ] features = [ "alloc" ]
@ -93,13 +94,14 @@ optional = true
version = "0.3.1" version = "0.3.1"
optional = true optional = true
# Support old version of embedded_nal interface only # Support `TcpStack` from old version of embedded_nal interface
# It is to operate with crates such as MiniMQ, which still depends on version 0.1.0 # It is to operate with crates such as MiniMQ, which still depends on version 0.1.0
[dependencies.embedded-nal] [dependencies.embedded-nal-tcp-stack]
package = "embedded-nal"
version = "0.1.0" version = "0.1.0"
optional = true optional = true
[features] [features]
default = [] default = []
std = [ "rand", "hex-literal", "simple_logger", "rsa/default" ] std = [ "rand", "hex-literal", "simple_logger", "rsa/default" ]
nal_stack = [ "embedded-nal" ] nal_tcp_stack = [ "embedded-nal-tcp-stack" ]

View File

@ -193,6 +193,7 @@ impl<'a> TlsBuffer<'a> {
macro_rules! export_byte_order_fn { macro_rules! export_byte_order_fn {
($($write_fn_name: ident, $read_fn_name: ident, $data_type: ty, $data_size: literal),+) => { ($($write_fn_name: ident, $read_fn_name: ident, $data_type: ty, $data_size: literal),+) => {
#[allow(dead_code)]
impl<'a> TlsBuffer<'a> { impl<'a> TlsBuffer<'a> {
$( $(
pub(crate) fn $write_fn_name(&mut self, data: $data_type) -> Result<()> { pub(crate) fn $write_fn_name(&mut self, data: $data_type) -> Result<()> {

View File

@ -13,7 +13,7 @@ pub mod fake_rng;
pub mod oid; pub mod oid;
pub mod set; pub mod set;
#[cfg(feature = "nal_stack")] #[cfg(feature = "nal_tcp_stack")]
pub mod tcp_stack; pub mod tcp_stack;
// TODO: Implement errors // TODO: Implement errors

View File

@ -19,7 +19,7 @@ use sha2::{ Digest, Sha256, Sha384, Sha512 };
use std::vec::Vec; use std::vec::Vec;
use hkdf::Hkdf; use hkdf::Hkdf;
use rand::rngs::OsRng; // use rand::rngs::OsRng;
use chrono::prelude::*; use chrono::prelude::*;
@ -57,29 +57,30 @@ impl TlsRng for CountingRng {}
static mut RNG: CountingRng = CountingRng(0); static mut RNG: CountingRng = CountingRng(0);
fn main() { fn main() {
let mut socket_set_entries: [_; 8] = Default::default(); // let mut socket_set_entries: [_; 8] = Default::default();
let mut sockets = SocketSet::new(&mut socket_set_entries[..]); // let mut sockets = SocketSet::new(&mut socket_set_entries[..]);
let mut tx_storage = [0; 4096]; // let mut tx_storage = [0; 4096];
let mut rx_storage = [0; 4096]; // let mut rx_storage = [0; 4096];
let mut tls_socket = unsafe { // let mut tls_socket = unsafe {
let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]); // let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]);
let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]); // let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]);
let tcp_socket = smoltcp::socket::TcpSocket::new(rx_buffer, tx_buffer); // let tcp_socket = smoltcp::socket::TcpSocket::new(rx_buffer, tx_buffer);
TlsSocket::new( // TlsSocket::new(
tcp_socket, // tcp_socket,
&mut RNG, // &mut RNG,
None // None
) // )
}; // };
tls_socket.connect(
// &mut sockets,
(Ipv4Address::new(192, 168, 1, 125), 1883),
49600
).unwrap();
// tls_socket.connect(
// // &mut sockets,
// (Ipv4Address::new(192, 168, 1, 125), 1883),
// 49600
// ).unwrap();
}
/*
// tls_socket.tls_connect(&mut sockets).unwrap(); // tls_socket.tls_connect(&mut sockets).unwrap();
simple_logger::SimpleLogger::new().init().unwrap(); simple_logger::SimpleLogger::new().init().unwrap();
@ -360,3 +361,4 @@ const ED25519_SIGNATURE: [u8; 64] =
hex_literal::hex!( hex_literal::hex!(
"e9988fcc188fbe85a66929634badb47c5b765c3c6087a7e44b41efda1fdcd0baf67ded6159a5af6d396ca59439de8907160fc729a42ed50e69a3f54abe6dad0c" "e9988fcc188fbe85a66929634badb47c5b765c3c6087a7e44b41efda1fdcd0baf67ded6159a5af6d396ca59439de8907160fc729a42ed50e69a3f54abe6dad0c"
); );
*/

View File

@ -2,7 +2,7 @@ use p256::{ EncodedPoint, ecdh::EphemeralSecret, ecdsa::signature::DigestVerifie
use heapless::{ Vec, consts::* }; use heapless::{ Vec, consts::* };
use sha2::{ Digest, Sha256, Sha384, Sha512, digest::FixedOutput }; use sha2::{ Digest, Sha256, Sha384, Sha512, digest::FixedOutput };
use aes_gcm::{ Aes128Gcm, Aes256Gcm, aes::Aes128 }; use aes_gcm::{ Aes128Gcm, Aes256Gcm, aes::Aes128 };
use aes_gcm::{ AeadInPlace, NewAead, aead::Buffer }; use aes_gcm::{ AeadInPlace, NewAead };
use chacha20poly1305::ChaCha20Poly1305; use chacha20poly1305::ChaCha20Poly1305;
use ccm::Ccm; use ccm::Ccm;
use hkdf::Hkdf; use hkdf::Hkdf;
@ -1072,7 +1072,7 @@ impl<'a> Session<'a> {
fn find_application_keying_info(&mut self) { fn find_application_keying_info(&mut self) {
// Key calculation // Key calculation
if let Ok(sha256) = self.hash.get_sha256_clone() { if let Ok(_sha256) = self.hash.get_sha256_clone() {
// Derive application traffic secret, key, IV on client's side // Derive application traffic secret, key, IV on client's side
// 1. Derive secret from "Handshake Secret" // 1. Derive secret from "Handshake Secret"
let hkdf = Hkdf::<Sha256>::from_prk( let hkdf = Hkdf::<Sha256>::from_prk(
@ -1243,7 +1243,7 @@ impl<'a> Session<'a> {
}, },
_ => unreachable!() _ => unreachable!()
} }
} else if let Ok(sha384) = self.hash.get_sha384_clone() { } else if let Ok(_sha384) = self.hash.get_sha384_clone() {
// Derive application traffic secret, key, IV on client's side // Derive application traffic secret, key, IV on client's side
// 1. Derive secret from "Handshake Secret" // 1. Derive secret from "Handshake Secret"
let hkdf = Hkdf::<Sha384>::from_prk( let hkdf = Hkdf::<Sha384>::from_prk(
@ -1418,10 +1418,6 @@ impl<'a> Session<'a> {
self.need_send_alert self.need_send_alert
} }
pub(crate) fn has_completed_handshake(&self) -> bool {
self.state == TlsState::CLIENT_CONNECTED
}
pub(crate) fn receive_change_cipher_spec(&mut self) { pub(crate) fn receive_change_cipher_spec(&mut self) {
self.changed_cipher_spec = true; self.changed_cipher_spec = true;
} }
@ -1774,38 +1770,6 @@ impl<'a> Session<'a> {
) )
} }
pub(crate) fn encrypt_in_place(
&self,
associated_data: &[u8],
buffer: &mut dyn Buffer
) -> Result<(), Error> {
let (seq_num, nonce, cipher): (u64, &Vec<u8, U12>, &Cipher) = match self.role {
TlsRole::Client => {(
self.client_sequence_number,
self.client_handshake_nonce.as_ref().unwrap(),
self.client_handshake_cipher.as_ref().unwrap()
)},
TlsRole::Server => {(
self.server_sequence_number,
self.server_handshake_nonce.as_ref().unwrap(),
self.server_handshake_cipher.as_ref().unwrap()
)},
TlsRole::Unknown => unreachable!()
};
// Calculate XOR'ed nonce
let nonce: u128 = NetworkEndian::read_uint128(nonce, 12);
let clipped_seq_num: u128 = seq_num.into();
let mut processed_nonce: [u8; 12] = [0; 12];
NetworkEndian::write_uint128(&mut processed_nonce, nonce ^ clipped_seq_num, 12);
cipher.encrypt_in_place(
&GenericArray::from_slice(&processed_nonce),
associated_data,
buffer
)
}
pub(crate) fn encrypt_in_place_detached( pub(crate) fn encrypt_in_place_detached(
&self, &self,
associated_data: &[u8], associated_data: &[u8],
@ -1878,39 +1842,6 @@ impl<'a> Session<'a> {
) )
} }
// Decryption using handshake keys
pub(crate) fn decrypt_in_place(
&self,
associated_data: &[u8],
buffer: &mut dyn Buffer
) -> Result<(), Error> {
let (seq_num, nonce, cipher): (u64, &Vec<u8, U12>, &Cipher) = match self.role {
TlsRole::Server => {(
self.client_sequence_number,
self.client_handshake_nonce.as_ref().unwrap(),
self.client_handshake_cipher.as_ref().unwrap()
)},
TlsRole::Client => {(
self.server_sequence_number,
self.server_handshake_nonce.as_ref().unwrap(),
self.server_handshake_cipher.as_ref().unwrap()
)},
TlsRole::Unknown => unreachable!()
};
// Calculate XOR'ed nonce
let nonce: u128 = NetworkEndian::read_uint128(nonce, 12);
let clipped_seq_num: u128 = seq_num.into();
let mut processed_nonce: [u8; 12] = [0; 12];
NetworkEndian::write_uint128(&mut processed_nonce, nonce ^ clipped_seq_num, 12);
cipher.decrypt_in_place(
&GenericArray::from_slice(&processed_nonce),
associated_data,
buffer
)
}
// A veriant for handshake decryption in-place and detached // A veriant for handshake decryption in-place and detached
// Caller need to manually discard the authentication bytes // Caller need to manually discard the authentication bytes
pub(crate) fn decrypt_in_place_detached( pub(crate) fn decrypt_in_place_detached(
@ -1974,10 +1905,6 @@ impl<'a> Session<'a> {
_ => unreachable!() _ => unreachable!()
} }
} }
pub(crate) fn get_session_role(&self) -> TlsRole {
self.role
}
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -2072,28 +1999,6 @@ pub(crate) enum Cipher {
} }
impl Cipher { impl Cipher {
pub(crate) fn encrypt_in_place(
&self,
nonce: &GenericArray<u8, U12>,
associated_data: &[u8],
buffer: &mut dyn Buffer
) -> Result<(), Error> {
match self {
Cipher::Aes128Gcm { aes128gcm } => {
aes128gcm.encrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Aes256Gcm { aes256gcm } => {
aes256gcm.encrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Chacha20poly1305 { chacha20poly1305 } => {
chacha20poly1305.encrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Ccm { ccm } => {
ccm.encrypt_in_place(nonce, associated_data, buffer)
}
}.map_err(|_| Error::EncryptionError)
}
pub(crate) fn encrypt_in_place_detached( pub(crate) fn encrypt_in_place_detached(
&self, &self,
nonce: &GenericArray<u8, U12>, nonce: &GenericArray<u8, U12>,
@ -2116,28 +2021,6 @@ impl Cipher {
}.map_err(|_| Error::EncryptionError) }.map_err(|_| Error::EncryptionError)
} }
pub(crate) fn decrypt_in_place(
&self,
nonce: &GenericArray<u8, U12>,
associated_data: &[u8],
buffer: &mut dyn Buffer
) -> Result<(), Error> {
match self {
Cipher::Aes128Gcm { aes128gcm } => {
aes128gcm.decrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Aes256Gcm { aes256gcm } => {
aes256gcm.decrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Chacha20poly1305 { chacha20poly1305 } => {
chacha20poly1305.decrypt_in_place(nonce, associated_data, buffer)
},
Cipher::Ccm { ccm } => {
ccm.decrypt_in_place(nonce, associated_data, buffer)
}
}.map_err(|_| Error::DecryptionError)
}
pub(crate) fn decrypt_in_place_detached( pub(crate) fn decrypt_in_place_detached(
&self, &self,
nonce: &GenericArray<u8, U12>, nonce: &GenericArray<u8, U12>,

View File

@ -2,7 +2,6 @@ use smoltcp as net;
use managed::ManagedSlice; use managed::ManagedSlice;
use crate::tls::TlsSocket; use crate::tls::TlsSocket;
use net::socket::SocketSet;
use net::phy::Device; use net::phy::Device;
use net::iface::EthernetInterface; use net::iface::EthernetInterface;
use net::time::Instant; use net::time::Instant;

View File

@ -1,12 +1,10 @@
use embedded_nal as nal; use embedded_nal_tcp_stack as nal;
use smoltcp as net; use smoltcp as net;
use crate::set::TlsSocketHandle as SocketHandle; use crate::set::TlsSocketHandle as SocketHandle;
use crate::set::TlsSocketSet as SocketSet; use crate::set::TlsSocketSet as SocketSet;
use crate::tls::TlsSocket;
use nal::{TcpStack, Mode, SocketAddr, nb}; use nal::{TcpStack, Mode, SocketAddr, nb};
use net::Error;
use net::iface::EthernetInterface; use net::iface::EthernetInterface;
use net::time::Instant; use net::time::Instant;
use net::phy::Device; use net::phy::Device;
@ -77,15 +75,13 @@ impl<'a, 'b, 'c> TcpStack for NetworkStack<'a, 'b, 'c> {
match self.unused_handles.borrow_mut().pop() { match self.unused_handles.borrow_mut().pop() {
Some(handle) => { Some(handle) => {
// Abort any active connections on the handle. // Abort any active connections on the handle.
log::info!("Have handle");
let mut sockets = self.sockets.borrow_mut(); let mut sockets = self.sockets.borrow_mut();
let mut internal_socket = sockets.get(handle); let internal_socket = sockets.get(handle);
internal_socket.close(); internal_socket.close().unwrap();
Ok(handle) Ok(handle)
} }
None => { None => {
log::info!("Insufficient handles");
Err(NetworkError::NoSocket) Err(NetworkError::NoSocket)
}, },
} }
@ -100,7 +96,7 @@ impl<'a, 'b, 'c> TcpStack for NetworkStack<'a, 'b, 'c> {
let internal_socket = sockets.get(socket); let internal_socket = sockets.get(socket);
match remote.ip() { match remote.ip() {
embedded_nal::IpAddr::V4(addr) => { nal::IpAddr::V4(addr) => {
let address = { let address = {
let octets = addr.octets(); let octets = addr.octets();
net::wire::Ipv4Address::new(octets[0], octets[1], octets[2], octets[3]) net::wire::Ipv4Address::new(octets[0], octets[1], octets[2], octets[3])
@ -109,7 +105,7 @@ impl<'a, 'b, 'c> TcpStack for NetworkStack<'a, 'b, 'c> {
.connect((address, remote.port()), self.get_ephemeral_port()) .connect((address, remote.port()), self.get_ephemeral_port())
.map_err(|_| NetworkError::ConnectionFailure)?; .map_err(|_| NetworkError::ConnectionFailure)?;
} }
embedded_nal::IpAddr::V6(addr) => { nal::IpAddr::V6(addr) => {
let address = { let address = {
let octets = addr.segments(); let octets = addr.segments();
net::wire::Ipv6Address::new( net::wire::Ipv6Address::new(
@ -163,7 +159,7 @@ impl<'a, 'b, 'c> TcpStack for NetworkStack<'a, 'b, 'c> {
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
let mut sockets = self.sockets.borrow_mut(); let mut sockets = self.sockets.borrow_mut();
let internal_socket = sockets.get(socket); let internal_socket = sockets.get(socket);
internal_socket.close(); internal_socket.close().unwrap();
self.unused_handles.borrow_mut().push(socket).unwrap(); self.unused_handles.borrow_mut().push(socket).unwrap();
Ok(()) Ok(())

View File

@ -2,7 +2,6 @@ use smoltcp::socket::TcpSocket;
use smoltcp::socket::TcpState; use smoltcp::socket::TcpState;
use smoltcp::socket::SocketHandle; use smoltcp::socket::SocketHandle;
use smoltcp::socket::SocketSet; use smoltcp::socket::SocketSet;
use smoltcp::socket::TcpSocketBuffer;
use smoltcp::wire::IpEndpoint; use smoltcp::wire::IpEndpoint;
use smoltcp::Result; use smoltcp::Result;
use smoltcp::Error; use smoltcp::Error;
@ -585,7 +584,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
let mut random: [u8; 32] = [0; 32]; let mut random: [u8; 32] = [0; 32];
self.rng.fill_bytes(&mut random); self.rng.fill_bytes(&mut random);
let (session_id, cipher_suite, server_ecdhe_public_key) = { let (session_id, cipher_suite, server_ecdhe_public_key) = {
let mut session = self.session.borrow(); let session = self.session.borrow();
( (
session.get_session_id(), session.get_session_id(),
session.get_cipher_suite(), session.get_cipher_suite(),
@ -665,7 +664,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// TODO: Option to allow a certificate request // TODO: Option to allow a certificate request
// Construct and send server certificate handshake content // Construct and send server certificate handshake content
let mut inner_plaintext = { let inner_plaintext = {
let mut inner_plaintext: Vec<u8> = Vec::new(); let mut inner_plaintext: Vec<u8> = Vec::new();
let session = self.session.borrow(); let session = self.session.borrow();
let certificates = session.get_private_certificate_slices().clone(); let certificates = session.get_private_certificate_slices().clone();
@ -735,7 +734,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
log::info!("sent certificate"); log::info!("sent certificate");
// Construct and send certificate verify // Construct and send certificate verify
let mut inner_plaintext = { let inner_plaintext = {
let mut inner_plaintext = Vec::new(); let mut inner_plaintext = Vec::new();
inner_plaintext.extend_from_slice(&[ inner_plaintext.extend_from_slice(&[
15, 15,
@ -1431,11 +1430,10 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// `key_share` extension: find the corresponding ECDHE shared key // `key_share` extension: find the corresponding ECDHE shared key
// `signature_algorithm`: pick a signature algorithm // `signature_algorithm`: pick a signature algorithm
// Will not handle PSK, no 0-RTT // Will not handle PSK, no 0-RTT
let mut version_check = false;
let mut offered_p256 = false; let mut offered_p256 = false;
let mut offered_x25519 = false; let mut offered_x25519 = false;
let mut ecdhe_public_key: Option<DiffieHellmanPublicKey> = None; let mut ecdhe_public_key: Option<DiffieHellmanPublicKey> = None;
let mut signature_algorithm: Option<SignatureScheme> = None; let signature_algorithm: Option<SignatureScheme>;
// Verify that TLS 1.3 is offered by the client // Verify that TLS 1.3 is offered by the client
if let Some(supported_version_extension) = client_hello.extensions.iter().find( if let Some(supported_version_extension) = client_hello.extensions.iter().find(
@ -1447,7 +1445,6 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
if let SupportedVersions::ClientHello { versions, .. } if let SupportedVersions::ClientHello { versions, .. }
= supported_version = supported_version
{ {
version_check = true;
if versions.iter().find( if versions.iter().find(
|&&version| version == TlsVersion::Tls13 |&&version| version == TlsVersion::Tls13
).is_none() ).is_none()
@ -1494,7 +1491,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
= &supported_groups.extension_data = &supported_groups.extension_data
{ {
// Mark down the offered and acceptable group // Mark down the offered and acceptable group
if let Some(group) = named_group_list.iter().find( if let Some(_group) = named_group_list.iter().find(
|&&named_group| { |&&named_group| {
named_group == NamedGroup::secp256r1 named_group == NamedGroup::secp256r1
} }
@ -1502,7 +1499,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
offered_p256 = true; offered_p256 = true;
} }
if let Some(group) = named_group_list.iter().find( if let Some(_group) = named_group_list.iter().find(
|&&named_group| { |&&named_group| {
named_group == NamedGroup::x25519 named_group == NamedGroup::x25519
} }

View File

@ -406,25 +406,6 @@ impl ClientHello {
self self
} }
pub(crate) fn add_sh_supported_versions(mut self) -> Self {
let selected_version = TlsVersion::Tls13;
let content = SupportedVersions::ServerHello {
selected_version
};
let extension_data = ExtensionData::SupportedVersions(content);
let length = extension_data.get_length();
let extension = Extension {
extension_type: ExtensionType::SupportedVersions,
length: length.try_into().unwrap(),
extension_data,
};
self.extensions.push(extension);
self
}
pub(crate) fn add_sig_algs(mut self) -> Self { pub(crate) fn add_sig_algs(mut self) -> Self {
let mut algorithms = Vec::new(); let mut algorithms = Vec::new();
{ {
@ -729,12 +710,6 @@ pub(crate) enum ExtensionType {
Unknown = 0xFFFF, Unknown = 0xFFFF,
} }
impl ExtensionType {
pub(crate) fn get_length(&self) -> u16 {
return 2;
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct Extension { pub(crate) struct Extension {
pub(crate) extension_type: ExtensionType, pub(crate) extension_type: ExtensionType,