Skip to content

Commit 8a299f9

Browse files
committed
Update for nginx PR 562.
1 parent 8d7d485 commit 8a299f9

File tree

3 files changed

+69
-6
lines changed

3 files changed

+69
-6
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
rust-version:
3838
- stable
3939
nginx-ref:
40-
- master
40+
- "pull/562/merge:client_hello_cb"
4141
- stable-1.28
4242
build:
4343
- debug

build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,18 @@ fn detect_nginx_features() {
5454
// Generate cfg values for version checks
5555

5656
println!("cargo::rustc-check-cfg=cfg(ngx_ssl_cache)");
57+
println!("cargo::rustc-check-cfg=cfg(ngx_ssl_client_hello_cb)");
5758
println!("cargo::rerun-if-env-changed=DEP_NGINX_VERSION_NUMBER");
5859
if let Ok(version) = env::var("DEP_NGINX_VERSION_NUMBER") {
5960
let version: u64 = version.parse().unwrap();
6061

6162
if version >= 1_027_002 {
6263
println!("cargo::rustc-cfg=ngx_ssl_cache");
6364
}
65+
66+
if version >= 1_029_002 {
67+
println!("cargo::rustc-cfg=ngx_ssl_client_hello_cb");
68+
}
6469
}
6570
}
6671

src/acme/solvers/tls_alpn.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ use crate::conf::AcmeMainConfig;
3737
use super::{ChallengeSolver, SolverError};
3838

3939
/// `openssl-sys` does not publish these constants.
40-
#[allow(non_upper_case_globals)]
41-
const TLSEXT_TYPE_application_layer_protocol_negotiation: c_uint = 16;
40+
#[allow(non_upper_case_globals, dead_code)]
41+
mod tlsext {
42+
use core::ffi::c_uint;
43+
44+
pub const TLSEXT_MAXLEN_host_name: usize = 255;
45+
pub const TLSEXT_NAMETYPE_host_name: u8 = 0;
46+
pub const TLSEXT_TYPE_server_name: c_uint = 0;
47+
pub const TLSEXT_TYPE_application_layer_protocol_negotiation: c_uint = 16;
48+
}
49+
use tlsext::*;
4250

4351
/// Registers tls-alpn-01 in the server merge configuration handler.
4452
pub fn merge_srv_conf(cf: &mut ngx_conf_t) -> Result<(), Status> {
@@ -166,7 +174,7 @@ impl<'a> Iterator for TlsAlpnIter<'a> {
166174
}
167175
}
168176

169-
#[cfg(openssl = "openssl")]
177+
#[cfg(any(openssl = "openssl", openssl = "awslc"))]
170178
fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
171179
use openssl_sys::{SSL_CLIENT_HELLO_ERROR, SSL_CLIENT_HELLO_SUCCESS};
172180

@@ -186,7 +194,7 @@ fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
186194

187195
extern "C" fn ssl_client_hello_cb(
188196
ssl: *mut SSL,
189-
_alert: *mut c_int,
197+
#[allow(unused)] alert: *mut c_int,
190198
_data: *mut c_void,
191199
) -> c_int {
192200
let ssl = unsafe { ssl.as_mut() }.expect("valid SSL ptr passed to callback");
@@ -213,6 +221,30 @@ fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
213221
return SSL_CLIENT_HELLO_ERROR;
214222
}
215223

224+
#[cfg(ngx_ssl_client_hello_cb)]
225+
match ssl_client_hello_get_ext(ssl, TLSEXT_TYPE_server_name)
226+
.as_ref()
227+
.map(ssl_parse_server_name_ext)
228+
{
229+
Some(Ok(x)) => {
230+
if unsafe {
231+
nginx_sys::ngx_http_ssl_servername(
232+
ptr::from_mut(ssl).cast(),
233+
alert,
234+
x.as_ptr().cast_mut().cast(),
235+
)
236+
} == openssl_sys::SSL_TLSEXT_ERR_ALERT_FATAL
237+
{
238+
return SSL_CLIENT_HELLO_ERROR;
239+
}
240+
}
241+
Some(Err(ad)) => {
242+
unsafe { *alert = ad };
243+
return SSL_CLIENT_HELLO_ERROR;
244+
}
245+
_ => (),
246+
};
247+
216248
SSL_CLIENT_HELLO_SUCCESS
217249
}
218250

@@ -225,7 +257,7 @@ fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
225257
};
226258
}
227259

228-
#[cfg(any(openssl = "awslc", openssl = "boringssl"))]
260+
#[cfg(openssl = "boringssl")]
229261
fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
230262
use openssl_sys::SSL_CLIENT_HELLO;
231263

@@ -287,6 +319,32 @@ fn acme_register_client_hello_cb(ssl_ctx: &mut SSL_CTX) {
287319
};
288320
}
289321

322+
#[cfg(all(ngx_ssl_client_hello_cb, not(openssl = "boringssl")))]
323+
fn ssl_parse_server_name_ext(p: &ngx_str_t) -> Result<&[u8], c_int> {
324+
use openssl_sys::{SSL_AD_DECODE_ERROR, SSL_AD_UNRECOGNIZED_NAME};
325+
326+
let ext = p.as_bytes();
327+
let (len, ext) = ext.split_first_chunk().ok_or(SSL_AD_DECODE_ERROR)?;
328+
329+
let len: usize = u16::from_be_bytes(*len).into();
330+
if len < 3 || len != ext.len() || ext[0] != TLSEXT_NAMETYPE_host_name {
331+
return Err(SSL_AD_DECODE_ERROR);
332+
}
333+
334+
let (len, ext) = ext[1..].split_first_chunk().ok_or(SSL_AD_DECODE_ERROR)?;
335+
336+
let len: usize = u16::from_be_bytes(*len).into();
337+
if len == 0 || len != ext.len() {
338+
return Err(SSL_AD_DECODE_ERROR);
339+
}
340+
341+
if len > TLSEXT_MAXLEN_host_name || ext.contains(&0) {
342+
return Err(SSL_AD_UNRECOGNIZED_NAME);
343+
}
344+
345+
Ok(ext)
346+
}
347+
290348
/// Get module configuration from a connection.
291349
///
292350
/// # Safety

0 commit comments

Comments
 (0)