Ejemplo n.º 1
0
int
pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
{
	int			res;
	PX_MD	   *md;

	s2k->key_len = pgp_get_cipher_key_size(cipher);
	if (s2k->key_len <= 0)
		return PXE_PGP_UNSUPPORTED_CIPHER;

	res = pgp_load_digest(s2k->digest_algo, &md);
	if (res < 0)
		return res;

	switch (s2k->mode)
	{
		case 0:
			res = calc_s2k_simple(s2k, md, key, key_len);
			break;
		case 1:
			res = calc_s2k_salted(s2k, md, key, key_len);
			break;
		case 3:
			res = calc_s2k_iter_salted(s2k, md, key, key_len);
			break;
		default:
			res = PXE_PGP_BAD_S2K_MODE;
	}
	px_md_free(md);
	return res;
}
static int
check_key_sha1(PullFilter *src, PGP_PubKey *pk)
{
	int			res;
	uint8		got_sha1[20];
	uint8		my_sha1[20];
	PX_MD	   *md;

	res = pullf_read_fixed(src, 20, got_sha1);
	if (res < 0)
		return res;

	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
	if (res < 0)
		goto err;
	switch (pk->algo)
	{
		case PGP_PUB_ELG_ENCRYPT:
			pgp_mpi_hash(md, pk->sec.elg.x);
			break;
		case PGP_PUB_RSA_SIGN:
		case PGP_PUB_RSA_ENCRYPT:
		case PGP_PUB_RSA_ENCRYPT_SIGN:
			pgp_mpi_hash(md, pk->sec.rsa.d);
			pgp_mpi_hash(md, pk->sec.rsa.p);
			pgp_mpi_hash(md, pk->sec.rsa.q);
			pgp_mpi_hash(md, pk->sec.rsa.u);
			break;
		case PGP_PUB_DSA_SIGN:
			pgp_mpi_hash(md, pk->sec.dsa.x);
			break;
	}
	px_md_finish(md, my_sha1);
	px_md_free(md);

	if (memcmp(my_sha1, got_sha1, 20) != 0)
	{
		px_debug("key sha1 check failed");
		res = PXE_PGP_KEYPKT_CORRUPT;
	}
err:
	memset(got_sha1, 0, 20);
	memset(my_sha1, 0, 20);
	return res;
}
static int
calc_key_id(PGP_PubKey *pk)
{
	int			res;
	PX_MD	   *md;
	int			len;
	uint8		hdr[3];
	uint8		hash[20];

	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
	if (res < 0)
		return res;

	len = 1 + 4 + 1;
	switch (pk->algo)
	{
		case PGP_PUB_ELG_ENCRYPT:
			len += 2 + pk->pub.elg.p->bytes;
			len += 2 + pk->pub.elg.g->bytes;
			len += 2 + pk->pub.elg.y->bytes;
			break;
		case PGP_PUB_RSA_SIGN:
		case PGP_PUB_RSA_ENCRYPT:
		case PGP_PUB_RSA_ENCRYPT_SIGN:
			len += 2 + pk->pub.rsa.n->bytes;
			len += 2 + pk->pub.rsa.e->bytes;
			break;
		case PGP_PUB_DSA_SIGN:
			len += 2 + pk->pub.dsa.p->bytes;
			len += 2 + pk->pub.dsa.q->bytes;
			len += 2 + pk->pub.dsa.g->bytes;
			len += 2 + pk->pub.dsa.y->bytes;
			break;
	}

	hdr[0] = 0x99;
	hdr[1] = len >> 8;
	hdr[2] = len & 0xFF;
	px_md_update(md, hdr, 3);

	px_md_update(md, &pk->ver, 1);
	px_md_update(md, pk->time, 4);
	px_md_update(md, &pk->algo, 1);

	switch (pk->algo)
	{
		case PGP_PUB_ELG_ENCRYPT:
			pgp_mpi_hash(md, pk->pub.elg.p);
			pgp_mpi_hash(md, pk->pub.elg.g);
			pgp_mpi_hash(md, pk->pub.elg.y);
			break;
		case PGP_PUB_RSA_SIGN:
		case PGP_PUB_RSA_ENCRYPT:
		case PGP_PUB_RSA_ENCRYPT_SIGN:
			pgp_mpi_hash(md, pk->pub.rsa.n);
			pgp_mpi_hash(md, pk->pub.rsa.e);
			break;
		case PGP_PUB_DSA_SIGN:
			pgp_mpi_hash(md, pk->pub.dsa.p);
			pgp_mpi_hash(md, pk->pub.dsa.q);
			pgp_mpi_hash(md, pk->pub.dsa.g);
			pgp_mpi_hash(md, pk->pub.dsa.y);
			break;
	}

	px_md_finish(md, hash);
	px_md_free(md);

	memcpy(pk->key_id, hash + 12, 8);
	memset(hash, 0, 20);

	return 0;
}