-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: support ssl.create_ctx and tcp:setsslctx #997
base: master
Are you sure you want to change the base?
Changes from 28 commits
e859096
91a6d7d
635a569
1c10853
2ec655d
df4387b
7086ff1
ca8c3cb
6ce2ea5
1b2eaac
697f0eb
0409076
17c3141
8b7e0f5
a30bbf3
73c5aa8
0b04b54
902ec8d
c94df6d
6e38b47
8e06dc5
c105935
69f841f
3bcc9f7
f52e7a2
b57b9db
f13fd50
fb52c37
1f1b090
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,10 @@ | |
#if (NGX_HTTP_SSL) | ||
|
||
|
||
static size_t ngx_http_lua_ssl_get_error(u_long e, u_char *ssl_err, | ||
size_t ssl_err_len, const char *default_err, size_t default_err_len); | ||
|
||
|
||
int ngx_http_lua_ssl_ctx_index = -1; | ||
|
||
|
||
|
@@ -34,4 +38,169 @@ ngx_http_lua_ssl_init(ngx_log_t *log) | |
} | ||
|
||
|
||
static size_t | ||
ngx_http_lua_ssl_get_error(u_long e, u_char *ssl_err, | ||
size_t ssl_err_len, const char *default_err, size_t default_err_len) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just put some notes here:
Current implementation of this function doesn't satisfy the deduction 1 and is vulnerable to the deduction 2. |
||
{ | ||
size_t len; | ||
|
||
if (e == 0) { | ||
len = ngx_min(ssl_err_len, default_err_len); | ||
ngx_memcpy(ssl_err, default_err, len); | ||
|
||
return len; | ||
} | ||
|
||
ERR_error_string_n(e, (char *) ssl_err, ssl_err_len); | ||
|
||
return ngx_strlen(ssl_err); | ||
} | ||
|
||
|
||
#ifndef NGX_LUA_NO_FFI_API | ||
|
||
|
||
void * | ||
ngx_http_lua_ffi_ssl_ctx_init(ngx_uint_t protocols, char **err) | ||
{ | ||
ngx_ssl_t ssl; | ||
|
||
ssl.log = ngx_cycle->log; | ||
if (ngx_ssl_create(&ssl, protocols, NULL) != NGX_OK) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if we should inherit existing configurations from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well. inheriting existing configurations from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @detailyang We'll add cosocket support to |
||
*err = "failed to create ssl ctx"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I think it would be better to return OpenSSL's own error messages if there's any. Otherwise fixed error messages made up in the caller does not give much helpful info. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, this is not a priority though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we reuse the |
||
return NULL; | ||
} | ||
|
||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ssl.log, 0, "lua ssl ctx init: %p:%d", | ||
ssl.ctx, ssl.ctx->references); | ||
|
||
return ssl.ctx; | ||
} | ||
|
||
|
||
int | ||
ngx_http_lua_ffi_ssl_ctx_set_cert(void *cdata_ctx, void *cdata_cert, | ||
u_char *err, size_t *err_len) | ||
{ | ||
const char *default_err; | ||
|
||
#ifdef LIBRESSL_VERSION_NUMBER | ||
|
||
default_err = "LibreSSL not supported"; | ||
goto failed; | ||
|
||
#else | ||
|
||
# if OPENSSL_VERSION_NUMBER < 0x1000205fL | ||
|
||
default_err = "at least OpenSSL 1.0.2e required but found " | ||
OPENSSL_VERSION_TEXT; | ||
goto failed; | ||
|
||
# else | ||
|
||
X509 *x509 = NULL; | ||
SSL_CTX *ssl_ctx = cdata_ctx; | ||
STACK_OF(X509) *cert = cdata_cert; | ||
|
||
# ifdef OPENSSL_IS_BORINGSSL | ||
size_t i; | ||
# else | ||
int i; | ||
# endif | ||
int num; | ||
size_t n; | ||
u_long e; | ||
|
||
num = sk_X509_num(cert); | ||
if (num < 1) { | ||
default_err = "sk_X509_num() failed"; | ||
goto failed; | ||
} | ||
|
||
x509 = sk_X509_value(cert, 0); | ||
if (x509 == NULL) { | ||
default_err = "sk_X509_value() failed"; | ||
goto failed; | ||
} | ||
|
||
if (SSL_CTX_use_certificate(ssl_ctx, x509) == 0) { | ||
default_err = "SSL_CTX_use_certificate() failed"; | ||
goto failed; | ||
} | ||
|
||
/* read rest of the chain */ | ||
|
||
for (i = 1; i < num; i++) { | ||
|
||
x509 = sk_X509_value(cert, i); | ||
if (x509 == NULL) { | ||
default_err = "sk_X509_value() failed"; | ||
goto failed; | ||
} | ||
|
||
if (SSL_CTX_add1_chain_cert(ssl_ctx, x509) == 0) { | ||
default_err = "SSL_add1_chain_cert() failed"; | ||
goto failed; | ||
} | ||
} | ||
|
||
return NGX_OK; | ||
|
||
# endif /* OPENSSL_VERSION_NUMBER < 0x1000205fL */ | ||
#endif | ||
|
||
failed: | ||
|
||
e = ERR_get_error(); | ||
n = ngx_strlen(default_err); | ||
*err_len = ngx_http_lua_ssl_get_error(e, err, *err_len, default_err, n); | ||
|
||
return NGX_ERROR; | ||
} | ||
|
||
|
||
int | ||
ngx_http_lua_ffi_ssl_ctx_set_priv_key(void *cdata_ctx, void *cdata_key, | ||
u_char *err, size_t *err_len) | ||
{ | ||
SSL_CTX *ssl_ctx = cdata_ctx; | ||
EVP_PKEY *key = cdata_key; | ||
|
||
size_t n; | ||
u_long e; | ||
const char *default_err; | ||
|
||
if (SSL_CTX_use_PrivateKey(ssl_ctx, key) == 0) { | ||
default_err = "SSL_CTX_use_PrivateKey() failed"; | ||
goto failed; | ||
} | ||
|
||
return NGX_OK; | ||
|
||
failed: | ||
|
||
e = ERR_get_error(); | ||
n = ngx_strlen(default_err); | ||
*err_len = ngx_http_lua_ssl_get_error(e, err, *err_len, default_err, n); | ||
|
||
return NGX_ERROR; | ||
} | ||
|
||
|
||
void | ||
ngx_http_lua_ffi_ssl_ctx_free(void *cdata) | ||
{ | ||
SSL_CTX *ssl_ctx = cdata; | ||
|
||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, | ||
0, "lua ssl ctx free: %p:%d", ssl_ctx, ssl_ctx->references); | ||
|
||
SSL_CTX_free(ssl_ctx); | ||
} | ||
|
||
|
||
#endif /* NGX_LUA_NO_FFI_API */ | ||
|
||
|
||
#endif /* NGX_HTTP_SSL */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# vim:set ft= ts=4 sw=4 et fdm=marker: | ||
|
||
use Test::Nginx::Socket::Lua; | ||
|
||
repeat_each(3); | ||
|
||
plan tests => repeat_each() * (blocks()); | ||
|
||
$ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); | ||
|
||
log_level 'debug'; | ||
|
||
no_long_string(); | ||
|
||
run_tests(); | ||
|
||
__DATA__ | ||
|
||
=== TEST 1: ssl ctx init and free | ||
--- log_level: debug | ||
--- http_config | ||
lua_package_path "../lua-resty-core/lib/?.lua;;"; | ||
--- config | ||
location /t { | ||
content_by_lua_block { | ||
local ssl = require "ngx.ssl" | ||
local ssl_ctx, err = ssl.create_ctx({}) | ||
ssl_ctx = nil | ||
collectgarbage("collect") | ||
} | ||
} | ||
--- request | ||
GET /t | ||
--- ignore_response | ||
--- grep_error_log eval: qr/lua ssl ctx (?:init|free): [0-9A-F]+:\d+/ | ||
--- grep_error_log_out eval | ||
qr/^lua ssl ctx init: ([0-9A-F]+):1 | ||
lua ssl ctx free: ([0-9A-F]+):1 | ||
$/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should increment ref count of
SSL_CTX*
?