Beispiel #1
0
int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset)
{
	git_signature *p = NULL;

	assert(name && email);

	*sig_out = NULL;

	if (contains_angle_brackets(name) ||
		contains_angle_brackets(email)) {
		return signature_error(
			"Neither `name` nor `email` should contain angle brackets chars.");
	}

	p = git__calloc(1, sizeof(git_signature));
	GITERR_CHECK_ALLOC(p);

	p->name = extract_trimmed(name, strlen(name));
	GITERR_CHECK_ALLOC(p->name);
	p->email = extract_trimmed(email, strlen(email));
	GITERR_CHECK_ALLOC(p->email);

	if (p->name[0] == '\0' || p->email[0] == '\0') {
		git_signature_free(p);
		return signature_error("Signature cannot have an empty name or email");
	}

	p->when.time = time;
	p->when.offset = offset;

	*sig_out = p;
	return 0;
}
Beispiel #2
0
static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty)
{
	const char *left, *right;
	size_t trimmed_input_length;

	assert(storage);

	left = skip_leading_spaces(input, input_end);
	right = skip_trailing_spaces(input, input_end - 1);

	if (right < left) {
		if (fail_when_empty)
			return signature_error("input is either empty of contains only spaces");

		right = left - 1;
	}

	trimmed_input_length = right - left + 1;

	*storage = git__malloc(trimmed_input_length + 1);
	GITERR_CHECK_ALLOC(*storage);

	memcpy(*storage, left, trimmed_input_length);
	(*storage)[trimmed_input_length] = 0;

	return 0;
}
Beispiel #3
0
int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset)
{
	git_signature *p = NULL;

	assert(name && email);

	*sig_out = NULL;

	p = git__calloc(1, sizeof(git_signature));
	GITERR_CHECK_ALLOC(p);

	if (process_trimming(name, &p->name, name + strlen(name), 1) < 0 ||
		process_trimming(email, &p->email, email + strlen(email), 1) < 0)
	{
		git_signature_free(p);
		return -1;
	}
		
	if (contains_angle_brackets(p->email) ||
		contains_angle_brackets(p->name))
	{
		git_signature_free(p);
		return signature_error("Neither `name` nor `email` should contain angle brackets chars.");
	}

	p->when.time = time;
	p->when.offset = offset;

	*sig_out = p;

	return 0;
}
SignedMeta::SignedMeta(std::vector<uint8_t> raw_meta, std::vector<uint8_t> signature, const Secret& secret, bool check_signature) :
	raw_meta_(std::make_shared<std::vector<uint8_t>>(std::move(raw_meta))),
	signature_(std::make_shared<std::vector<uint8_t>>(std::move(signature))) {

	if(check_signature) {
		try {
			CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA3_256>::Verifier verifier;
			CryptoPP::ECP::Point p;

			verifier.AccessKey().AccessGroupParameters().Initialize(CryptoPP::ASN1::secp256r1());
			verifier.AccessKey().AccessGroupParameters().SetPointCompression(true);
			verifier.AccessKey().GetGroupParameters().GetCurve().DecodePoint(p, secret.get_Public_Key().data(), secret.get_Public_Key().size());
			verifier.AccessKey().SetPublicElement(p);
			if(! verifier.VerifyMessage(raw_meta_->data(), raw_meta_->size(), signature_->data(), signature_->size()))
				throw signature_error();
		}catch(CryptoPP::Exception& e){
			throw signature_error();
		}
	}

	meta_ = std::make_shared<Meta>(*raw_meta_);
}
Beispiel #5
0
int git_signature__parse(git_signature *sig, const char **buffer_out,
		const char *buffer_end, const char *header, char ender)
{
	const char *buffer = *buffer_out;
	const char *email_start, *email_end;

	memset(sig, 0, sizeof(git_signature));

	if ((buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL)
		return signature_error("no newline given");

	if (header) {
		const size_t header_len = strlen(header);

		if (buffer + header_len >= buffer_end || memcmp(buffer, header, header_len) != 0)
			return signature_error("expected prefix doesn't match actual");

		buffer += header_len;
	}

	email_start = git__memrchr(buffer, '<', buffer_end - buffer);
	email_end = git__memrchr(buffer, '>', buffer_end - buffer);

	if (!email_start || !email_end || email_end <= email_start)
		return signature_error("malformed e-mail");

	email_start += 1;
	sig->name = extract_trimmed(buffer, email_start - buffer - 1);
	sig->email = extract_trimmed(email_start, email_end - email_start);

	/* Do we even have a time at the end of the signature? */
	if (email_end + 2 < buffer_end) {
		const char *time_start = email_end + 2;
		const char *time_end;

		if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0)
			return signature_error("invalid Unix timestamp");

		/* do we have a timezone? */
		if (time_end + 1 < buffer_end) {
			int offset, hours, mins;
			const char *tz_start, *tz_end;

			tz_start = time_end + 1;

			if ((tz_start[0] != '-' && tz_start[0] != '+') ||
				git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0) {
				//malformed timezone, just assume it's zero
				offset = 0;
			}

			hours = offset / 100;
			mins = offset % 100;

			/*
			 * only store timezone if it's not overflowing;
			 * see http://www.worldtimezone.com/faq.html
			 */
			if (hours < 14 && mins < 59) {
				sig->when.offset = (hours * 60) + mins;
				if (tz_start[0] == '-')
					sig->when.offset = -sig->when.offset;
			}
		}
	}

	*buffer_out = buffer_end + 1;
	return 0;
}