예제 #1
0
static void testDynArray (void)
{
	size_t testData[] = { 8466, 2651, 6624, 9575, 4628, 9361, 417,  8932, 4570, 343,  1866, 3135, 6617, 344,  9419, 2094, 5623,
			      4920, 2209, 8037, 8437, 7955, 5575, 8355, 1133, 6527, 8543, 3338, 1772, 2278, 7446, 8834, 7728, 665,
			      8519, 6079, 5060, 7429, 3843, 6923, 4073, 2245, 2784, 6620, 2887, 8497, 9360, 5752, 3195, 538,  1491,
			      8087, 8378, 5746, 4961, 5499, 8050, 2138, 1196, 1860, 4372, 6553, 4530, 8828, 4017, 9934, 3,    6274,
			      4405, 5021, 3416, 854,  4635, 9902, 5383, 7947, 5210, 8242, 1928, 3792, 7234, 759,  6571, 9514, 8451,
			      918,  9958, 1577, 96,   8644, 6815, 5584, 8585, 1252, 808,  5695, 910,  4157, 701,  77 };

	DynArray * dynArray = ELEKTRA_PLUGIN_FUNCTION (mmapstorage, dynArrayNew) ();

	for (size_t i = 0; i < 100; ++i)
	{
		ELEKTRA_PLUGIN_FUNCTION (mmapstorage, dynArrayFindOrInsert) ((Key *) testData[i], dynArray);
	}

	qsort (testData, 100, sizeof (size_t), cmpfunc);

	int error = 0;
	for (size_t i = 0; i < 100; ++i)
	{
		if (testData[i] != (size_t) dynArray->keyArray[i])
		{
			++error;
		}
	}

	succeed_if (error == 0, "dynArray does not sort array properly");

	ELEKTRA_PLUGIN_FUNCTION (mmapstorage, dynArrayDelete) (dynArray);
}
예제 #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 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;
}
예제 #3
0
static int fcryptGpgCallAndCleanup (Key * parentKey, KeySet * pluginConfig, char ** argv, int argc, int tmpFileFd, char * tmpFile)
{
	int parentKeyFd = -1;
	int result = ELEKTRA_PLUGIN_FUNCTION (gpgCall) (pluginConfig, parentKey, NULL, argv, argc);

	if (result == 1)
	{
		parentKeyFd = open (keyString (parentKey), O_WRONLY);

		// gpg call returned success, overwrite the original file with the gpg payload data
		if (rename (tmpFile, keyString (parentKey)) != 0)
		{
			ELEKTRA_SET_ERRORF (31, parentKey, "Renaming file %s to %s failed.", tmpFile, keyString (parentKey));
			result = -1;
		}
	}

	if (result == 1)
	{
		if (parentKeyFd >= 0)
		{
			shredTemporaryFile (parentKeyFd, parentKey);
		}
	}
	else
	{
		// if anything went wrong above the temporary file is shredded and removed
		shredTemporaryFile (tmpFileFd, parentKey);
		if (unlink (tmpFile))
		{
			ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_UNLINK, parentKey, "Affected file: %s, error description: %s", tmpFile,
					      strerror (errno));
		}
	}

	if (parentKeyFd >= 0 && close (parentKeyFd))
	{
		ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno));
	}
	if (close (tmpFileFd))
	{
		ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno));
	}
	elektraFree (tmpFile);
	return result;
}
예제 #4
0
static int gpg_available (KeySet * conf)
{
	int available = 0;
	char * gpgPath = NULL;
	Key * parentKey = keyNew ("system", KEY_END);

	int gpg_search_result = ELEKTRA_PLUGIN_FUNCTION (gpgGetBinary) (&gpgPath, conf, parentKey);
	if (gpg_search_result == 1)
	{
		available = 1;
	}

	if (gpgPath)
	{
		elektraFree (gpgPath);
	}
	keyDel (parentKey);
	ksDel (conf);
	return available;
}
예제 #5
0
/**
 * @brief decrypt the file specified at parentKey
 * @param pluginConfig holds the plugin configuration
 * @param parentKey holds the path to the file to be encrypted. Will hold an error description in case of failure.
 * @param state holds the plugin state
 * @retval 1 on success
 * @retval -1 on error, errorKey holds an error description
 */
static int fcryptDecrypt (KeySet * pluginConfig, Key * parentKey, fcryptState * state)
{
	int tmpFileFd = -1;
	char * tmpFile = getTemporaryFileName (pluginConfig, keyString (parentKey), &tmpFileFd);
	if (!tmpFile)
	{
		ELEKTRA_SET_ERROR (87, parentKey, "Memory allocation failed");
		return -1;
	}

	const size_t testMode = inTestMode (pluginConfig);

	// prepare argument vector for gpg call
	// 8 static arguments (magic number below) are:
	//   1. path to the binary
	//   2. --batch
	//   3. -o
	//   4. path to tmp file
	//   5. yes
	//   6. -d
	//   7. file to be encrypted
	//   8. NULL terminator
	int argc = 8 + (2 * testMode);
	char * argv[argc];
	int i = 0;

	argv[i++] = NULL;
	argv[i++] = "--batch";
	argv[i++] = "--yes";

	// if we are in test mode we add the trust model
	if (testMode)
	{
		argv[i++] = "--trust-model";
		argv[i++] = "always";
	}

	argv[i++] = "-o";
	argv[i++] = tmpFile;
	argv[i++] = "-d";
	// safely discarding const from keyString() return value
	argv[i++] = (char *) keyString (parentKey);
	argv[i++] = NULL;

	// NOTE the decryption process works like this:
	// gpg2 --batch --yes -o tmpfile -d configFile
	int result = ELEKTRA_PLUGIN_FUNCTION (gpgCall) (pluginConfig, parentKey, NULL, argv, argc);
	if (result == 1)
	{
		state->originalFilePath = elektraStrDup (keyString (parentKey));
		state->tmpFilePath = tmpFile;
		state->tmpFileFd = tmpFileFd;
		keySetString (parentKey, tmpFile);
	}
	else
	{
		// if anything went wrong above the temporary file is shredded and removed
		shredTemporaryFile (tmpFileFd, parentKey);
		if (unlink (tmpFile))
		{
			ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_UNLINK, parentKey, "Affected file: %s, error description: %s", tmpFile,
					      strerror (errno));
		}
		if (close (tmpFileFd))
		{
			ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno));
		}
		elektraFree (tmpFile);
	}
	return result;
}
void test_checkfile()
{
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("valid") == 1, "valid file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("/valid") == 0, "valid absolute file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("/absolute/valid") == 0, "valid absolute file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("../valid") == -1, "invalid file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("valid/..") == -1, "invalid file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("/../valid") == -1, "invalid absolute file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("/valid/..") == -1, "invalid absolute file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("very..strict") == -1, "resolver is currently very strict");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("very/..strict") == -1, "resolver is currently very strict");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("very../strict") == -1, "resolver is currently very strict");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("very/../strict") == -1, "resolver is currently very strict");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("/") == -1, "invalid absolute file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)(".") == -1, "invalid file not recognised");
	succeed_if (ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)("..") == -1, "invalid file not recognised");
}