Skip to content

Commit

Permalink
Merge pull request #9 from 3andne/prepare-v1-2
Browse files Browse the repository at this point in the history
multiple bug fix & features
  • Loading branch information
3andne committed Mar 9, 2023
2 parents 7f9948f + 3ea5f14 commit 33c5a28
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 72 deletions.
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

0 comments on commit 33c5a28

Please sign in to comment.