Beispiel #1
0
static void parse_commit_signature(struct format_commit_context *ctx)
{
	struct strbuf payload = STRBUF_INIT;
	struct strbuf signature = STRBUF_INIT;
	struct strbuf gpg_output = STRBUF_INIT;
	int status;

	ctx->commit_signature_parsed = 1;

	if (parse_signed_commit(ctx->commit->object.sha1,
				&payload, &signature) <= 0)
		goto out;
	status = verify_signed_buffer(payload.buf, payload.len,
				      signature.buf, signature.len,
				      &gpg_output);
	if (status && !gpg_output.len)
		goto out;
	ctx->signature.gpg_output = strbuf_detach(&gpg_output, NULL);
	parse_signature_lines(ctx);

 out:
	strbuf_release(&gpg_output);
	strbuf_release(&payload);
	strbuf_release(&signature);
}
Beispiel #2
0
static void prepare_push_cert_sha1(struct child_process *proc)
{
	static int already_done;

	if (!push_cert.len)
		return;

	if (!already_done) {
		struct strbuf gpg_output = STRBUF_INIT;
		struct strbuf gpg_status = STRBUF_INIT;
		int bogs /* beginning_of_gpg_sig */;

		already_done = 1;
		if (write_sha1_file(push_cert.buf, push_cert.len, "blob", push_cert_sha1))
			hashclr(push_cert_sha1);

		memset(&sigcheck, '\0', sizeof(sigcheck));
		sigcheck.result = 'N';

		bogs = parse_signature(push_cert.buf, push_cert.len);
		if (verify_signed_buffer(push_cert.buf, bogs,
					 push_cert.buf + bogs, push_cert.len - bogs,
					 &gpg_output, &gpg_status) < 0) {
			; /* error running gpg */
		} else {
			sigcheck.payload = push_cert.buf;
			sigcheck.gpg_output = gpg_output.buf;
			sigcheck.gpg_status = gpg_status.buf;
			parse_gpg_output(&sigcheck);
		}

		strbuf_release(&gpg_output);
		strbuf_release(&gpg_status);
		nonce_status = check_nonce(push_cert.buf, bogs);
	}
	if (!is_null_sha1(push_cert_sha1)) {
		argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s",
				 sha1_to_hex(push_cert_sha1));
		argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s",
				 sigcheck.signer ? sigcheck.signer : "");
		argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s",
				 sigcheck.key ? sigcheck.key : "");
		argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c",
				 sigcheck.result);
		if (push_cert_nonce) {
			argv_array_pushf(&proc->env_array,
					 "GIT_PUSH_CERT_NONCE=%s",
					 push_cert_nonce);
			argv_array_pushf(&proc->env_array,
					 "GIT_PUSH_CERT_NONCE_STATUS=%s",
					 nonce_status);
			if (nonce_status == NONCE_SLOP)
				argv_array_pushf(&proc->env_array,
						 "GIT_PUSH_CERT_NONCE_SLOP=%ld",
						 nonce_stamp_slop);
		}
	}
}
Beispiel #3
0
static void fmt_merge_msg_sigs(struct strbuf *out)
{
	int i, tag_number = 0, first_tag = 0;
	struct strbuf tagbuf = STRBUF_INIT;

	for (i = 0; i < origins.nr; i++) {
		unsigned char *sha1 = origins.items[i].util;
		enum object_type type;
		unsigned long size, len;
		char *buf = read_sha1_file(sha1, &type, &size);
		struct strbuf sig = STRBUF_INIT;

		if (!buf || type != OBJ_TAG)
			goto next;
		len = parse_signature(buf, size);

		if (size == len)
			; /* merely annotated */
		else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig, NULL)) {
			if (!sig.len)
				strbuf_addstr(&sig, "gpg verification failed.\n");
		}

		if (!tag_number++) {
			fmt_tag_signature(&tagbuf, &sig, buf, len);
			first_tag = i;
		} else {
			if (tag_number == 2) {
				struct strbuf tagline = STRBUF_INIT;
				strbuf_addch(&tagline, '\n');
				strbuf_add_commented_lines(&tagline,
						origins.items[first_tag].string,
						strlen(origins.items[first_tag].string));
				strbuf_insert(&tagbuf, 0, tagline.buf,
					      tagline.len);
				strbuf_release(&tagline);
			}
			strbuf_addch(&tagbuf, '\n');
			strbuf_add_commented_lines(&tagbuf,
					origins.items[i].string,
					strlen(origins.items[i].string));
			fmt_tag_signature(&tagbuf, &sig, buf, len);
		}
		strbuf_release(&sig);
	next:
		free(buf);
	}
	if (tagbuf.len) {
		strbuf_addch(out, '\n');
		strbuf_addbuf(out, &tagbuf);
	}
	strbuf_release(&tagbuf);
}
Beispiel #4
0
static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
{
	int len;

	len = parse_signature(buf, size);
	if (verbose)
		write_in_full(1, buf, len);

	if (size == len)
		return error("no signature found");

	return verify_signed_buffer(buf, len, buf + len, size - len, NULL);
}
Beispiel #5
0
static void show_one_mergetag(struct rev_info *opt,
			      struct commit_extra_header *extra,
			      struct commit *commit)
{
	unsigned char sha1[20];
	struct tag *tag;
	struct strbuf verify_message;
	int status, nth;
	size_t payload_size, gpg_message_offset;

	hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1);
	tag = lookup_tag(sha1);
	if (!tag)
		return; /* error message already given */

	strbuf_init(&verify_message, 256);
	if (parse_tag_buffer(tag, extra->value, extra->len))
		strbuf_addstr(&verify_message, "malformed mergetag\n");
	else if (is_common_merge(commit) &&
		 !hashcmp(tag->tagged->sha1,
			  commit->parents->next->item->object.sha1))
		strbuf_addf(&verify_message,
			    "merged tag '%s'\n", tag->tag);
	else if ((nth = which_parent(tag->tagged->sha1, commit)) < 0)
		strbuf_addf(&verify_message, "tag %s names a non-parent %s\n",
				    tag->tag, tag->tagged->sha1);
	else
		strbuf_addf(&verify_message,
			    "parent #%d, tagged '%s'\n", nth + 1, tag->tag);
	gpg_message_offset = verify_message.len;

	payload_size = parse_signature(extra->value, extra->len);
	if ((extra->len <= payload_size) ||
	    (verify_signed_buffer(extra->value, payload_size,
				  extra->value + payload_size,
				  extra->len - payload_size,
				  &verify_message) &&
	     verify_message.len <= gpg_message_offset)) {
		strbuf_addstr(&verify_message, "No signature\n");
		status = -1;
	}
	else if (strstr(verify_message.buf + gpg_message_offset,
			": Good signature from "))
		status = 0;
	else
		status = -1;

	show_sig_lines(opt, status, verify_message.buf);
	strbuf_release(&verify_message);
}
Beispiel #6
0
static void show_one_mergetag(struct commit *commit,
			      struct commit_extra_header *extra,
			      void *data)
{
	struct rev_info *opt = (struct rev_info *)data;
	unsigned char sha1[20];
	struct tag *tag;
	struct strbuf verify_message;
	int status, nth;
	size_t payload_size, gpg_message_offset;

	hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1);
	tag = lookup_tag(sha1);
	if (!tag)
		return; /* error message already given */

	strbuf_init(&verify_message, 256);
	if (parse_tag_buffer(tag, extra->value, extra->len))
		strbuf_addstr(&verify_message, "malformed mergetag\n");
	else if (is_common_merge(commit) &&
		 !oidcmp(&tag->tagged->oid,
			  &commit->parents->next->item->object.oid))
		strbuf_addf(&verify_message,
			    "merged tag '%s'\n", tag->tag);
	else if ((nth = which_parent(tag->tagged->oid.hash, commit)) < 0)
		strbuf_addf(&verify_message, "tag %s names a non-parent %s\n",
				    tag->tag, tag->tagged->oid.hash);
	else
		strbuf_addf(&verify_message,
			    "parent #%d, tagged '%s'\n", nth + 1, tag->tag);
	gpg_message_offset = verify_message.len;

	payload_size = parse_signature(extra->value, extra->len);
	status = -1;
	if (extra->len > payload_size) {
		/* could have a good signature */
		if (!verify_signed_buffer(extra->value, payload_size,
					  extra->value + payload_size,
					  extra->len - payload_size,
					  &verify_message, NULL))
			status = 0; /* good */
		else if (verify_message.len <= gpg_message_offset)
			strbuf_addstr(&verify_message, "No signature\n");
		/* otherwise we couldn't verify, which is shown as bad */
	}

	show_sig_lines(opt, status, verify_message.buf);
	strbuf_release(&verify_message);
}
Beispiel #7
0
static void show_signature(struct rev_info *opt, struct commit *commit)
{
	struct strbuf payload = STRBUF_INIT;
	struct strbuf signature = STRBUF_INIT;
	struct strbuf gpg_output = STRBUF_INIT;
	int status;

	if (parse_signed_commit(commit->object.sha1, &payload, &signature) <= 0)
		goto out;

	status = verify_signed_buffer(payload.buf, payload.len,
				      signature.buf, signature.len,
				      &gpg_output);
	if (status && !gpg_output.len)
		strbuf_addstr(&gpg_output, "No signature\n");

	show_sig_lines(opt, status, gpg_output.buf);

 out:
	strbuf_release(&gpg_output);
	strbuf_release(&payload);
	strbuf_release(&signature);
}
Beispiel #8
0
int check_signature(const char *payload, size_t plen, const char *signature,
	size_t slen, struct signature_check *sigc)
{
	struct strbuf gpg_output = STRBUF_INIT;
	struct strbuf gpg_status = STRBUF_INIT;
	int status;

	sigc->result = 'N';

	status = verify_signed_buffer(payload, plen, signature, slen,
				      &gpg_output, &gpg_status);
	if (status && !gpg_output.len)
		goto out;
	sigc->payload = xmemdupz(payload, plen);
	sigc->gpg_output = strbuf_detach(&gpg_output, NULL);
	sigc->gpg_status = strbuf_detach(&gpg_status, NULL);
	parse_gpg_output(sigc);

 out:
	strbuf_release(&gpg_status);
	strbuf_release(&gpg_output);

	return sigc->result != 'G' && sigc->result != 'U';
}