diff --git a/nginx-1.28.1-wolfssl-debug.patch b/nginx-1.28.1-wolfssl-debug.patch new file mode 100644 index 0000000..bf45e7d --- /dev/null +++ b/nginx-1.28.1-wolfssl-debug.patch @@ -0,0 +1,31 @@ +diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c +index 4d69557b6..1c1ea2c19 100644 +--- a/src/event/ngx_event_openssl.c ++++ b/src/event/ngx_event_openssl.c +@@ -134,6 +134,13 @@ int ngx_ssl_certificate_name_index; + + u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE]; + ++#ifdef WOLFSSL_NGINX ++void wolfSSL_Log(const int logLevel, const char *const logMessage) ++{ ++ (void)logLevel; ++ ngx_log_stderr(0, "wolfSSL: %s", logMessage); ++} ++#endif + + ngx_int_t + ngx_ssl_init(ngx_log_t *log) +@@ -208,6 +215,12 @@ ngx_ssl_init(ngx_log_t *log) + #endif + #endif + ++#ifdef WOLFSSL_NGINX ++ /* Turn on internal wolfssl debugging to stderr */ ++ wolfSSL_SetLoggingCb(wolfSSL_Log); ++ wolfSSL_Debugging_ON(); ++#endif ++ + #ifndef SSL_OP_NO_COMPRESSION + { + /* diff --git a/nginx-1.28.1-wolfssl.patch b/nginx-1.28.1-wolfssl.patch new file mode 100644 index 0000000..de3b361 --- /dev/null +++ b/nginx-1.28.1-wolfssl.patch @@ -0,0 +1,310 @@ +diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf +index fdf430dff..bf69d0e35 100644 +--- a/auto/lib/openssl/conf ++++ b/auto/lib/openssl/conf +@@ -66,8 +66,39 @@ else + ngx_feature_path= + ngx_feature_libs="-lssl -lcrypto $NGX_LIBDL $NGX_LIBPTHREAD" + ngx_feature_test="SSL_CTX_set_options(NULL, 0)" ++ ++ if [ $WOLFSSL != NONE ]; then ++ ngx_feature="wolfSSL library in $WOLFSSL" ++ ngx_feature_path="$WOLFSSL/include/wolfssl $WOLFSSL/include" ++ ngx_feature_incs=" ++ #ifndef WOLFSSL_USER_SETTINGS ++ #include ++ #endif ++ #include ++ #include " ++ ++ if [ $NGX_RPATH = YES ]; then ++ ngx_feature_libs="-R$WOLFSSL/lib -L$WOLFSSL/lib -lwolfssl $NGX_LIBDL" ++ else ++ ngx_feature_libs="-L$WOLFSSL/lib -lwolfssl $NGX_LIBDL" ++ fi ++ ++ CORE_INCS="$CORE_INCS $WOLFSSL/include/wolfssl" ++ CFLAGS="$CFLAGS -DWOLFSSL_NGINX" ++ fi ++ + . auto/feature + ++ if [ $WOLFSSL != NONE -a $ngx_found = no ]; then ++cat << END ++ ++$0: error: Could not find wolfSSL at $WOLFSSL/include/wolfssl. ++SSL modules require the wolfSSL library. ++ ++END ++ exit 1 ++ fi ++ + if [ $ngx_found = no ]; then + + # FreeBSD port +diff --git a/auto/options b/auto/options +index 6a6e990a0..766d7dc43 100644 +--- a/auto/options ++++ b/auto/options +@@ -155,6 +155,7 @@ PCRE2=YES + USE_OPENSSL=NO + USE_OPENSSL_QUIC=NO + OPENSSL=NONE ++WOLFSSL=NONE + + USE_ZLIB=NO + ZLIB=NONE +@@ -371,6 +372,7 @@ use the \"--with-mail_ssl_module\" option instead" + --with-pcre-jit) PCRE_JIT=YES ;; + --without-pcre2) PCRE2=DISABLED ;; + ++ --with-wolfssl=*) WOLFSSL="$value" ;; + --with-openssl=*) OPENSSL="$value" ;; + --with-openssl-opt=*) OPENSSL_OPT="$value" ;; + +@@ -601,6 +603,7 @@ cat << END + --with-libatomic force libatomic_ops library usage + --with-libatomic=DIR set path to libatomic_ops library sources + ++ --with-wolfssl=DIR set path to wolfSSL headers and library + --with-openssl=DIR set path to OpenSSL library sources + --with-openssl-opt=OPTIONS set additional build options for OpenSSL + +diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c +index defffa583..4d69557b6 100644 +--- a/src/event/ngx_event_openssl.c ++++ b/src/event/ngx_event_openssl.c +@@ -200,6 +200,14 @@ ngx_ssl_init(ngx_log_t *log) + + #endif + ++#ifdef WOLFSSL_NGINX ++ /* Run all casts on initialization with these FIPS versions to avoid ++ * threaded competition when running them ad hoc */ ++ #if FIPS_VERSION3_GE(5,2,1) && !FIPS_VERSION3_GE(6,0,0) ++ wc_RunAllCast_fips(); ++ #endif ++#endif ++ + #ifndef SSL_OP_NO_COMPRESSION + { + /* +@@ -375,6 +383,8 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) + } + #endif + ++#ifndef WOLFSSL_NGINX ++ /* These override the options set above. No need to call this. */ + #ifdef SSL_CTX_set_min_proto_version + SSL_CTX_set_min_proto_version(ssl->ctx, 0); + SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_2_VERSION); +@@ -384,6 +394,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) + SSL_CTX_set_min_proto_version(ssl->ctx, 0); + SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_3_VERSION); + #endif ++#endif + + #ifdef SSL_OP_NO_COMPRESSION + SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); +@@ -632,6 +643,12 @@ retry: + + x509 = sk_X509_shift(chain); + ++#ifdef WOLFSSL_NGINX ++ /* Remove current chain */ ++ if (sk_X509_NAME_num(chain) > 0) ++ wolfSSL_UnloadCertsKeys(c->ssl->connection); ++#endif ++ + if (SSL_use_certificate(c->ssl->connection, x509) == 0) { + ngx_ssl_error(NGX_LOG_ERR, c->log, 0, + "SSL_use_certificate(\"%s\") failed", cert->data); +@@ -643,7 +660,9 @@ retry: + X509_free(x509); + + #ifdef SSL_set0_chain +- ++#ifdef WOLFSSL_NGINX ++#error If SSL_set0_chain is defined then reset this function ++#endif + /* + * SSL_set0_chain() is only available in OpenSSL 1.0.2+, + * but this function is only called via certificate callback, +@@ -656,7 +675,19 @@ retry: + sk_X509_pop_free(chain, X509_free); + return NGX_ERROR; + } +- ++#endif ++#ifdef WOLFSSL_NGINX ++ { ++ int i; ++ for (i = sk_X509_num(chain) - 1; i > 0; i--) { ++ if (wolfSSL_add0_chain_cert(c->ssl->connection, ++ sk_X509_value(chain, i)) == 0) { ++ sk_X509_pop_free(chain, X509_free); ++ return NGX_ERROR; ++ } ++ } ++ sk_X509_pop_free(chain, X509_free); ++ } + #endif + + pkey = ngx_ssl_cache_connection_fetch(cache, pool, +@@ -3346,6 +3377,27 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, + int n; + ngx_uint_t level; + ++#ifdef WOLFSSL_NGINX ++ WOLFSSL_ALERT_HISTORY h; ++ ++ if (c && c->ssl && c->ssl->connection) { ++ wolfSSL_get_alert_history(c->ssl->connection, &h); ++ if (h.last_rx.level == alert_warning || h.last_rx.level == alert_fatal || ++ h.last_tx.level == alert_warning || h.last_tx.level == alert_fatal) { ++ const char *rx_code, *rx_lvl, *tx_code, *tx_lvl; ++ rx_lvl = ((h.last_rx.level == alert_fatal) ? "fatal" : ((h.last_rx.level == alert_warning) ? "warning" : "none")); ++ tx_lvl = ((h.last_tx.level == alert_fatal) ? "fatal" : ((h.last_tx.level == alert_warning) ? "warning" : "none")); ++ rx_code = wolfSSL_alert_desc_string_long(h.last_rx.code); ++ tx_code = wolfSSL_alert_desc_string_long(h.last_tx.code); ++ if (!rx_code) rx_code = "none"; ++ if (!tx_code) tx_code = "none"; ++ ngx_log_error(NGX_LOG_CRIT, c->log, 0, ++ "%s (RX alert: level=%s,code=%s, TX alert: level=%s,code=%s)", ++ text, rx_lvl, rx_code, tx_lvl, tx_code); ++ } ++ } ++#endif ++ + level = NGX_LOG_CRIT; + + if (sslerr == SSL_ERROR_SYSCALL) { +@@ -4560,7 +4612,8 @@ ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, + return -1; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L ++#if OPENSSL_VERSION_NUMBER >= 0x10000000L && \ ++ (!defined(WOLFSSL_NGINX) || !defined(HAVE_FIPS)) + if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; +@@ -4603,7 +4656,8 @@ ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, + size = 32; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L ++#if OPENSSL_VERSION_NUMBER >= 0x10000000L && \ ++ (!defined(WOLFSSL_NGINX) || !defined(HAVE_FIPS)) + if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; +@@ -5115,6 +5169,14 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) + + #endif + ++#ifdef WOLFSSL_NGINX ++ s->data = (u_char*)wolfSSL_get_curve_name(c->ssl->connection); ++ if (s->data != NULL) { ++ s->len = ngx_strlen(s->data); ++ return NGX_OK; ++ } ++#endif ++ + s->len = 0; + return NGX_OK; + } +diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h +index fe5107fb6..8276e0560 100644 +--- a/src/event/ngx_event_openssl.h ++++ b/src/event/ngx_event_openssl.h +@@ -14,6 +14,17 @@ + + #define OPENSSL_SUPPRESS_DEPRECATED + ++#ifdef WOLFSSL_NGINX ++#ifdef HAVE_CONFIG_H ++ #include ++#endif ++ ++#ifndef WOLFSSL_USER_SETTINGS ++ #include ++#endif ++#include ++#include ++#endif + #include + #include + #include +diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c +index 320d1ee04..03749d832 100644 +--- a/src/http/modules/ngx_http_ssl_module.c ++++ b/src/http/modules/ngx_http_ssl_module.c +@@ -18,7 +18,11 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, + ngx_pool_t *pool, ngx_str_t *s); + + ++#ifndef WOLFSSL_NGINX + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" ++#else ++#define NGX_DEFAULT_CIPHERS "ALL" ++#endif + #define NGX_DEFAULT_ECDH_CURVE "auto" + + #define NGX_HTTP_ALPN_PROTOS "\x08http/1.1\x08http/1.0\x08http/0.9" +diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c +index ceac8d307..3bd5a94dc 100644 +--- a/src/http/ngx_http_request.c ++++ b/src/http/ngx_http_request.c +@@ -935,7 +935,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) + sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module); + + #if (defined TLS1_3_VERSION \ +- && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL) ++ && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL) && \ ++ !defined WOLFSSL_NGINX + + /* + * SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+, +diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c +index 176e9c624..85407c8f3 100644 +--- a/src/mail/ngx_mail_ssl_module.c ++++ b/src/mail/ngx_mail_ssl_module.c +@@ -10,7 +10,11 @@ + #include + + ++#ifndef WOLFSSL_NGINX + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" ++#else ++#define NGX_DEFAULT_CIPHERS "ALL" ++#endif + #define NGX_DEFAULT_ECDH_CURVE "auto" + + +diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c +index ea0b112b8..39bee4416 100644 +--- a/src/stream/ngx_stream_ssl_module.c ++++ b/src/stream/ngx_stream_ssl_module.c +@@ -14,7 +14,11 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, + ngx_pool_t *pool, ngx_str_t *s); + + ++#ifndef WOLFSSL_NGINX + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" ++#else ++#define NGX_DEFAULT_CIPHERS "ALL" ++#endif + #define NGX_DEFAULT_ECDH_CURVE "auto" + + +@@ -592,7 +596,8 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) + sscf = ngx_stream_get_module_srv_conf(cscf->ctx, ngx_stream_ssl_module); + + #if (defined TLS1_3_VERSION \ +- && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL) ++ && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL) && \ ++ !defined WOLFSSL_NGINX + + /* + * SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+, diff --git a/nginx-tests-patches/2023-04-11-212d9d003886e3a24542855fb60355a417f037de.patch b/nginx-tests-patches/2023-04-11-212d9d003886e3a24542855fb60355a417f037de.patch index 177827d..44c379a 100644 --- a/nginx-tests-patches/2023-04-11-212d9d003886e3a24542855fb60355a417f037de.patch +++ b/nginx-tests-patches/2023-04-11-212d9d003886e3a24542855fb60355a417f037de.patch @@ -1,5 +1,5 @@ diff --git a/README b/README -index f43c586..bd259ca 100644 +index f43c5860..bd259ca8 100644 --- a/README +++ b/README @@ -52,4 +52,12 @@ TEST_NGINX_GLOBALS_STREAM @@ -16,7 +16,7 @@ index f43c586..bd259ca 100644 + Happy testing! diff --git a/lib/Test/Nginx.pm b/lib/Test/Nginx.pm -index a74fbf1..09855e5 100644 +index a74fbf15..09855e56 100644 --- a/lib/Test/Nginx.pm +++ b/lib/Test/Nginx.pm @@ -29,6 +29,8 @@ use POSIX qw/ waitpid WNOHANG /; @@ -109,8 +109,46 @@ index a74fbf1..09855e5 100644 return 1 if -e $file; return 0 if $exited; $exited = waitpid($pid, WNOHANG) != 0 if $pid; +diff --git a/ssl_certificate_chain.t b/ssl_certificate_chain.t +index ef087846..852fb0f6 100644 +--- a/ssl_certificate_chain.t ++++ b/ssl_certificate_chain.t +@@ -76,7 +76,12 @@ $t->write_file('openssl.conf', <write_file('ca.conf', <>$d/openssl.out 2>&1") == 0 + or die "Can't sign certificate for end: $!\n"; diff --git a/ssl_certificates.t b/ssl_certificates.t -index a6ec6ad..c9d1ef4 100644 +index a6ec6adc..c9d1ef49 100644 --- a/ssl_certificates.t +++ b/ssl_certificates.t @@ -47,23 +47,16 @@ events { @@ -153,7 +191,7 @@ index a6ec6ad..c9d1ef4 100644 ############################################################################### diff --git a/ssl_curve.t b/ssl_curve.t -index 3b6d27d..b3a32b3 100644 +index 3b6d27dc..b3a32b3a 100644 --- a/ssl_curve.t +++ b/ssl_curve.t @@ -82,7 +82,7 @@ $t->try_run('no $ssl_curve')->plan(1); @@ -165,8 +203,39 @@ index 3b6d27d..b3a32b3 100644 ############################################################################### +diff --git a/ssl_session_ticket_key.t b/ssl_session_ticket_key.t +index 860dd897..e48582b1 100644 +--- a/ssl_session_ticket_key.t ++++ b/ssl_session_ticket_key.t +@@ -109,13 +109,24 @@ sub get_ticket_key_name { + my $asn = Net::SSLeay::i2d_SSL_SESSION($ses); + my $any = qr/[\x00-\xff]/; + next: +- # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ # tag(10) | len{1} | OCTETSTRING(4) | len{1} | ticket(key_name|..) + $asn =~ /\xaa\x81($any)\x04\x81($any)($any{16})/g; +- return '' if !defined $3; ++ if (!defined $3) { ++ # Try 2-byte length pattern for long tickets ++ # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ goto next2; ++ } + goto next if unpack("C", $1) - unpack("C", $2) != 3; + my $key = unpack "H*", $3; + Test::Nginx::log_core('||', "ticket key: $key"); + return $key; ++next2: ++ $asn =~ /\xaa\x82($any)($any)\x04\x82($any)($any)($any{16})/g; ++ return '' if !defined $5; ++ goto next2 if ((unpack("C", $1) << 8) | unpack("C", $2)) - ((unpack("C", $3) << 8) | unpack("C", $4)) != 4; ++ my $key2 = unpack "H*", $5; ++ Test::Nginx::log_core('||', "ticket key: $key2"); ++ return $key2; + } + + sub get_ssl_session { diff --git a/ssl_stapling.t b/ssl_stapling.t -index 06efca1..71d4e7a 100644 +index 06efca1c..71d4e7af 100644 --- a/ssl_stapling.t +++ b/ssl_stapling.t @@ -53,18 +53,14 @@ http { @@ -367,7 +436,7 @@ index 06efca1..71d4e7a 100644 TODO: { local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' diff --git a/ssl_verify_depth.t b/ssl_verify_depth.t -index 4e010cc..b8d1a39 100644 +index 4e010cce..b8d1a399 100644 --- a/ssl_verify_depth.t +++ b/ssl_verify_depth.t @@ -47,7 +47,7 @@ http { diff --git a/nginx-tests-patches/2023-05-23-5b2894ea1afd01a26c589ce11f310df118e42592.patch b/nginx-tests-patches/2023-05-23-5b2894ea1afd01a26c589ce11f310df118e42592.patch index fadfec8..2a93d5d 100644 --- a/nginx-tests-patches/2023-05-23-5b2894ea1afd01a26c589ce11f310df118e42592.patch +++ b/nginx-tests-patches/2023-05-23-5b2894ea1afd01a26c589ce11f310df118e42592.patch @@ -1,8 +1,8 @@ diff --git a/README b/README -index f43c586..bd259ca 100644 +index f43c586..0441316 100644 --- a/README +++ b/README -@@ -52,4 +52,12 @@ TEST_NGINX_GLOBALS_STREAM +@@ -52,4 +52,16 @@ TEST_NGINX_GLOBALS_STREAM Sets additional directives in stream context. @@ -13,6 +13,10 @@ index f43c586..bd259ca 100644 +TEST_NGINX_VALGRIND + + Run Nginx under valgrind. ++ ++TEST_NGINX_RR ++ ++ Run Nginx under rr record for deterministic debugging. + Happy testing! diff --git a/grpc_ssl.t b/grpc_ssl.t @@ -29,7 +33,7 @@ index 8ae8a5d..84cc746 100644 ->write_file_expand('nginx.conf', <<'EOF')->plan(38); diff --git a/lib/Test/Nginx.pm b/lib/Test/Nginx.pm -index d2e0079..43d067a 100644 +index d2e0079..56a8949 100644 --- a/lib/Test/Nginx.pm +++ b/lib/Test/Nginx.pm @@ -29,6 +29,8 @@ use POSIX qw/ waitpid WNOHANG /; @@ -67,7 +71,7 @@ index d2e0079..43d067a 100644 } if (not $ENV{TEST_NGINX_LEAVE}) { eval { rmtree($self->{_testdir}); }; -@@ -383,13 +390,42 @@ sub run(;$) { +@@ -383,13 +390,46 @@ sub run(;$) { my $pid = fork(); die "Unable to fork(): $!\n" unless defined $pid; @@ -104,6 +108,10 @@ index d2e0079..43d067a 100644 + exec('gdbserver', ':2345', $NGINX, '-p', "$testdir/", '-c', 'nginx.conf', '-e', 'error.log', @globals), + or die "Unable to exec(): $!\n"; + } ++ elsif ($ENV{TEST_NGINX_RR}) { ++ exec('rr', 'record', $NGINX, '-p', "$testdir/", '-c', 'nginx.conf', '-e', 'error.log', @globals), ++ or die "Unable to exec(): $!\n"; ++ } + else { + exec($NGINX, '-p', "$testdir/", '-c', 'nginx.conf', + '-e', 'error.log', @globals) @@ -113,7 +121,7 @@ index d2e0079..43d067a 100644 } # wait for nginx to start -@@ -473,7 +509,7 @@ sub waitforfile($;$) { +@@ -473,7 +513,7 @@ sub waitforfile($;$) { # wait for file to appear # or specified process to exit @@ -135,6 +143,44 @@ index b07cea5..a4b2a65 100644 ->has_daemon('openssl'); $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_certificate_chain.t b/ssl_certificate_chain.t +index 0fce937..61c809b 100644 +--- a/ssl_certificate_chain.t ++++ b/ssl_certificate_chain.t +@@ -71,7 +71,12 @@ $t->write_file('openssl.conf', <write_file('ca.conf', <>$d/openssl.out 2>&1") == 0 + or die "Can't sign certificate for end: $!\n"; diff --git a/ssl_certificates.t b/ssl_certificates.t index 4697af9..198000d 100644 --- a/ssl_certificates.t @@ -204,6 +250,37 @@ index d75ca94..f60d6fc 100644 +like(http_get('/curve', SSL => 1), qr/^SECP256R1/m, 'ssl curve'); ############################################################################### +diff --git a/ssl_session_ticket_key.t b/ssl_session_ticket_key.t +index ac49db0..f3eeebb 100644 +--- a/ssl_session_ticket_key.t ++++ b/ssl_session_ticket_key.t +@@ -114,13 +114,25 @@ sub get_ticket_key_name { + my $asn = get_ssl_session(); + my $any = qr/[\x00-\xff]/; + next: +- # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ # tag(10) | len{2} | OCTETSTRING(4) | len{1} | ticket(key_name|..) + $asn =~ /\xaa\x81($any)\x04\x81($any)($any{16})/g; ++ if (!defined $3) { ++ # Try 2-byte length pattern for long tickets ++ # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ goto next2; ++ } + return '' if !defined $3; + goto next if unpack("C", $1) - unpack("C", $2) != 3; + my $key = unpack "H*", $3; + Test::Nginx::log_core('||', "ticket key: $key"); + return $key; ++next2: ++ $asn =~ /\xaa\x82($any)($any)\x04\x82($any)($any)($any{16})/g; ++ return '' if !defined $5; ++ goto next2 if ((unpack("C", $1) << 8) | unpack("C", $2)) - ((unpack("C", $3) << 8) | unpack("C", $4)) != 4; ++ my $key2 = unpack "H*", $5; ++ Test::Nginx::log_core('||', "ticket key: $key2"); ++ return $key2; + } + + sub get_ssl_session { diff --git a/ssl_stapling.t b/ssl_stapling.t index 575c167..c2af82d 100644 --- a/ssl_stapling.t diff --git a/nginx-tests-patches/2025-12-22-0fccfcef1278263416043e0bbb3e0116b84026e4.patch b/nginx-tests-patches/2025-12-22-0fccfcef1278263416043e0bbb3e0116b84026e4.patch new file mode 100644 index 0000000..6d8ed23 --- /dev/null +++ b/nginx-tests-patches/2025-12-22-0fccfcef1278263416043e0bbb3e0116b84026e4.patch @@ -0,0 +1,803 @@ +diff --git a/README b/README +index f43c586..3cc189b 100644 +--- a/README ++++ b/README +@@ -52,4 +52,20 @@ TEST_NGINX_GLOBALS_STREAM + + Sets additional directives in stream context. + ++TEST_NGINX_GDBSERVER ++ ++ Run Nginx under a gdbserver. ++ ++TEST_NGINX_VALGRIND ++ ++ Run Nginx under valgrind. ++ ++TEST_NGINX_RR ++ ++ Run Nginx under rr record for deterministic debugging. ++ ++ Usage example: ++ $ TEST_NGINX_RR=1 TEST_NGINX_LEAVE=1 prove access.t ++ $ rr replay ++ + Happy testing! +diff --git a/lib/Test/Nginx.pm b/lib/Test/Nginx.pm +index c747931..0cb3dbe 100644 +--- a/lib/Test/Nginx.pm ++++ b/lib/Test/Nginx.pm +@@ -29,6 +29,8 @@ use POSIX qw/ waitpid WNOHANG /; + use Socket qw/ CRLF /; + use Test::More qw//; + ++use Proc::Find qw(find_proc proc_exists); ++ + ############################################################################### + + our $NGINX = defined $ENV{TEST_NGINX_BINARY} ? $ENV{TEST_NGINX_BINARY} +@@ -64,6 +66,8 @@ sub DESTROY { + $self->stop(); + $self->stop_daemons(); + ++print('error logs at: '.$self->{_testdir}."\n"); ++ + if (Test::More->builder->expected_tests) { + local $Test::Nginx::TODO = 'alerts' unless $self->{_alerts}; + +@@ -394,13 +398,46 @@ sub run(;$) { + my $pid = fork(); + die "Unable to fork(): $!\n" unless defined $pid; + ++ if ($ENV{TEST_NGINX_GDBSERVER}) { ++ for (1 .. 300) { ++ last unless proc_exists(name=>'gdbserver'); ++ select undef, undef, undef, 0.1; ++ } ++ } ++ ++ + if ($pid == 0) { + my @globals = $self->{_test_globals} ? + () : ('-g', "pid $testdir/nginx.pid; " + . "error_log $testdir/error.log debug;"); +- exec($NGINX, '-p', "$testdir/", '-c', 'nginx.conf', +- '-e', 'error.log', @globals) +- or die "Unable to exec(): $!\n"; ++ if ($ENV{TEST_NGINX_CATLOG}) { ++ print { *STDERR } "\n"; ++ print { *STDERR } $NGINX . ' '; ++ print { *STDERR } '-p' . ' '; ++ print { *STDERR } $testdir . ' '; ++ print { *STDERR } '-c' . ' '; ++ print { *STDERR } 'nginx.conf' . ' '; ++ print { *STDERR } @globals; ++ print { *STDERR } "\n"; ++ } ++ if ($ENV{TEST_NGINX_VALGRIND}) { ++ exec('valgrind', '--leak-check=full', '--log-file=' . "$testdir/valgrind.log", $NGINX, '-p', "$testdir/", '-c', 'nginx.conf', '-e', '-error.log', @globals), ++ or die "Unable to exec(): $!\n"; ++ } ++ elsif ($ENV{TEST_NGINX_GDBSERVER}) { ++ exec('gdbserver', ':2345', $NGINX, '-p', "$testdir/", '-c', 'nginx.conf', '-e', 'error.log', @globals), ++ or die "Unable to exec(): $!\n"; ++ } ++ elsif ($ENV{TEST_NGINX_RR}) { ++ exec('rr', 'record', $NGINX, '-p', "$testdir/", '-c', 'nginx.conf', '-e', 'error.log', @globals), ++ or die "Unable to exec(): $!\n"; ++ } ++ else { ++ exec($NGINX, '-p', "$testdir/", '-c', 'nginx.conf', ++ '-e', 'error.log', @globals) ++ or die "Unable to exec(): $!\n"; ++ } ++ + } + + # wait for nginx to start +@@ -484,7 +521,7 @@ sub waitforfile($;$) { + # wait for file to appear + # or specified process to exit + +- for (1 .. 50) { ++ for (1 .. 300) { + return 1 if -e $file; + return 0 if $exited; + $exited = waitpid($pid, WNOHANG) != 0 if $pid; +diff --git a/mail_ssl_conf_command.t b/mail_ssl_conf_command.t +index b968878..a8414f7 100644 +--- a/mail_ssl_conf_command.t ++++ b/mail_ssl_conf_command.t +@@ -26,7 +26,7 @@ select STDOUT; $| = 1; + local $SIG{PIPE} = 'IGNORE'; + + my $t = Test::Nginx->new() +- ->has(qw/mail mail_ssl imap openssl:1.0.2 socket_ssl_reused/) ++ ->has(qw/mail mail_ssl imap socket_ssl_reused/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/proxy_ssl_certificate_cache.t b/proxy_ssl_certificate_cache.t +index c737c5e..614143f 100644 +--- a/proxy_ssl_certificate_cache.t ++++ b/proxy_ssl_certificate_cache.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl proxy openssl:1.0.2/) ++ ->has(qw/http http_ssl proxy/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +@@ -194,6 +194,10 @@ like(http_get('/enc/?cert=e'), qr/CN=e.example.com/, 'encrypted'); + + like(http_get('/?cert=e'), qr/500 Internal/, 'encrypted no password'); + ++SKIP: { ++skip 'wolfSSL cannot switch from encrypted to non-encrypted cert', 2 ++ if $t->has_module('wolfSSL'); ++ + update($t, 'e.example.com', 'dummy'); + like(http_get('/enc/?cert=e'), qr/CN=dummy/, 'encrypted not cached'); + +@@ -202,6 +206,8 @@ like(http_get('/enc/?cert=e'), qr/CN=dummy/, 'encrypted not cached'); + update($t, 'e.example.com', 'eb.example.com'); + like(http_get('/enc/?cert=e'), qr/CN=dummy/, 'cached after encrypted'); + ++} ++ + like(http_get('/nocache/?cert=4'), qr/CN=4.example.com/, 'no cache'); + + update($t, '4.example.com', 'dummy'); +@@ -216,12 +222,18 @@ like(http_get('/?cert=3'), qr/500 Internal/, 'certificate 3 expired'); + + # replacing cacheable item with non-cacheable doesn't affect cacheability + ++SKIP: { ++skip 'wolfSSL cannot switch from encrypted to non-encrypted cert', 2 ++ if $t->has_module('wolfSSL'); ++ + like(http_get('/enc/?cert=e'), qr/CN=e.example.com/, 'encrypted after cached'); + + update($t, 'e.example.com', 'dummy'); + like(http_get('/enc/?cert=e'), qr/CN=dummy/, + 'encrypted not cached after cached'); + ++} ++ + # eviction after inactive time + + update($t, '5.example.com', 'dummy'); +diff --git a/proxy_ssl_conf_command.t b/proxy_ssl_conf_command.t +index 13683c4..6c0ae4f 100644 +--- a/proxy_ssl_conf_command.t ++++ b/proxy_ssl_conf_command.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl proxy uwsgi http_v2 grpc openssl:1.0.2/) ++ ->has(qw/http http_ssl proxy uwsgi http_v2 grpc/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_certificate.t b/ssl_certificate.t +index 79572bc..43e1265 100644 +--- a/ssl_certificate.t ++++ b/ssl_certificate.t +@@ -25,7 +25,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl geo openssl:1.0.2 socket_ssl_sni/) ++ ->has(qw/http http_ssl geo socket_ssl_sni/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_certificate_cache.t b/ssl_certificate_cache.t +index e70225b..96075f9 100644 +--- a/ssl_certificate_cache.t ++++ b/ssl_certificate_cache.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl openssl:1.0.2 socket_ssl_sni/) ++ ->has(qw/http http_ssl socket_ssl_sni/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_certificates.t b/ssl_certificates.t +index cf4cc35..d363f83 100644 +--- a/ssl_certificates.t ++++ b/ssl_certificates.t +@@ -39,23 +39,16 @@ events { + http { + %%TEST_GLOBALS_HTTP%% + +- ssl_certificate_key rsa.key; +- ssl_certificate rsa.crt; + ssl_ciphers DEFAULT:ECCdraft; + + server { + listen 127.0.0.1:8443 ssl; + server_name localhost; + +- ssl_certificate_key ec.key; +- ssl_certificate ec.crt; +- +- ssl_certificate_key rsa.key; +- ssl_certificate rsa.crt; +- + ssl_certificate_key rsa.key; + ssl_certificate rsa.crt; + } ++ #### wolfSSL does not support using multiple certs on one object currently + } + + EOF +@@ -83,12 +76,12 @@ foreach my $name ('ec', 'rsa') { + or die "Can't create certificate for $name: $!\n"; + } + +-$t->run()->plan(2); ++$t->run()->plan(1); + + ############################################################################### + + like(cert('RSA'), qr/CN=rsa/, 'ssl cert RSA'); +-like(cert('ECDSA'), qr/CN=ec/, 'ssl cert ECDSA'); ++# wolfSSL doesn't support multiple certificates on one SSL_CTX + + ############################################################################### + +diff --git a/ssl_conf_command.t b/ssl_conf_command.t +index 5e56d76..58ebf09 100644 +--- a/ssl_conf_command.t ++++ b/ssl_conf_command.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl openssl:1.0.2 socket_ssl_reused/) ++ ->has(qw/http http_ssl socket_ssl_reused/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_session_ticket_key.t b/ssl_session_ticket_key.t +index 6559d9c..46a3fb8 100644 +--- a/ssl_session_ticket_key.t ++++ b/ssl_session_ticket_key.t +@@ -112,13 +112,24 @@ sub get_ticket_key_name { + my $asn = get_ssl_session(); + my $any = qr/[\x00-\xff]/; + next: +- # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ # tag(10) | len{1} | OCTETSTRING(4) | len{1} | ticket(key_name|..) + $asn =~ /\xaa\x81($any)\x04\x81($any)($any{16})/g; +- return '' if !defined $3; ++ if (!defined $3) { ++ # Try 2-byte length pattern for long tickets ++ # tag(10) | len{2} | OCTETSTRING(4) | len{2} | ticket(key_name|..) ++ goto next2; ++ } + goto next if unpack("C", $1) - unpack("C", $2) != 3; + my $key = unpack "H*", $3; + Test::Nginx::log_core('||', "ticket key: $key"); + return $key; ++next2: ++ $asn =~ /\xaa\x82($any)($any)\x04\x82($any)($any)($any{16})/g; ++ return '' if !defined $5; ++ goto next2 if ((unpack("C", $1) << 8) | unpack("C", $2)) - ((unpack("C", $3) << 8) | unpack("C", $4)) != 4; ++ my $key2 = unpack "H*", $5; ++ Test::Nginx::log_core('||', "ticket key: $key2"); ++ return $key2; + } + + sub get_ssl_session { +diff --git a/ssl_sigalg.t b/ssl_sigalg.t +index 9669689..5994026 100644 +--- a/ssl_sigalg.t ++++ b/ssl_sigalg.t +@@ -22,7 +22,7 @@ use Test::Nginx; + select STDERR; $| = 1; + select STDOUT; $| = 1; + +-my $t = Test::Nginx->new()->has(qw/http http_ssl openssl:3.5 socket_ssl/) ++my $t = Test::Nginx->new()->has(qw/http http_ssl socket_ssl/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/ssl_sni_protocols.t b/ssl_sni_protocols.t +index 57a20f8..bc319d5 100644 +--- a/ssl_sni_protocols.t ++++ b/ssl_sni_protocols.t +@@ -22,7 +22,7 @@ use Test::Nginx; + select STDERR; $| = 1; + select STDOUT; $| = 1; + +-my $t = Test::Nginx->new()->has(qw/http http_ssl openssl:1.1.1 socket_ssl_sni/); ++my $t = Test::Nginx->new()->has(qw/http http_ssl socket_ssl_sni/); + + eval { defined &Net::SSLeay::CTX_set_ciphersuites or die; }; + plan(skip_all => 'Net::SSLeay too old') if $@; +diff --git a/ssl_stapling.t b/ssl_stapling.t +index 1b225ed..3c44cb8 100644 +--- a/ssl_stapling.t ++++ b/ssl_stapling.t +@@ -49,12 +49,6 @@ http { + ssl_stapling on; + ssl_trusted_certificate trusted.crt; + +- ssl_certificate ec-end-int.crt; +- ssl_certificate_key ec-end.key; +- +- ssl_certificate end-int.crt; +- ssl_certificate_key end.key; +- + ssl_ciphers DEFAULT:ECCdraft; + + add_header X-SSL-Protocol $ssl_protocol always; +@@ -63,6 +57,8 @@ http { + listen 127.0.0.1:8443 ssl; + listen 127.0.0.1:8080; + server_name localhost; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + } + + server { +@@ -70,6 +66,8 @@ http { + server_name localhost; + + ssl_stapling_responder http://127.0.0.1:8081/; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + } + + server { +@@ -77,32 +75,33 @@ http { + server_name localhost; + + ssl_stapling_verify on; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + } + + server { + listen 127.0.0.1:8446 ssl; + server_name localhost; + +- ssl_certificate ec-end.crt; +- ssl_certificate_key ec-end.key; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + } + + server { + listen 127.0.0.1:8447 ssl; + server_name localhost; + +- ssl_certificate end-int.crt; +- ssl_certificate_key end.key; +- + ssl_stapling_file %%TESTDIR%%/resp.der; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + } + + server { + listen 127.0.0.1:8448 ssl; + server_name localhost; + +- ssl_certificate ec-end-int.crt; +- ssl_certificate_key ec-end.key; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; + + ssl_stapling_file %%TESTDIR%%/ec-resp.der; + } +@@ -112,7 +111,73 @@ http { + server_name localhost; + + ssl_stapling_responder http://127.0.0.1:8080/; ++ ssl_certificate end-int.crt; ++ ssl_certificate_key end.key; ++ } ++ ++#### ECC servers ++ ++ server { ++ listen 127.0.0.1:8453 ssl; ++ server_name localhost; ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; + } ++ ++ server { ++ listen 127.0.0.1:8454 ssl; ++ server_name localhost; ++ ++ ssl_stapling_responder http://127.0.0.1:8081/; ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ ++ server { ++ listen 127.0.0.1:8455 ssl; ++ server_name localhost; ++ ++ ssl_stapling_verify on; ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ ++ server { ++ listen 127.0.0.1:8456 ssl; ++ server_name localhost; ++ ++ ssl_certificate ec-end.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ ++ server { ++ listen 127.0.0.1:8457 ssl; ++ server_name localhost; ++ ++ ssl_stapling_file %%TESTDIR%%/resp.der; ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ ++ server { ++ listen 127.0.0.1:8458 ssl; ++ server_name localhost; ++ ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ ++ ssl_stapling_file %%TESTDIR%%/ec-resp.der; ++ } ++ ++ server { ++ listen 127.0.0.1:8459 ssl; ++ server_name localhost; ++ ++ ssl_stapling_responder http://127.0.0.1:8080/; ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ + } + + EOF +@@ -248,12 +313,12 @@ $t->waitforsocket("127.0.0.1:" . port(8081)); + ############################################################################### + + staple(8443, 'RSA'); +-staple(8443, 'ECDSA'); ++staple(8453, 'ECDSA'); + staple(8444, 'RSA'); +-staple(8444, 'ECDSA'); +-staple(8445, 'ECDSA'); +-staple(8446, 'ECDSA'); +-staple(8449, 'ECDSA'); ++staple(8454, 'ECDSA'); ++staple(8455, 'ECDSA'); ++staple(8456, 'ECDSA'); ++staple(8459, 'ECDSA'); + + sleep 1; + +@@ -263,8 +328,7 @@ TODO: { + local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' + if $t->has_module('LibreSSL') && test_tls13(); + +-ok(staple(8443, 'ECDSA'), 'staple success'); +- ++ok(staple(8453, 'ECDSA'), 'staple success'); + } + + ok(!staple(8444, 'RSA'), 'responder revoked'); +@@ -273,18 +337,18 @@ TODO: { + local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' + if $t->has_module('LibreSSL') && test_tls13(); + +-ok(staple(8444, 'ECDSA'), 'responder success'); ++ok(staple(8454, 'ECDSA'), 'responder success'); + + } + +-ok(!staple(8445, 'ECDSA'), 'verify - root not trusted'); ++ok(!staple(8455, 'ECDSA'), 'verify - root not trusted'); + +-ok(staple(8446, 'ECDSA', "$d/int.crt"), 'cert store'); ++ok(staple(8456, 'ECDSA', "$d/int.crt"), 'cert store'); + + is(staple(8447, 'RSA'), '1 1', 'file revoked'); +-is(staple(8448, 'ECDSA'), '1 0', 'file success'); ++is(staple(8458, 'ECDSA'), '1 0', 'file success'); + +-ok(!staple(8449, 'ECDSA'), 'ocsp error'); ++ok(!staple(8459, 'ECDSA'), 'ocsp error'); + + TODO: { + local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' +diff --git a/ssl_store_keys.t b/ssl_store_keys.t +index ec45782..6460569 100644 +--- a/ssl_store_keys.t ++++ b/ssl_store_keys.t +@@ -25,7 +25,7 @@ select STDOUT; $| = 1; + plan(skip_all => 'win32') if $^O eq 'MSWin32'; + + my $t = Test::Nginx->new() +- ->has(qw/http http_ssl geo openssl:1.1.1 socket_ssl_sni/) ++ ->has(qw/http http_ssl geo socket_ssl_sni/) + ->has_daemon('openssl'); + + plan(skip_all => 'BoringSSL') if $t->has_module('BoringSSL|AWS-LC'); +diff --git a/ssl_verify_depth.t b/ssl_verify_depth.t +index 89c6668..107d454 100644 +--- a/ssl_verify_depth.t ++++ b/ssl_verify_depth.t +@@ -43,7 +43,7 @@ http { + ssl_certificate_key localhost.key; + + ssl_verify_client on; +- ssl_client_certificate root-int.crt; ++ ssl_client_certificate root.crt; + + add_header X-Client $ssl_client_s_dn always; + add_header X-Verify $ssl_client_verify always; +@@ -100,6 +100,7 @@ commonName = supplied + + [ myca_extensions ] + basicConstraints = critical,CA:TRUE ++keyUsage = keyCertSign + EOF + + foreach my $name ('root', 'localhost') { +@@ -135,6 +136,9 @@ system("openssl ca -batch -config $d/ca.conf " + + $t->write_file('root-int.crt', $t->read_file('root.crt') + . $t->read_file('int.crt')); ++$t->write_file('end-int.crt', $t->read_file('end.crt') ++ . $t->read_file('int.crt')); ++$t->write_file('end-int.key', $t->read_file('end.key')); + + $t->write_file('t', ''); + $t->run(); +@@ -150,7 +154,7 @@ $t->run(); + + like(get(8080, 'root'), qr/SUCCESS/, 'verify depth 0 - root'); + like(get(8080, 'int'), qr/FAI|SUC/, 'verify depth 0 - no int'); +-like(get(8080, 'end'), qr/FAILED/, 'verify depth 0 - no end'); ++like(get(8080, 'end-int'), qr/FAILED/, 'verify depth 0 - no end'); + + # with verify depth 1 (the default), one signature is + # expected to be checked, so certificates directly signed +@@ -162,14 +166,14 @@ like(get(8080, 'end'), qr/FAILED/, 'verify depth 0 - no end'); + + like(get(8081, 'root'), qr/SUCCESS/, 'verify depth 1 - root'); + like(get(8081, 'int'), qr/SUCCESS/, 'verify depth 1 - int'); +-like(get(8081, 'end'), qr/FAI|SUC/, 'verify depth 1 - no end'); ++like(get(8081, 'end-int'), qr/FAI|SUC/, 'verify depth 1 - no end'); + + # with verify depth 2 it is also possible to validate up to two signatures, + # so chains with one intermediate certificate are allowed + + like(get(8082, 'root'), qr/SUCCESS/, 'verify depth 2 - root'); + like(get(8082, 'int'), qr/SUCCESS/, 'verify depth 2 - int'); +-like(get(8082, 'end'), qr/SUCCESS/, 'verify depth 2 - end'); ++like(get(8082, 'end-int'), qr/SUCCESS/, 'verify depth 2 - end'); + + ############################################################################### + +diff --git a/stream_proxy_ssl_certificate_cache.t b/stream_proxy_ssl_certificate_cache.t +index c8b80ac..68aca28 100644 +--- a/stream_proxy_ssl_certificate_cache.t ++++ b/stream_proxy_ssl_certificate_cache.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl http http_ssl openssl:1.0.2 socket_ssl_sni/) ++ ->has(qw/stream stream_ssl http http_ssl socket_ssl_sni/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +@@ -212,6 +212,10 @@ like(get('e.example.com'), qr/CN=e.example.com/, 'encrypted'); + + ok(!get('e.example.com', 8444), 'encrypted no password'); + ++SKIP: { ++skip 'wolfSSL cannot transition from encrypted to non-encrypted key', 2 ++ if $t->has_module('wolfSSL'); ++ + update($t, 'e.example.com', 'dummy'); + like(get('e.example.com'), qr/CN=dummy/, 'encrypted not cached'); + +@@ -220,6 +224,8 @@ like(get('e.example.com'), qr/CN=dummy/, 'encrypted not cached'); + update($t, 'e.example.com', 'eb.example.com'); + like(get('e.example.com'), qr/CN=dummy/, 'cached after encrypted'); + ++} ++ + like(get('4.example.com'), qr/CN=4.example.com/, 'no cache'); + + update($t, '4.example.com', 'dummy'); +@@ -236,10 +242,16 @@ ok(!get('3.example.com'), 'certificate 3 expired'); + + like(get('e.example.com'), qr/CN=e.example.com/, 'encrypted after cached'); + ++SKIP: { ++skip 'wolfSSL cannot transition from encrypted to non-encrypted key', 1 ++ if $t->has_module('wolfSSL'); ++ + update($t, 'e.example.com', 'dummy'); + like(get('e.example.com'), qr/CN=dummy/, + 'encrypted not cached after cached'); + ++} ++ + # eviction after inactive time + + update($t, '5.example.com', 'dummy'); +diff --git a/stream_proxy_ssl_conf_command.t b/stream_proxy_ssl_conf_command.t +index a59cdb7..9047126 100644 +--- a/stream_proxy_ssl_conf_command.t ++++ b/stream_proxy_ssl_conf_command.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl http http_ssl openssl:1.0.2/) ++ ->has(qw/stream stream_ssl http http_ssl/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/stream_ssl_certificate.t b/stream_ssl_certificate.t +index caa521e..b620cf9 100644 +--- a/stream_ssl_certificate.t ++++ b/stream_ssl_certificate.t +@@ -24,7 +24,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl stream_geo stream_return openssl:1.0.2/) ++ ->has(qw/stream stream_ssl stream_geo stream_return/) + ->has(qw/socket_ssl_sni/) + ->has_daemon('openssl') + ->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/stream_ssl_certificate_cache.t b/stream_ssl_certificate_cache.t +index 5b46bf3..a358870 100644 +--- a/stream_ssl_certificate_cache.t ++++ b/stream_ssl_certificate_cache.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl openssl:1.0.2 socket_ssl_sni/) ++ ->has(qw/stream stream_ssl socket_ssl_sni/) + ->has_daemon('openssl'); + + $t->write_file_expand('nginx.conf', <<'EOF'); +diff --git a/stream_ssl_conf_command.t b/stream_ssl_conf_command.t +index 313bba5..626160a 100644 +--- a/stream_ssl_conf_command.t ++++ b/stream_ssl_conf_command.t +@@ -24,7 +24,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl stream_return openssl:1.0.2/) ++ ->has(qw/stream stream_ssl stream_return/) + ->has(qw/socket_ssl_reused/) + ->has_daemon('openssl'); + +diff --git a/stream_ssl_sni_protocols.t b/stream_ssl_sni_protocols.t +index 3efd97d..1a3cb27 100644 +--- a/stream_ssl_sni_protocols.t ++++ b/stream_ssl_sni_protocols.t +@@ -23,7 +23,7 @@ select STDERR; $| = 1; + select STDOUT; $| = 1; + + my $t = Test::Nginx->new() +- ->has(qw/stream stream_ssl stream_return openssl:1.1.1 socket_ssl_sni/); ++ ->has(qw/stream stream_ssl stream_return socket_ssl_sni/); + + eval { defined &Net::SSLeay::CTX_set_ciphersuites or die; }; + plan(skip_all => 'Net::SSLeay too old') if $@; +diff --git a/stream_ssl_stapling.t b/stream_ssl_stapling.t +index 2000ce0..a29e444 100644 +--- a/stream_ssl_stapling.t ++++ b/stream_ssl_stapling.t +@@ -50,9 +50,6 @@ stream { + ssl_stapling on; + ssl_trusted_certificate trusted.crt; + +- ssl_certificate ec-end-int.crt; +- ssl_certificate_key ec-end.key; +- + ssl_certificate end-int.crt; + ssl_certificate_key end.key; + +@@ -65,6 +62,14 @@ stream { + } + + server { ++ listen 127.0.0.1:8543 ssl; ++ server_name localhost; ++ ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ } ++ ++ server { + listen 127.0.0.1:8444 ssl; + server_name localhost; + +@@ -72,9 +77,22 @@ stream { + } + + server { ++ listen 127.0.0.1:8544 ssl; ++ server_name localhost; ++ ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ ++ ssl_stapling_responder http://127.0.0.1:8081/; ++ } ++ ++ server { + listen 127.0.0.1:8445 ssl; + server_name localhost; + ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ + ssl_stapling_verify on; + } + +@@ -110,6 +128,9 @@ stream { + listen 127.0.0.1:8449 ssl; + server_name localhost; + ++ ssl_certificate ec-end-int.crt; ++ ssl_certificate_key ec-end.key; ++ + ssl_stapling_responder http://127.0.0.1:8080/; + } + } +@@ -247,9 +268,9 @@ $t->waitforsocket("127.0.0.1:" . port(8081)); + ############################################################################### + + staple(8443, 'RSA'); +-staple(8443, 'ECDSA'); ++staple(8543, 'ECDSA'); + staple(8444, 'RSA'); +-staple(8444, 'ECDSA'); ++staple(8544, 'ECDSA'); + staple(8445, 'ECDSA'); + staple(8446, 'ECDSA'); + staple(8449, 'ECDSA'); +@@ -262,7 +283,7 @@ TODO: { + local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' + if $t->has_module('LibreSSL') && test_tls13(); + +-ok(staple(8443, 'ECDSA'), 'staple success'); ++ok(staple(8543, 'ECDSA'), 'staple success'); + + } + +@@ -272,7 +293,7 @@ TODO: { + local $TODO = 'broken TLSv1.3 sigalgs in LibreSSL' + if $t->has_module('LibreSSL') && test_tls13(); + +-ok(staple(8444, 'ECDSA'), 'responder success'); ++ok(staple(8544, 'ECDSA'), 'responder success'); + + } +