Exemplo n.º 1
0
/**
 * @brief derive the cryptographic key and IV for a given (Elektra) Key k
 * @param config KeySet holding the plugin/backend configuration
 * @param errorKey holds an error description in case of failure
 * @param masterKey holds the decrypted master password from the plugin configuration
 * @param k the (Elektra)-Key to be encrypted
 * @param cKey (Elektra)-Key holding the cryptographic material
 * @param cIv (Elektra)-Key holding the initialization vector
 * @retval -1 on failure. errorKey holds the error description.
 * @retval 1 on success
 */
static int getKeyIvForDecryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
{
	gcry_error_t gcry_err;
	kdb_octet_t keyBuffer[KEY_BUFFER_SIZE];
	kdb_octet_t * saltBuffer = NULL;
	kdb_unsigned_long_t saltBufferLen = 0;

	ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");

	// get the salt
	if (CRYPTO_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, &saltBuffer, &saltBufferLen) != 1)
	{
		return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromPayload)()
	}

	// get the iteration count
	const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);

	// derive the cryptographic key and the IV
	if ((gcry_err = gcry_kdf_derive (keyValue (masterKey), keyGetValueSize (masterKey), GCRY_KDF_PBKDF2, GCRY_MD_SHA512, saltBuffer,
					 saltBufferLen, iterations, KEY_BUFFER_SIZE, keyBuffer)))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey,
				    "Failed to restore the cryptographic key for decryption because: %s", gcry_strerror (gcry_err));
		return -1;
	}

	keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_GCRY_KEYSIZE);
	keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_GCRY_KEYSIZE, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	return 1;
}
Exemplo n.º 2
0
/**
 * @brief derive the cryptographic key and IV for a given (Elektra) Key k
 * @param config KeySet holding the plugin/backend configuration
 * @param errorKey holds an error description in case of failure
 * @param masterKey holds the decrypted master password from the plugin configuration
 * @param k the (Elektra)-Key to be encrypted
 * @param cKey (Elektra)-Key holding the cryptographic material
 * @param cIv (Elektra)-Key holding the initialization vector
 * @retval -1 on failure. errorKey holds the error description.
 * @retval 1 on success
 */
static int getKeyIvForDecryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
{
	kdb_octet_t keyBuffer[KEY_BUFFER_SIZE];
	kdb_octet_t * saltBuffer = NULL;
	kdb_unsigned_long_t saltBufferLen = 0;

	ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");

	// get the salt
	if (CRYPTO_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, &saltBuffer, &saltBufferLen) != 1)
	{
		return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromPayload)()
	}

	// get the iteration count
	const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);

	// derive the cryptographic key and the IV
	pthread_mutex_lock (&mutex_ssl);
	if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), saltBuffer, saltBufferLen, iterations,
				     KEY_BUFFER_SIZE, keyBuffer))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey,
				    "Failed to restore the cryptographic key for decryption. Libcrypto returned the error code: %lu",
				    ERR_get_error ());
		pthread_mutex_unlock (&mutex_ssl);
		return -1;
	}
	pthread_mutex_unlock (&mutex_ssl);

	keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE);
	keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE);
	return 1;
}
/**
 * @brief create new KeySet and add a working configuration to it.
 */
static void getWorkingConfiguration(KeySet **ks)
{
	Key *configKey = keyNew("proc/elektra/modules/crypto/key-derivation/key", KEY_END);
	keySetBinary(configKey, key, sizeof(key));

	Key *configIv = keyNew("proc/elektra/modules/crypto/key-derivation/iv", KEY_END);
	keySetBinary(configIv, iv, sizeof(iv));

	(*ks) = ksNew(2,
		configKey,
		configIv,
		KS_END);
}
Exemplo n.º 4
0
static void test_keySetBinary (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, KDB_O_POP);
	succeed_if (found, "did not find key");

	// now set a new key value to the Key _after_ kdbGet
	size_t newValueSize = 4096;
	void * newValue = elektraMalloc (newValueSize);
	memset (newValue, 253, newValueSize);

	succeed_if (keySetBinary (found, newValue, newValueSize) == (ssize_t) newValueSize, "Key binary could not be set");

	ksAppendKey (ks, found);
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	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) newValueSize, "Key binary has wrong size");

	succeed_if (elektraStrNCmp (value, apiValue, realValueSize) != 0, "Key binary value is wrong");
	succeed_if (elektraStrNCmp (newValue, apiValue, newValueSize) == 0, "Key binary value is wrong");

	elektraFree (newValue);
	elektraFree (apiValue);
	elektraFree (value);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
/**
 * @brief create new KeySet and add an invalid configuration to it.
 *
 * The key in ks has an invalid size.
 */
static void getInvalidConfiguration(KeySet **ks)
{
	const unsigned char wrongKey[] = { 0x01, 0x02, 0x03 };

	Key *configKey = keyNew("proc/elektra/modules/crypto/key-derivation/key", KEY_END);
	keySetBinary(configKey, wrongKey, sizeof(wrongKey));

	Key *configIv = keyNew("proc/elektra/modules/crypto/key-derivation/iv", KEY_END);
	keySetBinary(configIv, iv, sizeof(iv));

	(*ks) = ksNew(2,
		configKey,
		configIv,
		KS_END);
}
Exemplo n.º 6
0
static KeySet * pwentToKS (struct passwd * pwd, Key * parentKey, SortBy index)
{
	KeySet * ks = ksNew (0, KS_END);
	Key * append = keyNew (keyName (parentKey), KEY_END);
	char id[ID_MAX_CHARACTERS];
	if (index == UID)
	{
		snprintf (id, sizeof (id), "%u", pwd->pw_uid);
		keyAddBaseName (append, id);
		keySetBinary (append, 0, 0);
		ksAppendKey (ks, keyDup (append));
		keyAddBaseName (append, "name");
		keySetString (append, pwd->pw_name);
	}
	else
	{
		keyAddBaseName (append, pwd->pw_name);
		keySetBinary (append, 0, 0);
		ksAppendKey (ks, keyDup (append));
		snprintf (id, sizeof (id), "%u", pwd->pw_uid);
		keyAddBaseName (append, "uid");
		keySetString (append, id);
	}
	ksAppendKey (ks, keyDup (append));
	keySetString (append, 0);
	keySetBaseName (append, "shell");
	keySetString (append, pwd->pw_shell);
	ksAppendKey (ks, keyDup (append));
	keySetString (append, 0);
	keySetBaseName (append, "home");
	keySetString (append, pwd->pw_dir);
	ksAppendKey (ks, keyDup (append));
	keySetString (append, 0);
	keySetBaseName (append, "gid");
	snprintf (id, sizeof (id), "%u", pwd->pw_gid);
	keySetString (append, id);
	ksAppendKey (ks, keyDup (append));
	keySetString (append, 0);
	keySetBaseName (append, "passwd");
	keySetString (append, pwd->pw_passwd);
	ksAppendKey (ks, keyDup (append));
	keySetString (append, 0);
	keySetBaseName (append, "gecos");
	keySetString (append, pwd->pw_gecos);
	ksAppendKey (ks, keyDup (append));
	keyDel (append);
	return ks;
}
Exemplo n.º 7
0
static int iniSectionToElektraKey (void *vhandle, const char *section)
{
	CallbackHandle *handle = (CallbackHandle *)vhandle;
	Key *appendKey = keyDup (handle->parentKey);
	keySetMeta(appendKey, "ini/lastSection", 0);
	createUnescapedKey(appendKey, section);
	Key *existingKey = NULL;
	if ((existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE)))
	{
		keyDel(appendKey);
		if(!handle->mergeSections)
		{
			ELEKTRA_SET_ERRORF(140, handle->parentKey, "Section name: %s\n", section);
			return 0;
		}
		keySetMeta(existingKey, "ini/duplicate", "");
		return 1;
	}
	setSectionNumber(handle->parentKey, appendKey, handle->result);
	setOrderNumber(handle->parentKey, appendKey);
	keySetBinary(appendKey, 0, 0);	
	flushCollectedComment (handle, appendKey);
	ksAppendKey(handle->result, appendKey);

	return 1;
}
Exemplo n.º 8
0
static void test_keyValue (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 valueSize = 42;
	void * value = elektraMalloc (valueSize);
	memset (value, 42, valueSize);

	Key * key = keyNew (name, KEY_END);
	keySetBinary (key, value, valueSize);
	ksAppendKey (ks, keyDup (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");
	compare_key (key, found);

	elektraFree (value);
	keyDel (parentKey);
	ksDel (ks);
	keyDel (key);
	closeStoragePlugin (storagePlugin);
}
static void test_enc_and_dec_with_null()
{
	elektraCryptoHandle *handle;
	KeySet *config;
	Key *errorKey = keyNew(KEY_END);

	Key *k = keyNew("user/plugins/crypto/gcrypt/test-enc-dec-null", KEY_END);
	keySetBinary(k, 0, 0);
	succeed_if( keyGetValueSize(k) == 0, "key is not NULL");

	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( keyGetValueSize(k) == 0, "key is not NULL");

	keyDel(k);
	keyDel(errorKey);
	ksDel(config);
	elektraCryptoTeardown();
}
Exemplo n.º 10
0
/**
 * @brief derive the cryptographic key and IV for a given (Elektra) Key k
 * @param config KeySet holding the plugin/backend configuration
 * @param errorKey holds an error description in case of failure
 * @param masterKey holds the decrypted master password from the plugin configuration
 * @param k the (Elektra)-Key to be encrypted
 * @param cKey (Elektra)-Key holding the cryptographic material
 * @param cIv (Elektra)-Key holding the initialization vector
 * @retval -1 on failure. errorKey holds the error description.
 * @retval 1 on success
 */
static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
{
	kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN] = { 0 };
	kdb_octet_t keyBuffer[KEY_BUFFER_SIZE] = { 0 };
	char * saltHexString = NULL;

	ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");

	// generate the salt
	pthread_mutex_lock (&mutex_ssl);
	if (!RAND_bytes (salt, ELEKTRA_CRYPTO_DEFAULT_SALT_LEN - 1))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "failed to generate random salt with error code %lu",
				    ERR_get_error ());
		pthread_mutex_unlock (&mutex_ssl);
		return -1;
	}
	pthread_mutex_unlock (&mutex_ssl);
	saltHexString = ELEKTRA_PLUGIN_FUNCTION (ELEKTRA_PLUGIN_NAME_C, base64Encode) (salt, sizeof (salt));
	if (!saltHexString)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return -1;
	}
	keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString);
	elektraFree (saltHexString);

	// read iteration count
	const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);

	// generate/derive the cryptographic key and the IV
	pthread_mutex_lock (&mutex_ssl);
	if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), salt, sizeof (salt), iterations, KEY_BUFFER_SIZE,
				     keyBuffer))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey,
				    "Failed to create a cryptographic key for encryption. Libcrypto returned error code: %lu",
				    ERR_get_error ());
		pthread_mutex_unlock (&mutex_ssl);
		return -1;
	}
	pthread_mutex_unlock (&mutex_ssl);

	keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE);
	keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE);
	return 1;
}
Exemplo n.º 11
0
/**
 * @brief create new KeySet and add an incomplete configuration to it.
 *
 * The required key "/elektra/modules/crypto/key-derivation/iv" is missing.
 */
static void getIncompleteConfiguration(KeySet **ks)
{
	Key *configKey = keyNew("proc/elektra/modules/crypto/key-derivation/key", KEY_END);
	keySetBinary(configKey, key, sizeof(key));

	(*ks) = ksNew(1,
		configKey,
		KS_END);
}
Exemplo n.º 12
0
KeySet *getNullKeys(void)
{
	Key *k1, *k2;
	KeySet *ks = ksNew(10,
			k1 = keyNew("user/tests/yajl/nullkey",
			       KEY_VALUE, "will be removed",
			       KEY_END),
			k2 = keyNew("user/tests/yajl/second_nullkey",
			       KEY_VALUE, "will be removed too",
			       KEY_END),
			KS_END
		);
	keySetBinary(k1, NULL, 0);
	keySetBinary(k2, NULL, 0);

	ksRewind(ks); // shouldn't that be default?
	return ks;
}
Exemplo n.º 13
0
/**
 * @brief derive the cryptographic key and IV for a given (Elektra) Key k
 * @param config KeySet holding the plugin/backend configuration
 * @param errorKey holds an error description in case of failure
 * @param masterKey holds the decrypted master password from the plugin configuration
 * @param k the (Elektra)-Key to be encrypted
 * @param cKey (Elektra)-Key holding the cryptographic material
 * @param cIv (Elektra)-Key holding the initialization vector
 * @retval -1 on failure. errorKey holds the error description.
 * @retval 1 on success
 */
static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
{
	gcry_error_t gcry_err;
	kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN];
	kdb_octet_t keyBuffer[KEY_BUFFER_SIZE];
	char * saltHexString = NULL;

	ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");

	// generate the salt
	gcry_create_nonce (salt, sizeof (salt));
	const int encodingResult = CRYPTO_PLUGIN_FUNCTION (base64Encode) (errorKey, salt, sizeof (salt), &saltHexString);
	if (encodingResult < 0)
	{
		// error in libinvoke - errorKey has been set by base64Encode
		return -1;
	}
	if (!saltHexString)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return -1;
	}
	keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString);
	elektraFree (saltHexString);

	// read iteration count
	const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);

	// generate/derive the cryptographic key and the IV
	if ((gcry_err = gcry_kdf_derive (keyValue (masterKey), keyGetValueSize (masterKey), GCRY_KDF_PBKDF2, GCRY_MD_SHA512, salt,
					 sizeof (salt), iterations, KEY_BUFFER_SIZE, keyBuffer)))
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey,
				    "Failed to create a cryptographic key for encryption because: %s", gcry_strerror (gcry_err));
		return -1;
	}

	keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_GCRY_KEYSIZE);
	keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_GCRY_KEYSIZE, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	return 1;
}
Exemplo n.º 14
0
void test_type()
{
	Key *key;

	succeed_if (key = keyNew(0), "could not create a new key");
	succeed_if (keyValue(keyGetMeta(key, "binary")) == 0, "wrong type after key creation");
	succeed_if (keySetString (key, "mystring") == sizeof("mystring"), "could not set string");
	succeed_if (keyValue(keyGetMeta(key, "binary")) == 0, "wrong type after setting string");
	succeed_if (keySetBinary (key, "mystring", sizeof("mystring")) == sizeof("mystring"),
			"could not set binary");
	succeed_if (keyValue(keyGetMeta(key, "binary")) != 0, "wrong type after setting string");

	keyDel (key);
}
Exemplo n.º 15
0
/**
 * @internal
 * Add plugin at placement to list plugin configuration and apply it.
 *
 * @param  list      List plugin
 * @param  plugin    Plugin to add
 * @param  placement Placement name
 * @retval 0 on error
 * @retval 0 on success
 */
static int listAddPlugin (Plugin * list, Plugin * plugin, char * placement)
{
	ELEKTRA_NOT_NULL (list);
	ELEKTRA_NOT_NULL (plugin);
	ELEKTRA_NOT_NULL (placement);

	KeySet * newConfig = ksDup (list->config);

	// Find name for next item in plugins array
	Key * configBase = keyNew ("user/plugins", KEY_END);
	KeySet * array = elektraArrayGet (configBase, newConfig);
	Key * pluginItem = elektraArrayGetNextKey (array);
	ELEKTRA_NOT_NULL (pluginItem);
	keySetString (pluginItem, plugin->name);
	keyDel (configBase);

	// Create key with plugin handle
	Key * pluginHandle = keyDup (pluginItem);
	keyAddName (pluginHandle, "handle");
	keySetBinary (pluginHandle, &plugin, sizeof (plugin));

	// Create key with plugin placement
	char * placementType = placementToListPositionType (placement);
	if (placementType == NULL)
	{
		keyDel (configBase);
		keyDel (pluginItem);
		keyDel (pluginHandle);
		return 0;
	}
	Key * pluginPlacements = keyDup (pluginItem);
	keyAddName (pluginPlacements, "placements/");
	keyAddName (pluginPlacements, placementType);
	keySetString (pluginPlacements, placement);

	// Append keys to list plugin configuration
	ksAppendKey (newConfig, pluginItem);
	ksAppendKey (newConfig, pluginHandle);
	ksAppendKey (newConfig, pluginPlacements);

	ksDel (array);
	ksDel (list->config);

	// Apply new configuration
	list->config = newConfig;
	list->kdbOpen (list, NULL);

	return 1;
}
Exemplo n.º 16
0
static int elektraYajlParseNull (void * ctx)
{
	KeySet * ks = (KeySet *)ctx;
	elektraYajlIncrementArrayEntry (ks);

	Key * current = ksCurrent (ks);

	keySetBinary (current, NULL, 0);

#ifdef ELEKTRA_YAJL_VERBOSE
	printf ("elektraYajlParseNull\n");
#endif

	return 1;
}
Exemplo n.º 17
0
void j (Key *k)
{
	size_t size = keyGetValueSize (k);
	char *value = malloc (size);
	int bstring = keyIsString (k);

	// receive key g_c
	memcpy (value, keyValue(k), size);
	keyCopy (k, g_c);
	if (bstring) keySetString (k, value);
	else keySetBinary (k, value, size);
	free (value);
	// the caller will see the changed key k
	// with the metadata from g_c
}
Exemplo n.º 18
0
static void test_gpg (void)
{
	// Plugin configuration
	KeySet * conf = newPluginConfiguration ();
	Key * errorKey = keyNew (0);

	// install the gpg key
	char * argv[] = { "", "-a", "--import", NULL };
	const size_t argc = 4;
	Key * msg = keyNew (0);
	keySetBinary (msg, test_key_asc, test_key_asc_len);

	succeed_if (CRYPTO_PLUGIN_FUNCTION (gpgCall) (conf, errorKey, msg, argv, argc) == 1, "failed to install the GPG test key");

	keyDel (msg);
	keyDel (errorKey);
	ksDel (conf);
}
Exemplo n.º 19
0
void test_ro()
{
	Key *key;

	key = keyNew(KEY_END);
	key->flags |= KEY_FLAG_RO;

	succeed_if (keySetString(key, "a") == -1, "read only string, not allowed to set");
	succeed_if (keySetBinary(key, "a", 2) == -1, "read only string, not allowed to set");
	succeed_if (keySetName(key, "user") == -1, "read only string, not allowed to set");
	succeed_if (keySetMeta(key, "meta", "value") == -1, "read only string, not allowed to set");

	keyDel (key);

	key = keyNew(KEY_END);
	succeed_if (keySetMeta(key, "meta", "value") == sizeof("value"), "could not set meta");

	// TODO check if RO
	keyDel (key);
}
Exemplo n.º 20
0
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();
}
Exemplo n.º 21
0
int elektraCryptoGcryDecrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
{
	kdb_octet_t * value = (kdb_octet_t *)keyValue (k);
	const size_t valueLen = keyGetValueSize (k);

	kdb_octet_t * output;
	kdb_octet_t cipherBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE];
	kdb_octet_t contentBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE];
	kdb_unsigned_long_t written = 0;
	gcry_error_t gcry_err;

	// initialize crypto header data
	kdb_unsigned_long_t contentLen = 0;
	kdb_octet_t flags = ELEKTRA_CRYPTO_FLAG_NONE;

	// check if key has been encrypted in the first place
	const Key * metaEncrypted = keyGetMeta (k, ELEKTRA_CRYPTO_META_ENCRYPT);
	if (metaEncrypted == NULL || strlen (keyValue (metaEncrypted)) == 0)
	{
		// nothing to do
		return 1;
	}

	// plausibility check
	if (valueLen % ELEKTRA_CRYPTO_GCRY_BLOCKSIZE != 0)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "value length is not a multiple of the block size");
		return (-1);
	}

	// prepare buffer for plain text output
	output = elektraMalloc (valueLen);
	if (output == NULL)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return (-1);
	}

	// decrypt the header (1st block)
	memcpy (cipherBuffer, value, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	gcry_err = gcry_cipher_decrypt (*handle, contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Decryption failed because: %s", gcry_strerror (gcry_err));
		elektraFree (output);
		return (-1);
	}

	// restore the header data
	memcpy (&flags, contentBuffer, sizeof (flags));
	memcpy (&contentLen, contentBuffer + sizeof (flags), sizeof (contentLen));

	// decrypt content block by block
	// (i = start of the current block and the 1st block has already been consumed)
	for (kdb_unsigned_long_t i = ELEKTRA_CRYPTO_GCRY_BLOCKSIZE; i < valueLen; i += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE)
	{
		memcpy (cipherBuffer, (value + i), ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		gcry_err = gcry_cipher_decrypt (*handle, contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, cipherBuffer,
						ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		if (gcry_err != 0)
		{
			ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Decryption failed because: %s",
					    gcry_strerror (gcry_err));
			elektraFree (output);
			return (-1);
		}
		memcpy ((output + i - ELEKTRA_CRYPTO_GCRY_BLOCKSIZE), contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		written += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
	}

	if (written < contentLen)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Content was shorter than described in the header");
		elektraFree (output);
		return (-1);
	}

	// write back the cipher text to the key
	if ((flags & ELEKTRA_CRYPTO_FLAG_STRING) == ELEKTRA_CRYPTO_FLAG_STRING)
	{
		keySetString (k, (const char *)output);
	}
	else if ((flags & ELEKTRA_CRYPTO_FLAG_NULL) == ELEKTRA_CRYPTO_FLAG_NULL || contentLen == 0)
	{
		keySetBinary (k, NULL, 0);
	}
	else
	{
		keySetBinary (k, output, contentLen);
	}

	elektraFree (output);
	return 1;
}
Exemplo n.º 22
0
int elektraCryptoGcryEncrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
{
	const kdb_octet_t * value = (kdb_octet_t *)keyValue (k);
	size_t outputLen;
	gcry_error_t gcry_err;

	kdb_octet_t * output;
	kdb_octet_t cipherBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE];
	kdb_octet_t contentBuffer[ELEKTRA_CRYPTO_GCRY_BLOCKSIZE] = { 0 };

	// check if key has been marked for encryption
	const Key * metaEncrypt = keyGetMeta (k, ELEKTRA_CRYPTO_META_ENCRYPT);
	if (metaEncrypt == NULL || strlen (keyValue (metaEncrypt)) == 0)
	{
		// nothing to do
		return 1;
	}

	// prepare the crypto header data
	const kdb_unsigned_long_t contentLen = keyGetValueSize (k);
	kdb_octet_t flags;

	switch (keyIsString (k))
	{
	case 1: // string
		flags = ELEKTRA_CRYPTO_FLAG_STRING;
		break;
	case -1: // NULL pointer
		flags = ELEKTRA_CRYPTO_FLAG_NULL;
		break;
	default: // binary
		flags = ELEKTRA_CRYPTO_FLAG_NONE;
		break;
	}

	// prepare buffer for cipher text output
	// NOTE the header goes into the first block
	if (contentLen % ELEKTRA_CRYPTO_GCRY_BLOCKSIZE == 0)
	{
		outputLen = (contentLen / ELEKTRA_CRYPTO_GCRY_BLOCKSIZE) + 1;
	}
	else
	{
		outputLen = (contentLen / ELEKTRA_CRYPTO_GCRY_BLOCKSIZE) + 2;
	}
	outputLen *= ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
	output = elektraMalloc (outputLen);
	if (output == NULL)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return (-1);
	}

	// encrypt the header (1st block)
	memcpy (contentBuffer, &flags, sizeof (flags));
	memcpy (contentBuffer + sizeof (flags), &contentLen, sizeof (contentLen));
	gcry_err = gcry_cipher_encrypt (*handle, cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, contentBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_ENCRYPT_FAIL, errorKey, "Encryption failed because: %s", gcry_strerror (gcry_err));
		elektraFree (output);
		return (-1);
	}
	memcpy (output, cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);

	// encrypt content block by block (i = start of the current block)
	for (kdb_unsigned_long_t i = 0; i < contentLen; i += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE)
	{
		// load content partition into the content buffer
		kdb_unsigned_long_t partitionLen = ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
		if ((i + 1) * ELEKTRA_CRYPTO_GCRY_BLOCKSIZE > contentLen)
		{
			partitionLen = contentLen - (i * ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		}
		memcpy (contentBuffer, (value + i), partitionLen);

		gcry_err = gcry_cipher_encrypt (*handle, cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, contentBuffer,
						ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
		if (gcry_err != 0)
		{
			ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_ENCRYPT_FAIL, errorKey, "Encryption failed because: %s",
					    gcry_strerror (gcry_err));
			elektraFree (output);
			return (-1);
		}
		memcpy ((output + i + ELEKTRA_CRYPTO_GCRY_BLOCKSIZE), cipherBuffer, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE);
	}

	// write back the cipher text to the key
	keySetBinary (k, output, outputLen);
	elektraFree (output);

	return 1;
}
Exemplo n.º 23
0
int elektraCryptoGcryDecrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
{
	gcry_error_t gcry_err;

	// parse salt length from crypto payload
	kdb_unsigned_long_t saltLen = 0;
	if (CRYPTO_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, NULL, &saltLen) != 1)
	{
		return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromPayload)()
	}
	saltLen += sizeof (kdb_unsigned_long_t);

	// set payload pointer
	const kdb_octet_t * payload = ((kdb_octet_t *) keyValue (k)) + saltLen + ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;
	const size_t payloadLen = keyGetValueSize (k) - saltLen - ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;

	// plausibility check
	if (payloadLen % ELEKTRA_CRYPTO_GCRY_BLOCKSIZE != 0)
	{
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "value length is not a multiple of the block size");
		return -1;
	}

	// prepare buffer for plain text output and crypto operations
	kdb_octet_t * output = elektraMalloc (payloadLen);
	if (!output)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		return -1;
	}

	// initialize crypto header data
	kdb_unsigned_long_t contentLen = 0;
	kdb_octet_t flags = ELEKTRA_CRYPTO_FLAG_NONE;

	// in-place decryption
	memcpy (output, payload, payloadLen);
	gcry_err = gcry_cipher_decrypt (*handle, output, payloadLen, NULL, 0);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey, "Decryption failed because: %s", gcry_strerror (gcry_err));
		memset (output, 0, payloadLen);
		elektraFree (output);
		return -1;
	}

	// restore the header data
	memcpy (&flags, output, sizeof (flags));
	memcpy (&contentLen, output + sizeof (flags), sizeof (contentLen));

	const kdb_octet_t * data = output + ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
	const size_t dataLen = payloadLen - ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;

	// validate restored content length
	if (contentLen > dataLen)
	{
		ELEKTRA_SET_ERROR (
			ELEKTRA_ERROR_CRYPTO_DECRYPT_FAIL, errorKey,
			"restored content length is bigger than the available amount of decrypted data. The header is possibly corrupted.");
		memset (output, 0, payloadLen);
		elektraFree (output);
		return -1;
	}

	// restore the key to its original status
	if ((flags & ELEKTRA_CRYPTO_FLAG_STRING) == ELEKTRA_CRYPTO_FLAG_STRING && contentLen > 0)
	{
		keySetString (k, (const char *) data);
	}
	else if ((flags & ELEKTRA_CRYPTO_FLAG_NULL) == ELEKTRA_CRYPTO_FLAG_NULL || contentLen == 0)
	{
		keySetBinary (k, NULL, 0);
	}
	else
	{
		keySetBinary (k, data, contentLen);
	}

	memset (output, 0, payloadLen);
	elektraFree (output);
	return 1;
}
Exemplo n.º 24
0
int elektraCryptoGcryEncrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
{
	size_t outputLen;
	gcry_error_t gcry_err;

	// prepare the salt for payload output
	kdb_unsigned_long_t saltLen = 0;
	kdb_octet_t * salt = NULL;

	if (CRYPTO_PLUGIN_FUNCTION (getSaltFromMetakey) (errorKey, k, &salt, &saltLen) != 1)
	{
		return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromMetakey)()
	}

	// remove salt as metakey because it will be encoded into the crypto payload
	keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, NULL);

	// prepare the crypto header data
	const kdb_octet_t * content = keyValue (k);
	const kdb_unsigned_long_t contentLen = keyGetValueSize (k);
	kdb_octet_t flags;

	switch (keyIsString (k))
	{
	case 1: // string
		flags = ELEKTRA_CRYPTO_FLAG_STRING;
		break;
	case -1: // NULL pointer
		flags = ELEKTRA_CRYPTO_FLAG_NULL;
		break;
	default: // binary
		flags = ELEKTRA_CRYPTO_FLAG_NONE;
		break;
	}

	// prepare buffer for cipher text output
	// NOTE the header goes into the first block
	if (contentLen % ELEKTRA_CRYPTO_GCRY_BLOCKSIZE == 0)
	{
		outputLen = (contentLen / ELEKTRA_CRYPTO_GCRY_BLOCKSIZE) + 1;
	}
	else
	{
		outputLen = (contentLen / ELEKTRA_CRYPTO_GCRY_BLOCKSIZE) + 2;
	}
	outputLen *= ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;
	outputLen += ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;
	outputLen += sizeof (kdb_unsigned_long_t) + saltLen;
	kdb_octet_t * output = elektraMalloc (outputLen);
	if (!output)
	{
		ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed");
		elektraFree (salt);
		return -1;
	}

	kdb_octet_t * current = output;

	// output of the magic number
	memcpy (current, ELEKTRA_CRYPTO_MAGIC_NUMBER, ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN);
	current += ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;

	// encode the salt into the crypto payload
	memcpy (current, &saltLen, sizeof (kdb_unsigned_long_t));
	current += sizeof (kdb_unsigned_long_t);
	memcpy (current, salt, saltLen);
	current += saltLen;

	// encrypt the header (1st block) using gcrypt's in-place encryption
	memcpy (current, &flags, sizeof (flags));
	memcpy (current + sizeof (flags), &contentLen, sizeof (contentLen));
	gcry_err = gcry_cipher_encrypt (*handle, current, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE, NULL, 0);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_ENCRYPT_FAIL, errorKey, "Encryption failed because: %s", gcry_strerror (gcry_err));
		memset (output, 0, outputLen);
		elektraFree (output);
		elektraFree (salt);
		return -1;
	}
	current += ELEKTRA_CRYPTO_GCRY_BLOCKSIZE;

	// encrypt the value using gcrypt's in-place encryption
	const size_t dataLen =
		outputLen - ELEKTRA_CRYPTO_GCRY_BLOCKSIZE - sizeof (kdb_unsigned_long_t) - saltLen - ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;
	if (contentLen) memcpy (current, content, contentLen);
	gcry_err = gcry_cipher_encrypt (*handle, current, dataLen, NULL, 0);
	if (gcry_err != 0)
	{
		ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_ENCRYPT_FAIL, errorKey, "Encryption failed because: %s", gcry_strerror (gcry_err));
		memset (output, 0, outputLen);
		elektraFree (output);
		elektraFree (salt);
		return -1;
	}

	// write back the cipher text to the key
	keySetBinary (k, output, outputLen);
	memset (output, 0, outputLen);
	elektraFree (output);
	elektraFree (salt);
	return 1;
}