From 3a307ca58555e160ba18ec271d2d344580dbabf0 Mon Sep 17 00:00:00 2001 From: Anli Shundi Date: Sat, 7 Apr 2018 00:41:23 -0400 Subject: [PATCH] add two alternative directives for explicit specification of de/encryption key --- src/ngx_http_encrypted_session_module.c | 122 ++++++++++++++++++++++++ t/sanity.t | 27 ++++++ 2 files changed, 149 insertions(+) diff --git a/src/ngx_http_encrypted_session_module.c b/src/ngx_http_encrypted_session_module.c index a2206be..15087fa 100644 --- a/src/ngx_http_encrypted_session_module.c +++ b/src/ngx_http_encrypted_session_module.c @@ -31,6 +31,12 @@ static ngx_int_t ngx_http_set_encode_encrypted_session(ngx_http_request_t *r, static ngx_int_t ngx_http_set_decode_encrypted_session(ngx_http_request_t *r, ngx_str_t *res, ngx_http_variable_value_t *v); +static ngx_int_t ngx_http_set_encode_encrypted_session_keyed(ngx_http_request_t *r, + ngx_str_t *res, ngx_http_variable_value_t *v); + +static ngx_int_t ngx_http_set_decode_encrypted_session_keyed(ngx_http_request_t *r, + ngx_str_t *res, ngx_http_variable_value_t *v); + static void ngx_http_encrypted_session_free_cipher_ctx(void *data); static char *ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd, @@ -69,6 +75,20 @@ static ndk_set_var_t ngx_http_set_decode_encrypted_session_filter = { }; +static ndk_set_var_t ngx_http_set_encode_encrypted_session_keyed_filter = { + NDK_SET_VAR_MULTI_VALUE, + (void *) ngx_http_set_encode_encrypted_session_keyed, + 2, + NULL +}; + +static ndk_set_var_t ngx_http_set_decode_encrypted_session_keyed_filter = { + NDK_SET_VAR_MULTI_VALUE, + (void *) ngx_http_set_decode_encrypted_session_keyed, + 2, + NULL +}; + static ngx_command_t ngx_http_encrypted_session_commands[] = { { ngx_string("encrypted_session_key"), @@ -115,6 +135,24 @@ static ngx_command_t ngx_http_encrypted_session_commands[] = { 0, &ngx_http_set_decode_encrypted_session_filter }, + { + ngx_string("set_encrypt_session_keyed"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF + |NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE3, + ndk_set_var_multi_value, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + &ngx_http_set_encode_encrypted_session_keyed_filter + }, + { + ngx_string("set_decrypt_session_keyed"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF + |NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE3, + ndk_set_var_multi_value, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + &ngx_http_set_decode_encrypted_session_keyed_filter + }, ngx_null_command }; @@ -195,6 +233,51 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r, return NGX_OK; } +static ngx_int_t +ngx_http_set_encode_encrypted_session_keyed(ngx_http_request_t *r, + ngx_str_t *res, ngx_http_variable_value_t *v) +{ + size_t len; + u_char *dst; + ngx_int_t rc; + + ngx_http_encrypted_session_conf_t *conf; + ngx_http_encrypted_session_main_conf_t *emcf; + + emcf = ngx_http_get_module_main_conf(r, ngx_http_encrypted_session_module); + conf = ngx_http_get_module_loc_conf(r, ngx_http_encrypted_session_module); + + u_char *actualKey = NULL; + if ((v+1)->len != ngx_http_encrypted_session_key_length) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "encrypted_session_keyed: specified key needs to be exactly %d characters long; got %d", + ngx_http_encrypted_session_key_length, (v+1)->len); + return NGX_ERROR; + } else { + actualKey = (v+1)->data; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "encrypted_session_keyed: expires=%T", conf->expires); + + rc = ngx_http_encrypted_session_aes_mac_encrypt(emcf, r->pool, + r->connection->log, conf->iv, ngx_http_encrypted_session_iv_length, + actualKey, ngx_http_encrypted_session_key_length, + v->data, v->len, (ngx_uint_t) conf->expires, &dst, &len); + + if (rc != NGX_OK) { + dst = NULL; + len = 0; + + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "encrypted_session_keyed: failed to encrypt"); + } + + res->data = dst; + res->len = len; + + return NGX_OK; +} static ngx_int_t ngx_http_set_decode_encrypted_session(ngx_http_request_t *r, @@ -234,6 +317,45 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r, return NGX_OK; } +static ngx_int_t +ngx_http_set_decode_encrypted_session_keyed(ngx_http_request_t *r, + ngx_str_t *res, ngx_http_variable_value_t *v) +{ + size_t len; + u_char *dst; + ngx_int_t rc; + + ngx_http_encrypted_session_conf_t *conf; + ngx_http_encrypted_session_main_conf_t *emcf; + + emcf = ngx_http_get_module_main_conf(r, ngx_http_encrypted_session_module); + conf = ngx_http_get_module_loc_conf(r, ngx_http_encrypted_session_module); + + u_char *actualKey; + if ((v+1)->len != ngx_http_encrypted_session_key_length) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "encrypted_session_keyed: specified key needs to be exactly %d characters long; got %d", + ngx_http_encrypted_session_key_length, (v+1)->len); + return NGX_ERROR; + } else { + actualKey = (v+1)->data; + } + + rc = ngx_http_encrypted_session_aes_mac_decrypt(emcf, r->pool, + r->connection->log, conf->iv, ngx_http_encrypted_session_iv_length, + actualKey, ngx_http_encrypted_session_key_length, + v->data, v->len, &dst, &len); + + if (rc != NGX_OK) { + dst = NULL; + len = 0; + } + + res->data = dst; + res->len = len; + + return NGX_OK; +} static char * ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) diff --git a/t/sanity.t b/t/sanity.t index 18a7f48..52eccc1 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -316,3 +316,30 @@ X-Foo: [a-z0-9=]+$ --- error_log encrypted_session: expires=1382400 + + +=== TEST 12: explicit key with default iv +--- config + encrypted_session_expires 0; + + location /encode { + set $a 'abc'; + + set $session_key "abcdefghijklmnopqrstuvwxyz123456"; + set_encrypt_session_keyed $res $a $session_key; + + set_encode_base32 $ppres $res; + + echo "res = $ppres"; + + set_decrypt_session $b $res; + echo "b = $b"; + } +--- request + GET /encode +--- response_body +res = ktrp3n437q42laejppc9d4bg0jpv0ejie106ooo65od9lf5huhs0==== +b = abc +--- error_log +encrypted_session: expires=0 +