예제 #1
0
static int get_sha1_1(const char *name, int len, unsigned char *sha1)
{
	int parent, ret;
	const char *cp;

	/* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
	if (len > 2 && name[len-2] == '^' &&
	    name[len-1] >= '0' && name[len-1] <= '9') {
		parent = name[len-1] - '0';
		len -= 2;
	}
	else if (len > 1 && name[len-1] == '^') {
		parent = 1;
		len--;
	} else
		parent = -1;

	if (parent >= 0)
		return get_parent(name, len, sha1, parent);

	/* "name~3" is "name^^^",
	 * "name~12" is "name^^^^^^^^^^^^", and
	 * "name~" and "name~0" are name -- not "name^0"!
	 */
	parent = 0;
	for (cp = name + len - 1; name <= cp; cp--) {
		int ch = *cp;
		if ('0' <= ch && ch <= '9')
			continue;
		if (ch != '~')
			parent = -1;
		break;
	}
	if (!parent && *cp == '~') {
		int len1 = cp - name;
		cp++;
		while (cp < name + len)
			parent = parent * 10 + *cp++ - '0';
		return get_nth_ancestor(name, len1, sha1, parent);
	}

	ret = peel_onion(name, len, sha1);
	if (!ret)
		return 0;

	ret = get_sha1_basic(name, len, sha1);
	if (!ret)
		return 0;
	return get_short_sha1(name, len, sha1, 0);
}
예제 #2
0
int main(int argc, char *argv[])
{
	secp256k1_context *ctx;
	struct onion onion;
	bool generate = false, decode = false;

	assert(EVP_CIPHER_iv_length(EVP_aes_128_ctr()) == sizeof(struct iv));
	
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "--generate <pubkey>... OR\n"
			   "--decode <privkey>\n"
			   "Either create an onion message, or decode one step",
			   "Print this message.");
	opt_register_noarg("--generate",
			   opt_set_bool, &generate,
			   "Generate onion through the given hex pubkeys");
	opt_register_noarg("--decode",
			   opt_set_bool, &decode,
			   "Decode onion given the private key");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
	if (generate) {
		secp256k1_pubkey pubkeys[MAX_HOPS];
		char *msgs[MAX_HOPS];
		size_t i;

		if (argc == 1)
			opt_usage_exit_fail("Expected at least one pubkey");
		if (argc-1 > MAX_HOPS)
			opt_usage_exit_fail("Expected at most %u pubkeys",
					    MAX_HOPS);
		for (i = 1; i < argc; i++) {
			if (!parse_onion_pubkey(ctx, argv[i], &pubkeys[i-1]))
				errx(1, "Bad pubkey '%s'", argv[i]);
			msgs[i-1] = make_message(ctx, &pubkeys[i-1]);
		}

		if (!create_onion(pubkeys, msgs, argc - 1, &onion))
			errx(1, "Creating onion packet failed");
		if (!write_all(STDOUT_FILENO, &onion, sizeof(onion)))
			err(1, "Writing onion packet");
		return 0;
	} else if (decode) {
		struct seckey seckey;
		secp256k1_pubkey pubkey;
		struct enckey enckey;
		struct iv pad_iv;

		if (argc != 2)
			opt_usage_exit_fail("Expect a privkey with --decode");

		if (!hex_decode(argv[1], strlen(argv[1]), &seckey, sizeof(seckey)))
			errx(1, "Invalid private key hex '%s'", argv[1]);
		if (!secp256k1_ec_pubkey_create(ctx, &pubkey, seckey.u.u8))
			errx(1, "Invalid private key '%s'", argv[1]);

		if (!read_all(STDIN_FILENO, &onion, sizeof(onion)))
			errx(1, "Reading in onion");

		if (!decrypt_onion(&seckey, &onion, &enckey, &pad_iv))
			errx(1, "Failed decrypting onion for '%s'", argv[1]);
		if (strncmp((char *)myhop(&onion)->msg, make_message(ctx, &pubkey),
			    sizeof(myhop(&onion)->msg)))
			errx(1, "Bad message '%s'", (char *)myhop(&onion)->msg);
		if (!peel_onion(&onion, &enckey, &pad_iv))
			errx(1, "Peeling onion for '%s'", argv[1]);
		if (!write_all(STDOUT_FILENO, &onion, sizeof(onion)))
			err(1, "Writing onion packet");
		return 0;
	} else
		opt_usage_exit_fail("Need --decode or --generate");
		
	secp256k1_context_destroy(ctx);
	return 0;
}