Skip to content

Commit 24731ef

Browse files
authored
Merge pull request #1 from abetterinternet/client_hello_callback_update_base
Update base.rs.
2 parents 05ad7eb + b3f7fd6 commit 24731ef

File tree

4 files changed

+352
-90
lines changed

4 files changed

+352
-90
lines changed

src/base.rs

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,108 @@
1-
use libc::size_t;
2-
use std::os::raw::{c_char, c_uchar, c_ushort};
1+
use libc::{c_char, size_t};
2+
use std::{marker::PhantomData, os::raw::{c_ushort}};
33

4-
/// A read-only view on a Rust utf-8 string.
5-
/// This is used to pass strings from crustls to callback functions provided
6-
/// by the user of the API. The `data` is not NUL-terminated.
7-
/// `len` indicates the number of utf-8 bytes than can be safely read.
8-
/// A `len` of 0 is used to represent a missing value.
4+
/// A read-only view on a Rust byte slice.
5+
///
6+
/// This is used to pass data from crustls to callback functions provided
7+
/// by the user of the API.
8+
/// `len` indicates the number of bytes than can be safely read.
9+
/// A `len` of 0 is used to represent a missing value OR an empty slice.
910
///
10-
/// The memmory exposed is available for the duration of the call (e.g.
11+
/// The memory exposed is available for the duration of the call (e.g.
1112
/// when passed to a callback) and must be copied if the values are
1213
/// needed for longer.
1314
#[allow(non_camel_case_types)]
1415
#[repr(C)]
15-
pub struct rustls_string {
16-
data: *const c_char,
16+
pub struct rustls_slice_bytes<'a> {
17+
data: *const u8,
1718
len: size_t,
19+
phantom: PhantomData<&'a [u8]>,
1820
}
1921

20-
impl<'a> From<&'a str> for rustls_string {
21-
fn from(s: &str) -> Self {
22-
rustls_string {
23-
data: s.as_ptr() as *const c_char,
22+
impl<'a> From<&'a [u8]> for rustls_slice_bytes<'a> {
23+
fn from(s: &[u8]) -> Self {
24+
rustls_slice_bytes {
25+
data: s.as_ptr() as *const u8,
2426
len: s.len() as size_t,
27+
phantom: PhantomData,
2528
}
2629
}
2730
}
2831

29-
/// A read-only view on a Rust slice of bytes.
32+
/// A read-only view on a vector of Rust byte slices.
33+
///
3034
/// This is used to pass data from crustls to callback functions provided
31-
/// by the user of the API. `len` indicates the number of bytes than can
32-
/// be safely read. A `len` of 0 is used to represent a missing value.
35+
/// by the user of the API. The `data` is an array of `rustls_slice_bytes`
36+
/// structures with `len` elements.
3337
///
34-
/// The memmory exposed is available for the duration of the call (e.g.
38+
/// The memory exposed is available for the duration of the call (e.g.
3539
/// when passed to a callback) and must be copied if the values are
3640
/// needed for longer.
3741
#[allow(non_camel_case_types)]
3842
#[repr(C)]
39-
pub struct rustls_bytes {
40-
data: *const c_uchar,
43+
pub struct rustls_vec_slice_bytes<'a> {
44+
data: *const rustls_slice_bytes<'a>,
4145
len: size_t,
4246
}
4347

44-
impl<'a> From<&'a [u8]> for rustls_bytes {
45-
fn from(s: &[u8]) -> Self {
46-
rustls_bytes {
47-
data: s.as_ptr() as *const c_uchar,
48-
len: s.len() as size_t,
48+
impl<'a> From<&'a [&[u8]]> for rustls_vec_slice_bytes<'a> {
49+
fn from(input: &'a [&[u8]]) -> Self {
50+
let mut output: Vec<rustls_slice_bytes> = vec![];
51+
for b in input {
52+
let b: &[u8] = b;
53+
output.push(b.into());
4954
}
50-
}
51-
}
52-
53-
pub(crate) fn rustls_bytes_vec_from_slices<'a>(
54-
values: Option<&'a [&'a [u8]]>,
55-
) -> Vec<rustls_bytes> {
56-
let mut strings: Vec<rustls_bytes> = Vec::new();
57-
match values {
58-
Some(values) => {
59-
for entry in values.iter() {
60-
strings.push(rustls_bytes::from(*entry))
61-
}
55+
rustls_vec_slice_bytes {
56+
data: output.as_ptr(),
57+
len: output.len(),
6258
}
63-
None => (),
64-
};
65-
strings
59+
}
6660
}
6761

68-
/// A read-only view on a list of Rust bytes.
62+
/// A read-only view on a Rust utf-8 string slice.
6963
/// This is used to pass data from crustls to callback functions provided
70-
/// by the user of the API. The `data` is an array of `rustls_bytes`
71-
/// structures with `len` elements.
64+
/// by the user of the API. The `data` is not NUL-terminated.
65+
/// `len` indicates the number of bytes than can be safely read.
66+
/// A `len` of 0 is used to represent a missing value OR an empty string.
7267
///
73-
/// The memmory exposed is available for the duration of the call (e.g.
68+
/// The memory exposed is available for the duration of the call (e.g.
7469
/// when passed to a callback) and must be copied if the values are
7570
/// needed for longer.
76-
///
7771
#[allow(non_camel_case_types)]
7872
#[repr(C)]
79-
pub struct rustls_vec_bytes {
80-
data: *const rustls_bytes,
73+
pub struct rustls_str<'a> {
74+
data: *const c_char,
8175
len: size_t,
76+
phantom: PhantomData<&'a str>,
8277
}
8378

84-
impl<'a> From<&'a Vec<rustls_bytes>> for rustls_vec_bytes {
85-
fn from(values: &Vec<rustls_bytes>) -> Self {
86-
rustls_vec_bytes {
87-
data: values.as_ptr(),
88-
len: values.len(),
79+
impl<'a> From<&'a str> for rustls_str<'a> {
80+
fn from(s: &str) -> Self {
81+
rustls_str {
82+
data: s.as_ptr() as *const c_char,
83+
len: s.len() as size_t,
84+
phantom: PhantomData,
85+
}
86+
}
87+
}
88+
89+
#[allow(non_camel_case_types)]
90+
#[repr(C)]
91+
pub struct rustls_vec_str<'a> {
92+
data: *const rustls_str<'a>,
93+
len: size_t,
94+
}
95+
96+
impl<'a> From<&'a [String]> for rustls_vec_str<'a> {
97+
fn from(input: &'a [String]) -> Self {
98+
let mut output: Vec<rustls_str> = vec![];
99+
for b in input {
100+
let b: &str = b;
101+
output.push(b.into());
102+
}
103+
rustls_vec_str {
104+
data: output.as_ptr(),
105+
len: output.len(),
89106
}
90107
}
91108
}
@@ -94,10 +111,9 @@ impl<'a> From<&'a Vec<rustls_bytes>> for rustls_vec_bytes {
94111
/// This is used to pass data from crustls to callback functions provided
95112
/// by the user of the API. The `data` is an array of `len` 16 bit values.
96113
///
97-
/// The memmory exposed is available for the duration of the call (e.g.
114+
/// The memory exposed is available for the duration of the call (e.g.
98115
/// when passed to a callback) and must be copied if the values are
99116
/// needed for longer.
100-
///
101117
#[allow(non_camel_case_types)]
102118
#[repr(C)]
103119
pub struct rustls_vec_ushort {

src/crustls.h

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -142,66 +142,67 @@ typedef struct rustls_server_session rustls_server_session;
142142
typedef void *rustls_client_hello_userdata;
143143

144144
/**
145-
* A read-only view on a Rust utf-8 string.
146-
* This is used to pass strings from crustls to callback functions provided
145+
* A read-only view on a Rust utf-8 string slice.
146+
* This is used to pass data from crustls to callback functions provided
147147
* by the user of the API. The `data` is not NUL-terminated.
148-
* `len` indicates the number of utf-8 bytes than can be safely read.
149-
* A `len` of 0 is used to represent a missing value.
148+
* `len` indicates the number of bytes than can be safely read.
149+
* A `len` of 0 is used to represent a missing value OR an empty string.
150150
*
151-
* The memmory exposed is available for the duration of the call (e.g.
151+
* The memory exposed is available for the duration of the call (e.g.
152152
* when passed to a callback) and must be copied if the values are
153153
* needed for longer.
154154
*/
155-
typedef struct rustls_string {
155+
typedef struct rustls_str {
156156
const char *data;
157157
size_t len;
158-
} rustls_string;
158+
} rustls_str;
159159

160160
/**
161161
* A read-only view on a list of Rust owned unsigned short values.
162162
* This is used to pass data from crustls to callback functions provided
163163
* by the user of the API. The `data` is an array of `len` 16 bit values.
164164
*
165-
* The memmory exposed is available for the duration of the call (e.g.
165+
* The memory exposed is available for the duration of the call (e.g.
166166
* when passed to a callback) and must be copied if the values are
167167
* needed for longer.
168-
*
169168
*/
170169
typedef struct rustls_vec_ushort {
171170
const unsigned short *data;
172171
size_t len;
173172
} rustls_vec_ushort;
174173

175174
/**
176-
* A read-only view on a Rust slice of bytes.
175+
* A read-only view on a Rust byte slice.
176+
*
177177
* This is used to pass data from crustls to callback functions provided
178-
* by the user of the API. `len` indicates the number of bytes than can
179-
* be safely read. A `len` of 0 is used to represent a missing value.
178+
* by the user of the API.
179+
* `len` indicates the number of bytes than can be safely read.
180+
* A `len` of 0 is used to represent a missing value OR an empty slice.
180181
*
181-
* The memmory exposed is available for the duration of the call (e.g.
182+
* The memory exposed is available for the duration of the call (e.g.
182183
* when passed to a callback) and must be copied if the values are
183184
* needed for longer.
184185
*/
185-
typedef struct rustls_bytes {
186-
const unsigned char *data;
186+
typedef struct rustls_slice_bytes {
187+
const uint8_t *data;
187188
size_t len;
188-
} rustls_bytes;
189+
} rustls_slice_bytes;
189190

190191
/**
191-
* A read-only view on a list of Rust bytes.
192+
* A read-only view on a vector of Rust byte slices.
193+
*
192194
* This is used to pass data from crustls to callback functions provided
193-
* by the user of the API. The `data` is an array of `rustls_bytes`
195+
* by the user of the API. The `data` is an array of `rustls_slice_bytes`
194196
* structures with `len` elements.
195197
*
196-
* The memmory exposed is available for the duration of the call (e.g.
198+
* The memory exposed is available for the duration of the call (e.g.
197199
* when passed to a callback) and must be copied if the values are
198200
* needed for longer.
199-
*
200201
*/
201-
typedef struct rustls_vec_bytes {
202-
const struct rustls_bytes *data;
202+
typedef struct rustls_vec_slice_bytes {
203+
const struct rustls_slice_bytes *data;
203204
size_t len;
204-
} rustls_vec_bytes;
205+
} rustls_vec_slice_bytes;
205206

206207
/**
207208
* The TLS Client Hello information provided to a ClientHelloCallback function.
@@ -222,9 +223,9 @@ typedef struct rustls_vec_bytes {
222223
* the rustls library is re-evaluating their current approach to client hello handling.
223224
*/
224225
typedef struct rustls_client_hello {
225-
struct rustls_string sni_name;
226+
struct rustls_str sni_name;
226227
struct rustls_vec_ushort signature_schemes;
227-
struct rustls_vec_bytes alpn;
228+
struct rustls_vec_slice_bytes alpn;
228229
} rustls_client_hello;
229230

230231
/**

src/server.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ use std::sync::Arc;
77

88
use rustls::{ClientHello, NoClientAuth, ServerConfig, ServerSession, Session};
99

10-
use crate::arc_with_incref_from_raw;
11-
use crate::base::{
12-
rustls_bytes, rustls_bytes_vec_from_slices, rustls_string, rustls_vec_bytes, rustls_vec_ushort,
13-
};
14-
use crate::cipher::{rustls_cipher_certified_key, rustls_cipher_map_signature_schemes};
10+
use crate::{arc_with_incref_from_raw, base::rustls_vec_slice_bytes, cipher::rustls_cipher_certified_key};
11+
use crate::base::{rustls_str, rustls_vec_ushort};
12+
use crate::cipher::rustls_cipher_map_signature_schemes;
1513
use crate::error::{map_error, rustls_result};
1614
use crate::{
1715
ffi_panic_boundary, ffi_panic_boundary_bool, ffi_panic_boundary_generic,
@@ -533,10 +531,10 @@ impl rustls::ResolvesServerCert for ResolvesServerCertFromChoices {
533531
/// the rustls library is re-evaluating their current approach to client hello handling.
534532
#[allow(non_camel_case_types)]
535533
#[repr(C)]
536-
pub struct rustls_client_hello {
537-
sni_name: rustls_string,
534+
pub struct rustls_client_hello<'a> {
535+
sni_name: rustls_str<'a>,
538536
signature_schemes: rustls_vec_ushort,
539-
alpn: rustls_vec_bytes,
537+
alpn: rustls_vec_slice_bytes<'a>,
540538
}
541539

542540
/// Any context information the callback will receive when invoked.
@@ -598,11 +596,13 @@ impl rustls::ResolvesServerCert for ClientHelloResolver {
598596
}
599597
};
600598
let mapped_sigs: Vec<u16> = rustls_cipher_map_signature_schemes(client_hello.sigschemes());
601-
let alpn: Vec<rustls_bytes> = rustls_bytes_vec_from_slices(client_hello.alpn());
599+
// Unwrap the Option. None becomes an empty slice.
600+
let alpn: &[&[u8]] = client_hello.alpn().unwrap_or(&[]);
601+
let alpn: rustls_vec_slice_bytes = alpn.into();
602602
let hello = rustls_client_hello {
603-
sni_name: rustls_string::from(sni_name),
603+
sni_name: rustls_str::from(sni_name),
604604
signature_schemes: rustls_vec_ushort::from(&mapped_sigs),
605-
alpn: rustls_vec_bytes::from(&alpn),
605+
alpn,
606606
};
607607
let cb = self.callback;
608608
let key_ptr = unsafe { cb(self.userdata, &hello) };

0 commit comments

Comments
 (0)