Skip to content

PSK and DTLS support #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 6, 2022
Merged
11 changes: 10 additions & 1 deletion mbedtls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ cc = "1.0"
default = ["std", "aesni", "time", "padlock"]
std = ["mbedtls-sys-auto/std", "serde/std", "yasna"]
debug = ["mbedtls-sys-auto/debug"]
no_std_deps = ["core_io", "spin"]
no_std_deps = ["core_io", "spin", "serde/alloc"]
force_aesni_support = ["mbedtls-sys-auto/custom_has_support", "mbedtls-sys-auto/aes_alt", "aesni"]
mpi_force_c_code = ["mbedtls-sys-auto/mpi_force_c_code"]
rdrand = []
Expand All @@ -68,11 +68,20 @@ padlock = ["mbedtls-sys-auto/padlock"]
dsa = ["std", "yasna", "num-bigint", "bit-vec"]
pkcs12 = ["std", "yasna"]
pkcs12_rc2 = ["pkcs12", "rc2", "block-modes"]
legacy_protocols = ["mbedtls-sys-auto/legacy_protocols"]

[[example]]
name = "client"
required-features = ["std"]

[[example]]
name = "client_dtls"
required-features = ["std"]

[[example]]
name = "client_psk"
required-features = ["std"]

[[example]]
name = "server"
required-features = ["std"]
Expand Down
57 changes: 57 additions & 0 deletions mbedtls/examples/client_dtls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

// needed to have common code for `mod support` in unit and integrations tests
extern crate mbedtls;

use std::io::{self, stdin, stdout, Write};
use std::net::UdpSocket;
use std::sync::Arc;

use mbedtls::rng::CtrDrbg;
use mbedtls::ssl::config::{Endpoint, Preset, Transport};
use mbedtls::ssl::{Config, Context};
use mbedtls::x509::Certificate;
use mbedtls::Result as TlsResult;

#[path = "../tests/support/mod.rs"]
mod support;
use support::entropy::entropy_new;
use support::keys;

fn result_main(addr: &str) -> TlsResult<()> {
let entropy = Arc::new(entropy_new());
let rng = Arc::new(CtrDrbg::new(entropy, None)?);
let cert = Arc::new(Certificate::from_pem_multiple(keys::ROOT_CA_CERT.as_bytes())?);
let mut config = Config::new(Endpoint::Client, Transport::Datagram, Preset::Default);
config.set_rng(rng);
config.set_ca_list(cert, None);
let mut ctx = Context::new(Arc::new(config));
ctx.set_timer_callback(Box::new(mbedtls::ssl::context::Timer::new()));

let sock = UdpSocket::bind("localhost:12345").unwrap();
let sock = mbedtls::ssl::context::ConnectedUdpSocket::connect(sock, addr).unwrap();
ctx.establish(sock, None).unwrap();

let mut line = String::new();
stdin().read_line(&mut line).unwrap();
ctx.write_all(line.as_bytes()).unwrap();
io::copy(&mut ctx, &mut stdout()).unwrap();
Ok(())
}

fn main() {
let mut args = std::env::args();
args.next();
result_main(
&args
.next()
.expect("supply destination in command-line argument"),
)
.unwrap();
}
52 changes: 52 additions & 0 deletions mbedtls/examples/client_psk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright (c) Fortanix, Inc.
*
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
* option. This file may not be copied, modified, or distributed except
* according to those terms. */

// needed to have common code for `mod support` in unit and integrations tests
extern crate mbedtls;

use std::io::{self, stdin, stdout, Write};
use std::net::TcpStream;
use std::sync::Arc;

use mbedtls::rng::CtrDrbg;
use mbedtls::ssl::config::{Endpoint, Preset, Transport};
use mbedtls::ssl::{Config, Context};
use mbedtls::Result as TlsResult;

#[path = "../tests/support/mod.rs"]
mod support;
use support::entropy::entropy_new;

fn result_main(addr: &str) -> TlsResult<()> {
let entropy = Arc::new(entropy_new());
let rng = Arc::new(CtrDrbg::new(entropy, None)?);
let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default);
config.set_rng(rng);
config.set_psk(&[0x12, 0x34, 0x56, 0x78], "client").unwrap();
let mut ctx = Context::new(Arc::new(config));

let conn = TcpStream::connect(addr).unwrap();
ctx.establish(conn, None)?;

let mut line = String::new();
stdin().read_line(&mut line).unwrap();
ctx.write_all(line.as_bytes()).unwrap();
io::copy(&mut ctx, &mut stdout()).unwrap();
Ok(())
}

fn main() {
let mut args = std::env::args();
args.next();
result_main(
&args
.next()
.expect("supply destination in command-line argument"),
)
.unwrap();
}
23 changes: 22 additions & 1 deletion mbedtls/src/ssl/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::pk::Pk;
use crate::pk::dhparam::Dhm;
use crate::private::UnsafeFrom;
use crate::rng::RngCallback;
use crate::ssl::cookie::CookieCallback;
use crate::ssl::context::HandshakeContext;
use crate::ssl::ticket::TicketCallback;
use crate::x509::{self, Certificate, Crl, Profile, VerifyCallback};
Expand Down Expand Up @@ -164,6 +165,7 @@ define!(
sni_callback: Option<Arc<dyn SniCallback + 'static>>,
ticket_callback: Option<Arc<dyn TicketCallback + 'static>>,
ca_callback: Option<Arc<dyn CaCallback + 'static>>,
dtls_cookies: Option<Arc<dyn CookieCallback + 'static>>,
};
const drop: fn(&mut Self) = ssl_config_free;
impl<'a> Into<ptr> {}
Expand Down Expand Up @@ -199,6 +201,7 @@ impl Config {
sni_callback: None,
ticket_callback: None,
ca_callback: None,
dtls_cookies: None,
}
}

Expand Down Expand Up @@ -457,6 +460,25 @@ impl Config {
self.dbg_callback = Some(Arc::new(cb));
unsafe { ssl_conf_dbg(self.into(), Some(dbg_callback::<F>), &**self.dbg_callback.as_mut().unwrap() as *const _ as *mut c_void) }
}

/// Sets the PSK and the PSK-Identity
///
/// Only a single entry is supported at the moment. If another one was set before, it will be
/// overridden.
pub fn set_psk(&mut self, psk: &[u8], psk_identity: &str) -> Result<()> {
unsafe {
// This allocates and copies the buffers and does not store any pointer to them
ssl_conf_psk(self.into(), psk.as_ptr(), psk.len(), psk_identity.as_ptr(), psk_identity.len())
.into_result()
.map(|_| ())
}
}

/// Sets the cookie context and callbacks which are required for DTLS servers
pub fn set_dtls_cookies<T: CookieCallback + 'static>(&mut self, dtls_cookies: Arc<T>) {
unsafe { ssl_conf_dtls_cookies(self.into(), Some(T::cookie_write), Some(T::cookie_check), dtls_cookies.data_ptr()) };
self.dtls_cookies = Some(dtls_cookies);
}
}

// TODO
Expand All @@ -466,7 +488,6 @@ impl Config {
// ssl_conf_dtls_badmac_limit
// ssl_conf_handshake_timeout
// ssl_conf_session_cache
// ssl_conf_psk
// ssl_conf_psk_cb
// ssl_conf_sig_hashes
// ssl_conf_alpn_protocols
Expand Down
Loading