@@ -37,8 +37,16 @@ use crate::conf::AcmeMainConfig;
3737use 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.
4452pub 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" ) ) ]
170178fn 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" ) ]
229261fn 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