mirror of https://github.com/nginx/nginx.git
Compare commits
21 Commits
release-1.
...
master
Author | SHA1 | Date |
---|---|---|
![]() |
78d1ab5a2c | |
![]() |
25b03d6500 | |
![]() |
f5a989cda2 | |
![]() |
3494f25c3e | |
![]() |
7f71abdd14 | |
![]() |
9d5cdc616c | |
![]() |
a144d828cb | |
![]() |
c2a266fa78 | |
![]() |
6f81314a07 | |
![]() |
8255bd29ac | |
![]() |
93ff1ee12c | |
![]() |
af436c58ca | |
![]() |
4c9ae11dff | |
![]() |
7f9ced0ce0 | |
![]() |
0373fe5d98 | |
![]() |
bc71625dcc | |
![]() |
417c87b78d | |
![]() |
eb5ebbbed7 | |
![]() |
446ce033e5 | |
![]() |
1a82df8cca | |
![]() |
36d40e5610 |
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
name: F5 CLA
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, closed, synchronize]
|
||||||
|
permissions: read-all
|
||||||
|
jobs:
|
||||||
|
f5-cla:
|
||||||
|
name: F5 CLA
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
actions: write
|
||||||
|
pull-requests: write
|
||||||
|
statuses: write
|
||||||
|
steps:
|
||||||
|
- name: Run F5 Contributor License Agreement (CLA) assistant
|
||||||
|
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have hereby read the F5 CLA and agree to its terms') || github.event_name == 'pull_request_target'
|
||||||
|
uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1
|
||||||
|
with:
|
||||||
|
# Path to the CLA document.
|
||||||
|
path-to-document: https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md
|
||||||
|
# Custom CLA messages.
|
||||||
|
custom-notsigned-prcomment: '🎉 Thank you for your contribution! It appears you have not yet signed the [F5 Contributor License Agreement (CLA)](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md), which is required for your changes to be incorporated into an F5 Open Source Software (OSS) project. Please kindly read the [F5 CLA](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md) and reply on a new comment with the following text to agree:'
|
||||||
|
custom-pr-sign-comment: 'I have hereby read the F5 CLA and agree to its terms'
|
||||||
|
custom-allsigned-prcomment: '✅ All required contributors have signed the F5 CLA for this PR. Thank you!'
|
||||||
|
# Remote repository storing CLA signatures.
|
||||||
|
remote-organization-name: f5
|
||||||
|
remote-repository-name: f5-cla-data
|
||||||
|
# Branch where CLA signatures are stored.
|
||||||
|
branch: main
|
||||||
|
path-to-signatures: signatures/signatures.json
|
||||||
|
# Comma separated list of usernames for maintainers or any other individuals who should not be prompted for a CLA.
|
||||||
|
# NOTE: You will want to edit the usernames to suit your project needs.
|
||||||
|
allowlist: bot*
|
||||||
|
# Do not lock PRs after a merge.
|
||||||
|
lock-pullrequest-aftermerge: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PERSONAL_ACCESS_TOKEN: ${{ secrets.F5_CLA_TOKEN }}
|
|
@ -36,8 +36,6 @@ http {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
|
||||||
#charset koi8-r;
|
|
||||||
|
|
||||||
#access_log logs/host.access.log main;
|
#access_log logs/host.access.log main;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
|
|
@ -5,8 +5,115 @@
|
||||||
<change_log title="nginx">
|
<change_log title="nginx">
|
||||||
|
|
||||||
|
|
||||||
|
<changes ver="1.29.2" date="2025-10-07">
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь nginx можно собрать с AWS-LC.<br/>
|
||||||
|
Спасибо Samuel Chiang.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now nginx can be built with AWS-LC.<br/>
|
||||||
|
Thanks Samuel Chiang.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь директива ssl_protocols работает
|
||||||
|
в виртуальном сервере, отличном от сервера по умолчанию,
|
||||||
|
при использовании OpenSSL 1.1.1 и новее.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now the "ssl_protocols" directive works
|
||||||
|
in a virtual server different from the default server
|
||||||
|
when using OpenSSL 1.1.1 or newer.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
при использовании TLSv1.3 с OpenSSL и клиентских сертификатов
|
||||||
|
SSL handshake всегда завершался ошибкой
|
||||||
|
при восстановлении сессии с другим значением SNI;
|
||||||
|
ошибка появилась в 1.27.4.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
SSL handshake always failed
|
||||||
|
when using TLSv1.3 with OpenSSL and client certificates
|
||||||
|
and resuming a session with a different SNI value;
|
||||||
|
the bug had appeared in 1.27.4.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
при использовании QUIC и директивы ssl_reject_handshake
|
||||||
|
в логах могли появляться сообщения
|
||||||
|
"ignoring stale global SSL error";
|
||||||
|
ошибка появилась в 1.29.0.<br/>
|
||||||
|
Спасибо Владимиру Хомутову.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
the "ignoring stale global SSL error"
|
||||||
|
alerts might appear in logs
|
||||||
|
when using QUIC and the "ssl_reject_handshake" directive;
|
||||||
|
the bug had appeared in 1.29.0.<br/>
|
||||||
|
Thanks to Vladimir Homutov.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в обработке delta-seconds
|
||||||
|
в строке "Cache-Control" в заголовке ответа бэкенда.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
in delta-seconds processing
|
||||||
|
in the "Cache-Control" backend response header line.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
команда XCLIENT не использовала кодировку xtext.<br/>
|
||||||
|
Спасибо Igor Morgenstern из Aisle Research.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
an XCLIENT command didn't use the xtext encoding.<br/>
|
||||||
|
Thanks to Igor Morgenstern of Aisle Research.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в кешировании SSL-сертификатов во время переконфигурации.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
in SSL certificate caching during reconfiguration.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.29.1" date="2025-08-13">
|
<changes ver="1.29.1" date="2025-08-13">
|
||||||
|
|
||||||
|
<change type="security">
|
||||||
|
<para lang="ru">
|
||||||
|
обработка специально созданного логина/пароля при использовании
|
||||||
|
метода аутентификации "none" в модуле ngx_mail_smtp_module
|
||||||
|
могла приводить к отправке серверу аутентификации
|
||||||
|
части содержимого памяти рабочего процесса (CVE-2025-53859).
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
processing of a specially crafted login/password when using
|
||||||
|
the "none" authentication method in the ngx_mail_smtp_module
|
||||||
|
might cause worker process memory disclosure
|
||||||
|
to the authentication server (CVE-2025-53859).
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
<change type="change">
|
<change type="change">
|
||||||
<para lang="ru">
|
<para lang="ru">
|
||||||
теперь сжатие сертификатов в протоколе TLSv1.3 по умолчанию запрещено.
|
теперь сжатие сертификатов в протоколе TLSv1.3 по умолчанию запрещено.
|
||||||
|
@ -8721,7 +8828,7 @@ Thanks to Piotr Sikora.
|
||||||
Спасибо Piotr Sikora.
|
Спасибо Piotr Sikora.
|
||||||
</para>
|
</para>
|
||||||
<para lang="en">
|
<para lang="en">
|
||||||
now nginx can be build with BoringSSL and LibreSSL.<br/>
|
now nginx can be built with BoringSSL and LibreSSL.<br/>
|
||||||
Thanks to Piotr Sikora.
|
Thanks to Piotr Sikora.
|
||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
@ -26004,7 +26111,7 @@ the ECONNABORTED error log level was changed to "error" from "crit".
|
||||||
модуль ngx_http_perl_module не собирался без модуля ngx_http_ssi_filter_module.
|
модуль ngx_http_perl_module не собирался без модуля ngx_http_ssi_filter_module.
|
||||||
</para>
|
</para>
|
||||||
<para lang="en">
|
<para lang="en">
|
||||||
the ngx_http_perl_module could not be build without
|
the ngx_http_perl_module could not be built without
|
||||||
the ngx_http_ssi_filter_module.
|
the ngx_http_ssi_filter_module.
|
||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
|
@ -6,9 +6,9 @@ TEMP = tmp
|
||||||
|
|
||||||
CC = cl
|
CC = cl
|
||||||
OBJS = objs.msvc8
|
OBJS = objs.msvc8
|
||||||
OPENSSL = openssl-3.5.2
|
OPENSSL = openssl-3.5.4
|
||||||
ZLIB = zlib-1.3.1
|
ZLIB = zlib-1.3.1
|
||||||
PCRE = pcre2-10.45
|
PCRE = pcre2-10.46
|
||||||
|
|
||||||
|
|
||||||
release: export
|
release: export
|
||||||
|
|
|
@ -3,7 +3,7 @@ make -f misc/GNUmakefile release
|
||||||
|
|
||||||
the required tools:
|
the required tools:
|
||||||
*) xsltproc to build CHANGES,
|
*) xsltproc to build CHANGES,
|
||||||
*) xslscript.pl ( http://hg.nginx.org/xslscript ) to build XSLTs
|
*) xslscript.pl ( https://github.com/nginx/xslscript ) to build XSLTs
|
||||||
from XSLScript sources.
|
from XSLScript sources.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#define _NGINX_H_INCLUDED_
|
#define _NGINX_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
#define nginx_version 1029001
|
#define nginx_version 1029003
|
||||||
#define NGINX_VERSION "1.29.1"
|
#define NGINX_VERSION "1.29.3"
|
||||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||||
|
|
||||||
#ifdef NGX_BUILD
|
#ifdef NGX_BUILD
|
||||||
|
|
|
@ -1494,8 +1494,9 @@ ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
|
||||||
uintptr_t
|
uintptr_t
|
||||||
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
{
|
{
|
||||||
ngx_uint_t n;
|
u_char prefix;
|
||||||
uint32_t *escape;
|
uint32_t *escape;
|
||||||
|
ngx_uint_t n;
|
||||||
static u_char hex[] = "0123456789ABCDEF";
|
static u_char hex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1633,11 +1634,36 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
|
|
||||||
/* mail_auth is the same as memcached */
|
/* mail_auth is the same as memcached */
|
||||||
|
|
||||||
|
/* " ", "+", "=", not allowed */
|
||||||
|
|
||||||
|
static uint32_t mail_xtext[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0x20000801, /* 0010 0000 0000 0000 0000 1000 0000 0001 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
static uint32_t *map[] =
|
static uint32_t *map[] =
|
||||||
{ uri, args, uri_component, html, refresh, memcached, memcached };
|
{ uri, args, uri_component, html, refresh, memcached, memcached,
|
||||||
|
mail_xtext };
|
||||||
|
|
||||||
|
static u_char map_char[] =
|
||||||
|
{ '%', '%', '%', '%', '%', '%', '%', '+' };
|
||||||
|
|
||||||
|
|
||||||
escape = map[type];
|
escape = map[type];
|
||||||
|
prefix = map_char[type];
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
|
|
||||||
|
@ -1658,7 +1684,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
||||||
*dst++ = '%';
|
*dst++ = prefix;
|
||||||
*dst++ = hex[*src >> 4];
|
*dst++ = hex[*src >> 4];
|
||||||
*dst++ = hex[*src & 0xf];
|
*dst++ = hex[*src & 0xf];
|
||||||
src++;
|
src++;
|
||||||
|
|
|
@ -203,6 +203,7 @@ u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
|
||||||
#define NGX_ESCAPE_REFRESH 4
|
#define NGX_ESCAPE_REFRESH 4
|
||||||
#define NGX_ESCAPE_MEMCACHED 5
|
#define NGX_ESCAPE_MEMCACHED 5
|
||||||
#define NGX_ESCAPE_MAIL_AUTH 6
|
#define NGX_ESCAPE_MAIL_AUTH 6
|
||||||
|
#define NGX_ESCAPE_MAIL_XTEXT 7
|
||||||
|
|
||||||
#define NGX_UNESCAPE_URI 1
|
#define NGX_UNESCAPE_URI 1
|
||||||
#define NGX_UNESCAPE_REDIRECT 2
|
#define NGX_UNESCAPE_REDIRECT 2
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
@ -19,6 +23,13 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
|
static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
|
||||||
|
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
||||||
|
static int ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn,
|
||||||
|
CBB *out, const uint8_t *in, size_t in_len);
|
||||||
|
static void *ngx_ssl_cert_compression_alloc(void *opaque, u_int items,
|
||||||
|
u_int size);
|
||||||
|
static void ngx_ssl_cert_compression_free(void *opaque, void *address);
|
||||||
|
#endif
|
||||||
static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
|
static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
|
||||||
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
|
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
|
||||||
int ret);
|
int ret);
|
||||||
|
@ -128,6 +139,8 @@ int ngx_ssl_ticket_keys_index;
|
||||||
int ngx_ssl_ocsp_index;
|
int ngx_ssl_ocsp_index;
|
||||||
int ngx_ssl_index;
|
int ngx_ssl_index;
|
||||||
int ngx_ssl_certificate_name_index;
|
int ngx_ssl_certificate_name_index;
|
||||||
|
int ngx_ssl_certificate_comp_index;
|
||||||
|
int ngx_ssl_client_hello_arg_index;
|
||||||
|
|
||||||
|
|
||||||
u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
||||||
|
@ -270,6 +283,21 @@ ngx_ssl_init(ngx_log_t *log)
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_ssl_certificate_comp_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
|
if (ngx_ssl_certificate_comp_index == -1) {
|
||||||
|
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_ssl_client_hello_arg_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
if (ngx_ssl_client_hello_arg_index == -1) {
|
||||||
|
ngx_ssl_error(NGX_LOG_ALERT, log, 0,
|
||||||
|
"SSL_CTX_get_ex_new_index() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,10 +477,18 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
{
|
{
|
||||||
char *err;
|
char *err;
|
||||||
X509 *x509, **elm;
|
X509 *x509, **elm;
|
||||||
|
u_long n;
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
|
ngx_uint_t mask;
|
||||||
STACK_OF(X509) *chain;
|
STACK_OF(X509) *chain;
|
||||||
|
|
||||||
chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT, &err, cert, NULL);
|
mask = 0;
|
||||||
|
elm = NULL;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
|
||||||
|
chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT | mask,
|
||||||
|
&err, cert, NULL);
|
||||||
if (chain == NULL) {
|
if (chain == NULL) {
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
@ -492,11 +528,16 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elm = ngx_array_push(&ssl->certs);
|
|
||||||
if (elm == NULL) {
|
if (elm == NULL) {
|
||||||
X509_free(x509);
|
elm = ngx_array_push(&ssl->certs);
|
||||||
sk_X509_pop_free(chain, X509_free);
|
if (elm == NULL) {
|
||||||
return NGX_ERROR;
|
X509_free(x509);
|
||||||
|
sk_X509_pop_free(chain, X509_free);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
X509_free(*elm);
|
||||||
}
|
}
|
||||||
|
|
||||||
*elm = x509;
|
*elm = x509;
|
||||||
|
@ -519,11 +560,21 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
/* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */
|
/* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */
|
||||||
|
|
||||||
|
#ifdef SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS
|
||||||
|
/* OpenSSL 1.0.1+ */
|
||||||
|
SSL_CTX_clear_extra_chain_certs(ssl->ctx);
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (ssl->ctx->extra_certs) {
|
||||||
|
sk_X509_pop_free(ssl->ctx->extra_certs, X509_free);
|
||||||
|
ssl->ctx->extra_certs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
n = sk_X509_num(chain);
|
n = sk_X509_num(chain);
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
|
@ -539,10 +590,11 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_X509_free(chain);
|
sk_X509_free(chain);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY, &err, key, passwords);
|
pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY | mask,
|
||||||
|
&err, key, passwords);
|
||||||
if (pkey == NULL) {
|
if (pkey == NULL) {
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
@ -554,9 +606,23 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
|
if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
|
||||||
|
/* there can be mismatched pairs on uneven cache update */
|
||||||
|
|
||||||
|
n = ERR_peek_last_error();
|
||||||
|
|
||||||
|
if (ERR_GET_LIB(n) == ERR_LIB_X509
|
||||||
|
&& ERR_GET_REASON(n) == X509_R_KEY_VALUES_MISMATCH
|
||||||
|
&& mask == 0)
|
||||||
|
{
|
||||||
|
ERR_clear_error();
|
||||||
|
mask = NGX_SSL_CACHE_INVALIDATE;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
"SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
|
"SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,6 +748,18 @@ ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
|
|
||||||
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
|
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
|
||||||
|
|
||||||
|
#elif (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
||||||
|
|
||||||
|
if (SSL_CTX_add_cert_compression_alg(ssl->ctx, TLSEXT_cert_compression_zlib,
|
||||||
|
ngx_ssl_cert_compression_callback,
|
||||||
|
NULL)
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
"SSL_CTX_add_cert_compression_alg() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
|
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
|
||||||
|
@ -694,6 +772,155 @@ ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
|
||||||
|
|
||||||
|
static int
|
||||||
|
ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn, CBB *out,
|
||||||
|
const uint8_t *in, size_t in_len)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
X509 *cert;
|
||||||
|
u_char *p;
|
||||||
|
z_stream zstream;
|
||||||
|
ngx_str_t *comp, tmp;
|
||||||
|
ngx_pool_t *pool;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_IS_BORINGSSL
|
||||||
|
{
|
||||||
|
SSL_CTX *ssl_ctx;
|
||||||
|
ngx_ssl_t *ssl;
|
||||||
|
|
||||||
|
/* BoringSSL doesn't have certificate slots, we take the last set */
|
||||||
|
|
||||||
|
ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
|
||||||
|
ssl = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_index);
|
||||||
|
cert = ((X509 **) ssl->certs.elts)[ssl->certs.nelts - 1];
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AWS-LC saves leaf certificate in SSL to associate with SSL_CTX,
|
||||||
|
* see https://github.com/aws/aws-lc/commit/e1ba2b3e5
|
||||||
|
*/
|
||||||
|
|
||||||
|
cert = SSL_get_certificate(ssl_conn);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
comp = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);
|
||||||
|
|
||||||
|
if (comp != NULL) {
|
||||||
|
return CBB_add_bytes(out, comp->data, comp->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = ngx_ssl_get_connection(ssl_conn);
|
||||||
|
|
||||||
|
pool = ngx_create_pool(256, c->log);
|
||||||
|
if (pool == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool->log = c->log;
|
||||||
|
|
||||||
|
ngx_memzero(&zstream, sizeof(z_stream));
|
||||||
|
|
||||||
|
zstream.zalloc = ngx_ssl_cert_compression_alloc;
|
||||||
|
zstream.zfree = ngx_ssl_cert_compression_free;
|
||||||
|
zstream.opaque = pool;
|
||||||
|
|
||||||
|
rc = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
|
||||||
|
|
||||||
|
if (rc != Z_OK) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateInit() failed: %d", rc);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.len = deflateBound(&zstream, in_len);
|
||||||
|
tmp.data = ngx_palloc(pool, tmp.len);
|
||||||
|
if (tmp.data == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
zstream.next_in = (u_char *) in;
|
||||||
|
zstream.avail_in = in_len;
|
||||||
|
zstream.next_out = tmp.data;
|
||||||
|
zstream.avail_out = tmp.len;
|
||||||
|
|
||||||
|
rc = deflate(&zstream, Z_FINISH);
|
||||||
|
|
||||||
|
if (rc != Z_STREAM_END) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
||||||
|
"deflate(Z_FINISH) failed: %d", rc);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.len -= zstream.avail_out;
|
||||||
|
|
||||||
|
rc = deflateEnd(&zstream);
|
||||||
|
|
||||||
|
if (rc != Z_OK) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateEnd() failed: %d", rc);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_alloc(sizeof(ngx_str_t) + tmp.len, c->log);
|
||||||
|
if (p == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
comp = (ngx_str_t *) p;
|
||||||
|
|
||||||
|
comp->len = tmp.len;
|
||||||
|
comp->data = p + sizeof(ngx_str_t);
|
||||||
|
|
||||||
|
ngx_memcpy(comp->data, tmp.data, tmp.len);
|
||||||
|
|
||||||
|
if (X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, p) == 0) {
|
||||||
|
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_set_ex_data() failed");
|
||||||
|
ngx_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = CBB_add_bytes(out, tmp.data, tmp.len);
|
||||||
|
|
||||||
|
ngx_destroy_pool(pool);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
ngx_destroy_pool(pool);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
ngx_ssl_cert_compression_alloc(void *opaque, u_int items, u_int size)
|
||||||
|
{
|
||||||
|
ngx_pool_t *pool = opaque;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pool->log, 0,
|
||||||
|
"cert compression alloc: n:%ud s:%ud", items, size);
|
||||||
|
|
||||||
|
return ngx_palloc(pool, items * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ngx_ssl_cert_compression_free(void *opaque, void *address)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
ngx_pool_t *pool = opaque;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0,
|
||||||
|
"cert compression free: %p", address);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
|
||||||
ngx_uint_t prefer_server_ciphers)
|
ngx_uint_t prefer_server_ciphers)
|
||||||
|
@ -1645,6 +1872,118 @@ ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ngx_ssl_set_client_hello_callback(SSL_CTX *ssl_ctx,
|
||||||
|
ngx_ssl_client_hello_arg *cb)
|
||||||
|
{
|
||||||
|
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
||||||
|
|
||||||
|
SSL_CTX_set_client_hello_cb(ssl_ctx, ngx_ssl_client_hello_callback, NULL);
|
||||||
|
SSL_CTX_set_ex_data(ssl_ctx, ngx_ssl_client_hello_arg_index, cb);
|
||||||
|
|
||||||
|
#elif defined OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
|
SSL_CTX_set_select_certificate_cb(ssl_ctx, ngx_ssl_select_certificate);
|
||||||
|
SSL_CTX_set_ex_data(ssl_ctx, ngx_ssl_client_hello_arg_index, cb);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
||||||
|
|
||||||
|
int
|
||||||
|
ngx_ssl_client_hello_callback(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
{
|
||||||
|
u_char *p;
|
||||||
|
size_t len;
|
||||||
|
ngx_int_t rc;
|
||||||
|
ngx_str_t host;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_ssl_client_hello_arg *cb;
|
||||||
|
|
||||||
|
c = ngx_ssl_get_connection(ssl_conn);
|
||||||
|
cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
|
||||||
|
ngx_ssl_client_hello_arg_index);
|
||||||
|
|
||||||
|
if (SSL_client_hello_get0_ext(ssl_conn, TLSEXT_TYPE_server_name,
|
||||||
|
(const unsigned char **) &p, &len)
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
ngx_str_null(&host);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 6066 mandates non-zero HostName length, we follow OpenSSL.
|
||||||
|
* No more than one ServerName is expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (len < 5
|
||||||
|
|| (size_t) (p[0] << 8) + p[1] + 2 != len
|
||||||
|
|| p[2] != TLSEXT_NAMETYPE_host_name
|
||||||
|
|| (size_t) (p[3] << 8) + p[4] + 2 + 3 != len)
|
||||||
|
{
|
||||||
|
*ad = SSL_AD_DECODE_ERROR;
|
||||||
|
return SSL_CLIENT_HELLO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= 5;
|
||||||
|
p += 5;
|
||||||
|
|
||||||
|
if (len > TLSEXT_MAXLEN_host_name || ngx_strlchr(p, p + len, '\0')) {
|
||||||
|
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
|
return SSL_CLIENT_HELLO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
host.len = len;
|
||||||
|
host.data = p;
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
rc = cb->servername(ssl_conn, ad, &host);
|
||||||
|
|
||||||
|
if (rc == SSL_TLSEXT_ERR_ALERT_FATAL) {
|
||||||
|
return SSL_CLIENT_HELLO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_CLIENT_HELLO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined OPENSSL_IS_BORINGSSL
|
||||||
|
|
||||||
|
enum ssl_select_cert_result_t ngx_ssl_select_certificate(
|
||||||
|
const SSL_CLIENT_HELLO *client_hello)
|
||||||
|
{
|
||||||
|
int ad;
|
||||||
|
ngx_int_t rc;
|
||||||
|
ngx_ssl_conn_t *ssl_conn;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_ssl_client_hello_arg *cb;
|
||||||
|
|
||||||
|
ssl_conn = client_hello->ssl;
|
||||||
|
c = ngx_ssl_get_connection(ssl_conn);
|
||||||
|
cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
|
||||||
|
ngx_ssl_client_hello_arg_index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BoringSSL sends a hardcoded "handshake_failure" alert on errors,
|
||||||
|
* we use it to map SSL_AD_INTERNAL_ERROR. To preserve other alert
|
||||||
|
* values, error handling is postponed to the servername callback.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rc = cb->servername(ssl_conn, &ad, NULL);
|
||||||
|
|
||||||
|
if (rc == SSL_TLSEXT_ERR_ALERT_FATAL && ad == SSL_AD_INTERNAL_ERROR) {
|
||||||
|
return ssl_select_cert_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssl_select_cert_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
||||||
{
|
{
|
||||||
|
@ -4792,10 +5131,19 @@ ngx_ssl_cleanup_ctx(void *data)
|
||||||
ngx_ssl_t *ssl = data;
|
ngx_ssl_t *ssl = data;
|
||||||
|
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
|
u_char *p;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
|
||||||
for (i = 0; i < ssl->certs.nelts; i++) {
|
for (i = 0; i < ssl->certs.nelts; i++) {
|
||||||
cert = ((X509 **) ssl->certs.elts)[i];
|
cert = ((X509 **) ssl->certs.elts)[i];
|
||||||
|
|
||||||
|
p = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
ngx_free(p);
|
||||||
|
X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,6 @@
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#endif
|
#endif
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#if (NGX_QUIC)
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
|
||||||
#include <openssl/hkdf.h>
|
|
||||||
#include <openssl/chacha.h>
|
|
||||||
#else
|
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#ifndef OPENSSL_NO_OCSP
|
#ifndef OPENSSL_NO_OCSP
|
||||||
#include <openssl/ocsp.h>
|
#include <openssl/ocsp.h>
|
||||||
|
@ -151,6 +143,7 @@ struct ngx_ssl_connection_s {
|
||||||
unsigned in_ocsp:1;
|
unsigned in_ocsp:1;
|
||||||
unsigned early_preread:1;
|
unsigned early_preread:1;
|
||||||
unsigned write_blocked:1;
|
unsigned write_blocked:1;
|
||||||
|
unsigned sni_accepted:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,6 +190,13 @@ typedef struct {
|
||||||
} ngx_ssl_session_cache_t;
|
} ngx_ssl_session_cache_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*ngx_ssl_servername_pt)(ngx_ssl_conn_t *, int *, void *);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_ssl_servername_pt servername;
|
||||||
|
} ngx_ssl_client_hello_arg;
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SSL_SSLv2 0x0002
|
#define NGX_SSL_SSLv2 0x0002
|
||||||
#define NGX_SSL_SSLv3 0x0004
|
#define NGX_SSL_SSLv3 0x0004
|
||||||
#define NGX_SSL_TLSv1 0x0008
|
#define NGX_SSL_TLSv1 0x0008
|
||||||
|
@ -286,6 +286,15 @@ ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||||
ngx_array_t *paths);
|
ngx_array_t *paths);
|
||||||
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
||||||
|
|
||||||
|
void ngx_ssl_set_client_hello_callback(SSL_CTX *ssl_ctx,
|
||||||
|
ngx_ssl_client_hello_arg *cb);
|
||||||
|
#ifdef SSL_CLIENT_HELLO_SUCCESS
|
||||||
|
int ngx_ssl_client_hello_callback(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
|
||||||
|
#elif defined OPENSSL_IS_BORINGSSL
|
||||||
|
enum ssl_select_cert_result_t ngx_ssl_select_certificate(
|
||||||
|
const SSL_CLIENT_HELLO *client_hello);
|
||||||
|
#endif
|
||||||
|
|
||||||
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
|
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
|
||||||
ngx_uint_t flags);
|
ngx_uint_t flags);
|
||||||
|
|
||||||
|
@ -382,6 +391,8 @@ extern int ngx_ssl_ticket_keys_index;
|
||||||
extern int ngx_ssl_ocsp_index;
|
extern int ngx_ssl_ocsp_index;
|
||||||
extern int ngx_ssl_index;
|
extern int ngx_ssl_index;
|
||||||
extern int ngx_ssl_certificate_name_index;
|
extern int ngx_ssl_certificate_name_index;
|
||||||
|
extern int ngx_ssl_certificate_comp_index;
|
||||||
|
extern int ngx_ssl_client_hello_arg_index;
|
||||||
|
|
||||||
|
|
||||||
extern u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
extern u_char ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];
|
||||||
|
|
|
@ -193,6 +193,7 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
|
ngx_uint_t invalidate;
|
||||||
ngx_file_uniq_t uniq;
|
ngx_file_uniq_t uniq;
|
||||||
ngx_file_info_t fi;
|
ngx_file_info_t fi;
|
||||||
ngx_ssl_cache_t *cache, *old_cache;
|
ngx_ssl_cache_t *cache, *old_cache;
|
||||||
|
@ -202,10 +203,17 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
|
|
||||||
*err = NULL;
|
*err = NULL;
|
||||||
|
|
||||||
|
invalidate = index & NGX_SSL_CACHE_INVALIDATE;
|
||||||
|
index &= ~NGX_SSL_CACHE_INVALIDATE;
|
||||||
|
|
||||||
if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
|
if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id.type == NGX_SSL_CACHE_DATA) {
|
||||||
|
invalidate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
|
cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
|
||||||
ngx_openssl_cache_module);
|
ngx_openssl_cache_module);
|
||||||
|
|
||||||
|
@ -215,7 +223,12 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
|
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
|
||||||
|
|
||||||
if (cn != NULL) {
|
if (cn != NULL) {
|
||||||
return type->ref(err, cn->value);
|
if (!invalidate) {
|
||||||
|
return type->ref(err, cn->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
type->free(cn->value);
|
||||||
|
ngx_rbtree_delete(&cache->rbtree, &cn->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = NULL;
|
value = NULL;
|
||||||
|
@ -236,7 +249,7 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
|
||||||
|
|
||||||
old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
|
old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
|
||||||
|
|
||||||
if (old_cache && old_cache->inheritable) {
|
if (old_cache && old_cache->inheritable && !invalidate) {
|
||||||
cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
|
cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
|
||||||
|
|
||||||
if (cn != NULL) {
|
if (cn != NULL) {
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
#elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION)
|
#elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION)
|
||||||
#define NGX_QUIC_QUICTLS_API 1
|
#define NGX_QUIC_QUICTLS_API 1
|
||||||
|
|
||||||
#elif (defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER)
|
#elif (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC \
|
||||||
|
|| defined LIBRESSL_VERSION_NUMBER)
|
||||||
#define NGX_QUIC_BORINGSSL_API 1
|
#define NGX_QUIC_BORINGSSL_API 1
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
#include <ngx_event_quic_connection.h>
|
#include <ngx_event_quic_connection.h>
|
||||||
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
|
#include <openssl/hkdf.h>
|
||||||
|
#include <openssl/chacha.h>
|
||||||
|
#else
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */
|
/* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */
|
||||||
|
@ -33,7 +39,7 @@ static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
|
||||||
|
|
||||||
static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
|
static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
static ngx_int_t ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
static ngx_int_t ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
const u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,7 +64,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
|
||||||
case TLS1_3_CK_AES_128_GCM_SHA256:
|
case TLS1_3_CK_AES_128_GCM_SHA256:
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
ciphers->c = EVP_aead_aes_128_gcm();
|
ciphers->c = EVP_aead_aes_128_gcm();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_aes_128_gcm();
|
ciphers->c = EVP_aes_128_gcm();
|
||||||
|
@ -69,7 +75,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS1_3_CK_AES_256_GCM_SHA384:
|
case TLS1_3_CK_AES_256_GCM_SHA384:
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
ciphers->c = EVP_aead_aes_256_gcm();
|
ciphers->c = EVP_aead_aes_256_gcm();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_aes_256_gcm();
|
ciphers->c = EVP_aes_256_gcm();
|
||||||
|
@ -80,12 +86,12 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
|
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
ciphers->c = EVP_aead_chacha20_poly1305();
|
ciphers->c = EVP_aead_chacha20_poly1305();
|
||||||
#else
|
#else
|
||||||
ciphers->c = EVP_chacha20_poly1305();
|
ciphers->c = EVP_chacha20_poly1305();
|
||||||
#endif
|
#endif
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
|
ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
|
||||||
#else
|
#else
|
||||||
ciphers->hp = EVP_chacha20();
|
ciphers->hp = EVP_chacha20();
|
||||||
|
@ -94,7 +100,7 @@ ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers)
|
||||||
len = 32;
|
len = 32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
case TLS1_3_CK_AES_128_CCM_SHA256:
|
case TLS1_3_CK_AES_128_CCM_SHA256:
|
||||||
ciphers->c = EVP_aes_128_ccm();
|
ciphers->c = EVP_aes_128_ccm();
|
||||||
ciphers->hp = EVP_aes_128_ctr();
|
ciphers->hp = EVP_aes_128_ctr();
|
||||||
|
@ -263,7 +269,7 @@ static ngx_int_t
|
||||||
ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
|
ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
|
||||||
const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
|
const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
|
|
||||||
if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
|
if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
|
||||||
== 0)
|
== 0)
|
||||||
|
@ -325,7 +331,7 @@ ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest,
|
||||||
const u_char *secret, size_t secret_len, const u_char *salt,
|
const u_char *secret, size_t secret_len, const u_char *salt,
|
||||||
size_t salt_len)
|
size_t salt_len)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
|
|
||||||
if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
|
if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
|
||||||
salt_len)
|
salt_len)
|
||||||
|
@ -388,7 +394,7 @@ ngx_quic_crypto_init(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
|
||||||
ngx_quic_md_t *key, ngx_int_t enc, ngx_log_t *log)
|
ngx_quic_md_t *key, ngx_int_t enc, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
EVP_AEAD_CTX *ctx;
|
EVP_AEAD_CTX *ctx;
|
||||||
|
|
||||||
ctx = EVP_AEAD_CTX_new(cipher, key->data, key->len,
|
ctx = EVP_AEAD_CTX_new(cipher, key->data, key->len,
|
||||||
|
@ -448,7 +454,7 @@ static ngx_int_t
|
||||||
ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
if (EVP_AEAD_CTX_open(s->ctx, out->data, &out->len, out->len, nonce,
|
if (EVP_AEAD_CTX_open(s->ctx, out->data, &out->len, out->len, nonce,
|
||||||
s->iv.len, in->data, in->len, ad->data, ad->len)
|
s->iv.len, in->data, in->len, ad->data, ad->len)
|
||||||
!= 1)
|
!= 1)
|
||||||
|
@ -468,7 +474,7 @@ ngx_int_t
|
||||||
ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
if (EVP_AEAD_CTX_seal(s->ctx, out->data, &out->len, out->len, nonce,
|
if (EVP_AEAD_CTX_seal(s->ctx, out->data, &out->len, out->len, nonce,
|
||||||
s->iv.len, in->data, in->len, ad->data, ad->len)
|
s->iv.len, in->data, in->len, ad->data, ad->len)
|
||||||
!= 1)
|
!= 1)
|
||||||
|
@ -484,7 +490,7 @@ ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, const u_char *nonce,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
#if !(NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
|
||||||
|
@ -563,7 +569,7 @@ void
|
||||||
ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
|
ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
|
||||||
{
|
{
|
||||||
if (s->ctx) {
|
if (s->ctx) {
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
EVP_AEAD_CTX_free(s->ctx);
|
EVP_AEAD_CTX_free(s->ctx);
|
||||||
#else
|
#else
|
||||||
EVP_CIPHER_CTX_free(s->ctx);
|
EVP_CIPHER_CTX_free(s->ctx);
|
||||||
|
@ -579,7 +585,7 @@ ngx_quic_crypto_hp_init(const EVP_CIPHER *cipher, ngx_quic_secret_t *s,
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX *ctx;
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
if (cipher == (EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
|
if (cipher == (EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
|
||||||
/* no EVP interface */
|
/* no EVP interface */
|
||||||
s->hp_ctx = NULL;
|
s->hp_ctx = NULL;
|
||||||
|
@ -615,7 +621,7 @@ ngx_quic_crypto_hp(ngx_quic_secret_t *s, u_char *out, u_char *in,
|
||||||
|
|
||||||
ctx = s->hp_ctx;
|
ctx = s->hp_ctx;
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (NGX_QUIC_BORINGSSL_EVP_API)
|
||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
|
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
|
|
|
@ -22,10 +22,12 @@
|
||||||
#define NGX_QUIC_MAX_MD_SIZE 48
|
#define NGX_QUIC_MAX_MD_SIZE 48
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC)
|
||||||
|
#define NGX_QUIC_BORINGSSL_EVP_API 1
|
||||||
#define ngx_quic_cipher_t EVP_AEAD
|
#define ngx_quic_cipher_t EVP_AEAD
|
||||||
#define ngx_quic_crypto_ctx_t EVP_AEAD_CTX
|
#define ngx_quic_crypto_ctx_t EVP_AEAD_CTX
|
||||||
#else
|
#else
|
||||||
|
#define NGX_QUIC_BORINGSSL_EVP_API 0
|
||||||
#define ngx_quic_cipher_t EVP_CIPHER
|
#define ngx_quic_cipher_t EVP_CIPHER
|
||||||
#define ngx_quic_crypto_ctx_t EVP_CIPHER_CTX
|
#define ngx_quic_crypto_ctx_t EVP_CIPHER_CTX
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -695,30 +695,35 @@ ngx_quic_handshake(ngx_connection_t *c)
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
|
||||||
|
|
||||||
if (qc->error) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
sslerr = SSL_get_error(ssl_conn, n);
|
sslerr = SSL_get_error(ssl_conn, n);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d",
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d",
|
||||||
sslerr);
|
sslerr);
|
||||||
|
|
||||||
|
if (c->ssl->handshake_rejected) {
|
||||||
|
ngx_connection_error(c, 0, "handshake rejected");
|
||||||
|
ERR_clear_error();
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qc->error) {
|
||||||
|
ngx_connection_error(c, 0, "SSL_do_handshake() failed");
|
||||||
|
ERR_clear_error();
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (sslerr != SSL_ERROR_WANT_READ) {
|
if (sslerr != SSL_ERROR_WANT_READ) {
|
||||||
|
|
||||||
if (c->ssl->handshake_rejected) {
|
|
||||||
ngx_connection_error(c, 0, "handshake rejected");
|
|
||||||
ERR_clear_error();
|
|
||||||
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_ssl_connection_error(c, sslerr, 0, "SSL_do_handshake() failed");
|
ngx_ssl_connection_error(c, sslerr, 0, "SSL_do_handshake() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qc->error) {
|
||||||
|
ngx_connection_error(c, 0, "SSL_do_handshake() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SSL_is_init_finished(ssl_conn)) {
|
if (!SSL_is_init_finished(ssl_conn)) {
|
||||||
if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0)
|
if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0)
|
||||||
&& qc->client_tp_done)
|
&& qc->client_tp_done)
|
||||||
|
@ -968,7 +973,7 @@ ngx_quic_init_connection(ngx_connection_t *c)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_IS_BORINGSSL
|
#if (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC)
|
||||||
if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) {
|
if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) {
|
||||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||||
"quic SSL_set_quic_early_data_context() failed");
|
"quic SSL_set_quic_early_data_context() failed");
|
||||||
|
|
|
@ -490,7 +490,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
if (value[i].len == 0) {
|
if (value[i].len == 0) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
"index \"%V\" in \"index\" directive is invalid",
|
"index \"%V\" in \"index\" directive is invalid",
|
||||||
&value[1]);
|
&value[i]);
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -749,6 +749,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
cln->data = &conf->ssl;
|
cln->data = &conf->ssl;
|
||||||
|
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
|
{
|
||||||
|
static ngx_ssl_client_hello_arg cb = { ngx_http_ssl_servername };
|
||||||
|
|
||||||
|
ngx_ssl_set_client_hello_callback(conf->ssl.ctx, &cb);
|
||||||
|
|
||||||
if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
||||||
ngx_http_ssl_servername)
|
ngx_http_ssl_servername)
|
||||||
|
@ -759,7 +763,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
"dynamically to an OpenSSL library which has no tlsext support, "
|
"dynamically to an OpenSSL library which has no tlsext support, "
|
||||||
"therefore SNI is not available");
|
"therefore SNI is not available");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
@ -906,13 +910,19 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
if (conf->stapling) {
|
if (conf->stapling) {
|
||||||
|
|
||||||
|
if (conf->certificate_compression) {
|
||||||
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
|
"\"ssl_stapling\" is incompatible with "
|
||||||
|
"\"ssl_certificate_compression\"");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
||||||
&conf->stapling_responder, conf->stapling_verify)
|
&conf->stapling_responder, conf->stapling_verify)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
|
if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
|
||||||
|
|
|
@ -891,27 +891,46 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->ssl->sni_accepted) {
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ssl->handshake_rejected) {
|
||||||
|
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
}
|
||||||
|
|
||||||
hc = c->data;
|
hc = c->data;
|
||||||
|
|
||||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
if (arg != NULL) {
|
||||||
|
host = *(ngx_str_t *) arg;
|
||||||
|
|
||||||
if (servername == NULL) {
|
if (host.data == NULL) {
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
"SSL server name: null");
|
"SSL server name: null");
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
|
if (servername == NULL) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
|
"SSL server name: null");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
host.len = ngx_strlen(servername);
|
||||||
|
host.data = (u_char *) servername;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
"SSL server name: \"%s\"", servername);
|
"SSL server name: \"%V\"", &host);
|
||||||
|
|
||||||
host.len = ngx_strlen(servername);
|
|
||||||
|
|
||||||
if (host.len == 0) {
|
if (host.len == 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.data = (u_char *) servername;
|
|
||||||
|
|
||||||
rc = ngx_http_validate_host(&host, c->pool, 1);
|
rc = ngx_http_validate_host(&host, c->pool, 1);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
|
@ -933,31 +952,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+,
|
|
||||||
* but servername being negotiated in every TLSv1.3 handshake
|
|
||||||
* is only returned in OpenSSL 1.1.1+ as well
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (sscf->verify) {
|
|
||||||
const char *hostname;
|
|
||||||
|
|
||||||
hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn));
|
|
||||||
|
|
||||||
if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) {
|
|
||||||
c->ssl->handshake_rejected = 1;
|
|
||||||
*ad = SSL_AD_ACCESS_DENIED;
|
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
||||||
if (hc->ssl_servername == NULL) {
|
if (hc->ssl_servername == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -971,6 +965,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
|
||||||
ngx_set_connection_log(c, clcf->error_log);
|
ngx_set_connection_log(c, clcf->error_log);
|
||||||
|
|
||||||
|
sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
|
||||||
|
|
||||||
c->ssl->buffer_size = sscf->buffer_size;
|
c->ssl->buffer_size = sscf->buffer_size;
|
||||||
|
|
||||||
if (sscf->ssl.ctx) {
|
if (sscf->ssl.ctx) {
|
||||||
|
@ -1019,6 +1015,7 @@ done:
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->ssl->sni_accepted = 1;
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -116,6 +116,10 @@ static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||||
|
#if (NGX_HTTP_CACHE)
|
||||||
|
static ngx_int_t ngx_http_upstream_process_delta_seconds(u_char *p,
|
||||||
|
u_char *last);
|
||||||
|
#endif
|
||||||
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
|
||||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||||
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
|
||||||
|
@ -5066,18 +5070,9 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = 0;
|
n = ngx_http_upstream_process_delta_seconds(p + offset, last);
|
||||||
|
|
||||||
for (p += offset; p < last; p++) {
|
|
||||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p >= '0' && *p <= '9') {
|
|
||||||
n = n * 10 + (*p - '0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (n == NGX_ERROR) {
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
@ -5087,7 +5082,8 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->cache->valid_sec = ngx_time() + n;
|
r->cache->valid_sec = ngx_min((ngx_uint_t) ngx_time() + n,
|
||||||
|
NGX_MAX_INT_T_VALUE);
|
||||||
u->headers_in.expired = 0;
|
u->headers_in.expired = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5097,18 +5093,9 @@ extensions:
|
||||||
23 - 1);
|
23 - 1);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = 0;
|
n = ngx_http_upstream_process_delta_seconds(p + 23, last);
|
||||||
|
|
||||||
for (p += 23; p < last; p++) {
|
|
||||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p >= '0' && *p <= '9') {
|
|
||||||
n = n * 10 + (*p - '0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (n == NGX_ERROR) {
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
@ -5120,18 +5107,9 @@ extensions:
|
||||||
p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1);
|
p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
n = 0;
|
n = ngx_http_upstream_process_delta_seconds(p + 15, last);
|
||||||
|
|
||||||
for (p += 15; p < last; p++) {
|
|
||||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p >= '0' && *p <= '9') {
|
|
||||||
n = n * 10 + (*p - '0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (n == NGX_ERROR) {
|
||||||
u->cacheable = 0;
|
u->cacheable = 0;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
@ -5145,6 +5123,41 @@ extensions:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HTTP_CACHE)
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_upstream_process_delta_seconds(u_char *p, u_char *last)
|
||||||
|
{
|
||||||
|
ngx_int_t n, cutoff, cutlim;
|
||||||
|
|
||||||
|
cutoff = NGX_MAX_INT_T_VALUE / 10;
|
||||||
|
cutlim = NGX_MAX_INT_T_VALUE % 10;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for ( /* void */ ; p < last; p++) {
|
||||||
|
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p < '0' || *p > '9') {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n >= cutoff && (n > cutoff || *p - '0' > cutlim)) {
|
||||||
|
n = NGX_MAX_INT_T_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = n * 10 + (*p - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
ngx_uint_t offset)
|
ngx_uint_t offset)
|
||||||
|
|
|
@ -531,6 +531,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t line, auth, encoded;
|
ngx_str_t line, auth, encoded;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
|
uintptr_t n;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_mail_session_t *s;
|
ngx_mail_session_t *s;
|
||||||
ngx_mail_proxy_conf_t *pcf;
|
ngx_mail_proxy_conf_t *pcf;
|
||||||
|
@ -627,6 +628,10 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
CRLF) - 1
|
CRLF) - 1
|
||||||
+ s->connection->addr_text.len + s->login.len + s->host.len;
|
+ s->connection->addr_text.len + s->login.len + s->host.len;
|
||||||
|
|
||||||
|
n = ngx_escape_uri(NULL, s->login.data, s->login.len,
|
||||||
|
NGX_ESCAPE_MAIL_XTEXT);
|
||||||
|
line.len += n * 2;
|
||||||
|
|
||||||
#if (NGX_HAVE_INET6)
|
#if (NGX_HAVE_INET6)
|
||||||
if (s->connection->sockaddr->sa_family == AF_INET6) {
|
if (s->connection->sockaddr->sa_family == AF_INET6) {
|
||||||
line.len += sizeof("IPV6:") - 1;
|
line.len += sizeof("IPV6:") - 1;
|
||||||
|
@ -654,7 +659,14 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||||
|
|
||||||
if (s->login.len && !pcf->smtp_auth) {
|
if (s->login.len && !pcf->smtp_auth) {
|
||||||
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
|
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
|
||||||
p = ngx_copy(p, s->login.data, s->login.len);
|
|
||||||
|
if (n == 0) {
|
||||||
|
p = ngx_copy(p, s->login.data, s->login.len);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
p = (u_char *) ngx_escape_uri(p, s->login.data, s->login.len,
|
||||||
|
NGX_ESCAPE_MAIL_XTEXT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1);
|
p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1);
|
||||||
|
|
|
@ -555,27 +555,46 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->ssl->sni_accepted) {
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ssl->handshake_rejected) {
|
||||||
|
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
|
}
|
||||||
|
|
||||||
s = c->data;
|
s = c->data;
|
||||||
|
|
||||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
if (arg) {
|
||||||
|
host = *(ngx_str_t *) arg;
|
||||||
|
|
||||||
if (servername == NULL) {
|
if (host.data == NULL) {
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||||
"SSL server name: null");
|
"SSL server name: null");
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
|
if (servername == NULL) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||||
|
"SSL server name: null");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
host.len = ngx_strlen(servername);
|
||||||
|
host.data = (u_char *) servername;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||||
"SSL server name: \"%s\"", servername);
|
"SSL server name: \"%V\"", &host);
|
||||||
|
|
||||||
host.len = ngx_strlen(servername);
|
|
||||||
|
|
||||||
if (host.len == 0) {
|
if (host.len == 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.data = (u_char *) servername;
|
|
||||||
|
|
||||||
rc = ngx_stream_validate_host(&host, c->pool, 1);
|
rc = ngx_stream_validate_host(&host, c->pool, 1);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
|
@ -596,35 +615,12 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+,
|
|
||||||
* but servername being negotiated in every TLSv1.3 handshake
|
|
||||||
* is only returned in OpenSSL 1.1.1+ as well
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (sscf->verify) {
|
|
||||||
const char *hostname;
|
|
||||||
|
|
||||||
hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn));
|
|
||||||
|
|
||||||
if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) {
|
|
||||||
c->ssl->handshake_rejected = 1;
|
|
||||||
*ad = SSL_AD_ACCESS_DENIED;
|
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s->srv_conf = cscf->ctx->srv_conf;
|
s->srv_conf = cscf->ctx->srv_conf;
|
||||||
|
|
||||||
ngx_set_connection_log(c, cscf->error_log);
|
ngx_set_connection_log(c, cscf->error_log);
|
||||||
|
|
||||||
|
sscf = ngx_stream_get_module_srv_conf(cscf->ctx, ngx_stream_ssl_module);
|
||||||
|
|
||||||
if (sscf->ssl.ctx) {
|
if (sscf->ssl.ctx) {
|
||||||
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -663,6 +659,7 @@ done:
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->ssl->sni_accepted = 1;
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1002,8 +999,14 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
cln->data = &conf->ssl;
|
cln->data = &conf->ssl;
|
||||||
|
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
|
{
|
||||||
|
static ngx_ssl_client_hello_arg cb = { ngx_stream_ssl_servername };
|
||||||
|
|
||||||
|
ngx_ssl_set_client_hello_callback(conf->ssl.ctx, &cb);
|
||||||
|
|
||||||
SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
|
||||||
ngx_stream_ssl_servername);
|
ngx_stream_ssl_servername);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
@ -1152,13 +1155,19 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
if (conf->stapling) {
|
if (conf->stapling) {
|
||||||
|
|
||||||
|
if (conf->certificate_compression) {
|
||||||
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
|
"\"ssl_stapling\" is incompatible with "
|
||||||
|
"\"ssl_certificate_compression\"");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
|
||||||
&conf->stapling_responder, conf->stapling_verify)
|
&conf->stapling_responder, conf->stapling_verify)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
||||||
|
|
Loading…
Reference in New Issue