Ejemplo n.º 1
0
static int test_sign(const char *private_key, const char *public_key, bool success)
{
	char *sig = NULL;
	char *file = NULL;
	int ret = -1;

	sig = str_or_die("%s/sig", test_dir);
	file = __FILE__;

	if (sign(private_key, public_key, file, sig) < 0) {
		goto error;
	}

	if (!signature_init(public_key, NULL)) {
		goto error;
	}

	// Check if signature match
	check_goto(signature_verify(file, sig, false) == success, error);

	// Check signature against wrong file
	check_goto(signature_verify(sig, sig, false) == false, error);

	ret = 0;

error:
	signature_deinit();
	free(sig);
	return ret;
}
Ejemplo n.º 2
0
/*Run a benchmark with different curve parameters and print CSV result to out
 *Comma-Separated Values (CSV), RFC 4180: http://tools.ietf.org/html/rfc4180 */
void benchmark(FILE* out, int i)
{
	//Print CSV header
	fprintf(out, "Curve, Public key generation time, Signature generation time, Signature verification time, Operation time\r\n");

	//If the illiterator is invalid use default illiterator
	if(i < 1)
		i = DEFAULT_TEST_ILLITERATOR;	

	//Loop through all curves, since we're benchmarking them towards eachother.
	int curve_i;
	for(curve_i = 0;curve_i < NUMBER_OF_CURVES;curve_i++)
	{
		//Set initial timer
		clock_t start = clock();

		int test_i;

		//Load curve
		domain_parameters curve = domain_parameters_init();
		domain_parameters_load_curve(curve, curve_i);

		//Print curve name
		fprintf(out, "%s, ", curve->name);

		//Get a private key
		mpz_t d;mpz_init(d);
		mpz_sub_ui(d, curve->n, 2);	//Private key must be between 1 and n-1

		//Get a message to sign
		mpz_t m;mpz_init(m);
		mpz_sub_ui(m, curve->n, 2);	//Must be between 1 and n-1
		//NOTE: I assume we're using a hash algorithm giving result with the biggest bit-length possible

		//Initialize a signature
		signature sig = signature_init();

		//Initialize public key
		point Q = point_init();

		//Save time at the start of public key generation
		clock_t start_gen_Q = clock();

		//Generate public key
		for(test_i = 0; test_i < i; test_i++)		
			signature_generate_key(Q, d, curve);

		//Save time between public key generation and signature generation
		clock_t start_sign = clock();

		//Generate signature
		for(test_i = 0; test_i < i; test_i++)
			signature_sign(sig, m, d, curve);

		//Save time between signature generation and signature verification
		clock_t start_verify = clock();

		//Verify signature
		bool result;
		for(test_i = 0; test_i < i; test_i++)
			result = signature_verify(m, sig, Q, curve);

		//Save time after verification
		clock_t end_verify = clock();

		//Clear variables
		mpz_clear(d);
		domain_parameters_clear(curve);
		signature_clear(sig);
		mpz_clear(m);

		//Save time before printing
		clock_t end = clock();

		//Print public key generation time
		fprintf(out, "%.4f, ", ((double) (start_sign - start_gen_Q)) / CLOCKS_PER_SEC);

		//Print signature generation time
		fprintf(out, "%.4f, ", ((double) (start_verify - start_sign)) / CLOCKS_PER_SEC);

		//Print signature verification time
		fprintf(out, "%.4f, ", ((double) (end_verify - start_verify)) / CLOCKS_PER_SEC);

		//Print operation time
		if(result)
			fprintf(out, "%.4f", ((double) (end - start)) / CLOCKS_PER_SEC);
		else
			fprintf(out, "-1");

		//print a new line
		fprintf(out, "\r\n");	//Acoording to RFC4180 this must be done with CLRF
	}
}
Ejemplo n.º 3
0
retvalue signature_requirement_add(struct signature_requirement **list_p, const char *condition) {
	struct signature_requirement *req;
	const char *full_condition = condition;
	retvalue r;

	r = signature_init(false);
	if (RET_WAS_ERROR(r))
		return r;

	if (condition == NULL || strcmp(condition, "blindtrust") == 0)
		return RET_NOTHING;

	/* no need to add the same condition multiple times */
	for (req = *list_p ; req != NULL ; req = req->next) {
		if (strcmp(req->condition, condition) == 0)
			return RET_NOTHING;
	}

	req = malloc(sizeof_requirement(1));
	if (FAILEDTOALLOC(req))
		return RET_ERROR_OOM;
	req->next = NULL;
	req->condition = strdup(condition);
	if (FAILEDTOALLOC(req->condition)) {
		free(req);
		return RET_ERROR_OOM;
	}
	req->num_keys = 0;
	do {
		bool allow_subkeys, allow_bad;
		char *next_key IFSTUPIDCC(=NULL);

		r = parse_condition_part(&allow_subkeys, &allow_bad,
				full_condition, &condition, &next_key);
		ASSERT_NOT_NOTHING(r);
		if (RET_WAS_ERROR(r)) {
			signature_requirements_free(req);
			return r;
		}
		req->keys[req->num_keys].allow_bad = allow_bad;
		r = load_key(next_key, allow_subkeys, allow_bad,
				full_condition,
				&req->keys[req->num_keys].key,
				&req->keys[req->num_keys].subkey);
		free(next_key);
		if (RET_WAS_ERROR(r)) {
			signature_requirements_free(req);
			return r;
		}
		req->num_keys++;

		if (*condition != '\0') {
			struct signature_requirement *h;

			h = realloc(req, sizeof_requirement(req->num_keys+1));
			if (FAILEDTOALLOC(h)) {
				signature_requirements_free(req);
				return r;
			}
			req = h;
		} else
			break;
	} while (true);
	req->next = *list_p;
	*list_p = req;
	return RET_OK;
}
Ejemplo n.º 4
0
static retvalue extract_signed_data(const char *buffer, size_t bufferlen, const char *filenametoshow, char **chunkread, /*@null@*/ /*@out@*/struct signatures **signatures_p, bool *brokensignature) {
	char *chunk;
	gpg_error_t err;
	gpgme_data_t dh, dh_gpg;
	size_t plain_len;
	char *plain_data;
	retvalue r;
	struct signatures *signatures = NULL;
	bool foundbroken = false;

	r = signature_init(false);
	if (RET_WAS_ERROR(r))
		return r;

	err = gpgme_data_new_from_mem(&dh_gpg, buffer, bufferlen, 0);
	if (err != 0)
		return gpgerror(err);

	err = gpgme_data_new(&dh);
	if (err != 0) {
		gpgme_data_release(dh_gpg);
		return gpgerror(err);
	}
	err = gpgme_op_verify(context, dh_gpg, NULL, dh);
	if (gpg_err_code(err) == GPG_ERR_NO_DATA) {
		if (verbose > 5)
			fprintf(stderr,
"Data seems not to be signed trying to use directly....\n");
		gpgme_data_release(dh);
		gpgme_data_release(dh_gpg);
		return RET_NOTHING;
	} else {
		if (err != 0) {
			gpgme_data_release(dh_gpg);
			gpgme_data_release(dh);
			return gpgerror(err);
		}
		if (signatures_p != NULL || brokensignature != NULL) {
			r = checksigs(filenametoshow,
				(signatures_p!=NULL)?&signatures:NULL,
				(brokensignature!=NULL)?&foundbroken:NULL);
			if (RET_WAS_ERROR(r)) {
				gpgme_data_release(dh_gpg);
				gpgme_data_release(dh);
				return r;
			}
		}
		gpgme_data_release(dh_gpg);
		plain_data = gpgme_data_release_and_get_mem(dh, &plain_len);
		if (plain_data == NULL) {
			fprintf(stderr,
"(not yet fatal) ERROR: libgpgme failed to extract the plain data out of\n"
"'%s'.\n"
"While it did so in a way indicating running out of memory, experience says\n"
"this also happens when gpg returns a error code it does not understand.\n"
"To check this please try running gpg --verify '%s' manually.\n"
"Continuing extracting it ignoring all signatures...",
					filenametoshow, filenametoshow);
			signatures_free(signatures);
			return RET_NOTHING;
		}
		if (signatures != NULL) {
			r = check_primary_keys(signatures);
			if (RET_WAS_ERROR(r)) {
				signatures_free(signatures);
				return r;
			}
		}
	}

	if (FAILEDTOALLOC(plain_data))
		r = RET_ERROR_OOM;
	else {
		size_t len;
		const char *afterchanges;

		chunk = malloc(plain_len + 1);
		len = chunk_extract(chunk, plain_data, plain_len, false,
				&afterchanges);
		if (len == 0) {
			fprintf(stderr,
"Could only find spaces within '%s'!\n",
					filenametoshow);
			free(chunk);
			r = RET_ERROR;
		} else if (afterchanges != plain_data + plain_len) {
			if (*afterchanges == '\0')
				fprintf(stderr,
"Unexpected \\0 character within '%s'!\n",
					filenametoshow);
			else
				fprintf(stderr,
"Unexpected data after ending empty line in '%s'!\n",
					filenametoshow);
			free(chunk);
			r = RET_ERROR;
		} else
			*chunkread = chunk;
	}
#ifdef HAVE_GPGPME_FREE
	gpgme_free(plain_data);
#else
	free(plain_data);
#endif
	if (RET_IS_OK(r)) {
		if (signatures_p != NULL)
			*signatures_p = signatures;
		if (brokensignature != NULL)
			*brokensignature = foundbroken;
	} else {
		signatures_free(signatures);
	}
	return r;
}