-
Notifications
You must be signed in to change notification settings - Fork 83
Add PSK support #107
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
Add PSK support #107
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -329,6 +329,49 @@ impl<'c> Config<'c> { | |
) | ||
} | ||
} | ||
|
||
/// psk and psk_identity cannot be empty | ||
pub fn set_psk(&mut self, psk: &[u8], psk_identity: &str) -> Result<()> { | ||
assert!(psk_identity.len()>0); | ||
assert!(psk.len()>0); | ||
unsafe { ssl_conf_psk(&mut self.inner, | ||
psk.as_ptr(), psk.len(), | ||
psk_identity.as_ptr(), psk_identity.len()) | ||
.into_result().map(|_| ()) | ||
} | ||
} | ||
|
||
pub fn set_psk_callback<F>(&mut self, cb: &'c mut F) | ||
where | ||
F: FnMut(&mut HandshakeContext, &str) -> Result<()>, | ||
{ | ||
unsafe extern "C" fn psk_callback<F>( | ||
closure: *mut c_void, | ||
ctx: *mut ssl_context, | ||
psk_identity: *const c_uchar, | ||
identity_len: size_t) -> c_int | ||
where | ||
F: FnMut(&mut HandshakeContext, &str) -> Result<()>, | ||
{ | ||
assert!(identity_len>0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, I don't see a reason for the assert. |
||
let cb = &mut *(closure as *mut F); | ||
let mut ctx = UnsafeFrom::from(ctx).expect("valid context"); | ||
let psk_identity = &*(from_raw_parts(psk_identity, identity_len) | ||
as *const [u8] as *const str); | ||
match cb(&mut ctx, psk_identity) { | ||
Ok(()) => 0, | ||
Err(e) => e.to_int(), | ||
} | ||
} | ||
|
||
unsafe { | ||
ssl_conf_psk_cb( | ||
&mut self.inner, | ||
Some(psk_callback::<F>), | ||
cb as *mut F as _ | ||
) | ||
} | ||
} | ||
} | ||
|
||
/// Builds a linked list of x509_crt instances, all of which are owned by mbedtls. That is, the | ||
|
@@ -417,8 +460,6 @@ impl<'a> Iterator for KeyCertIter<'a> { | |
// 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 | ||
// ssl_conf_fallback | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,6 +205,16 @@ impl<'ctx> HandshakeContext<'ctx> { | |
.map(|_| ()) | ||
} | ||
} | ||
|
||
/// psk cannot be empty | ||
pub fn set_psk(&mut self, psk: &[u8]) -> Result<()> { | ||
assert!(psk.len()>0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, I don't see a reason for the assert. |
||
unsafe { | ||
ssl_set_hs_psk(self.inner, psk.as_ptr(), psk.len()) | ||
.into_result() | ||
.map(|_| ()) | ||
} | ||
} | ||
} | ||
|
||
impl<'ctx> ::core::ops::Deref for HandshakeContext<'ctx> { | ||
|
@@ -315,7 +325,6 @@ impl<'a> Drop for Session<'a> { | |
// ssl_renegotiate | ||
// ssl_send_alert_message | ||
// ssl_set_client_transport_id | ||
// ssl_set_hs_psk | ||
// ssl_set_timer_cb | ||
// | ||
// ssl_handshake_step | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#![allow(dead_code)] | ||
extern crate mbedtls; | ||
|
||
use std::net::TcpStream; | ||
|
||
mod support; | ||
use support::entropy::entropy_new; | ||
|
||
use mbedtls::rng::CtrDrbg; | ||
use mbedtls::ssl::config::{Endpoint, Preset, Transport}; | ||
use mbedtls::ssl::{Config, Context, HandshakeContext}; | ||
use mbedtls::Result as TlsResult; | ||
|
||
|
||
fn client(mut conn: TcpStream, psk: &[u8]) -> TlsResult<()> { | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: this doesn't need to be in it's own block |
||
let mut entropy = entropy_new(); | ||
let mut rng = CtrDrbg::new(&mut entropy, None)?; | ||
let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); | ||
config.set_rng(Some(&mut rng)); | ||
config.set_psk(psk, "Client_identity")?; | ||
let mut ctx = Context::new(&config)?; | ||
ctx.establish(&mut conn, None).map(|_| ())?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
fn server<F>(mut conn: TcpStream, mut psk_callback: F) -> TlsResult<()> | ||
where | ||
F: FnMut(&mut HandshakeContext, &str) -> TlsResult<()> { | ||
let mut entropy = entropy_new(); | ||
let mut rng = CtrDrbg::new(&mut entropy, None)?; | ||
let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); | ||
config.set_rng(Some(&mut rng)); | ||
config.set_psk_callback(&mut psk_callback); | ||
let mut ctx = Context::new(&config)?; | ||
let _ = ctx.establish(&mut conn, None)?; | ||
Ok(()) | ||
} | ||
|
||
#[cfg(unix)] | ||
mod test { | ||
use super::*; | ||
use std::thread; | ||
use crate::support::net::create_tcp_pair; | ||
use crate::support::keys; | ||
|
||
#[test] | ||
fn callback_standard_psk() { | ||
let (c, s) = create_tcp_pair().unwrap(); | ||
let psk_callback = | ||
|ctx: &mut HandshakeContext, _: &str| { ctx.set_psk(keys::PRESHARED_KEY) }; | ||
let c = thread::spawn(move || super::client(c, keys::PRESHARED_KEY).unwrap()); | ||
let s = thread::spawn(move || super::server(s, psk_callback).unwrap()); | ||
c.join().unwrap(); | ||
s.join().unwrap(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
mbedtls_ssl_conf_psk
function already checks these arguments. I don't see a reason to check them here again