Ejemplo n.º 1
0
void load_settings(struct settings *settings) {
	struct uci_context *ctx = uci_alloc_context();
	if (!ctx) {
		fprintf(stderr, "autoupdater: error: failed to allocate UCI context\n");
		abort();
	}

	ctx->flags &= ~UCI_FLAG_STRICT;

	struct uci_package *p;
	struct uci_section *s;

	if (uci_load(ctx, "autoupdater", &p) != UCI_OK) {
		fputs("autoupdater: error: unable to load UCI package\n", stderr);
		exit(1);
	}

	s = uci_lookup_section(ctx, p, "settings");
	if (!s || strcmp(s->type, "autoupdater")) {
		fputs("autoupdater: error: unable to load UCI settings\n", stderr);
		exit(1);
	}

	const char *enabled = uci_lookup_option_string(ctx, s, "enabled");
	if ((!enabled || strcmp(enabled, "1")) && !settings->force) {
		fputs("autoupdater is disabled\n", stderr);
		exit(0);
	}

	const char *version_file = uci_lookup_option_string(ctx, s, "version_file");
	if (version_file)
		settings->old_version = read_one_line(version_file);

	if (!settings->branch)
		settings->branch = uci_lookup_option_string(ctx, s, "branch");

	if (!settings->branch) {
		fputs("autoupdater: error: no branch given in settings or command line\n", stderr);
		exit(1);
	}

	struct uci_section *branch = uci_lookup_section(ctx, p, settings->branch);
	if (!branch || strcmp(branch->type, "branch")) {
		fprintf(stderr, "autoupdater: error: unable to load branch configuration for branch '%s'\n", settings->branch);
		exit(1);
	}

	settings->good_signatures = load_positive_number(ctx, branch, "good_signatures");
	if (settings->n_mirrors == 0)
		settings->mirrors = load_string_list(ctx, branch, "mirror", &settings->n_mirrors);

	const char **pubkeys_str = load_string_list(ctx, branch, "pubkey", &settings->n_pubkeys);
	settings->pubkeys = safe_malloc(settings->n_pubkeys * sizeof(ecc_25519_work_t));
	size_t ignored_keys = 0;
	for (size_t i = 0; i < settings->n_pubkeys; i++) {
		ecc_int256_t pubkey_packed;
		if (!pubkeys_str[i])
			goto pubkey_fail;
		if (!parsehex(pubkey_packed.p, pubkeys_str[i], 32))
			goto pubkey_fail;
		if (!ecc_25519_load_packed_legacy(&settings->pubkeys[i-ignored_keys], &pubkey_packed))
			goto pubkey_fail;
		if (!ecdsa_is_valid_pubkey(&settings->pubkeys[i-ignored_keys]))
			goto pubkey_fail;
		continue;

pubkey_fail:
		fprintf(stderr, "autoupdater: warning: ignoring invalid public key %s\n", pubkeys_str[i]);
		ignored_keys++;
	}
	settings->n_pubkeys -= ignored_keys;

	/* Don't free UCI context, we still reference values from it */
}
Ejemplo n.º 2
0
int verify(const char *command, int argc, char **argv) {
  int ret = 1;
  unsigned char signature[sizeof(ecdsa_signature_t)];

  set pubkeys, signatures;
  set_init(&pubkeys, sizeof(ecc_25519_work_t), 5);
  set_init(&signatures, sizeof(signature), 5);

  size_t min_good_signatures = 1;

  int opt;
  while ((opt = getopt(argc, argv, "s:p:n:")) != -1) {
    ecc_int256_t pubkey_packed;
    ecc_25519_work_t pubkey;

    switch (opt) {
      case 's':
        if (!parsehex(signature, optarg, sizeof(signature))) {
          fprintf(stderr, "Error while reading signature %s\n", optarg);
          break;
        }

        if (!set_add(&signatures, signature)) {
          fprintf(stderr, "Error in array_add\n");
          goto out;
        }
        break;
      case 'p':
        if (!parsehex(pubkey_packed.p, optarg, 32)) {
          fprintf(stderr, "Error while reading pubkey %s\n", optarg);
          break;
        }

        int ok = ecc_25519_load_packed_legacy(&pubkey, &pubkey_packed);
        if (!ok || !ecdsa_is_valid_pubkey(&pubkey)) {
          fprintf(stderr, "Invalid pubkey %s\n", optarg);
          break;
        }

        if (!set_add(&pubkeys, &pubkey)) {
          fprintf(stderr, "Error in array_add\n");
          goto out;
        }
        break;
      case 'n':
        min_good_signatures = atoi(optarg);
    }
  }

  if (optind > argc) {
    fprintf(stderr, "Usage: %s [-s signature ...] [-p pubkey ...] [-n num] file\n", command);
    goto out;
  }

  ecc_int256_t hash;

  if (!sha256_file((optind <= argc) ? argv[optind] : NULL, hash.p)) {
    fprintf(stderr, "Error while hashing file\n");
    goto out;
  }

  {
    ecdsa_verify_context_t ctxs[signatures.size];
    for (size_t i = 0; i < signatures.size; i++)
      ecdsa_verify_prepare_legacy(&ctxs[i], &hash, SET_INDEX(signatures, i));

    size_t good_signatures = ecdsa_verify_list_legacy(ctxs, signatures.size, pubkeys.content, pubkeys.size);

    if (good_signatures >= min_good_signatures)
      ret = 0;
  }

out:
  set_destroy(&pubkeys);
  set_destroy(&signatures);
  return ret;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
  unsigned char signature[64];

  array pubkeys, signatures;
  array_init(&pubkeys, sizeof(ecc_25519_work_t), 5);
  array_init(&signatures, sizeof(signature), 5);

  int min_good_signatures = 1;

  int opt;
  while ((opt = getopt(argc, argv, "s:p:n:")) != -1) {
    ecc_int256_t pubkey_packed;
    ecc_25519_work_t pubkey;

    switch (opt) {
      case 's':
        if (!parsehex(signature, optarg, 64)) {
          fprintf(stderr, "Error while reading signature %s\n", optarg);
          break;
        }

        if (!array_add(&signatures, signature, sizeof(signature))) {
          fprintf(stderr, "Error in array_add\n");
          goto error_out;
        }
        break;
      case 'p':
        if (!parsehex(pubkey_packed.p, optarg, 32)) {
          fprintf(stderr, "Error while reading pubkey %s\n", optarg);
          break;
        }

        int ret;

        ret = ecc_25519_load_packed(&pubkey, &pubkey_packed);

        if (!ret || !ecdsa_is_valid_pubkey(&pubkey)) {
          fprintf(stderr, "Invalid pubkey %s\n", optarg);
          break;
        }

        if (!array_add(&pubkeys, &pubkey, sizeof(ecc_25519_work_t))) {
          fprintf(stderr, "Error in array_add\n");
          goto error_out;
        }
        break;
      case 'n':
        min_good_signatures = atoi(optarg);
    }
  }

  if (optind >= argc) {
    fprintf(stderr, "Usage: %s [-s signature ...] [-p pubkey ...] [-n num] file\n", argv[0]);
    goto error_out;
  }

  ecc_int256_t hash;

  if (!sha256_file(argv[optind], hash.p)) {
    fprintf(stderr, "Error while hashing file\n");
    goto error_out;
  }

  int good_signatures = 0;

  array_nub(&pubkeys);
  array_nub(&signatures);

  for (int i = 0; i < signatures.size; i++) {
    unsigned char *signature;
    ecdsa_verify_context ctx;

    signature = ARRAY_INDEX(signatures, i);

    ecdsa_verify_prepare(&ctx, &hash, signature);

    for (int i = 0; i < pubkeys.size; i++) {
      ecc_25519_work_t *pubkey;
      pubkey = ARRAY_INDEX(pubkeys, i);

      if (ecdsa_verify_with_pubkey(&ctx, pubkey)) {
        good_signatures++;
        array_rm(&pubkeys, i);
        break;
      }
    }
  }

  array_destroy(&pubkeys);
  array_destroy(&signatures);

  if (good_signatures >= min_good_signatures)
    return 0;

  return 1;

error_out:
  array_destroy(&pubkeys);
  array_destroy(&signatures);
  return 1;
}