Shows a simple encryptor as a plug in library.
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <wiredtiger.h>
#include <wiredtiger_ext.h>
typedef struct {
int rot_N;
char *keyid;
char *secretkey;
u_char *shift_forw;
u_char *shift_back;
size_t shift_len;
} ROTN_ENCRYPTOR;
#define CHKSUM_LEN 4
#define IV_LEN 16
static void
make_cksum(uint8_t *dst)
{
int i;
for (i = 0; i < CHKSUM_LEN; i++)
dst[i] = 'C';
}
static void
make_iv(uint8_t *dst)
{
int i;
for (i = 0; i < IV_LEN; i++)
dst[i] = 'I';
}
static void
do_rotate(char *buf, size_t len, int rotn)
{
uint32_t i;
for (i = 0; i < len; i++) {
if ('a' <= buf[i] && buf[i] <= 'z')
buf[i] = ((buf[i] - 'a') + rotn) % 26 + 'a';
else if ('A' <= buf[i] && buf[i] <= 'Z')
buf[i] = ((buf[i] - 'A') + rotn) % 26 + 'A';
}
}
static void
do_shift(uint8_t *buf, size_t len, u_char *shift, size_t shiftlen)
{
uint32_t i;
for (i = 0; i < len; i++)
buf[i] += shift[i % shiftlen];
}
static int
uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len,
size_t *result_lenp)
{
ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
uint32_t i;
(void)session;
if (dst_len < src_len + CHKSUM_LEN + IV_LEN)
return (ENOMEM);
i = CHKSUM_LEN + IV_LEN;
memcpy(&dst[i], &src[0], src_len);
if (rotn_encryptor->shift_len == 0)
do_rotate((char *)dst + i, src_len, rotn_encryptor->rot_N);
else
do_shift(&dst[i], src_len,
rotn_encryptor->shift_forw, rotn_encryptor->shift_len);
i = 0;
make_cksum(&dst[i]);
i += CHKSUM_LEN;
make_iv(&dst[i]);
*result_lenp = dst_len;
return (0);
}
static int
uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len,
size_t *result_lenp)
{
ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
size_t mylen;
uint32_t i;
(void)session;
mylen = src_len - (CHKSUM_LEN + IV_LEN);
if (dst_len < mylen) {
fprintf(stderr, "Rotate: ENOMEM ERROR\n");
return (ENOMEM);
}
i = CHKSUM_LEN + IV_LEN;
memcpy(&dst[0], &src[i], mylen);
if (rotn_encryptor->shift_len == 0)
do_rotate((char *)dst, mylen, 26 - rotn_encryptor->rot_N);
else
do_shift(&dst[0], mylen,
rotn_encryptor->shift_back, rotn_encryptor->shift_len);
*result_lenp = mylen;
return (0);
}
static int
size_t *expansion_constantp)
{
(void)encryptor;
(void)session;
*expansion_constantp = CHKSUM_LEN + IV_LEN;
return (0);
}
static int
{
const ROTN_ENCRYPTOR *orig;
ROTN_ENCRYPTOR *rotn_encryptor;
size_t i, len;
int ret, keyid_val;
u_char base;
ret = 0;
keyid_val = 0;
orig = (const ROTN_ENCRYPTOR *)encryptor;
wt_api = orig->wt_api;
if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL)
return (errno);
*rotn_encryptor = *orig;
rotn_encryptor->keyid = rotn_encryptor->secretkey = NULL;
if ((ret = wt_api->
config_get(wt_api, session, encrypt_config,
"keyid", &keyid)) == 0 && keyid.
len != 0) {
if ((keyid_val = atoi(keyid.
str)) < 0) {
ret = EINVAL;
goto err;
}
if ((rotn_encryptor->keyid = malloc(keyid.
len + 1)) == NULL) {
ret = errno;
goto err;
}
strncpy(rotn_encryptor->keyid, keyid.
str, keyid.
len + 1);
rotn_encryptor->keyid[keyid.
len] =
'\0';
}
if ((ret = wt_api->
config_get(wt_api, session, encrypt_config,
"secretkey", &secret)) == 0 && secret.
len != 0) {
if ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL ||
(rotn_encryptor->shift_forw = malloc(len)) == NULL ||
(rotn_encryptor->shift_back = malloc(len)) == NULL) {
ret = errno;
goto err;
}
for (i = 0; i < len; i++) {
if (
'a' <= secret.
str[i] && secret.
str[i] <=
'z')
base = 'a';
else if (
'A' <= secret.
str[i] && secret.
str[i] <=
'Z')
base = 'A';
else {
ret = EINVAL;
goto err;
}
base -= (u_char)keyid_val;
rotn_encryptor->shift_forw[i] =
(u_char)secret.
str[i] - base;
rotn_encryptor->shift_back[i] =
base - (u_char)secret.
str[i];
}
rotn_encryptor->shift_len = len;
strncpy(rotn_encryptor->secretkey, secret.
str, secret.
len + 1);
rotn_encryptor->secretkey[secret.
len] =
'\0';
}
rotn_encryptor->rot_N = keyid_val;
return (0);
err: free(rotn_encryptor->keyid);
free(rotn_encryptor->secretkey);
free(rotn_encryptor->shift_forw);
free(rotn_encryptor->shift_back);
free(rotn_encryptor);
return (ret);
}
static int
{
ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
(void)session;
free(rotn_encryptor->secretkey);
free(rotn_encryptor->keyid);
free(rotn_encryptor->shift_forw);
free(rotn_encryptor->shift_back);
free(encryptor);
return (0);
}
int
{
ROTN_ENCRYPTOR *rotn_encryptor;
(void)config;
if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL)
return (errno);
rotn_encryptor->encryptor.encrypt = rotn_encrypt;
rotn_encryptor->encryptor.decrypt = rotn_decrypt;
rotn_encryptor->encryptor.sizing = rotn_sizing;
rotn_encryptor->encryptor.customize = rotn_customize;
rotn_encryptor->encryptor.terminate = rotn_terminate;
}