Skip to content

Commit

Permalink
feat(module): remove page level encryption
Browse files Browse the repository at this point in the history
This feature is unmaintained in upstream LMDB and has known issues that prevents it from being used.
  • Loading branch information
chronolaw authored Jul 13, 2023
1 parent 8fcd4de commit 951926f
Show file tree
Hide file tree
Showing 7 changed files with 2 additions and 544 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[submodule "lmdb"]
path = lmdb
url = https://github.com/LMDB/lmdb.git
branch = mdb.master3
branch = LMDB_0.9.31

23 changes: 0 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ Table of Contents
* [lmdb_environment_path](#lmdb_environment_path)
* [lmdb_max_databases](#lmdb_max_databases)
* [lmdb_map_size](#lmdb_map_size)
* [lmdb_encryption_key](#lmdb_encryption_key)
* [lmdb_encryption_mode](#lmdb_encryption_mode)
* [Copyright and license](#copyright-and-license)

## APIs
Expand Down Expand Up @@ -230,27 +228,6 @@ Set the size of the memory map, the default value is `1048576`(1MB).

[Back to TOC](#table-of-contents)

### lmdb_encryption_key

**syntax:** *lmdb_encryption_key path/to/keyfile;*

**context:** *main*

Encrypt the lmdb database. Encryption is enabled only when the `lmdb_encryption_key` is set. The
content of keyfile will be used to derive a key to encrypt lmdb.

[Back to TOC](#table-of-contents)

### lmdb_encryption_mode

**syntax:** *lmdb_encryption_mode "aes-256-gcm";*

**context:** *main*

Set the lmdb database encryption mode. The default encryption mode is "aes-256-gcm". The optional encryption
modes are "chacha20-poly1305" and "aes-256-gcm". Note that `lmdb_encryption_mode` needs to be set only when
`lmdb_encryption_key` is set.

[Back to TOC](#table-of-contents)

## Copyright and license
Expand Down
251 changes: 0 additions & 251 deletions src/ngx_lua_resty_lmdb_module.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
#include <ngx_lua_resty_lmdb_module.h>


#define NGX_LUA_RESTY_LMDB_MAX_BUF_LEN 512
#define NGX_LUA_RESTY_LMDB_ENC_KEY_LEN 32


#define NGX_LUA_RESTY_LMDB_FILE_MODE 0600
#define NGX_LUA_RESTY_LMDB_DIR_MODE 0700


#ifndef NGX_LUA_RESTY_LMDB_DIGEST_CONSTANT
#define NGX_LUA_RESTY_LMDB_DIGEST_CONSTANT "konglmdb"
#endif


static ngx_str_t ngx_lua_resty_lmdb_file_names[] = {
ngx_string("/data.mdb"),
ngx_string("/lock.mdb"),
Expand All @@ -28,11 +19,6 @@ static ngx_int_t ngx_lua_resty_lmdb_init_worker(ngx_cycle_t *cycle);
static void ngx_lua_resty_lmdb_exit_worker(ngx_cycle_t *cycle);


static int ngx_lua_resty_lmdb_digest_key(ngx_str_t *passwd, MDB_val *key);
static int ngx_lua_resty_lmdb_cipher(const MDB_val *src, MDB_val *dst,
const MDB_val *key, int encdec);


static ngx_command_t ngx_lua_resty_lmdb_commands[] = {

{ ngx_string("lmdb_environment_path"),
Expand All @@ -56,20 +42,6 @@ static ngx_command_t ngx_lua_resty_lmdb_commands[] = {
offsetof(ngx_lua_resty_lmdb_conf_t, map_size),
NULL },

{ ngx_string("lmdb_encryption_key"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
0,
offsetof(ngx_lua_resty_lmdb_conf_t, key_file),
NULL },

{ ngx_string("lmdb_encryption_mode"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
0,
offsetof(ngx_lua_resty_lmdb_conf_t, encryption_mode),
NULL },

ngx_null_command
};

Expand Down Expand Up @@ -112,7 +84,6 @@ ngx_lua_resty_lmdb_create_conf(ngx_cycle_t *cycle)
*
* conf->env_path = NULL;
* conf->env = NULL;
* conf->cipher = NULL;
*/

lcf->max_databases = NGX_CONF_UNSET_SIZE;
Expand All @@ -126,114 +97,12 @@ static char *
ngx_lua_resty_lmdb_init_conf(ngx_cycle_t *cycle, void *conf)
{
ngx_lua_resty_lmdb_conf_t *lcf = conf;
ngx_file_t file;
ngx_file_info_t fi;
size_t size;
ssize_t n;
u_char *buf;

ngx_conf_init_size_value(lcf->max_databases, 1);

/* same as mdb.c DEFAULT_MAPSIZE */
ngx_conf_init_size_value(lcf->map_size, 1048576);

/* The default encryption mode is aes-256-gcm */
if (lcf->encryption_mode.data == NULL) {
ngx_str_set(&lcf->encryption_mode, "aes-256-gcm");
}

if (ngx_strcasecmp(
lcf->encryption_mode.data, (u_char*)"aes-256-gcm") != 0 &&
ngx_strcasecmp(
lcf->encryption_mode.data, (u_char*)"chacha20-poly1305") != 0 ) {

ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"invalid \"lmdb_encryption_mode\": \"%V\"",
&lcf->encryption_mode);

return NGX_CONF_ERROR;
}

if (lcf->key_file.data != NULL) {
if (ngx_conf_full_name(cycle, &lcf->key_file, 1) != NGX_OK) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"search \"%V\" failed", &lcf->key_file);
return NGX_CONF_ERROR;
}

ngx_memzero(&file, sizeof(ngx_file_t));
file.name = lcf->key_file;
file.log = cycle->log;

file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
NGX_FILE_OPEN, 0);

if (file.fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
ngx_open_file_n " \"%V\" failed", &file.name);
return NGX_CONF_ERROR;
}

if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
ngx_fd_info_n " \"%V\" failed", &file.name);
ngx_close_file(file.fd);
return NGX_CONF_ERROR;
}

size = ngx_file_size(&fi);

if (size > NGX_LUA_RESTY_LMDB_MAX_BUF_LEN) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"\"%V\" must be less than %d bytes",
&file.name, NGX_LUA_RESTY_LMDB_MAX_BUF_LEN);
ngx_close_file(file.fd);
return NGX_CONF_ERROR;
}

buf = ngx_pcalloc(cycle->pool, size);
if (buf == NULL) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"allocate key memory failed");
ngx_close_file(file.fd);
return NGX_CONF_ERROR;
}

n = ngx_read_file(&file, buf, size, 0);

if (n == NGX_ERROR) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
ngx_read_file_n " \"%V\" failed", &file.name);
ngx_close_file(file.fd);
return NGX_CONF_ERROR;
}

if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
ngx_read_file_n " \"%V\" returned only "
"%z bytes instead of %uz", &file.name, n, size);
ngx_close_file(file.fd);
return NGX_CONF_ERROR;
}

lcf->key_data.data = buf;
lcf->key_data.len = size;

ngx_close_file(file.fd);
}

if (lcf->key_data.data != NULL) {
lcf->cipher = EVP_get_cipherbyname((char *)lcf->encryption_mode.data);

if (lcf->cipher == NULL ) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"init \"lmdb_encryption\": \"%V\" failed",
&lcf->encryption_mode);

return NGX_CONF_ERROR;
}
}

return NGX_CONF_OK;
}

Expand All @@ -244,9 +113,6 @@ ngx_lua_resty_lmdb_create_env(ngx_cycle_t *cycle,
ngx_flag_t is_master)
{
int rc;
MDB_val enckey;
int block_size = 0;
u_char keybuf[2048];

rc = mdb_env_create(&lcf->env);
if (rc != 0) {
Expand All @@ -272,47 +138,6 @@ ngx_lua_resty_lmdb_create_env(ngx_cycle_t *cycle,
goto failed;
}

if (lcf->cipher == NULL) {
return NGX_OK;
}

/* setup lmdb encryption */

enckey.mv_data = keybuf;
enckey.mv_size = NGX_LUA_RESTY_LMDB_ENC_KEY_LEN;

rc = ngx_lua_resty_lmdb_digest_key(&lcf->key_data, &enckey);
if (rc != 0) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"unable to set LMDB encryption key, string to key");
goto failed;
}

block_size = EVP_CIPHER_block_size(lcf->cipher);
if (block_size == 0) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"unable to set LMDB encryption key, block size");
goto failed;
}

rc = mdb_env_set_encrypt(lcf->env, ngx_lua_resty_lmdb_cipher,
&enckey, block_size);
if (rc != 0) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"unable to set LMDB encryption key: %s",
mdb_strerror(rc));
goto failed;
}

/* worker will destroy secret data */
if (is_master == 0) {
ngx_explicit_memzero(lcf->key_data.data, lcf->key_data.len);
ngx_explicit_memzero(lcf->encryption_mode.data, lcf->encryption_mode.len);

ngx_str_null(&lcf->key_data);
ngx_str_null(&lcf->encryption_mode);
}

return NGX_OK;

failed:
Expand Down Expand Up @@ -605,79 +430,3 @@ static void ngx_lua_resty_lmdb_exit_worker(ngx_cycle_t *cycle)
}


static int ngx_lua_resty_lmdb_digest_key(ngx_str_t *passwd, MDB_val *key)
{
unsigned int size;
int rc;
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();

rc = EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
if (rc) {
rc = EVP_DigestUpdate(mdctx,
NGX_LUA_RESTY_LMDB_DIGEST_CONSTANT,
sizeof(NGX_LUA_RESTY_LMDB_DIGEST_CONSTANT));
}

if (rc) {
rc = EVP_DigestUpdate(mdctx, passwd->data, passwd->len);
}

if (rc) {
rc = EVP_DigestFinal_ex(mdctx, key->mv_data, &size);
}

EVP_MD_CTX_free(mdctx);

return rc == 0;
}


static int
ngx_lua_resty_lmdb_cipher(const MDB_val *src, MDB_val *dst,
const MDB_val *key, int encdec)
{
ngx_lua_resty_lmdb_conf_t *lcf;

u_char iv[12];
int ivl, outl, rc;
mdb_size_t *ptr;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();

lcf = (ngx_lua_resty_lmdb_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
ngx_lua_resty_lmdb_module);

ngx_lua_resty_lmdb_assert(lcf->cipher != NULL);

ptr = key[1].mv_data;
ivl = ptr[0] & 0xffffffff;
ngx_memcpy(iv, &ivl, sizeof(int));
ngx_memcpy(iv + sizeof(int), ptr + 1, sizeof(mdb_size_t));

rc = EVP_CipherInit_ex(ctx, lcf->cipher, NULL, key[0].mv_data, iv, encdec);
if (rc) {
EVP_CIPHER_CTX_set_padding(ctx, 0);
}

if (rc && !encdec) {
rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
key[2].mv_size, key[2].mv_data);
}

if (rc) {
rc = EVP_CipherUpdate(ctx, dst->mv_data, &outl,
src->mv_data, src->mv_size);
}

if (rc) {
rc = EVP_CipherFinal_ex(ctx, key[2].mv_data, &outl);
}

if (rc && encdec) {
rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
key[2].mv_size, key[2].mv_data);
}

EVP_CIPHER_CTX_free(ctx);

return rc == 0;
}
6 changes: 0 additions & 6 deletions src/ngx_lua_resty_lmdb_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ struct ngx_lua_resty_lmdb_conf_s {
size_t map_size;
MDB_env *env;
MDB_txn *ro_txn;

ngx_str_t key_file;
ngx_str_t key_data;
ngx_str_t encryption_mode;

const EVP_CIPHER *cipher;
};


Expand Down
Loading

0 comments on commit 951926f

Please sign in to comment.