Skip to content

Commit 5a54a4d

Browse files
committed
add test case for TicketKeyCallbackResult::Noop
1 parent 2a43889 commit 5a54a4d

File tree

1 file changed

+111
-10
lines changed

1 file changed

+111
-10
lines changed

boring/src/ssl/test/session_resumption.rs

Lines changed: 111 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use std::ffi::c_void;
99
use std::sync::atomic::{AtomicU8, Ordering};
1010
use std::sync::OnceLock;
1111

12-
static CUSTOM_ENCRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
13-
static CUSTOM_DECRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
12+
static SUCCESS_ENCRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
13+
static SUCCESS_DECRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
14+
static NOOP_ENCRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
15+
static NOOP_DECRYPTION_CALLED_BACK: AtomicU8 = AtomicU8::new(0);
1416

1517
#[test]
1618
fn resume_session() {
@@ -59,7 +61,7 @@ fn custom_callback() {
5961
server.expected_connections_count(2);
6062
server
6163
.ctx()
62-
.set_ticket_key_callback(test_tickey_key_callback);
64+
.set_ticket_key_callback(test_success_tickey_key_callback);
6365
let server = server.build();
6466

6567
let mut client = server.client();
@@ -77,8 +79,8 @@ fn custom_callback() {
7779

7880
assert!(!ssl_stream.ssl().session_reused());
7981
assert!(SESSION_TICKET.get().is_some());
80-
assert_eq!(CUSTOM_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 2);
81-
assert_eq!(CUSTOM_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 0);
82+
assert_eq!(SUCCESS_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 2);
83+
assert_eq!(SUCCESS_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 0);
8284
assert_eq!(NST_RECIEVED_COUNT.load(Ordering::SeqCst), 2);
8385

8486
// Retrieve the session ticket
@@ -91,12 +93,111 @@ fn custom_callback() {
9193
let ssl_stream_2 = ssl_builder.connect();
9294

9395
assert!(ssl_stream_2.ssl().session_reused());
94-
assert_eq!(CUSTOM_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 4);
95-
assert_eq!(CUSTOM_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 1);
96+
assert_eq!(SUCCESS_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 4);
97+
assert_eq!(SUCCESS_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 1);
98+
}
99+
100+
#[test]
101+
fn custom_callback_unrecognized_decryption_ticket() {
102+
static SESSION_TICKET: OnceLock<Vec<u8>> = OnceLock::new();
103+
static NST_RECIEVED_COUNT: AtomicU8 = AtomicU8::new(0);
104+
105+
let mut server = Server::builder();
106+
server.expected_connections_count(2);
107+
server
108+
.ctx()
109+
.set_ticket_key_callback(test_noop_tickey_key_callback);
110+
let server = server.build();
111+
112+
let mut client = server.client();
113+
client
114+
.ctx()
115+
.set_session_cache_mode(SslSessionCacheMode::CLIENT);
116+
client.ctx().set_new_session_callback(|_, session| {
117+
NST_RECIEVED_COUNT.fetch_add(1, Ordering::SeqCst);
118+
// The server sends multiple session tickets but we only care to retrieve one.
119+
if SESSION_TICKET.get().is_none() {
120+
SESSION_TICKET.set(session.to_der().unwrap()).unwrap();
121+
}
122+
});
123+
let ssl_stream = client.connect();
124+
125+
assert!(!ssl_stream.ssl().session_reused());
126+
assert!(SESSION_TICKET.get().is_some());
127+
assert_eq!(SUCCESS_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 2);
128+
assert_eq!(NOOP_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 0);
129+
assert_eq!(NST_RECIEVED_COUNT.load(Ordering::SeqCst), 2);
130+
131+
// Retrieve the session ticket
132+
let session_ticket = SslSession::from_der(SESSION_TICKET.get().unwrap()).unwrap();
133+
134+
// Attempt to resume the connection using the session ticket
135+
let client_2 = server.client();
136+
let mut ssl_builder = client_2.build().builder();
137+
unsafe { ssl_builder.ssl().set_session(&session_ticket).unwrap() };
138+
let ssl_stream_2 = ssl_builder.connect();
139+
140+
// Second connection was NOT resumed due to TicketKeyCallbackResult::Noop on decryption
141+
assert!(!ssl_stream_2.ssl().session_reused());
142+
assert_eq!(SUCCESS_ENCRYPTION_CALLED_BACK.load(Ordering::SeqCst), 4);
143+
assert_eq!(NOOP_DECRYPTION_CALLED_BACK.load(Ordering::SeqCst), 1);
144+
}
145+
146+
// Successfully return a session ticket in encryption mode but return a
147+
// TicketKeyCallbackResult::Noop in decryption mode.
148+
fn test_noop_tickey_key_callback(
149+
_ssl: &SslRef,
150+
_key_name: &mut [u8; 16],
151+
_iv: *mut u8,
152+
evp_ctx: *mut ffi::EVP_CIPHER_CTX,
153+
hmac_ctx: *mut ffi::HMAC_CTX,
154+
encrypt: bool,
155+
) -> TicketKeyCallbackResult {
156+
// These should only be used for testing purposes.
157+
const TEST_CBC_IV: [u8; 16] = [1; 16];
158+
const TEST_AES_128_CBC_KEY: [u8; 16] = [2; 16];
159+
const TEST_HMAC_KEY: [u8; 32] = [3; 32];
160+
161+
let digest = MessageDigest::sha256();
162+
let cipher = Cipher::aes_128_cbc();
163+
164+
if encrypt {
165+
NOOP_ENCRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
166+
// Set the encryption context.
167+
let ret = unsafe {
168+
ffi::EVP_EncryptInit_ex(
169+
evp_ctx,
170+
cipher.as_ptr(),
171+
// ENGINE api is deprecated
172+
core::ptr::null_mut(),
173+
TEST_AES_128_CBC_KEY.as_ptr(),
174+
TEST_CBC_IV.as_ptr(),
175+
)
176+
};
177+
assert!(ret == 1);
178+
179+
// Set the hmac context.
180+
let ret = unsafe {
181+
ffi::HMAC_Init_ex(
182+
hmac_ctx,
183+
TEST_HMAC_KEY.as_ptr() as *const c_void,
184+
TEST_HMAC_KEY.len(),
185+
digest.as_ptr(),
186+
// ENGINE api is deprecated
187+
core::ptr::null_mut(),
188+
)
189+
};
190+
assert!(ret == 1);
191+
192+
TicketKeyCallbackResult::Success
193+
} else {
194+
NOOP_DECRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
195+
TicketKeyCallbackResult::Noop
196+
}
96197
}
97198

98199
// Custom callback to encrypt and decrypt session tickets
99-
fn test_tickey_key_callback(
200+
fn test_success_tickey_key_callback(
100201
_ssl: &SslRef,
101202
_key_name: &mut [u8; 16],
102203
_iv: *mut u8,
@@ -113,7 +214,7 @@ fn test_tickey_key_callback(
113214
let cipher = Cipher::aes_128_cbc();
114215

115216
if encrypt {
116-
CUSTOM_ENCRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
217+
SUCCESS_ENCRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
117218
// Set the encryption context.
118219
let ret = unsafe {
119220
ffi::EVP_EncryptInit_ex(
@@ -140,7 +241,7 @@ fn test_tickey_key_callback(
140241
};
141242
assert!(ret == 1);
142243
} else {
143-
CUSTOM_DECRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
244+
SUCCESS_DECRYPTION_CALLED_BACK.fetch_add(1, Ordering::SeqCst);
144245
let ret = unsafe {
145246
ffi::EVP_DecryptInit_ex(
146247
evp_ctx,

0 commit comments

Comments
 (0)