parent
0bc8a4e929
commit
93c72a7726
@ -0,0 +1,62 @@ |
|||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <openssl/engine.h> |
||||||
|
|
||||||
|
#include "lmdb.h" |
||||||
|
|
||||||
|
MDB_crypto_hooks MDB_crypto; |
||||||
|
|
||||||
|
static EVP_CIPHER *cipher; |
||||||
|
|
||||||
|
static int str2key(const char *passwd, MDB_val *key) |
||||||
|
{ |
||||||
|
unsigned int size; |
||||||
|
EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); |
||||||
|
EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); |
||||||
|
EVP_DigestUpdate(mdctx, "Just a Constant", sizeof("Just a Constant")); |
||||||
|
EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); |
||||||
|
EVP_DigestFinal_ex(mdctx, key->mv_data, &size); |
||||||
|
EVP_MD_CTX_free(mdctx); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int encfunc(const MDB_val *src, MDB_val *dst, const MDB_val *key, int encdec) |
||||||
|
{ |
||||||
|
unsigned char iv[12]; |
||||||
|
int ivl, outl, rc; |
||||||
|
mdb_size_t *ptr; |
||||||
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); |
||||||
|
|
||||||
|
ptr = key[1].mv_data; |
||||||
|
ivl = ptr[0] & 0xffffffff; |
||||||
|
memcpy(iv, &ivl, 4); |
||||||
|
memcpy(iv+4, ptr+1, sizeof(mdb_size_t)); |
||||||
|
EVP_CipherInit_ex(ctx, cipher, NULL, key[0].mv_data, iv, encdec); |
||||||
|
EVP_CIPHER_CTX_set_padding(ctx, 0); |
||||||
|
if (!encdec) { |
||||||
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, key[2].mv_size, key[2].mv_data); |
||||||
|
} |
||||||
|
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) { |
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
static const MDB_crypto_funcs table = { |
||||||
|
str2key, |
||||||
|
encfunc, |
||||||
|
NULL, |
||||||
|
32, |
||||||
|
16, |
||||||
|
0 |
||||||
|
}; |
||||||
|
|
||||||
|
MDB_crypto_funcs *MDB_crypto() |
||||||
|
{ |
||||||
|
cipher = (EVP_CIPHER *)EVP_chacha20_poly1305(); |
||||||
|
return (MDB_crypto_funcs *)&table; |
||||||
|
} |
@ -0,0 +1,188 @@ |
|||||||
|
/* mtest_enc.c - memory-mapped database tester/toy with encryption */ |
||||||
|
/*
|
||||||
|
* Copyright 2011-2017 Howard Chu, Symas Corp. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted only as authorized by the Symas |
||||||
|
* Dual-Use License. |
||||||
|
* |
||||||
|
* A copy of this license is available in the file LICENSE in the |
||||||
|
* source distribution. |
||||||
|
*/ |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <time.h> |
||||||
|
#include "lmdb.h" |
||||||
|
|
||||||
|
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) |
||||||
|
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) |
||||||
|
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ |
||||||
|
"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) |
||||||
|
|
||||||
|
extern MDB_crypto_hooks MDB_crypto; |
||||||
|
MDB_crypto_funcs *cf; |
||||||
|
|
||||||
|
int main(int argc,char * argv[]) |
||||||
|
{ |
||||||
|
int i = 0, j = 0, rc; |
||||||
|
MDB_env *env; |
||||||
|
MDB_dbi dbi; |
||||||
|
MDB_val key, data; |
||||||
|
MDB_txn *txn; |
||||||
|
MDB_stat mst; |
||||||
|
MDB_cursor *cursor, *cur2; |
||||||
|
MDB_cursor_op op; |
||||||
|
MDB_val enckey; |
||||||
|
int count; |
||||||
|
int *values; |
||||||
|
char sval[32] = ""; |
||||||
|
char password[] = "This is my passphrase for now"; |
||||||
|
char ekey[32]; |
||||||
|
|
||||||
|
srand(time(NULL)); |
||||||
|
|
||||||
|
count = (rand()%384) + 64; |
||||||
|
values = (int *)malloc(count*sizeof(int)); |
||||||
|
|
||||||
|
for(i = 0;i<count;i++) { |
||||||
|
values[i] = rand()%1024; |
||||||
|
} |
||||||
|
|
||||||
|
cf = MDB_crypto(); |
||||||
|
enckey.mv_data = ekey; |
||||||
|
enckey.mv_size = sizeof(ekey); |
||||||
|
cf->mcf_str2key(password, &enckey); |
||||||
|
|
||||||
|
E(mdb_env_create(&env)); |
||||||
|
E(mdb_env_set_maxreaders(env, 1)); |
||||||
|
E(mdb_env_set_mapsize(env, 10485760)); |
||||||
|
E(mdb_env_set_encrypt(env, cf->mcf_encfunc, &enckey, cf->mcf_esumsize)); |
||||||
|
E(mdb_env_open(env, "./testdb", 0 /*|MDB_NOSYNC*/, 0664)); |
||||||
|
|
||||||
|
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||||
|
E(mdb_dbi_open(txn, NULL, 0, &dbi)); |
||||||
|
|
||||||
|
key.mv_size = sizeof(int); |
||||||
|
key.mv_data = sval; |
||||||
|
|
||||||
|
printf("Adding %d values\n", count); |
||||||
|
for (i=0;i<count;i++) {
|
||||||
|
sprintf(sval, "%03x %d foo bar", values[i], values[i]); |
||||||
|
/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */ |
||||||
|
data.mv_size = sizeof(sval); |
||||||
|
data.mv_data = sval; |
||||||
|
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) { |
||||||
|
j++; |
||||||
|
data.mv_size = sizeof(sval); |
||||||
|
data.mv_data = sval; |
||||||
|
} |
||||||
|
} |
||||||
|
if (j) printf("%d duplicates skipped\n", j); |
||||||
|
E(mdb_txn_commit(txn)); |
||||||
|
E(mdb_env_stat(env, &mst)); |
||||||
|
|
||||||
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||||
|
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||||
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||||
|
printf("key: %p %.*s, data: %p %.*s\n", |
||||||
|
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||||
|
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||||
|
} |
||||||
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||||
|
mdb_cursor_close(cursor); |
||||||
|
mdb_txn_abort(txn); |
||||||
|
|
||||||
|
j=0; |
||||||
|
key.mv_data = sval; |
||||||
|
for (i= count - 1; i > -1; i-= (rand()%5)) { |
||||||
|
j++; |
||||||
|
txn=NULL; |
||||||
|
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||||
|
sprintf(sval, "%03x ", values[i]); |
||||||
|
if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { |
||||||
|
j--; |
||||||
|
mdb_txn_abort(txn); |
||||||
|
} else { |
||||||
|
E(mdb_txn_commit(txn)); |
||||||
|
} |
||||||
|
} |
||||||
|
free(values); |
||||||
|
printf("Deleted %d values\n", j); |
||||||
|
|
||||||
|
E(mdb_env_stat(env, &mst)); |
||||||
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||||
|
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||||
|
printf("Cursor next\n"); |
||||||
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||||
|
printf("key: %.*s, data: %.*s\n", |
||||||
|
(int) key.mv_size, (char *) key.mv_data, |
||||||
|
(int) data.mv_size, (char *) data.mv_data); |
||||||
|
} |
||||||
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||||
|
printf("Cursor last\n"); |
||||||
|
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||||
|
printf("key: %.*s, data: %.*s\n", |
||||||
|
(int) key.mv_size, (char *) key.mv_data, |
||||||
|
(int) data.mv_size, (char *) data.mv_data); |
||||||
|
printf("Cursor prev\n"); |
||||||
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { |
||||||
|
printf("key: %.*s, data: %.*s\n", |
||||||
|
(int) key.mv_size, (char *) key.mv_data, |
||||||
|
(int) data.mv_size, (char *) data.mv_data); |
||||||
|
} |
||||||
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||||
|
printf("Cursor last/prev\n"); |
||||||
|
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||||
|
printf("key: %.*s, data: %.*s\n", |
||||||
|
(int) key.mv_size, (char *) key.mv_data, |
||||||
|
(int) data.mv_size, (char *) data.mv_data); |
||||||
|
E(mdb_cursor_get(cursor, &key, &data, MDB_PREV)); |
||||||
|
printf("key: %.*s, data: %.*s\n", |
||||||
|
(int) key.mv_size, (char *) key.mv_data, |
||||||
|
(int) data.mv_size, (char *) data.mv_data); |
||||||
|
|
||||||
|
mdb_cursor_close(cursor); |
||||||
|
mdb_txn_abort(txn); |
||||||
|
|
||||||
|
printf("Deleting with cursor\n"); |
||||||
|
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||||
|
E(mdb_cursor_open(txn, dbi, &cur2)); |
||||||
|
for (i=0; i<50; i++) { |
||||||
|
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT))) |
||||||
|
break; |
||||||
|
printf("key: %p %.*s, data: %p %.*s\n", |
||||||
|
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||||
|
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||||
|
E(mdb_del(txn, dbi, &key, NULL)); |
||||||
|
} |
||||||
|
|
||||||
|
printf("Restarting cursor in txn\n"); |
||||||
|
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||||
|
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op))) |
||||||
|
break; |
||||||
|
printf("key: %p %.*s, data: %p %.*s\n", |
||||||
|
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||||
|
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||||
|
} |
||||||
|
mdb_cursor_close(cur2); |
||||||
|
E(mdb_txn_commit(txn)); |
||||||
|
|
||||||
|
printf("Restarting cursor outside txn\n"); |
||||||
|
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||||
|
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||||
|
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||||
|
if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op))) |
||||||
|
break; |
||||||
|
printf("key: %p %.*s, data: %p %.*s\n", |
||||||
|
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||||
|
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||||
|
} |
||||||
|
mdb_cursor_close(cursor); |
||||||
|
mdb_txn_abort(txn); |
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi); |
||||||
|
mdb_env_close(env); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
Loading…
Reference in new issue