Skip to content

Commit b13b462

Browse files
spacewanderagentzh
authored andcommitted
feature: added support for OpenSSL 1.1.0.
EVP_CIPHER_CTX is opaque after OpenSSL 1.1.0. Replace EVP_CIPHER_CTX_init and EVP_CIPHER_CTX_cleanup with EVP_CIPHER_CTX_new and EVP_CIPHER_CTX_free. Signed-off-by: Yichun Zhang (agentzh) <[email protected]>
1 parent 6483e14 commit b13b462

File tree

4 files changed

+154
-35
lines changed

4 files changed

+154
-35
lines changed

.travis.yml

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,25 @@ env:
1717
- LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1
1818
- LUA_INCLUDE_DIR=$LUAJIT_INC
1919
- LUA_CMODULE_DIR=/lib
20+
- OPENSSL_PREFIX=/opt/ssl
21+
- OPENSSL_LIB=$OPENSSL_PREFIX/lib
22+
- OPENSSL_INC=$OPENSSL_PREFIX/include
23+
- PCRE_VER=8.41
24+
- PCRE_PREFIX=/opt/pcre
25+
- PCRE_LIB=$PCRE_PREFIX/lib
26+
- PCRE_INC=$PCRE_PREFIX/include
2027
- JOBS=3
2128
- NGX_BUILD_JOBS=$JOBS
2229
matrix:
23-
- NGINX_VERSION=1.9.15
30+
- NGINX_VERSION=1.13.6 OPENSSL_VER=1.0.2k
31+
- NGINX_VERSION=1.13.6 OPENSSL_VER=1.1.0c
2432

2533
before_install:
2634
- sudo apt-get install -qq -y axel cpanminus libtest-base-perl libtext-diff-perl liburi-perl libwww-perl libtest-longstring-perl liblist-moreutils-perl > build.log 2>&1 || (cat build.log && exit 1)
2735

2836
install:
37+
- if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-$PCRE_VER.tar.gz; fi
38+
- if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz; fi
2939
- git clone https://github.com/openresty/nginx-devel-utils.git
3040
- git clone https://github.com/openresty/openresty.git ../openresty
3141
- git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
@@ -41,6 +51,18 @@ script:
4151
- make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT' > build.log 2>&1 || (cat build.log && exit 1)
4252
- sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)
4353
- cd ..
54+
- tar zxf download-cache/pcre-$PCRE_VER.tar.gz
55+
- cd pcre-$PCRE_VER/
56+
- ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1)
57+
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
58+
- sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1)
59+
- cd ..
60+
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
61+
- cd openssl-$OPENSSL_VER/
62+
- ./config no-threads shared -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
63+
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
64+
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
65+
- cd ..
4466
- cd test-nginx && sudo cpanm . && cd ..
4567
- export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH
4668
- export NGX_BUILD_CC=$CC

src/ngx_http_encrypted_session_cipher.c

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ static uint64_t ngx_http_encrypted_session_htonll(uint64_t n);
2121

2222

2323
ngx_int_t
24-
ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool, ngx_log_t *log,
25-
const u_char *iv, size_t iv_len, const u_char *key, size_t key_len,
26-
const u_char *in, size_t in_len, ngx_uint_t expires, u_char **dst,
27-
size_t *dst_len)
24+
ngx_http_encrypted_session_aes_mac_encrypt(
25+
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
26+
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
27+
size_t key_len, const u_char *in, size_t in_len, ngx_uint_t expires,
28+
u_char **dst, size_t *dst_len)
2829
{
29-
EVP_CIPHER_CTX ctx;
3030
const EVP_CIPHER *cipher;
3131
u_char *p, *data;
3232
int ret;
@@ -39,7 +39,15 @@ ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool, ngx_log_t *log,
3939
return NGX_ERROR;
4040
}
4141

42-
EVP_CIPHER_CTX_init(&ctx);
42+
if (emcf->session_ctx == NULL) {
43+
emcf->session_ctx = EVP_CIPHER_CTX_new();
44+
if (emcf->session_ctx == NULL) {
45+
ngx_log_error(NGX_LOG_ERR, log, 0,
46+
"encrypted_session: aes_mac_encrypt: no memory");
47+
48+
return NGX_ERROR;
49+
}
50+
}
4351

4452
cipher = EVP_aes_256_cbc();
4553

@@ -53,7 +61,7 @@ ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool, ngx_log_t *log,
5361

5462
p = ngx_palloc(pool, buf_size + data_size);
5563
if (p == NULL) {
56-
return NGX_ERROR;
64+
goto evp_error;
5765
}
5866

5967
*dst = p;
@@ -83,25 +91,23 @@ ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool, ngx_log_t *log,
8391

8492
p += MD5_DIGEST_LENGTH;
8593

86-
ret = EVP_EncryptInit(&ctx, cipher, key, iv);
94+
ret = EVP_EncryptInit(emcf->session_ctx, cipher, key, iv);
8795
if (!ret) {
8896
goto evp_error;
8997
}
9098

9199
/* encrypt the raw input data */
92100

93-
ret = EVP_EncryptUpdate(&ctx, p, &len, data, data_size);
101+
ret = EVP_EncryptUpdate(emcf->session_ctx, p, &len, data, data_size);
94102
if (!ret) {
95103
goto evp_error;
96104
}
97105

98106
p += len;
99107

100-
ret = EVP_EncryptFinal(&ctx, p, &len);
108+
ret = EVP_EncryptFinal(emcf->session_ctx, p, &len);
101109

102-
/* XXX we should still explicitly release the ctx
103-
* or we'll leak memory here */
104-
EVP_CIPHER_CTX_cleanup(&ctx);
110+
emcf->reset_cipher_ctx(emcf->session_ctx);
105111

106112
if (!ret) {
107113
return NGX_ERROR;
@@ -122,18 +128,19 @@ ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool, ngx_log_t *log,
122128

123129
evp_error:
124130

125-
EVP_CIPHER_CTX_cleanup(&ctx);
131+
emcf->reset_cipher_ctx(emcf->session_ctx);
126132

127133
return NGX_ERROR;
128134
}
129135

130136

131137
ngx_int_t
132-
ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool, ngx_log_t *log,
133-
const u_char *iv, size_t iv_len, const u_char *key, size_t key_len,
134-
const u_char *in, size_t in_len, u_char **dst, size_t *dst_len)
138+
ngx_http_encrypted_session_aes_mac_decrypt(
139+
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
140+
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
141+
size_t key_len, const u_char *in, size_t in_len, u_char **dst,
142+
size_t *dst_len)
135143
{
136-
EVP_CIPHER_CTX ctx;
137144
const EVP_CIPHER *cipher;
138145
int ret;
139146
size_t block_size, buf_size;
@@ -153,11 +160,19 @@ ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool, ngx_log_t *log,
153160

154161
digest = in;
155162

156-
EVP_CIPHER_CTX_init(&ctx);
163+
if (emcf->session_ctx == NULL) {
164+
emcf->session_ctx = EVP_CIPHER_CTX_new();
165+
if (emcf->session_ctx == NULL) {
166+
ngx_log_error(NGX_LOG_ERR, log, 0,
167+
"encrypted_session: aes_mac_encrypt: no memory");
168+
169+
return NGX_ERROR;
170+
}
171+
}
157172

158173
cipher = EVP_aes_256_cbc();
159174

160-
ret = EVP_DecryptInit(&ctx, cipher, key, iv);
175+
ret = EVP_DecryptInit(emcf->session_ctx, cipher, key, iv);
161176
if (!ret) {
162177
goto evp_error;
163178
}
@@ -169,12 +184,12 @@ ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool, ngx_log_t *log,
169184

170185
p = ngx_palloc(pool, buf_size);
171186
if (p == NULL) {
172-
return NGX_ERROR;
187+
goto evp_error;
173188
}
174189

175190
*dst = p;
176191

177-
ret = EVP_DecryptUpdate(&ctx, p, &len, in + MD5_DIGEST_LENGTH,
192+
ret = EVP_DecryptUpdate(emcf->session_ctx, p, &len, in + MD5_DIGEST_LENGTH,
178193
in_len - MD5_DIGEST_LENGTH);
179194

180195
if (!ret) {
@@ -184,11 +199,9 @@ ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool, ngx_log_t *log,
184199

185200
p += len;
186201

187-
ret = EVP_DecryptFinal(&ctx, p, &len);
202+
ret = EVP_DecryptFinal(emcf->session_ctx, p, &len);
188203

189-
/* XXX we should still explicitly release the ctx
190-
* or we'll leak memory here */
191-
EVP_CIPHER_CTX_cleanup(&ctx);
204+
emcf->reset_cipher_ctx(emcf->session_ctx);
192205

193206
if (!ret) {
194207
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0,
@@ -250,7 +263,7 @@ ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool, ngx_log_t *log,
250263

251264
evp_error:
252265

253-
EVP_CIPHER_CTX_cleanup(&ctx);
266+
emcf->reset_cipher_ctx(emcf->session_ctx);
254267

255268
return NGX_ERROR;
256269
}

src/ngx_http_encrypted_session_cipher.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,29 @@
77
#include <openssl/evp.h>
88

99

10+
typedef int (*cipher_ctx_reset_handle) (EVP_CIPHER_CTX *ctx);
11+
12+
13+
typedef struct {
14+
EVP_CIPHER_CTX *session_ctx;
15+
cipher_ctx_reset_handle reset_cipher_ctx;
16+
} ngx_http_encrypted_session_main_conf_t;
17+
18+
1019
enum {
1120
ngx_http_encrypted_session_key_length = 256 / 8,
1221
ngx_http_encrypted_session_iv_length = EVP_MAX_IV_LENGTH
1322
};
1423

1524

16-
ngx_int_t ngx_http_encrypted_session_aes_mac_encrypt(ngx_pool_t *pool,
25+
ngx_int_t ngx_http_encrypted_session_aes_mac_encrypt(
26+
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
1727
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
1828
size_t key_len, const u_char *in, size_t in_len,
1929
ngx_uint_t expires, u_char **dst, size_t *dst_len);
2030

21-
ngx_int_t ngx_http_encrypted_session_aes_mac_decrypt(ngx_pool_t *pool,
31+
ngx_int_t ngx_http_encrypted_session_aes_mac_decrypt(
32+
ngx_http_encrypted_session_main_conf_t *emcf, ngx_pool_t *pool,
2233
ngx_log_t *log, const u_char *iv, size_t iv_len, const u_char *key,
2334
size_t key_len, const u_char *in, size_t in_len, u_char **dst,
2435
size_t *dst_len);

src/ngx_http_encrypted_session_module.c

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ static ngx_int_t ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
3131
static ngx_int_t ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
3232
ngx_str_t *res, ngx_http_variable_value_t *v);
3333

34+
static void ngx_http_encrypted_session_free_cipher_ctx(void *data);
3435

3536
static char *ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd,
3637
void *conf);
@@ -42,6 +43,11 @@ static char *ngx_http_encrypted_session_expires(ngx_conf_t *cf,
4243
ngx_command_t *cmd, void *conf);
4344

4445

46+
static ngx_int_t ngx_http_encrypted_session_init(ngx_conf_t *cf);
47+
static void *ngx_http_encrypted_session_create_main_conf(ngx_conf_t *cf);
48+
static char *ngx_http_encrypted_session_init_main_conf(ngx_conf_t *cf,
49+
void *conf);
50+
4551
static void *ngx_http_encrypted_session_create_conf(ngx_conf_t *cf);
4652

4753
static char *ngx_http_encrypted_session_merge_conf(ngx_conf_t *cf, void *parent,
@@ -116,10 +122,10 @@ static ngx_command_t ngx_http_encrypted_session_commands[] = {
116122

117123
static ngx_http_module_t ngx_http_encrypted_session_module_ctx = {
118124
NULL, /* preconfiguration */
119-
NULL, /* postconfiguration */
125+
ngx_http_encrypted_session_init, /* postconfiguration */
120126

121-
NULL, /* create main configuration */
122-
NULL, /* init main configuration */
127+
ngx_http_encrypted_session_create_main_conf, /* create main configuration */
128+
ngx_http_encrypted_session_init_main_conf, /* init main configuration */
123129

124130
NULL, /* create server configuration */
125131
NULL, /* merge server configuration */
@@ -154,7 +160,9 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
154160
ngx_int_t rc;
155161

156162
ngx_http_encrypted_session_conf_t *conf;
163+
ngx_http_encrypted_session_main_conf_t *emcf;
157164

165+
emcf = ngx_http_get_module_main_conf(r, ngx_http_encrypted_session_module);
158166
conf = ngx_http_get_module_loc_conf(r, ngx_http_encrypted_session_module);
159167

160168
if (conf->key == NULL) {
@@ -168,7 +176,7 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
168176
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
169177
"encrypted_session: expires=%T", conf->expires);
170178

171-
rc = ngx_http_encrypted_session_aes_mac_encrypt(r->pool,
179+
rc = ngx_http_encrypted_session_aes_mac_encrypt(emcf, r->pool,
172180
r->connection->log, conf->iv, ngx_http_encrypted_session_iv_length,
173181
conf->key, ngx_http_encrypted_session_key_length,
174182
v->data, v->len, (ngx_uint_t) conf->expires, &dst, &len);
@@ -197,7 +205,9 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
197205
ngx_int_t rc;
198206

199207
ngx_http_encrypted_session_conf_t *conf;
208+
ngx_http_encrypted_session_main_conf_t *emcf;
200209

210+
emcf = ngx_http_get_module_main_conf(r, ngx_http_encrypted_session_module);
201211
conf = ngx_http_get_module_loc_conf(r, ngx_http_encrypted_session_module);
202212

203213
if (conf->key == NULL) {
@@ -208,7 +218,7 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
208218
return NGX_ERROR;
209219
}
210220

211-
rc = ngx_http_encrypted_session_aes_mac_decrypt(r->pool,
221+
rc = ngx_http_encrypted_session_aes_mac_decrypt(emcf, r->pool,
212222
r->connection->log, conf->iv, ngx_http_encrypted_session_iv_length,
213223
conf->key, ngx_http_encrypted_session_key_length,
214224
v->data, v->len, &dst, &len);
@@ -316,6 +326,69 @@ ngx_http_encrypted_session_expires(ngx_conf_t *cf, ngx_command_t *cmd,
316326
}
317327

318328

329+
static void
330+
ngx_http_encrypted_session_free_cipher_ctx(void *data)
331+
{
332+
ngx_http_encrypted_session_main_conf_t *emcf = data;
333+
334+
if (emcf->session_ctx != NULL) {
335+
EVP_CIPHER_CTX_free(emcf->session_ctx);
336+
emcf->session_ctx = NULL;
337+
}
338+
}
339+
340+
341+
static ngx_int_t
342+
ngx_http_encrypted_session_init(ngx_conf_t *cf)
343+
{
344+
ngx_pool_cleanup_t *cln;
345+
ngx_http_encrypted_session_main_conf_t *emcf;
346+
347+
emcf =
348+
ngx_http_conf_get_module_main_conf(cf,
349+
ngx_http_encrypted_session_module);
350+
351+
cln = ngx_pool_cleanup_add(cf->pool, 0);
352+
if (cln == NULL) {
353+
return NGX_ERROR;
354+
}
355+
356+
cln->data = emcf;
357+
cln->handler = ngx_http_encrypted_session_free_cipher_ctx;
358+
return NGX_OK;
359+
}
360+
361+
362+
static void *
363+
ngx_http_encrypted_session_create_main_conf(ngx_conf_t *cf)
364+
{
365+
ngx_http_encrypted_session_main_conf_t *emcf;
366+
367+
emcf = ngx_pcalloc(cf->pool,
368+
sizeof(ngx_http_encrypted_session_main_conf_t));
369+
if (emcf == NULL) {
370+
return NULL;
371+
}
372+
373+
return emcf;
374+
}
375+
376+
377+
static char *
378+
ngx_http_encrypted_session_init_main_conf(ngx_conf_t *cf, void *conf)
379+
{
380+
ngx_http_encrypted_session_main_conf_t *emcf = conf;
381+
382+
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
383+
emcf->reset_cipher_ctx = EVP_CIPHER_CTX_reset;
384+
#else
385+
emcf->reset_cipher_ctx = EVP_CIPHER_CTX_cleanup;
386+
#endif
387+
388+
return NGX_CONF_OK;
389+
}
390+
391+
319392
static void *
320393
ngx_http_encrypted_session_create_conf(ngx_conf_t *cf)
321394
{

0 commit comments

Comments
 (0)