Пример #1
0
static void
http_decode(const char *in, char **rp)
{
	size_t	 i, j, sz;

	sz = strlen(in);
	*rp = kcalloc(sz + 1, 1);

	for (i = j = 0; i < sz; i++, j++) {
		if ('+' == in[i]) {
			(*rp)[j] = ' ';
			continue;
		} else if ('%' != in[i]) {
			(*rp)[j] = in[i];
			continue;
		}
		if ('\0' == in[i + 1] ||
		    '\0' == in[i + 2] ||
		    ! isalnum((int)in[i + 1]) ||
		    ! isalnum((int)in[i + 2])) {
			(*rp)[j] = in[i];
			continue;
		}
		(*rp)[j] = 
			parsehex(in[i + 1]) << 4 |
			parsehex(in[i + 2]);
		i += 2;
	}
}
Пример #2
0
/*
 * Note that this implementation does not (and should not!) obey
 * locale settings; you cannot simply substitute strtol here, since
 * it does obey locale.
 */
static int64_t
mtree_atol16(char **p)
{
	int64_t l, limit, last_digit_limit;
	int base, digit, sign;

	base = 16;

	if (**p == '-') {
		sign = -1;
		limit = ((uint64_t)(INT64_MAX) + 1) / base;
		last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
		++(*p);
	} else {
		sign = 1;
		limit = INT64_MAX / base;
		last_digit_limit = INT64_MAX % base;
	}

	l = 0;
	digit = parsehex(**p);
	while (digit >= 0 && digit < base) {
		if (l > limit || (l == limit && digit > last_digit_limit))
			return (sign < 0) ? INT64_MIN : INT64_MAX;
		l = (l * base) + digit;
		digit = parsehex(*++(*p));
	}
	return (sign < 0) ? -l : l;
}
Пример #3
0
static int dlist_tohex64(struct dlist *dl, bit64 *valp)
{
    const char *end = NULL;
    bit64 newval;

    if (!dl) return 0;

    switch (dl->type) {
    case DL_ATOM:
    case DL_BUF:
        if (parsehex(dl->sval, &end, dl->nval, &newval))
            return 0;
        if (end - dl->sval != (int)dl->nval)
            return 0;
        /* successfully parsed - switch to a numeric value */
        dlist_makehex64(dl, newval);
        break;

    case DL_NUM:
    case DL_HEX:
    case DL_DATE:
        dl->type = DL_HEX;
        break;

    default:
        return 0;
    }

    if (valp) *valp = dl->nval;

    return 1;
}
Пример #4
0
void sign(int argc, char **argv) {
  ecc_int256_t secret, hash, k, krecip, r, s, tmp;
  ecc_25519_work_t kG;

  if (argc != 2)
    exit_error(1, 0, "Usage: ecdsautil sign file (secret is read from stdin)");

  if (!sha256_file(argv[1], tmp.p))
    exit_error(1, 0, "Error while hashing file");

  char secret_string[65];

  if (fgets(secret_string, sizeof(secret_string), stdin) == NULL)
    exit_error(1, 0, "Error reading secret");

  if (!parsehex(secret.p, secret_string, 32))
    exit_error(1, 0, "Error reading secret");

  // Reduce hash (instead of clearing 3 bits)
  ecc_25519_gf_reduce(&hash, &tmp);

  // Generate k
  generate_k(k.p, secret.p, tmp.p);
  ecc_25519_gf_sanitize_secret(&k, &k);

  // calculate k^(-1)
  ecc_25519_gf_recip(&krecip, &k);

  // calculate kG = k * base point
  ecc_25519_scalarmult_base(&kG, &k);

  // store x coordinate of kG in r
  ecc_25519_store_xy(&tmp, NULL, &kG);
  ecc_25519_gf_reduce(&r, &tmp);

  if (ecc_25519_gf_is_zero(&r))
    exit_error(1, 0, "Error: r is zero (this should never happen)");

  // tmp = r * secret
  ecc_25519_gf_mult(&tmp, &r, &secret);

  // s = hash + tmp = hash + r * secret
  ecc_25519_gf_add(&s, &hash, &tmp);

  // tmp = krecip * s = k^(-1) * s
  ecc_25519_gf_mult(&tmp, &krecip, &s);

  // mod n (order of G)
  ecc_25519_gf_reduce(&s, &tmp);

  if (ecc_25519_gf_is_zero(&s))
    exit_error(1, 0, "Error: s is zero (this should never happen)");

  hexdump(stdout, r.p, 32);
  hexdump(stdout, s.p, 32);
  puts("");
}
Пример #5
0
void show_key(void) {
  char secret_string[65];
  ecc_int256_t pubkey, secret;

  if (fgets(secret_string, sizeof(secret_string), stdin) == NULL)
    goto secret_error;

  if (!parsehex(secret.p, secret_string, 32))
    goto secret_error;

  ecdsa_public_from_secret(&pubkey, &secret);

  output_key(&pubkey);
  return;

secret_error:
  exit_error(1, 0, "Error reading secret");
}
Пример #6
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;
}
Пример #7
0
static void
parseclose(void *dat, const XML_Char *s)
{
	struct parse	 *p = dat;
	size_t		  i, j, sz, len;
	int		  c;
	char		**array;

	switch (calelem_find(s)) {
	case (CALELEM_CALENDAR_MULTIGET):
	case (CALELEM_CALENDAR_QUERY):
	case (CALELEM_PROPERTYUPDATE):
	case (CALELEM_PROPFIND):
		/* Clear our parsing context. */
		XML_SetDefaultHandler(p->xp, NULL);
		XML_SetElementHandler(p->xp, NULL, NULL);
		break;
	case (CALELEM_HREF):
		if (0 == p->buf.sz)
			break;
		/*
		 * According to the WebDAV RFC 4918, we need to URL
		 * decode this.
		 */
		array = reallocarray(p->p->hrefs, 
			p->p->hrefsz + 1, sizeof(char *));
		if (NULL == array) {
			caldav_err(p, "memory exhausted");
			break;
		}
		p->p->hrefs = array;
		sz = strlen(p->buf.buf);
		len = sz + 1;
		p->p->hrefs[p->p->hrefsz] = calloc(len, 1);
		if (NULL == p->p->hrefs[p->p->hrefsz]) {
			caldav_err(p, "memory exhausted");
			break;
		}
		p->p->hrefsz++;
		for (i = j = 0; i < sz; i++, j++) {
			c = p->buf.buf[i];
			if ('+' == c) {
				p->p->hrefs[p->p->hrefsz - 1][j] = ' ';
				continue;
			} else if ('%' != c) {
				p->p->hrefs[p->p->hrefsz - 1][j] = c;
				continue;
			}

			if ('\0' == p->buf.buf[i + 1] ||
			    '\0' == p->buf.buf[i + 2] ||
			    ! isalnum(p->buf.buf[i + 1]) ||
			    ! isalnum(p->buf.buf[i + 2])) {
				caldav_err(p, "bad percent-encoding");
				break;
			}

			p->p->hrefs[p->p->hrefsz - 1][j] = 
				parsehex(p->buf.buf[i + 1]) << 4 |
				parsehex(p->buf.buf[i + 2]);
			i += 2;
		}

		XML_SetDefaultHandler(p->xp, NULL);
		break;
	default:
		break;
	}
}
Пример #8
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 */
}
Пример #9
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;
}
Пример #10
0
static int
run_file(const char *filename)
{
	FILE *tv;
	char buf[1024], *eol;
	const char *cp, *errstr;
	int lnum = 0, fail = 0;
	u_char *key, *plaintext, *ciphertext;
	u_int keylen, textlen, tmp;
	int blocksize, keysize, test;

	if ((tv = fopen(filename, "r")) == NULL)
		err(1, "fopen(\"%s\")", filename);

	keylen = textlen = tmp = 0;
	key = ciphertext = plaintext = NULL;
	blocksize = keysize = test = -1;
	while ((fgets(buf, sizeof(buf), tv)) != NULL) {
		lnum++;
		eol = buf + strlen(buf) - 1;
		if (*eol != '\n')
			errx(1, "line %d: too long", lnum);
		if (eol > buf && *(eol - 1) == '\r')
			eol--;
		*eol = '\0';
		if ((cp = startswith(buf, "BLOCKSIZE=")) != NULL) {
			if (blocksize != -1)
				errx(1, "line %d: blocksize already set", lnum);
			blocksize = (int)strtonum(cp, 128, 128, &errstr);
			if (errstr)
				errx(1, "line %d: blocksize is %s: \"%s\"",
				    lnum, errstr, cp);
		} else if ((cp = startswith(buf, "KEYSIZE=")) != NULL) {
			if (keysize != -1)
				errx(1, "line %d: keysize already set", lnum);
			keysize = (int)strtonum(cp, 128, 256, &errstr);
			if (errstr)
				errx(1, "line %d: keysize is %s: \"%s\"",
				    lnum, errstr, cp);
			if (keysize != 128 && keysize != 256)
				errx(1, "line %d: XXX only 128 or 256 "
				    "bit keys for now (keysize = %d)",
				    lnum, keysize);
		} else if ((cp = startswith(buf, "PT=")) != NULL) {
			if (plaintext != NULL)
				free(plaintext);
			parsehex(cp, &plaintext, &tmp);
			if (tmp * 8 != (u_int)blocksize)
				errx(1, "line %d: plaintext len %u != "
				    "blocklen %d", lnum, tmp, blocksize);
			if (textlen != 0) {
				if (textlen != tmp)
					errx(1, "line %d: plaintext len %u != "
					    "ciphertext len %d", lnum, tmp,
					    textlen);
			} else
				textlen = tmp;
		} else if ((cp = startswith(buf, "CT=")) != NULL) {
			if (ciphertext != NULL)
				free(ciphertext);
			parsehex(cp, &ciphertext, &tmp);
			if (tmp * 8 != (u_int)blocksize)
				errx(1, "line %d: ciphertext len %u != "
				    "blocklen %d", lnum, tmp, blocksize);
			if (textlen != 0) {
				if (textlen != tmp)
					errx(1, "line %d: ciphertext len %u != "
					    "plaintext len %d", lnum, tmp,
					    textlen);
			} else
				textlen = tmp;
		} else if ((cp = startswith(buf, "KEY=")) != NULL) {
			if (key != NULL)
				free(key);
			parsehex(cp, &key, &keylen);
			if (keylen * 8 != (u_int)keysize)
				errx(1, "line %d: ciphertext len %u != "
				    "blocklen %d", lnum, tmp, textlen);
		} else if ((cp = startswith(buf, "TEST=")) != NULL) {
			if (plaintext == NULL || ciphertext == NULL ||
			    key == NULL || blocksize == -1 || keysize == -1) {
				if (test != -1)
					errx(1, "line %d: new test before "
					    "parameters", lnum);
				goto parsetest;
			}
			/* do the tests */
			fail += do_tests(filename, test, key, keylen,
			    plaintext, ciphertext, textlen);
 parsetest:
			test = (int)strtonum(cp, 0, 65536, &errstr);
			if (errstr)
				errx(1, "line %d: test is %s: \"%s\"",
				    lnum, errstr, cp);
		} else {
			/* don't care */
			continue;
		}
	}
	fclose(tv);

	return fail;
}