int elektraCryptoGcryHandleCreate (elektraCryptoHandle ** handle, KeySet * config, Key * errorKey) { gcry_error_t gcry_err; unsigned char keyBuffer[64], ivBuffer[64]; size_t keyLength, ivLength; (*handle) = NULL; // retrieve keys from configuration Key * key = elektraCryptoReadParamKey (config, errorKey); Key * iv = elektraCryptoReadParamIv (config, errorKey); if (key == NULL || iv == NULL) { return (-1); } keyLength = keyGetBinary (key, keyBuffer, sizeof (keyBuffer)); ivLength = keyGetBinary (iv, ivBuffer, sizeof (ivBuffer)); // create the handle (*handle) = elektraMalloc (sizeof (elektraCryptoHandle)); if (*handle == NULL) { memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed"); return (-1); } if ((gcry_err = gcry_cipher_open (*handle, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0)) != 0) { goto error; } if ((gcry_err = gcry_cipher_setkey (**handle, keyBuffer, keyLength)) != 0) { goto error; } if ((gcry_err = gcry_cipher_setiv (**handle, ivBuffer, ivLength)) != 0) { goto error; } memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); return 1; error: memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_CONFIG_FAULT, errorKey, "Failed to create handle because: %s", gcry_strerror (gcry_err)); gcry_cipher_close (**handle); elektraFree (*handle); (*handle) = NULL; return (-1); }
static void test_keyGetBinary (const size_t storagePlugin, const char * tmpFile) { Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END); open_storage_plugin (storagePlugin); Plugin * plugin = plugins[storagePlugin]; KeySet * ks = metaTestKeySet (); const char * name = "user/tests/storage/specialkey"; size_t realValueSize = 42; void * value = elektraMalloc (realValueSize); memset (value, 42, realValueSize); Key * key = keyNew (name, KEY_END); keySetBinary (key, value, realValueSize); ksAppendKey (ks, key); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); Key * found = ksLookupByName (ks, name, 0); succeed_if (found, "did not find key"); ssize_t apiValueSize = keyGetValueSize (found); char * apiValue = elektraMalloc (apiValueSize); succeed_if (keyGetBinary (found, apiValue, apiValueSize) == (ssize_t) realValueSize, "Key binary has wrong size"); succeed_if (elektraStrNCmp (value, apiValue, realValueSize) == 0, "Key binary value is wrong"); elektraFree (apiValue); elektraFree (value); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
/** * Generate a C-Style key and stream it. * * This keyset can be used to include as c-code for * applikations using elektra. * * @param key the key object to work with * @param stream the file pointer where to send the stream * @param options KDB_O_SHOWINDICES, KDB_O_IGNORE_COMMENT, KDB_O_SHOWINFO * @retval 1 on success * @ingroup stream */ int keyGenerate(const Key * key, FILE *stream, option_t options) { size_t s; char * str; size_t c; char * com; size_t n; char * nam; n = keyGetNameSize (key); if (n>1) { nam = (char*) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (key, nam, n); fprintf(stream,"\tkeyNew (\"%s\"", nam); elektraFree (nam); } s = keyGetValueSize (key); if (s>1) { str = (char*) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary(key)) keyGetBinary(key, str, s); else keyGetString (key, str, s); fprintf(stream,", KEY_VALUE, \"%s\"", str); elektraFree (str); } c = keyGetCommentSize (key); if (c>1) { com = (char*) elektraMalloc (c); if (com == NULL) return -1; keyGetComment (key, com, c); fprintf(stream,", KEY_COMMENT, \"%s\"", com); elektraFree (com); } if (! (keyGetMode(key) == 0664 || (keyGetMode(key) == 0775))) { fprintf(stream,", KEY_MODE, 0%3o", keyGetMode(key)); } fprintf(stream,", KEY_END)"); if (options == 0) return 1; /* dummy to make icc happy */ return 1; }
void test_checkfile () { printf ("Check file\n"); KeySet * modules = ksNew (0, KS_END); elektraModulesInit (modules, 0); Plugin * plugin = elektraPluginOpen ("resolver", modules, set_pluginconf (), 0); exit_if_fail (plugin, "did not find a resolver"); Key * root = keyNew ("system/elektra/modules", KEY_END); keyAddBaseName (root, plugin->name); KeySet * contract = ksNew (5, KS_END); plugin->kdbGet (plugin, contract, root); keyAddName (root, "/exports/checkfile"); Key * found = ksLookup (contract, root, 0); exit_if_fail (found, "did not find checkfile symbol"); typedef int (*func_t) (const char *); union { func_t f; void * v; } conversation; succeed_if (keyGetBinary (found, &conversation.v, sizeof (conversation)) == sizeof (conversation), "could not get binary"); func_t checkFile = conversation.f; succeed_if (checkFile ("valid") == 1, "valid file not recognised"); succeed_if (checkFile ("/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("/absolute/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("../valid") == -1, "invalid file not recognised"); succeed_if (checkFile ("valid/..") == -1, "invalid file not recognised"); succeed_if (checkFile ("/../valid") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("/valid/..") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("very..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("/") == -1, "invalid absolute file not recognised"); succeed_if (checkFile (".") == -1, "invalid file not recognised"); succeed_if (checkFile ("..") == -1, "invalid file not recognised"); ksDel (contract); keyDel (root); elektraPluginClose (plugin, 0); elektraModulesClose (modules, 0); ksDel (modules); }
/** * Generate a C-Style key and stream it. * * This keyset can be used to include as c-code for * applikations using elektra. * * @param key the key object to work with * @param stream the file pointer where to send the stream * @param options KDB_O_SHOWINDICES, KDB_O_IGNORE_COMMENT, KDB_O_SHOWINFO * @retval 1 on success * @ingroup stream */ int keyGenerate (const Key * key, FILE * stream, option_t options) { size_t n = keyGetNameSize (key); if (n > 1) { char * nam = (char *) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (key, nam, n); fprintf (stream, "\tkeyNew (\"%s\"", nam); elektraFree (nam); } size_t s = keyGetValueSize (key); if (s > 1) { char * str = (char *) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary (key)) { keyGetBinary (key, str, s); fprintf (stream, ", KEY_SIZE, \"%zd\"", keyGetValueSize (key)); } else { keyGetString (key, str, s); } fprintf (stream, ", KEY_VALUE, \"%s\"", str); elektraFree (str); } const Key * meta; Key * dup = keyDup (key); keyRewindMeta (dup); while ((meta = keyNextMeta (dup))) { fprintf (stream, ", KEY_META, \"%s\", \"%s\"", keyName (meta), keyString (meta)); } keyDel (dup); fprintf (stream, ", KEY_END)"); if (options == 0) return 1; /* dummy to make icc happy */ return 1; }
static void test_enc_and_dec_with_binary() { elektraCryptoHandle *handle; KeySet *config; Key *errorKey = keyNew(KEY_END); const unsigned char original[] = { 0x00, 0x01, 0x02, 0x03 }; unsigned char content[64]; unsigned long read = 0; Key *k = keyNew("user/plugins/crypto/gcrypt/test-enc-dec-bin", KEY_END); keySetBinary(k, original, sizeof(original)); getWorkingConfiguration(&config); succeed_if( elektraCryptoInit(errorKey) == 1, "crypto initialization failed" ); // 1. encrypt succeed_if( elektraCryptoHandleCreate(&handle, config, errorKey) == 1, "handle initialization with compliant config failed" ); succeed_if( elektraCryptoEncrypt(handle, k, errorKey) == 1, "encryption failed" ); elektraCryptoHandleDestroy(handle); // 2. decrypt succeed_if( elektraCryptoHandleCreate(&handle, config, errorKey) == 1, "handle initialization with compliant config failed" ); succeed_if( elektraCryptoDecrypt(handle, k, errorKey) == 1, "decryption failed" ); elektraCryptoHandleDestroy(handle); // 3. check result succeed_if( keyIsBinary(k) == 1, "key is of non-binary type"); read = keyGetBinary(k, content, sizeof(content)); succeed_if( read == sizeof(original), "decrypted value is of different length than original" ); if(read == sizeof(original)) { succeed_if( memcmp(original, content, read) == 0, "decrypted value differs from original"); } keyDel(k); keyDel(errorKey); ksDel(config); elektraCryptoTeardown(); }
/** * Output every information of a single key depending on options. * * The format is not very strict and only intend to be read * by human eyes for debugging purposes. Don't rely on the * format in your applications. * * @param k the key object to work with * @param stream the file pointer where to send the stream * @param options see text above * @see ksOutput() * @retval 1 on success * @retval -1 on allocation errors * @ingroup stream */ int keyOutput (const Key * k, FILE *stream, option_t options) { time_t t; size_t s; char * tmc; char * str; size_t c; char * com; size_t n; char * nam; n = keyGetNameSize (k); if (n>1) { nam = (char*) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (k, nam, n); fprintf(stream,"Name[%d]: %s : ", (int)n, nam); elektraFree (nam); } s = keyGetValueSize (k); if (options & KEY_VALUE && s>1) { str = (char*) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary(k)) { /* char * bin; bin = (char*) elektraMalloc (s*3+1); keyGetBinary(k, str, s); kdbbEncode (str, s, bin); elektraFree (bin); */ keyGetBinary (k, str, s); fprintf(stream,"Binary[%d]: %s : ", (int)s, str); } else { keyGetString (k, str, s); fprintf(stream,"String[%d]: %s : ", (int)s, str); } elektraFree (str); } c = keyGetCommentSize (k); if (options & KEY_COMMENT && c>1) { com = (char*) elektraMalloc (c); if (com == NULL) return -1; keyGetComment (k, com, c); fprintf(stream,"Comment[%d]: %s : ", (int)c, com); elektraFree (com); } if (options & KDB_O_SHOWMETA) fprintf(stream," : "); if (options & KEY_UID) fprintf(stream,"UID: %d : ", (int)keyGetUID (k)); if (options & KEY_GID) fprintf(stream,"GID: %d : ", (int)keyGetGID (k)); if (options & KEY_MODE) fprintf(stream,"Mode: %o : ", (int)keyGetMode (k)); if (options & KEY_ATIME) { t=keyGetATime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"ATime: %s : ", tmc); } if (options & KEY_MTIME) { t=keyGetMTime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"MTime: %s : ", tmc); } if (options & KEY_CTIME) { t=keyGetCTime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"CTime: %s : ", tmc); } if (options & KDB_O_SHOWFLAGS) { if (!(options & KDB_O_SHOWMETA)) fprintf(stream, " "); fprintf (stream,"Flags: "); if (keyIsBinary(k)) fprintf(stream,"b"); if (keyIsString(k)) fprintf(stream,"s"); if (keyIsInactive(k)) fprintf(stream,"i"); if (keyNeedSync(k)) fprintf(stream,"s"); } fprintf(stream,"\n"); return 1; }
int elektraCryptoGcryHandleCreate (elektraCryptoHandle ** handle, KeySet * config, Key * errorKey, Key * masterKey, Key * k, const enum ElektraCryptoOperation op) { gcry_error_t gcry_err; unsigned char keyBuffer[64], ivBuffer[64]; size_t keyLength, ivLength; (*handle) = NULL; // retrieve/derive the cryptographic material Key * key = keyNew (0); Key * iv = keyNew (0); switch (op) { case ELEKTRA_CRYPTO_ENCRYPT: if (getKeyIvForEncryption (config, errorKey, masterKey, k, key, iv) != 1) { keyDel (key); keyDel (iv); return -1; } break; case ELEKTRA_CRYPTO_DECRYPT: if (getKeyIvForDecryption (config, errorKey, masterKey, k, key, iv) != 1) { keyDel (key); keyDel (iv); return -1; } break; default: // not supported keyDel (key); keyDel (iv); return -1; } keyLength = keyGetBinary (key, keyBuffer, sizeof (keyBuffer)); ivLength = keyGetBinary (iv, ivBuffer, sizeof (ivBuffer)); // create the handle (*handle) = elektraMalloc (sizeof (elektraCryptoHandle)); if (*handle == NULL) { memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); keyDel (key); keyDel (iv); ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed"); return -1; } if ((gcry_err = gcry_cipher_open (*handle, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0)) != 0) { goto error; } if ((gcry_err = gcry_cipher_setkey (**handle, keyBuffer, keyLength)) != 0) { goto error; } if ((gcry_err = gcry_cipher_setiv (**handle, ivBuffer, ivLength)) != 0) { goto error; } memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); keyDel (key); keyDel (iv); return 1; error: memset (keyBuffer, 0, sizeof (keyBuffer)); memset (ivBuffer, 0, sizeof (ivBuffer)); ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_CONFIG_FAULT, errorKey, "Failed to create handle because: %s", gcry_strerror (gcry_err)); gcry_cipher_close (**handle); elektraFree (*handle); (*handle) = NULL; keyDel (key); keyDel (iv); return -1; }