Exemplo n.º 1
0
static inline retvalue verify_signature(const struct signature_requirement *requirements, const char *releasegpg, const char *releasename) {
	gpgme_verify_result_t result;
	int i;
	const struct signature_requirement *req;

	result = gpgme_op_verify_result(context);
	if (result == NULL) {
		fprintf(stderr,
"Internal error communicating with libgpgme: no result record!\n\n");
		return RET_ERROR_GPGME;
	}

	for (req = requirements ; req != NULL ; req = req->next) {
		bool fullfilled = false;

		/* check first for good signatures, and then for good enough
		   signatures, to not pester the user with warnings of one
		   of the alternate keys, if the last one is good enough */

		for (i = 0 ; (size_t)i < req->num_keys ; i++) {

			if (key_good(&req->keys[i], result->signatures)) {
				fullfilled = true;
				break;
			}
		}
		for (i = 0 ; !fullfilled && (size_t)i < req->num_keys ; i++) {

			if (key_good_enough(&req->keys[i], result->signatures,
						releasegpg, releasename)) {
				fullfilled = true;
				break;
			}
		}
		if (!fullfilled) {
			fprintf(stderr,
"ERROR: Condition '%s' not fullfilled for '%s'.\n",
					req->condition, releasegpg);
			print_signatures(stderr, result->signatures,
					releasegpg);
			return RET_ERROR_BADSIG;
		}
		if (verbose > 10) {
			fprintf(stdout, "Condition '%s' fullfilled for '%s'.\n",
					req->condition, releasegpg);
		}
	}
	if (verbose > 20)
		print_signatures(stdout, result->signatures, releasegpg);
	return RET_OK;
}
Exemplo n.º 2
0
retvalue signature_check(const struct signature_requirement *requirements, const char *releasegpg, const char *release) {
	gpg_error_t err;
	int fd, gpgfd;
	gpgme_data_t dh, dh_gpg;
	gpgme_verify_result_t result;
	int i;
	const struct signature_requirement *req;

	assert (requirements != NULL);

	if (FAILEDTOALLOC(release) || FAILEDTOALLOC(releasegpg))
		return RET_ERROR_OOM;

	assert (context != NULL);

	/* Read the file and its signature into memory: */
	gpgfd = open(releasegpg, O_RDONLY|O_NOCTTY);
	if (gpgfd < 0) {
		int e = errno;
		fprintf(stderr, "Error opening '%s': %s\n",
				releasegpg, strerror(e));
		return RET_ERRNO(e);
	}
	fd = open(release, O_RDONLY|O_NOCTTY);
	if (fd < 0) {
		int e = errno;
		(void)close(gpgfd);
		fprintf(stderr, "Error opening '%s': %s\n",
			       release, strerror(e));
		return RET_ERRNO(e);
	}
	err = gpgme_data_new_from_fd(&dh_gpg, gpgfd);
	if (err != 0) {
		(void)close(gpgfd); (void)close(fd);
		fprintf(stderr, "Error reading '%s':\n", releasegpg);
		return gpgerror(err);
	}
	err = gpgme_data_new_from_fd(&dh, fd);
	if (err != 0) {
		gpgme_data_release(dh_gpg);
		(void)close(gpgfd); (void)close(fd);
		fprintf(stderr, "Error reading '%s':\n", release);
		return gpgerror(err);
	}

	/* Verify the signature */

	err = gpgme_op_verify(context, dh_gpg, dh, NULL);
	gpgme_data_release(dh_gpg);
	gpgme_data_release(dh);
	close(gpgfd); close(fd);
	if (err != 0) {
		fprintf(stderr, "Error verifying '%s':\n", releasegpg);
		return gpgerror(err);
	}

	result = gpgme_op_verify_result(context);
	if (result == NULL) {
		fprintf(stderr,
"Internal error communicating with libgpgme: no result record!\n\n");
		return RET_ERROR_GPGME;
	}

	for (req = requirements ; req != NULL ; req = req->next) {
		bool fullfilled = false;

		/* check first for good signatures, and then for good enough
		   signatures, to not pester the user with warnings of one
		   of the alternate keys, if the last one is good enough */

		for (i = 0 ; (size_t)i < req->num_keys ; i++) {

			if (key_good(&req->keys[i], result->signatures)) {
				fullfilled = true;
				break;
			}
		}
		for (i = 0 ; !fullfilled && (size_t)i < req->num_keys ; i++) {

			if (key_good_enough(&req->keys[i], result->signatures,
						releasegpg, release)) {
				fullfilled = true;
				break;
			}
		}
		if (!fullfilled) {
			fprintf(stderr,
"ERROR: Condition '%s' not fullfilled for '%s'.\n",
					req->condition, releasegpg);
			print_signatures(stderr, result->signatures,
					releasegpg);
			return RET_ERROR_BADSIG;
		}
		if (verbose > 10) {
			fprintf(stdout, "Condition '%s' fullfilled for '%s'.\n",
					req->condition, releasegpg);
		}
	}
	if (verbose > 20)
		print_signatures(stdout, result->signatures, releasegpg);
	return RET_OK;
}