DataVaccinator Client  1.1.0
DataVaccinator Client Documentation

Introduction

This is a DataVaccinator Client library which is designed for native use on PC based computer systems running Linux/Unix or Microsoft Windows operating systems.

DataVaccinator protects your sensitive data known as PID against abuse. The service allows you to split out your PID data at the very moment it is generated and uses advanced pseudonymisation techniques to replace it with a corresponding VID.

Thus, DataVaccinator reduces cyber security risks in the health, industry, finance and any other sector and helps service providers, device manufacturers, data generating and data handling parties to manage sensitive data in a secure and GDPR-compliant manner. In contrast to other offerings, DataVaccinator industrialises pseudonymisation, thereby making pseudonymisation replicable and affordable.

The API of this library has two main parts to it:

Data Specification

The general DataVaccinator Vault data specification can be found here https://github.com/DataVaccinator/dv-vault/blob/master/docs/DataVaccinator-protocol.adoc#data This section focuses on the implementation of the payload part. It is documented here to facilitate cross platform compatibility with other DataVaccinator Client implementations. Our payload is authenticated https://en.wikipedia.org/wiki/Authenticated_encryption#MAC-then-Encrypt_(MtE) style.

The following use of bytes in variables implies usage of actual bytes and not hex encoded representations thereof. Our payload is implemented in the following way:

cs = last 2 bytes of the app-id
ivbytes = randomBytes ( 16 )
ivhex = hexencode ( ivbytes )

sumbytes = sha256 ( PID )
bytes = PID + PKCS#7 Padding + sumbytes
cipherbytes = aes256cbc ( ivbytes , bytes )
payload = base64 (cipherbytes )

data = "aes-256-cbc:" + cs + ":" + ivhex + ":b:" + payload

Example Usage

This usage example can also be found under examples/datause.c:

#include <vaccinator.h>
#include <string.h>
int32_t headerCb(void* usrCtx, dvSetHeaderFn setHeader, void* headerCtx) {
// This a static example that ignores the userCtx
return setHeader(headerCtx, "Cache-Control", "max-age=60");
}
int32_t postCb(void* usrCtx, dvSetPostFn setPostField, void* postCtx) {
// abort the request when usrCtx is not set as we need it here
if (!usrCtx) return RUE_PARAMETER_NOT_SET;
const char* user = "testuser";
int32_t ret = setPostField(postCtx, "username", (void*)user, strlen(user));
// abort the request on failure
if (ret) return ret;
// usrCtx could be any kind of structure, we just showcase a string here.
char* passwd = (char*) usrCtx;
return setPostField(postCtx, "password", (void*)passwd, strlen(passwd));
}
int main ( int argc, char **argv ) {
int ret;
KvStore *kvs = NULL;
dvCtx dc = NULL;
const char *name = "John Doe", *address = "Mystreet 42";
const char *passwd = "mysecret", *logfile = CACHE_DIR "/debug.log";
char *namevid = NULL, *addrvid = NULL, *a1 = NULL;
ruList vids = NULL, indexTerms = NULL, searchTerms = NULL, foundVids = NULL;
ruMap data = NULL;
ruSinkCtx rsc = NULL;
do {
// local cache
if (!ruIsDir(CACHE_DIR)) {
ret = ruMkdir(CACHE_DIR, 0755, false);
if (!ruIsDir(CACHE_DIR)) {
printf("failed to create folder '%s' ec [%d]\n", CACHE_DIR, ret);
break;
}
}
kvs = ruNewFileStore(CACHE_DIR, &ret);
if (ret) break;
if (argc > 1) {
a1 = argv[1];
// -d turns on verbose debug logging
// -v turns on verbose debug logging with curl debug logging
if (ruStrCmp(a1, "-v") == 0 || ruStrCmp(a1, "-d") == 0) {
rsc = ruSinkCtxNew(logfile, NULL, NULL);
} else {
a1 = NULL;
}
}
// setup
ret = dvNew(&dc, PROVIDER_URL, APPID, kvs);
if (ret) break;
// check for easy SSL mode
if (ruStrCmp("1", ruGetenv("EASYSSL")) == 0) {
// disable certificate checks
ret = dvSetProp(dc, DV_SKIP_CERT_CHECK, "1");
if (ret) break;
}
if (ruStrCmp(a1, "-v") == 0) {
// turn on curl debug logging
ret = dvSetProp(dc, DV_CURL_LOGGING, "1");
if (ret) break;
}
// sample usage of the header callback
ret = dvSetHeaderCb(dc, &headerCb, NULL);
if (ret) break;
// Mask our password in the logs so it is replace by ^^^SECRET^^^
// or whatever was set by DV_SECRET_PLACE_HOLDER last
// APPID has already been masked by dvNew
ret = dvSetProp(dc, DV_SECRET, passwd);
if (ret) break;
// sample usage of the post fields callback
ret = dvSetPostCb(dc, &postCb, (void *) passwd);
if (ret) break;
// add data
ret = dvAdd(dc, name, NULL, &namevid);
if (ret) break;
printf("namevid: %s\n", namevid);
// add searchable data
ret = dvAddIndexWord(&indexTerms, APPID, address);
if (ret) break;
ret = dvAdd(dc, address, indexTerms, &addrvid);
if (ret) break;
printf("addrvid: %s\n", addrvid);
// retrieve data
vids = ruListNew(NULL);
ret = ruListAppend(vids, namevid);
if (ret) break;
ret = ruListAppend(vids, addrvid);
if (ret) break;
ret = dvGet(dc, vids, &data);
if (ret) break;
ruIterator li = ruListIter(vids);
for(char *out, *vd = ruIterNext(li, char*); li;
vd = ruIterNext(li, char*)) {
ret = dvGetVid(data, vd, &out);
if (ret == RUE_OK) {
printf("pid for vid: '%s' is: '%s'\n", vd, out);
}
}
ruMapFree(data);
data = NULL;
// search data
ret = dvAddSearchWord(&searchTerms, APPID, "Mystreet");
if (ret) break;
ret = dvSearch(dc, searchTerms, &foundVids);
if (ret) break;
li = ruListIter(foundVids);
for(char* vd = ruIterNext(li, char*); li; vd = ruIterNext(li, char*)) {
printf("found vid: '%s'\n", vd);
}
// wipe cache
ret = dvWipe(dc, vids);
if (ret) break;
// delete data
ret = dvDelete(dc, vids);
if (ret) break;
ret = dvDelete(dc, foundVids);
if (ret) break;
} while (false);
if (namevid) free(namevid);
if (addrvid) free(addrvid);
if (vids) ruListFree(vids);
if (indexTerms) ruListFree(indexTerms);
if (searchTerms) ruListFree(searchTerms);
if (foundVids) ruListFree(foundVids);
if (data) ruMapFree(data);
if (dc) dvFree(dc);
if (kvs) ruFreeStore(kvs);
if (a1) {
printf("You will find debug logging in '%s'\n", logfile);
}
return ret;
}
int32_t(* dvSetPostFn)(void *ctx, const char *name, void *buf, size_t len)
Definition: vaccinator.h:532
int32_t(* dvSetHeaderFn)(void *ctx, const char *name, const char *value)
Definition: vaccinator.h:482
DVAPI int32_t dvSetHeaderCb(dvCtx dc, dvHeaderCb callback, void *cbCtx)
DVAPI int dvSetProp(dvCtx dc, enum dvCtxOpt opt, const char *value)
Sets a DataVaccinator Client context dvCtxOpt option.
DVAPI void dvFree(dvCtx dc)
DVAPI int32_t dvNew(dvCtx *dc, const char *serviceUrl, const char *appId, KvStore *cache)
DVAPI int32_t dvSetPostCb(dvCtx dc, dvPostCb callback, void *cbCtx)
void * dvCtx
Definition: vaccinator.h:167
DVAPI void dvSetCleanLogger(ruLogFunc logger, uint32_t logLevel, perm_ptr userData)
Sets the global logging function for this process.
@ DV_SECRET
Definition: vaccinator.h:639
@ DV_CURL_LOGGING
Definition: vaccinator.h:657
@ DV_SKIP_CERT_CHECK
Definition: vaccinator.h:652
DVAPI int32_t dvGet(dvCtx dc, ruList vids, ruMap *vidMap)
DVAPI int32_t dvAdd(dvCtx dc, const char *data, ruList indexWords, char **vid)
DVAPI int32_t dvAddSearchWord(ruList *searchWords, const char *appId, const char *word)
DVAPI int32_t dvGetVid(ruMap vidMap, const char *vid, char **pid)
DVAPI int32_t dvAddIndexWord(ruList *indexWords, const char *appId, const char *word)
DVAPI int32_t dvDelete(dvCtx dc, ruList vids)
DVAPI int32_t dvSearch(dvCtx dc, ruList searchWords, ruList *vids)
DVAPI int32_t dvWipe(dvCtx dc, ruList vids)
RUAPI ruMap ruMapFree(ruMap rm)
void * ruMap
RUAPI bool ruIsDir(trans_chars filename)
RUAPI int32_t ruMkdir(trans_chars pathname, int mode, bool deep)
RUAPI KvStore * ruNewFileStore(const char *folderPath, int32_t *code)
RUAPI void ruFreeStore(void *obj)
#define ruListAppend(rl, data)
void * ruIterator
RUAPI ruList ruListFree(ruList rl)
RUAPI ruList ruListNew(ruType valueType)
void * ruList
#define ruListIter(rl)
#define ruIterNext(re, type)
RUAPI void ruFileLogSink(perm_ptr rsc, uint32_t logLevel, trans_chars msg)
RUAPI ruSinkCtx ruSinkCtxFree(ruSinkCtx rsc)
#define RU_LOG_VERB
ptr ruSinkCtx
RUAPI ruSinkCtx ruSinkCtxNew(trans_chars filePath, ruCloseFunc closeCb, perm_ptr closeCtx)
RUAPI trans_chars ruGetenv(const char *variable)
#define RUE_PARAMETER_NOT_SET
#define RUE_OK
RUAPI int32_t ruStrCmp(trans_chars str1, trans_chars str2)