Skip to content
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

multiple bug fix & features #9

Merged
merged 3 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,5 @@ To deploy a Restls Service:
host: "vscode.dev" # Must be a TLS 1.2 server
password: [YOUR_RESTLS_PASSWORD]
version-hint: "tls12"
curve-id-hint: "curvep384" # One of: x25519, curvep384, curvep521 or curvep256
# If you have no idea, just choose a random one.
# If that's incorrect, your first connection will fail.
# But the client will correct that for you.
client-id: firefox # One of: chrome, ios, firefox or safari
```
4 changes: 2 additions & 2 deletions src/client_hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ impl ClientHello {
key_share
}

pub(crate) fn parse(buf: &mut Cursor<&[u8]>) -> Result<ClientHello> {
debug!("parsing client hello: {}", buf.remaining());
pub(crate) fn parse(buf: &mut Cursor<&[u8]>, id: usize) -> Result<ClientHello> {
debug!("[{}]parsing client hello: {}", id, buf.remaining());

buf.advance(5); // record header
let mut _client_random = [0; 32];
Expand Down
17 changes: 13 additions & 4 deletions src/client_key_exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::io::Cursor;

use crate::{
client_hello::ClientHello,
common::{HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE, RECORD_HANDSHAKE, RESTLS_HANDSHAKE_HMAC_LEN},
common::{
curve_id_to_index, CLIENT_AUTH_LAYOUT3, CLIENT_AUTH_LAYOUT4,
HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE, RECORD_HANDSHAKE,
},
};

pub struct ClientKeyExchange {}
Expand All @@ -15,6 +18,7 @@ impl ClientKeyExchange {
pub(crate) fn check(
buf: &mut Cursor<&[u8]>,
client_hello: &ClientHello,
curve: usize,
mut hasher: Hasher,
) -> Result<()> {
assert_eq!(buf.get_u8(), RECORD_HANDSHAKE);
Expand All @@ -28,9 +32,14 @@ impl ClientKeyExchange {
hasher.update(buf.chunk());
let actual_hash = hasher.finalize().into_bytes();

if &client_hello.session_id[..RESTLS_HANDSHAKE_HMAC_LEN]
!= &actual_hash[..RESTLS_HANDSHAKE_HMAC_LEN]
{
let curve_index = curve_id_to_index(curve)?;
let range = if client_hello.session_ticket.len() > 0 {
CLIENT_AUTH_LAYOUT4[curve_index]..CLIENT_AUTH_LAYOUT4[curve_index + 1]
} else {
CLIENT_AUTH_LAYOUT3[curve_index]..CLIENT_AUTH_LAYOUT3[curve_index + 1]
};
let hash_len = range.len();
if &client_hello.session_id[range] != &actual_hash[..hash_len] {
Err(anyhow!(
"reject: tls 1.2 client pub key mismatched, expect {:?}, actual {:?}, key {:?}",
&client_hello.session_id,
Expand Down
31 changes: 28 additions & 3 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use anyhow::{anyhow, Result};

// protocol constants
pub const REQUIRED_SESSION_ID_LEN: usize = 32;
pub const RESTLS_HANDSHAKE_HMAC_LEN: usize = 16;
pub const RESTLS_APPDATA_HMAC_LEN: usize = 8;
pub const RESTLS_APPDATA_LEN_OFFSET: usize = 5 + RESTLS_APPDATA_HMAC_LEN;
pub const RESTLS_APPDATA_LEN_OFFSET: usize = RESTLS_APPDATA_HMAC_LEN;
pub const RESTLS_MASK_LEN: usize = 4;
pub const RESTLS_APPDATA_OFFSET: usize = 5 + RESTLS_APPDATA_HMAC_LEN + RESTLS_MASK_LEN;
pub const RESTLS_APPDATA_OFFSET: usize = RESTLS_APPDATA_HMAC_LEN + RESTLS_MASK_LEN;
pub const TLS_RECORD_HEADER_LEN: usize = 5;

// record type
pub const RECORD_HANDSHAKE: u8 = 0x16;
Expand All @@ -22,6 +25,7 @@ pub const EXTENSION_KEY_SHARE: u16 = 0x0033;
pub const HANDSHAKE_TYPE_CLIENT_HELLO: u8 = 01;
pub const HANDSHAKE_TYPE_SERVER_HELLO: u8 = 02;
pub const HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE: u8 = 0x10;
pub const HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE: u8 = 0x0c;
pub const _HANDSHAKE_TYPE_SERVER_HELLO_DONE: u8 = 0x0e;

pub const HELLO_RETRY_RANDOM: [u8; 32] = [
Expand All @@ -34,4 +38,25 @@ pub const TO_SERVER_MAGIC: &'static [u8] = "client-to-server".as_bytes();

pub const BUF_SIZE: usize = 0x3000;

pub const CCS_RECORD: &'static [u8] = &[0x14, 0x03, 0x03, 0x00, 0x01, 0x01];
pub const CCS_RECORD: &'static [u8] = &[0x14, 0x03, 0x03, 0x00, 0x01, 0x01];

pub const CLIENT_AUTH_LAYOUT3: &'static [usize] = &[0, 11, 22, 32];
pub const CLIENT_AUTH_LAYOUT4: &'static [usize] = &[0, 8, 16, 24, 32];
pub const CLIENT_AUTH_SESSION_TICKET_OFFSET: usize = CLIENT_AUTH_LAYOUT4[3];
pub const CLIENT_AUTH_SESSION_TICKET_LEN: usize =
CLIENT_AUTH_LAYOUT4[4] - CLIENT_AUTH_SESSION_TICKET_OFFSET;

pub const CURVE_P256: usize = 23;
pub const CURVE_P384: usize = 24;
pub const X25519: usize = 29;

pub fn curve_id_to_index(curve_id: usize) -> Result<usize> {
match curve_id {
X25519 => Ok(0),
CURVE_P256 => Ok(1),
CURVE_P384 => Ok(2),
_ => Err(anyhow!("reject: unsupported curve id")),
}
}

pub const TLS12_GCM_CIPHER_SUITES: &[u16] = &[0xc02f, 0xc02b, 0xc030, 0xc02c];
Loading