@@ -7,10 +7,10 @@ use core::ffi::{c_char, c_void, CStr};
7
7
use core:: { mem, ptr} ;
8
8
9
9
use nginx_sys:: {
10
- ngx_command_t, ngx_conf_parse, ngx_conf_t, ngx_http_core_srv_conf_t , ngx_str_t , ngx_uint_t ,
11
- NGX_CONF_1MORE , NGX_CONF_BLOCK , NGX_CONF_FLAG , NGX_CONF_NOARGS , NGX_CONF_TAKE1 ,
12
- NGX_HTTP_MAIN_CONF , NGX_HTTP_MAIN_CONF_OFFSET , NGX_HTTP_SRV_CONF , NGX_HTTP_SRV_CONF_OFFSET ,
13
- NGX_LOG_EMERG ,
10
+ ngx_command_t, ngx_conf_parse, ngx_conf_t, ngx_decode_base64url , ngx_http_core_srv_conf_t ,
11
+ ngx_str_t , ngx_uint_t , NGX_CONF_1MORE , NGX_CONF_BLOCK , NGX_CONF_FLAG , NGX_CONF_NOARGS ,
12
+ NGX_CONF_TAKE1 , NGX_CONF_TAKE2 , NGX_HTTP_MAIN_CONF , NGX_HTTP_MAIN_CONF_OFFSET ,
13
+ NGX_HTTP_SRV_CONF , NGX_HTTP_SRV_CONF_OFFSET , NGX_LOG_EMERG ,
14
14
} ;
15
15
use ngx:: collections:: Vec ;
16
16
use ngx:: core:: { Pool , Status , NGX_CONF_ERROR , NGX_CONF_OK } ;
@@ -80,7 +80,7 @@ pub static mut NGX_HTTP_ACME_COMMANDS: [ngx_command_t; 4] = [
80
80
ngx_command_t:: empty ( ) ,
81
81
] ;
82
82
83
- static mut NGX_HTTP_ACME_ISSUER_COMMANDS : [ ngx_command_t ; 8 ] = [
83
+ static mut NGX_HTTP_ACME_ISSUER_COMMANDS : [ ngx_command_t ; 9 ] = [
84
84
ngx_command_t {
85
85
name : ngx_string ! ( "uri" ) ,
86
86
type_ : NGX_CONF_TAKE1 as ngx_uint_t ,
@@ -105,6 +105,14 @@ static mut NGX_HTTP_ACME_ISSUER_COMMANDS: [ngx_command_t; 8] = [
105
105
offset : 0 ,
106
106
post : ptr:: null_mut ( ) ,
107
107
} ,
108
+ ngx_command_t {
109
+ name : ngx_string ! ( "external_account_key" ) ,
110
+ type_ : NGX_CONF_TAKE2 as ngx_uint_t ,
111
+ set : Some ( cmd_issuer_set_external_account_key) ,
112
+ conf : 0 ,
113
+ offset : 0 ,
114
+ post : ptr:: null_mut ( ) ,
115
+ } ,
108
116
ngx_command_t {
109
117
name : ngx_string ! ( "ssl_trusted_certificate" ) ,
110
118
type_ : NGX_CONF_TAKE1 as ngx_uint_t ,
@@ -391,6 +399,62 @@ extern "C" fn cmd_issuer_set_account_key(
391
399
NGX_CONF_OK
392
400
}
393
401
402
+ extern "C" fn cmd_issuer_set_external_account_key (
403
+ cf : * mut ngx_conf_t ,
404
+ _cmd : * mut ngx_command_t ,
405
+ conf : * mut c_void ,
406
+ ) -> * mut c_char {
407
+ let cf = unsafe { cf. as_mut ( ) . expect ( "cf" ) } ;
408
+ let issuer = unsafe { conf. cast :: < Issuer > ( ) . as_mut ( ) . expect ( "issuer conf" ) } ;
409
+
410
+ if issuer. eab_key . is_some ( ) {
411
+ return NGX_CONF_DUPLICATE ;
412
+ }
413
+
414
+ let mut pool = cf. pool ( ) ;
415
+ // NGX_CONF_TAKE2 ensures that args contains 3 elements
416
+ let args = cf. args ( ) ;
417
+
418
+ if args[ 1 ] . is_empty ( ) || args[ 2 ] . is_empty ( ) {
419
+ return NGX_CONF_INVALID_VALUE ;
420
+ }
421
+
422
+ // SAFETY: the value is not empty, well aligned, and the conversion result is assigned to an
423
+ // object in the same pool.
424
+ let Ok ( kid) = ( unsafe { conf_value_to_str ( & args[ 1 ] ) } ) else {
425
+ return NGX_CONF_INVALID_VALUE ;
426
+ } ;
427
+
428
+ let mut encoded = if let Some ( arg) = args[ 2 ] . strip_prefix ( b"data:" ) {
429
+ arg
430
+ } else {
431
+ match crate :: util:: read_to_ngx_str ( cf, & args[ 2 ] ) {
432
+ Ok ( x) => x,
433
+ Err ( e) => return cf. error ( args[ 0 ] , & e) ,
434
+ }
435
+ } ;
436
+
437
+ crate :: util:: ngx_str_trim ( & mut encoded) ;
438
+
439
+ let len = encoded. len . div_ceil ( 4 ) * 3 ;
440
+ let mut key = ngx_str_t {
441
+ data : pool. alloc_unaligned ( len) . cast ( ) ,
442
+ len,
443
+ } ;
444
+
445
+ if key. data . is_null ( ) {
446
+ return NGX_CONF_ERROR ;
447
+ }
448
+
449
+ if !Status ( unsafe { ngx_decode_base64url ( & mut key, & mut encoded) } ) . is_ok ( ) {
450
+ return c"invalid base64url encoded value" . as_ptr ( ) . cast_mut ( ) ;
451
+ }
452
+
453
+ issuer. eab_key = Some ( issuer:: ExternalAccountKey { kid, key } ) ;
454
+
455
+ NGX_CONF_OK
456
+ }
457
+
394
458
extern "C" fn cmd_issuer_set_uri (
395
459
cf : * mut ngx_conf_t ,
396
460
_cmd : * mut ngx_command_t ,
0 commit comments