@@ -37,6 +37,10 @@ static u_char *ngx_http_lua_log_ssl_cert_error(ngx_log_t *log, u_char *buf,
3737static ngx_int_t ngx_http_lua_ssl_cert_by_chunk (lua_State * L ,
3838 ngx_http_request_t * r );
3939
40+ #ifndef OPENSSL_IS_BORINGSSL
41+ static int ngx_http_lua_is_grease_cipher (uint16_t cipher_id );
42+ #endif
43+
4044
4145ngx_int_t
4246ngx_http_lua_ssl_cert_handler_file (ngx_http_request_t * r ,
@@ -450,6 +454,18 @@ ngx_http_lua_log_ssl_cert_error(ngx_log_t *log, u_char *buf, size_t len)
450454}
451455
452456
457+ #ifndef OPENSSL_IS_BORINGSSL
458+ static int
459+ ngx_http_lua_is_grease_cipher (uint16_t cipher_id )
460+ {
461+ /* GREASE values follow pattern: 0x?A?A where ? can be any hex digit */
462+ /* and both ? must be the same */
463+ /* Check if both bytes follow ?A pattern and high nibbles match */
464+ return (cipher_id & 0x0F0F ) == 0x0A0A ;
465+ }
466+ #endif
467+
468+
453469static ngx_int_t
454470ngx_http_lua_ssl_cert_by_chunk (lua_State * L , ngx_http_request_t * r )
455471{
@@ -837,6 +853,70 @@ ngx_http_lua_ffi_ssl_raw_server_addr(ngx_http_request_t *r, char **addr,
837853}
838854
839855
856+ int
857+ ngx_http_lua_ffi_req_shared_ssl_ciphers (ngx_http_request_t * r ,
858+ uint16_t * ciphers , uint16_t * nciphers , int filter_grease , char * * err )
859+ {
860+ #ifdef OPENSSL_IS_BORINGSSL
861+
862+ * err = "BoringSSL is not supported for SSL cipher operations" ;
863+ return NGX_ERROR ;
864+
865+ #else
866+ ngx_ssl_conn_t * ssl_conn ;
867+ STACK_OF (SSL_CIPHER ) * sk , * ck ;
868+ int sn , cn , i , n ;
869+ uint16_t cipher ;
870+
871+ if (r == NULL || r -> connection == NULL || r -> connection -> ssl == NULL ) {
872+ * err = "bad request" ;
873+ return NGX_ERROR ;
874+ }
875+
876+ ssl_conn = r -> connection -> ssl -> connection ;
877+ if (ssl_conn == NULL ) {
878+ * err = "bad ssl conn" ;
879+ return NGX_ERROR ;
880+ }
881+
882+ sk = SSL_get1_supported_ciphers (ssl_conn );
883+ ck = SSL_get_client_ciphers (ssl_conn );
884+ sn = sk_SSL_CIPHER_num (sk );
885+ cn = sk_SSL_CIPHER_num (ck );
886+
887+ if (sn > * nciphers ) {
888+ * err = "buffer too small" ;
889+ * nciphers = 0 ;
890+ sk_SSL_CIPHER_free (sk );
891+ return NGX_ERROR ;
892+ }
893+
894+ for (* nciphers = 0 , i = 0 ; i < sn ; i ++ ) {
895+ cipher = SSL_CIPHER_get_protocol_id (sk_SSL_CIPHER_value (sk , i ));
896+
897+ /* Skip GREASE ciphers if filtering is enabled */
898+ if (filter_grease && ngx_http_lua_is_grease_cipher (cipher )) {
899+ continue ;
900+ }
901+
902+ for (n = 0 ; n < cn ; n ++ ) {
903+ if (SSL_CIPHER_get_protocol_id (sk_SSL_CIPHER_value (ck , n ))
904+ == cipher )
905+ {
906+ ciphers [(* nciphers )++ ] = cipher ;
907+ break ;
908+ }
909+ }
910+ }
911+
912+ sk_SSL_CIPHER_free (sk );
913+
914+ return NGX_OK ;
915+ #endif
916+
917+ }
918+
919+
840920int
841921ngx_http_lua_ffi_ssl_server_name (ngx_http_request_t * r , char * * name ,
842922 size_t * namelen , char * * err )
0 commit comments