Example #1
0
/* Run the selftests for pubkey algorithm ALGO with optional reporting
   function REPORT.  */
gpg_error_t
_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
{
  gcry_err_code_t ec;
  gcry_pk_spec_t *spec;

  algo = map_algo (algo);
  spec = spec_from_algo (algo);
  if (spec && !spec->flags.disabled && spec->selftest)
    ec = spec->selftest (algo, extended, report);
  else
    {
      ec = GPG_ERR_PUBKEY_ALGO;
      /* Fixme: We need to change the report fucntion to allow passing
         of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
      if (report)
        report ("pubkey", algo, "module",
                spec && !spec->flags.disabled?
                "no selftest available" :
                spec? "algorithm disabled" :
                "algorithm not found");
    }

  return gpg_error (ec);
}
Example #2
0
/* Return the spec structure for the cipher algorithm ALGO.  For
   an unknown algorithm NULL is returned.  */
static gcry_cipher_spec_t *
spec_from_algo (int algo)
{
  int idx;
  gcry_cipher_spec_t *spec;

  algo = map_algo (algo);

  for (idx = 0; (spec = cipher_list[idx]); idx++)
    if (algo == spec->algo)
      return spec;
  return NULL;
}
Example #3
0
gcry_sexp_t
_gcry_pk_get_param (int algo, const char *name)
{
  gcry_sexp_t result = NULL;
  gcry_pk_spec_t *spec = NULL;

  algo = map_algo (algo);

  if (algo != GCRY_PK_ECC)
    return NULL;

  spec = spec_from_name ("ecc");
  if (spec)
    {
      if (spec && spec->get_curve_param)
        result = spec->get_curve_param (name);
    }
  return result;
}
Example #4
0
static int parse_signature_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_packet_len)
{
	if (!i_packet_len) /* 1st sanity check, we need at least the version */
		return -1;

	p_sig->version = *p_buf++;

	size_t i_read;
	switch (p_sig->version)
	{
		case 3:
			i_read = parse_signature_v3_packet(p_sig, p_buf, i_packet_len);
			break;
		case 4:
			p_sig->specific.v4.hashed_data = nullptr;
			p_sig->specific.v4.unhashed_data = nullptr;
			i_read = parse_signature_v4_packet(p_sig, p_buf, i_packet_len);
			break;
		default:
			return -1;
	}

	if (i_read == 0) /* signature packet parsing has failed */
		goto error;

	if (!map_algo(p_sig->public_key_algo))
		goto error;

	if (!map_digestalgo(p_sig->digest_algo))
		goto error;

	switch (p_sig->type)
	{
		case BINARY_SIGNATURE:
		case TEXT_SIGNATURE:
		case GENERIC_KEY_SIGNATURE:
		case PERSONA_KEY_SIGNATURE:
		case CASUAL_KEY_SIGNATURE:
		case POSITIVE_KEY_SIGNATURE:
			break;
		default:
			goto error;
	}

	p_buf--; /* rewind to the version byte */
	p_buf += i_read;

	if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_DSA)
	{
		READ_MPI(p_sig->algo_specific.dsa.r, 160);
		READ_MPI(p_sig->algo_specific.dsa.s, 160);
	}
	else if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_RSA)
		READ_MPI(p_sig->algo_specific.rsa.s, 4096);
	else
		goto error;

	if (i_read != i_packet_len)
		goto error;

	return 0;

error:
	if (p_sig->version == 4)
	{
		free(p_sig->specific.v4.hashed_data);
		free(p_sig->specific.v4.unhashed_data);
	}

	return -1;
}
Example #5
0
/*
 * fill a signature_packet_v4_t from signature packet data
 * verify that it was used with a DSA or RSA public key
 */
static size_t parse_signature_v4_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
{
	size_t i_read = 1; /* we already read the version byte */

	if (i_sig_len < 10) /* signature is at least 10 bytes + the 2 MPIs */
		return 0;

	p_sig->type = *p_buf++; i_read++;

	p_sig->public_key_algo = *p_buf++; i_read++;

	p_sig->digest_algo = *p_buf++; i_read++;
	if (!map_algo(p_sig->public_key_algo))
		return 0;

	memcpy(p_sig->specific.v4.hashed_data_len, p_buf, 2);
	p_buf += 2; i_read += 2;

	size_t i_hashed_data_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
	i_read += i_hashed_data_len;
	if (i_read + 4 > i_sig_len || i_hashed_data_len > i_sig_len)
		return 0;

	p_sig->specific.v4.hashed_data = (uint8_t*) malloc(i_hashed_data_len);
	if (!p_sig->specific.v4.hashed_data)
		return 0;
	memcpy(p_sig->specific.v4.hashed_data, p_buf, i_hashed_data_len);
	p_buf += i_hashed_data_len;

	memcpy(p_sig->specific.v4.unhashed_data_len, p_buf, 2);
	p_buf += 2; i_read += 2;

	size_t i_unhashed_data_len = scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
	i_read += i_unhashed_data_len;
	if (i_read + 2 > i_sig_len || i_unhashed_data_len > i_sig_len)
		return 0;

	p_sig->specific.v4.unhashed_data = (uint8_t*) malloc(i_unhashed_data_len);
	if (!p_sig->specific.v4.unhashed_data)
		return 0;

	memcpy(p_sig->specific.v4.unhashed_data, p_buf, i_unhashed_data_len);
	p_buf += i_unhashed_data_len;

	memcpy(p_sig->hash_verification, p_buf, 2);
	p_buf += 2; i_read += 2;

	uint8_t *p, *max_pos;
	p = p_sig->specific.v4.unhashed_data;
	max_pos = p + i_unhashed_data_len;

	for (;;)
	{
		if (p > max_pos)
			return 0;

		size_t i_subpacket_len;
		if (*p < 192)
		{
			if (p + 1 > max_pos)
				return 0;
			i_subpacket_len = *p++;
		}
		else if (*p < 255)
		{
			if (p + 2 > max_pos)
				return 0;
			i_subpacket_len = (*p++ - 192) << 8;
			i_subpacket_len += *p++ + 192;
		}
		else
		{
			if (p + 4 > max_pos)
				return 0;
			i_subpacket_len = size_t(*++p) << 24;
			i_subpacket_len += *++p << 16;
			i_subpacket_len += *++p << 8;
			i_subpacket_len += *++p;
		}

		if (*p == ISSUER_SUBPACKET)
		{
			if (p + 9 > max_pos)
				return 0;

			memcpy(&p_sig->issuer_longid, p + 1, 8);

			return i_read;
		}

		if (i_subpacket_len > i_unhashed_data_len)
			return 0;

		p += i_subpacket_len;
	}
}