Compare commits

..

No commits in common. "fe6418df36e8d27f53181ecaa23ec165a71667fe" and "25cdd234061a336c7d413c4c15538f74061d6102" have entirely different histories.

3 changed files with 182 additions and 418 deletions

View File

@ -14,7 +14,6 @@ use smoltcp::wire::IpEndpoint;
use crate::tls::TlsState; use crate::tls::TlsState;
use crate::tls_packet::CipherSuite; use crate::tls_packet::CipherSuite;
use crate::tls_packet::AlertType;
use crate::key::*; use crate::key::*;
use crate::tls_packet::SignatureScheme; use crate::tls_packet::SignatureScheme;
use crate::Error; use crate::Error;
@ -83,8 +82,6 @@ pub(crate) struct Session<'a> {
// Client must cent Certificate extension iff server requested it // Client must cent Certificate extension iff server requested it
need_send_client_cert: bool, need_send_client_cert: bool,
client_cert_verify_sig_alg: Option<crate::tls_packet::SignatureScheme>, client_cert_verify_sig_alg: Option<crate::tls_packet::SignatureScheme>,
// Flag for the need of sending alert to terminate TLS session
need_send_alert: Option<AlertType>
} }
impl<'a> Session<'a> { impl<'a> Session<'a> {
@ -124,8 +121,7 @@ impl<'a> Session<'a> {
cert_public_key: None, cert_public_key: None,
cert_private_key: certificate_with_key, cert_private_key: certificate_with_key,
need_send_client_cert: false, need_send_client_cert: false,
client_cert_verify_sig_alg: None, client_cert_verify_sig_alg: None
need_send_alert: None
} }
} }
@ -147,21 +143,6 @@ impl<'a> Session<'a> {
self.state = TlsState::SERVER_START; self.state = TlsState::SERVER_START;
} }
pub(crate) fn invalidate_session(
&mut self,
alert: AlertType,
received_slice: &[u8]
) {
self.hash.update(received_slice);
self.need_send_alert = Some(alert);
}
pub(crate) fn reset_state(&mut self) {
// Clear alert
self.need_send_alert = None;
self.state = TlsState::DEFAULT;
}
// State transition from START to WAIT_SH // State transition from START to WAIT_SH
pub(crate) fn client_update_for_ch( pub(crate) fn client_update_for_ch(
&mut self, &mut self,
@ -1414,10 +1395,6 @@ impl<'a> Session<'a> {
self.remote_endpoint self.remote_endpoint
} }
pub(crate) fn get_need_send_alert(&self) -> Option<AlertType> {
self.need_send_alert
}
pub(crate) fn has_completed_handshake(&self) -> bool { pub(crate) fn has_completed_handshake(&self) -> bool {
self.state == TlsState::CLIENT_CONNECTED self.state == TlsState::CLIENT_CONNECTED
} }

View File

@ -57,7 +57,7 @@ pub(crate) enum TlsState {
SERVER_WAIT_CERT, SERVER_WAIT_CERT,
SERVER_WAIT_CV, SERVER_WAIT_CV,
SERVER_WAIT_FINISHED, SERVER_WAIT_FINISHED,
SERVER_CONNECTED SERVER_CONNECTED,
} }
pub struct TlsSocket<'a, 'b, 'c> pub struct TlsSocket<'a, 'b, 'c>
@ -148,19 +148,15 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
self.session.borrow().get_tls_state() self.session.borrow().get_tls_state()
}; };
let need_send_alert = {
self.session.borrow().get_need_send_alert()
};
// Check TCP socket/ TLS session // Check TCP socket/ TLS session
{ {
let tcp_state = self.sockets.get::<TcpSocket>(self.tcp_handle).state(); let tcp_state = self.sockets.get::<TcpSocket>(self.tcp_handle).state();
//Close TCP socket if necessary // // Check if it should connect to client or not
if tcp_state == TcpState::Established && tls_state == TlsState::DEFAULT { // if tls_socket.get_session_role() != crate::session::TlsRole::Client {
self.sockets.get::<TcpSocket>(self.tcp_handle).close(); // // Return true for no need to do anymore handshake
return Ok(false); // return Ok(true);
} // }
// Skip handshake processing if it is already completed // Skip handshake processing if it is already completed
// However, redo TCP handshake if TLS socket is trying to connect and // However, redo TCP handshake if TLS socket is trying to connect and
@ -181,117 +177,6 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
return Ok(false); return Ok(false);
} }
} }
// Send alert to start terminating TLS session if necessary
if let Some(alert) = need_send_alert {
match tls_state {
// Client side socket:
// States that expects plaintext payload
TlsState::WAIT_SH | TlsState::SERVER_START => {
// Send the cooresponding alert in plaintext
let mut tcp_socket = self.sockets.get::<TcpSocket>(self.tcp_handle);
tcp_socket.send(
|data| {
// Set up a TLS buffer on the internal buffer of TCP socket
let mut buffer = TlsBuffer::new(data);
// Instantiate a TLS bytes-representation with pre-determined alert
let tls_repr = TlsRepr::new().alert(alert);
if buffer.enqueue_tls_repr(tls_repr).is_err() {
return (0, ())
}
let slice: &[u8] = buffer.into();
(slice.len(), ())
}
)?;
},
// States that expects enrypted payload using handshake secret
TlsState::WAIT_EE |
TlsState::WAIT_CERT_CR |
TlsState::CLIENT_WAIT_CERT |
TlsState::CLIENT_WAIT_CV |
TlsState::CLIENT_WAIT_FINISHED |
TlsState::SERVER_COMPLETED |
TlsState::NEGOTIATED |
TlsState::WAIT_FLIGHT |
TlsState::SERVER_WAIT_CERT |
TlsState::SERVER_WAIT_CV => {
// Send the corresponding alert in ciphertext using handshake secret
let severity: u8 = match alert {
AlertType::CloseNotify | AlertType::UserCanceled => {
1
},
_ => 2
};
let mut alert_array: [u8; 3] = [
severity,
u8::try_from(alert).unwrap(),
21 // Alert content type
];
self.send_application_slice(&mut alert_array)?;
},
// States that expects enrypted payload using application data secret
TlsState::CLIENT_CONNECTED |
TlsState::SERVER_WAIT_FINISHED |
TlsState::SERVER_CONNECTED => {
// Send the corresponding alert in ciphertext using application data secret
// Sending order:
// 1. Associated data/ TLS Record layer
// 2. Encrypted { Alert }
// 3. Authentication tag (16 bytes for all supported AEADs)
let mut associated_data: [u8; 5] = [
0x17, // Application data
0x03, 0x03, // TLS 1.3 record disguised as TLS 1.2
0x00, 0x00 // Length of encrypted data, yet to be determined conveniently
];
NetworkEndian::write_u16(&mut associated_data[3..5],
2 // Payload length
+ 1 // Content type length
+ 16 // Auth tag length
);
// Alert: Warning (1) , Close notify (0)
let severity: u8 = match alert {
AlertType::CloseNotify | AlertType::UserCanceled => {
1
},
_ => 2
};
let mut alert_array: [u8; 3] = [
severity,
u8::try_from(alert).unwrap(),
21 // Alert content type
];
let mut session = self.session.borrow_mut();
let tag = session.encrypt_application_data_in_place_detached(
&associated_data,
&mut alert_array
).unwrap();
session.increment_local_sequence_number();
let mut tcp_socket = self.sockets.get::<TcpSocket>(self.tcp_handle);
if !tcp_socket.can_send() {
return Err(Error::Illegal);
}
tcp_socket.send_slice(&associated_data)?;
tcp_socket.send_slice(&alert_array)?;
tcp_socket.send_slice(&tag)?;
},
// Other states, such as client_start and default should never send alert
// These stages are too early to raise exceptions
_ => unreachable!()
}
// Finally, revert the FSM to DEFAULT to signal an invokation of
// `close()` to the TCP socket
self.session.borrow_mut().reset_state();
return Ok(false);
}
// Handle TLS handshake through TLS states // Handle TLS handshake through TLS states
match tls_state { match tls_state {
// Do nothing on the default state // Do nothing on the default state
@ -791,6 +676,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
return Ok(self.session.borrow().has_completed_handshake()) return Ok(self.session.borrow().has_completed_handshake())
} }
log::info!("Tls can recv");
// Peak into the first 5 bytes (TLS record layer) // Peak into the first 5 bytes (TLS record layer)
// This tells the length of the entire record // This tells the length of the entire record
let length = match tcp_socket.peek(5) { let length = match tcp_socket.peek(5) {
@ -798,6 +685,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
_ => return Ok(self.session.borrow().has_completed_handshake()) _ => return Ok(self.session.borrow().has_completed_handshake())
}; };
log::info!("tls record length: {:?}", length);
// Recv the entire TLS record // Recv the entire TLS record
tcp_socket.recv( tcp_socket.recv(
|buffer| ((length + 5).into(), Vec::from(&buffer[..(length + 5).into()])) |buffer| ((length + 5).into(), Vec::from(&buffer[..(length + 5).into()]))
@ -872,6 +761,119 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} }
log::info!("Processed record"); log::info!("Processed record");
} }
// // Finally dequeue the record from buffer
// if tcp_socket.recv(|_| (length.into(), ())).is_err() {
// return Ok(self.session.borrow().has_completed_handshake())
// }
// tcp_socket.recv(
// |buffer| {
// // log::info!("Received Buffer: {:?}", buffer);
// let buffer_size = buffer.len();
// // Provide a way to end the process early
// if buffer_size == 0 {
// return (0, ())
// }
// log::info!("Received something");
// let mut tls_repr_vec: Vec<(&[u8], TlsRepr)> = Vec::new();
// let mut bytes = &buffer[..buffer_size];
// // Sequentially push reprs into vec
// loop {
// match parse_tls_repr(bytes) {
// Ok((rest, (repr_slice, repr))) => {
// tls_repr_vec.push(
// (repr_slice, repr)
// );
// if rest.len() == 0 {
// break;
// } else {
// bytes = rest;
// }
// },
// // Dequeue everything and abort processing if it is malformed
// _ => return (buffer_size, ())
// };
// }
// // Sequencially process the representations in vector
// // Decrypt and split the handshake if necessary
// let tls_repr_vec_size = tls_repr_vec.len();
// for _index in 0..tls_repr_vec_size {
// let (repr_slice, mut repr) = tls_repr_vec.remove(0);
// // Process record base on content type
// log::info!("Record type: {:?}", repr.content_type);
// if repr.content_type == TlsContentType::ApplicationData {
// log::info!("Found application data");
// // Take the payload out of TLS Record and decrypt
// let mut app_data = repr.payload.take().unwrap();
// let mut associated_data = [0; 5];
// associated_data[0] = repr.content_type.into();
// NetworkEndian::write_u16(
// &mut associated_data[1..3],
// repr.version.into()
// );
// NetworkEndian::write_u16(
// &mut associated_data[3..5],
// repr.length
// );
// {
// let mut session = self.session.borrow_mut();
// session.decrypt_in_place_detached(
// &associated_data,
// &mut app_data
// ).unwrap();
// session.increment_remote_sequence_number();
// }
// // Discard last 16 bytes (auth tag)
// let inner_plaintext = &app_data[..app_data.len()-16];
// let (inner_content_type, _) = get_content_type_inner_plaintext(
// inner_plaintext
// );
// if inner_content_type != TlsContentType::Handshake {
// // Silently ignore non-handshakes
// continue;
// }
// let (_, mut inner_handshakes) = complete(
// parse_inner_plaintext_for_handshake
// )(inner_plaintext).unwrap();
// // Sequentially process all handshakes
// let num_of_handshakes = inner_handshakes.len();
// for _ in 0..num_of_handshakes {
// let (handshake_slice, handshake_repr) = inner_handshakes.remove(0);
// if self.process(
// handshake_slice,
// TlsRepr {
// content_type: TlsContentType::Handshake,
// version: repr.version,
// length: u16::try_from(handshake_repr.length).unwrap() + 4,
// payload: None,
// handshake: Some(handshake_repr)
// }
// ).is_err() {
// return (buffer_size, ())
// }
// }
// }
// else {
// if self.process(repr_slice, repr).is_err() {
// return (buffer_size, ())
// }
// log::info!("Processed record");
// }
// }
// (buffer_size, ())
// }
// )?;
} }
Ok(self.session.borrow().has_completed_handshake()) Ok(self.session.borrow().has_completed_handshake())
@ -924,23 +926,15 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// Check random: Cannot be SHA-256 of "HelloRetryRequest" // Check random: Cannot be SHA-256 of "HelloRetryRequest"
if server_hello.random == HRR_RANDOM { if server_hello.random == HRR_RANDOM {
// Abort communication with illegal parameter alert // Abort communication
self.session.borrow_mut().invalidate_session( todo!()
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
// Check session_id_echo // Check session_id_echo
// The socket should have a session_id after moving from START state // The socket should have a session_id after moving from START state
if !self.session.borrow().verify_session_id_echo(server_hello.session_id_echo) { if !self.session.borrow().verify_session_id_echo(server_hello.session_id_echo) {
// Abort communication with illegal parameter alert // Abort communication
self.session.borrow_mut().invalidate_session( todo!()
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
// Note the selected cipher suite // Note the selected cipher suite
@ -948,12 +942,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// TLSv13 forbidden key compression // TLSv13 forbidden key compression
if server_hello.compression_method != 0 { if server_hello.compression_method != 0 {
// Abort communication with illegal parameter alert // Abort communciation
self.session.borrow_mut().invalidate_session( todo!()
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
for extension in server_hello.extensions.iter() { for extension in server_hello.extensions.iter() {
@ -964,21 +954,12 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} }
) = extension.extension_data { ) = extension.extension_data {
if selected_version != TlsVersion::Tls13 { if selected_version != TlsVersion::Tls13 {
// Abort for choosing not offered TLS version, // Abort for choosing not offered TLS version
// with illegal parameter alert todo!()
self.session.borrow_mut().invalidate_session(
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Abort for malformatted extension, with decode error alert // Abort for illegal extension
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} }
@ -1004,17 +985,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
x25519_server_key x25519_server_key
) )
); );
},
// The client side implementation of this TLS socket only offers
// P-256 and x25519 as ECDHE key exchange algorithms
// Respond with illegal parameter alert and then terminate
_ => {
self.session.borrow_mut().invalidate_session(
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
_ => todo!()
} }
} }
} }
@ -1022,24 +994,13 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} else { } else {
// Handle invalid TLS packet // Handle invalid TLS packet
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
// Check that both selected_cipher and (p256_public OR x25519_public) were received // Check that both selected_cipher and (p256_public XNOR x25519_public) were received
// The case where key_share extension exists but no appropriate keys are returned
// is considered in above. The only remaining case is that the `key share` entry extension
// is not sent at all.
if selected_cipher.is_none() || (p256_public.is_none() && x25519_public.is_none()) { if selected_cipher.is_none() || (p256_public.is_none() && x25519_public.is_none()) {
// Abort communication // Abort communication
self.session.borrow_mut().invalidate_session( todo!()
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
// Get slice without reserialization // Get slice without reserialization
@ -1061,19 +1022,14 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// Verify that it is indeed an EE // Verify that it is indeed an EE
let might_be_ee = repr.handshake.take().unwrap(); let might_be_ee = repr.handshake.take().unwrap();
if might_be_ee.get_msg_type() != HandshakeType::EncryptedExtensions { if might_be_ee.get_msg_type() != HandshakeType::EncryptedExtensions {
// Unexpected message types // Process the other handshakes in "handshake_vec"
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
// Possiblity: Process payload // TODO: Process payload
// Practically, nothing will be done about cookies/server name
// These fields are typically not session related
// Extension processing is therefore skipped
// Practically, nothing will be done about cookies/server name
// Extension processing is therefore skipped
// Update hash of the session, get EE by taking appropriate length of data // Update hash of the session, get EE by taking appropriate length of data
// Length of handshake header is 4 // Length of handshake header is 4
let (_handshake_slice, ee_slice) = let (_handshake_slice, ee_slice) =
@ -1123,7 +1079,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
cert.get_cert_public_key().unwrap() cert.get_cert_public_key().unwrap()
); );
log::info!("Received WAIT_CERT_CR"); log::info!("Received WAIT_CERT_CR");
} else if might_be_cert.get_msg_type() == HandshakeType::CertificateRequest { }
else if might_be_cert.get_msg_type() == HandshakeType::CertificateRequest {
// Process signature algorithm extension // Process signature algorithm extension
// Signature algorithm for the private key of client cert must be included // Signature algorithm for the private key of client cert must be included
// within the list of signature algorithms // within the list of signature algorithms
@ -1164,23 +1121,17 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
); );
} }
} else { } else {
// Reject connection, CertificateRequest must have // Reject connection, CertificateRequest must have
// SignatureAlgorithm extension // SignatureAlgorithm extension
self.session.borrow_mut().invalidate_session( todo!()
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
log::info!("Received WAIT_CERT_CR"); log::info!("Received WAIT_CERT_CR");
} else { }
// Throw alert for not recving certificate/certificate request from server side else {
self.session.borrow_mut().invalidate_session( // Throw alert
AlertType::UnexpectedMessage, todo!()
handshake_slice
);
return Ok(());
} }
}, },
@ -1221,11 +1172,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} else { } else {
// Unexpected handshakes // Unexpected handshakes
// Throw alert // Throw alert
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
}, },
@ -1236,11 +1183,7 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
let might_be_cert_verify = repr.handshake.take().unwrap(); let might_be_cert_verify = repr.handshake.take().unwrap();
if might_be_cert_verify.get_msg_type() != HandshakeType::CertificateVerify { if might_be_cert_verify.get_msg_type() != HandshakeType::CertificateVerify {
// Process the other handshakes in "handshake_vec" // Process the other handshakes in "handshake_vec"
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
// Take out the portion for CertificateVerify // Take out the portion for CertificateVerify
@ -1269,12 +1212,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// Ensure that it is Finished // Ensure that it is Finished
let might_be_server_finished = repr.handshake.take().unwrap(); let might_be_server_finished = repr.handshake.take().unwrap();
if might_be_server_finished.get_msg_type() != HandshakeType::Finished { if might_be_server_finished.get_msg_type() != HandshakeType::Finished {
// Server Finished is expected. // Process the other handshakes in "handshake_vec"
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
// Take out the portion for server Finished // Take out the portion for server Finished
@ -1300,12 +1239,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// Ensure that is a Client Hello // Ensure that is a Client Hello
let might_be_client_hello = repr.handshake.take().unwrap(); let might_be_client_hello = repr.handshake.take().unwrap();
if might_be_client_hello.get_msg_type() != HandshakeType::ClientHello { if might_be_client_hello.get_msg_type() != HandshakeType::ClientHello {
// Throw alert. Client Hello is expected. // Throw alert
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
// Process as Client Hello // Process as Client Hello
@ -1330,14 +1265,9 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
if let Some(Some(nominated_cipher_suite)) = recognized_cipher_suite { if let Some(Some(nominated_cipher_suite)) = recognized_cipher_suite {
nominated_cipher_suite nominated_cipher_suite
} else { } else {
// No appropriate cipher found, // Not appropriate cipher found
// the full set of security measures cannot be set up. // Send alert
// Send alert for this todo!()
self.session.borrow_mut().invalidate_session(
AlertType::HandshakeFailure,
handshake_slice
);
return Ok(());
} }
}; };
@ -1370,36 +1300,20 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
{ {
// TLS 1.3 was not offered by client // TLS 1.3 was not offered by client
// Reject connection immediately // Reject connection immediately
self.session.borrow_mut().invalidate_session( todo!()
AlertType::IllegalParameter,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Wrong variant appeared, probably malformed // Wrong variant appeared, probably malformed
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Malformed TLS packet // Malformed TLS packet
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} else { } else {
// No supported_version extension was found, // No supported_version extension was found,
// Terminate by sending alert // Terminate by sending alert
self.session.borrow_mut().invalidate_session( todo!()
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
// Check offered ECDHE algorithm // Check offered ECDHE algorithm
@ -1427,23 +1341,11 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} }
} else { } else {
// Malformed TLS packet // Malformed TLS packet
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Client did not offer ECDHE algorithm within `supported version` extension // Client did not offer ECDHE algorithm
// While it is allowed, HRR is not handled as acceptable parameters todo!()
// should have been offered already initially.
// Possibility: Tolerate minor mismatch of client hello, and send HRR instead
self.session.borrow_mut().invalidate_session(
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
// Select usable key // Select usable key
@ -1493,32 +1395,20 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} }
} }
// There are no applicable offered client key, // If there are no applicable offered client key,
// Proper way of handling: Send a HelloRetryRequest with key generated // consider sending a ClientHelloRetry
if ecdhe_public_key.is_none() { if ecdhe_public_key.is_none() {
self.session.borrow_mut().invalidate_session( todo!()
AlertType::HandshakeFailure,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Malformed packet // Malformed packet
// Send alert to client // Send alert to client
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} else { } else {
// The key_share extension was not sent // The key_share extension was not sent
// Proper way of handling: Send a HelloRetryRequest with key generated // Consider sending a ClientHelloRequest
self.session.borrow_mut().invalidate_session( todo!()
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
// Select signature algorithm // Select signature algorithm
@ -1566,12 +1456,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
signature_algorithm = Some(*server_signature_algorithm); signature_algorithm = Some(*server_signature_algorithm);
} else { } else {
// Cannot find a suitable signature algorithm for the server side // Cannot find a suitable signature algorithm for the server side
// Terminate the negotiation with an alert // Terminate the negotiation with alert
self.session.borrow_mut().invalidate_session( todo!()
AlertType::HandshakeFailure,
handshake_slice
);
return Ok(());
} }
} else { } else {
@ -1581,20 +1467,12 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
} }
} else { } else {
// Malformed packet, type does not match content // Malformed packet, type does not match content
self.session.borrow_mut().invalidate_session( todo!()
AlertType::DecodeError,
handshake_slice
);
return Ok(());
} }
} else { } else {
// Will only accept authentication through certificate // Will only accept authentication through certificate
// Send alert if there are no signature algorithms extension // Send alert if there are no signature algorithms extension
self.session.borrow_mut().invalidate_session( todo!()
AlertType::MissingExtension,
handshake_slice
);
return Ok(());
} }
{ {
@ -1616,12 +1494,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
// Ensure that it is Finished // Ensure that it is Finished
let might_be_client_finished = repr.handshake.take().unwrap(); let might_be_client_finished = repr.handshake.take().unwrap();
if might_be_client_finished.get_msg_type() != HandshakeType::Finished { if might_be_client_finished.get_msg_type() != HandshakeType::Finished {
// Expected to recv client finished // Process the other handshakes in "handshake_vec"
self.session.borrow_mut().invalidate_session( todo!()
AlertType::UnexpectedMessage,
handshake_slice
);
return Ok(());
} }
// Take out the portion for server Finished // Take out the portion for server Finished
@ -1829,43 +1703,8 @@ impl<'a, 'b, 'c> TlsSocket<'a, 'b, 'c> {
Ok(()) Ok(())
} }
// Send `Close notify` alert to remote side pub fn get_tcp_handle(&self) -> SocketHandle {
// Set state to `CLOSED` self.tcp_handle
// Leave TCP termination to polling method
pub fn close(&mut self) -> Result<()> {
let mut session = self.session.borrow_mut();
match session.get_tls_state() {
// Send a `close notify` if handshake is established
TlsState::CLIENT_CONNECTED | TlsState::SERVER_CONNECTED => {
session.invalidate_session(
AlertType::CloseNotify,
&[]
);
},
// Do nothing if handshake hasn't even started
TlsState::DEFAULT => {},
// Send `user cancaled` to cancel the handshake negotiation
// if it is currently in the middle of one
_ => {
session.invalidate_session(
AlertType::UserCanceled,
&[]
);
}
} }
Ok(())
}
}
use core::fmt;
impl<'a, 'b, 'c> fmt::Write for TlsSocket<'a, 'b, 'c> {
fn write_str(&mut self, slice: &str) -> fmt::Result {
let slice = slice.as_bytes();
if self.send_slice(slice) == Ok(()) {
Ok(())
} else {
Err(fmt::Error)
}
}
} }

View File

@ -29,40 +29,6 @@ pub(crate) enum TlsContentType {
ApplicationData = 23 ApplicationData = 23
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub(crate) enum AlertType {
CloseNotify = 0,
UnexpectedMessage = 10,
BadRecordMac = 20,
RecordOverflow = 22,
HandshakeFailure = 40,
BadCertificate = 42,
UnsupportedCertificate = 43,
CertificateRevoked = 44,
CertificateExpired = 45,
CertificateUnknown = 46,
IllegalParameter = 47,
UnknownCA = 48,
AccessDenied = 49,
DecodeError = 50,
DecryptError = 51,
ProtocolVersion = 70,
InsufficientSecurity = 71,
InternalError = 80,
InappropriateFallback = 86,
UserCanceled = 90,
MissingExtension = 109,
UnsupportedExtension = 110,
UnrecognizedName = 112,
BadCertificateStatusResponse = 113,
UnknownPSKIdentity = 115,
CertificateRequired = 116,
NoApplicationProtcol = 120,
#[num_enum(default)]
UnknownAlert = 255
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)] #[repr(u16)]
pub(crate) enum TlsVersion { pub(crate) enum TlsVersion {
@ -147,24 +113,6 @@ impl<'a> TlsRepr<'a> {
self self
} }
pub(crate) fn alert(mut self, alert: AlertType) -> Self {
self.content_type = TlsContentType::Alert;
self.version = TlsVersion::Tls12;
let mut application_data: Vec<u8> = Vec::new();
match alert {
AlertType::CloseNotify | AlertType::UserCanceled => {
application_data.push(1)
},
_ => {
application_data.push(2)
}
};
application_data.push(alert.try_into().unwrap());
self.length = 2;
self.payload = Some(application_data);
self
}
// TODO: Consider replace all these boolean function // TODO: Consider replace all these boolean function
// into a single function that returns the HandshakeType. // into a single function that returns the HandshakeType.
pub(crate) fn is_server_hello(&self) -> bool { pub(crate) fn is_server_hello(&self) -> bool {