Пример #1
0
/**
 * gnutls_openpgp_keyring_get_crt_count:
 * @ring: is an OpenPGP key ring
 *
 * This function will return the number of OpenPGP certificates
 * present in the given keyring.
 *
 * Returns: the number of subkeys, or a negative error code on error.
 **/
int gnutls_openpgp_keyring_get_crt_count(gnutls_openpgp_keyring_t ring)
{
	cdk_kbnode_t knode;
	cdk_error_t err;
	cdk_keydb_search_t st;
	int ret = 0;

	err =
	    cdk_keydb_search_start(&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
	if (err != CDK_Success) {
		gnutls_assert();
		return _gnutls_map_cdk_rc(err);
	}

	do {
		err = cdk_keydb_search(st, ring->db, &knode);
		if (err != CDK_Error_No_Key && err != CDK_Success) {
			gnutls_assert();
			cdk_keydb_search_release(st);
			return _gnutls_map_cdk_rc(err);
		}

		if (knode_is_pkey(knode))
			ret++;

		cdk_kbnode_release(knode);

	}
	while (err != CDK_Error_No_Key);

	cdk_keydb_search_release(st);
	return ret;
}
Пример #2
0
Файл: pgp.c Проект: intgr/gnutls
/**
 * gnutls_openpgp_crt_import:
 * @key: The structure to store the parsed key.
 * @data: The RAW or BASE64 encoded key.
 * @format: One of gnutls_openpgp_crt_fmt_t elements.
 *
 * This function will convert the given RAW or Base64 encoded key to
 * the native #gnutls_openpgp_crt_t format. The output will be stored
 * in 'key'.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key,
                           const gnutls_datum_t * data,
                           gnutls_openpgp_crt_fmt_t format)
{
  cdk_packet_t pkt;
  int rc, armor;

  if (data->data == NULL || data->size == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  if (format == GNUTLS_OPENPGP_FMT_RAW) armor = 0;
  else armor = 1;

  rc = cdk_kbnode_read_from_mem (&key->knode, armor, data->data, data->size);
  if (rc)
    {
      rc = _gnutls_map_cdk_rc (rc);
      gnutls_assert ();
      return rc;
    }

  /* Test if the import was successful. */
  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
  if (pkt == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  return 0;
}
Пример #3
0
/**
 * gnutls_openpgp_keyring_get_crt:
 * @ring: Holds the keyring.
 * @idx: the index of the certificate to export
 * @cert: An uninitialized #gnutls_openpgp_crt_t structure
 *
 * This function will extract an OpenPGP certificate from the given
 * keyring.  If the index given is out of range
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. The
 * returned structure needs to be deinited.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring,
                                unsigned int idx, gnutls_openpgp_crt_t * cert)
{
    cdk_kbnode_t knode;
    cdk_error_t err;
    int ret = 0;
    unsigned int count = 0;
    cdk_keydb_search_t st;

    err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
    if (err != CDK_Success)
    {
        gnutls_assert ();
        return _gnutls_map_cdk_rc (err);
    }

    do
    {
        err = cdk_keydb_search (st, ring->db, &knode);
        if (err != CDK_EOF && err != CDK_Success)
        {
            gnutls_assert ();
            cdk_keydb_search_release (st);
            return _gnutls_map_cdk_rc (err);
        }

        if (idx == count && err == CDK_Success)
        {
            ret = gnutls_openpgp_crt_init (cert);
            if (ret == 0)
                (*cert)->knode = knode;
            cdk_keydb_search_release (st);
            return ret;
        }

        if (knode_is_pkey (knode))
            count++;

        cdk_kbnode_release (knode);

    }
    while (err != CDK_EOF);

    cdk_keydb_search_release (st);
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}
Пример #4
0
/**
 * gnutls_openpgp_crt_verify_ring:
 * @key: the structure that holds the key.
 * @keyring: holds the keyring to check against
 * @flags: unused (should be 0)
 * @verify: will hold the certificate verification output.
 *
 * Verify all signatures in the key, using the given set of keys
 * (keyring).
 *
 * The key verification output will be put in @verify and will be one
 * or more of the #gnutls_certificate_status_t enumerated elements
 * bitwise or'd.
 *
 * %GNUTLS_CERT_INVALID: A signature on the key is invalid.
 *
 * %GNUTLS_CERT_REVOKED: The key has been revoked.
 *
 * Note that this function does not verify using any "web of trust".
 * You may use GnuPG for that purpose, or any other external PGP
 * application.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t key,
                                gnutls_openpgp_keyring_t keyring,
                                unsigned int flags, unsigned int *verify)
{
  gnutls_openpgp_keyid_t id;
  cdk_error_t rc;
  int status;

  if (!key || !keyring)
    {
      gnutls_assert ();
      return GNUTLS_E_NO_CERTIFICATE_FOUND;
    }

  *verify = 0;

  rc = cdk_pk_check_sigs (key->knode, keyring->db, &status);
  if (rc == CDK_Error_No_Key)
    {
      rc = GNUTLS_E_NO_CERTIFICATE_FOUND;
      gnutls_assert ();
      return rc;
    }
  else if (rc != CDK_Success)
    {
      _gnutls_x509_log ("cdk_pk_check_sigs: error %d\n", rc);
      rc = _gnutls_map_cdk_rc (rc);
      gnutls_assert ();
      return rc;
    }
  _gnutls_x509_log ("status: %x\n", status);

  if (status & CDK_KEY_INVALID)
    *verify |= GNUTLS_CERT_INVALID;
  if (status & CDK_KEY_REVOKED)
    *verify |= GNUTLS_CERT_REVOKED;
  if (status & CDK_KEY_NOSIGNER)
    *verify |= GNUTLS_CERT_SIGNER_NOT_FOUND;

  /* Check if the key is included in the ring. */
  if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
    {
      rc = gnutls_openpgp_crt_get_key_id (key, id);
      if (rc < 0)
        {
          gnutls_assert ();
          return rc;
        }

      rc = gnutls_openpgp_keyring_check_id (keyring, id, 0);
      /* If it exists in the keyring don't treat it as unknown. */
      if (rc == 0 && *verify & GNUTLS_CERT_SIGNER_NOT_FOUND)
        *verify ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
    }

  return 0;
}
Пример #5
0
/**
  * gnutls_openpgp_key_import - This function will import a RAW or BASE64 encoded key
  * @key: The structure to store the parsed key.
  * @data: The RAW or BASE64 encoded key.
  * @format: One of gnutls_openpgp_key_fmt_t elements.
  *
  * This function will convert the given RAW or Base64 encoded key
  * to the native gnutls_openpgp_key_t format. The output will be stored in 'key'.
  *
  * Returns 0 on success.
  *
  **/
int
gnutls_openpgp_key_import (gnutls_openpgp_key_t key,
			   const gnutls_datum_t * data,
			   gnutls_openpgp_key_fmt_t format)
{
  int rc;

  if (format == GNUTLS_OPENPGP_FMT_RAW)
    {
      rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
      if (rc)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }
  else
    {				/* base64 */
      key->inp = cdk_stream_tmp_from_mem (data->data, data->size);
      if (key->inp == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      rc = cdk_stream_set_armor_flag (key->inp, 0);
      if (rc)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}

      rc = cdk_keydb_get_keyblock (key->inp, &key->knode);
      if (rc)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }

  return 0;
}
Пример #6
0
/**
 * gnutls_openpgp_privkey_import:
 * @key: The structure to store the parsed key.
 * @data: The RAW or BASE64 encoded key.
 * @format: One of #gnutls_openpgp_crt_fmt_t elements.
 * @password: not used for now
 * @flags: should be zero
 *
 * This function will convert the given RAW or Base64 encoded key to
 * the native gnutls_openpgp_privkey_t format.  The output will be
 * stored in 'key'.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
			       const gnutls_datum_t * data,
			       gnutls_openpgp_crt_fmt_t format,
			       const char *password, unsigned int flags)
{
  cdk_stream_t inp;
  cdk_packet_t pkt;
  int rc;

  if (data->data == NULL || data->size == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  if (format == GNUTLS_OPENPGP_FMT_RAW)
    {
      rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }
  else
    {
      rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}

      if (cdk_armor_filter_use (inp))
	{
	  rc = cdk_stream_set_armor_flag (inp, 0);
	  if (rc != 0)
	    {
	      rc = _gnutls_map_cdk_rc (rc);
	      cdk_stream_close (inp);
	      gnutls_assert ();
	      return rc;
	    }
	}

      rc = cdk_keydb_get_keyblock (inp, &key->knode);
      cdk_stream_close (inp);

      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }

  /* Test if the import was successful. */
  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
  if (pkt == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  return 0;
}
Пример #7
0
/**
 * gnutls_openpgp_keyring_import:
 * @keyring: The structure to store the parsed key.
 * @data: The RAW or BASE64 encoded keyring.
 * @format: One of #gnutls_openpgp_keyring_fmt elements.
 *
 * This function will convert the given RAW or Base64 encoded keyring
 * to the native #gnutls_openpgp_keyring_t format.  The output will be
 * stored in 'keyring'.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring,
			      const gnutls_datum_t * data,
			      gnutls_openpgp_crt_fmt_t format)
{
	cdk_error_t err;
	cdk_stream_t input = NULL;
	size_t raw_len = 0;
	uint8_t *raw_data = NULL;
	unsigned free_data = 0;

	if (data->data == NULL || data->size == 0) {
		gnutls_assert();
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;
	}

	_gnutls_debug_log("PGP: keyring import format '%s'\n",
			  format ==
			  GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64");

	/* Create a new stream from the given data, decode it, and import
	 * the raw database. This to avoid using opencdk streams which are
	 * not thread safe.
	 */
	if (format == GNUTLS_OPENPGP_FMT_BASE64) {
		size_t seen = 0;

		err =
		    cdk_stream_tmp_from_mem(data->data, data->size,
					    &input);
		if (err == 0)
			err = cdk_stream_set_armor_flag(input, 0);
		if (err) {
			gnutls_assert();
			err = _gnutls_map_cdk_rc(err);
			goto error;
		}

		raw_len = cdk_stream_get_length(input);
		if (raw_len == 0) {
			gnutls_assert();
			err = GNUTLS_E_BASE64_DECODING_ERROR;
			goto error;
		}

		raw_data = gnutls_malloc(raw_len);
		if (raw_data == NULL) {
			gnutls_assert();
			err = GNUTLS_E_MEMORY_ERROR;
			goto error;
		}

		do {
			err =
			    cdk_stream_read(input, raw_data + seen,
					    raw_len - seen);

			if (err > 0)
				seen += err;
		}
		while (seen < raw_len && err != EOF && err > 0);

		raw_len = seen;
		if (raw_len == 0) {
			gnutls_assert();
			err = GNUTLS_E_BASE64_DECODING_ERROR;
			goto error;
		}

		free_data = 1;
	} else {		/* RAW */
		raw_len = data->size;
		raw_data = data->data;
	}

	err =
	    cdk_keydb_new_from_mem(&keyring->db, 0, 0, raw_data, raw_len);
	if (err)
		gnutls_assert();

	if (free_data) {
		err = _gnutls_map_cdk_rc(err);
		goto error;
	}

	return _gnutls_map_cdk_rc(err);

      error:
	gnutls_free(raw_data);
	cdk_stream_close(input);

	return err;
}
Пример #8
0
/**
  * gnutls_openpgp_key_export - This function will export a RAW or BASE64 encoded key
  * @key: Holds the key.
  * @format: One of gnutls_openpgp_key_fmt_t elements.
  * @output_data: will contain the key base64 encoded or raw
  * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
  *
  * This function will convert the given key to RAW or Base64 format.
  * If the buffer provided is not long enough to hold the output, then
  * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
  *
  * Returns 0 on success.
  *
  **/
int
gnutls_openpgp_key_export (gnutls_openpgp_key_t key,
			   gnutls_openpgp_key_fmt_t format,
			   void *output_data, size_t * output_data_size)
{
  int rc;
  size_t input_data_size = *output_data_size;

  rc = cdk_kbnode_write_to_mem (key->knode, output_data, output_data_size);
  if (rc)
    {
      rc = _gnutls_map_cdk_rc (rc);
      gnutls_assert ();
      return rc;
    }

  if (format == GNUTLS_OPENPGP_FMT_BASE64)
    {
      cdk_stream_t s;

      s = cdk_stream_tmp_from_mem (output_data, *output_data_size);
      if (s == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_MEMORY_ERROR;
	}

      cdk_stream_tmp_set_mode (s, 1);
      rc = cdk_stream_set_armor_flag (s, CDK_ARMOR_PUBKEY);
      if (rc)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  cdk_stream_close (s);
	  return rc;
	}


      *output_data_size = input_data_size;

      rc = cdk_stream_read (s, output_data, *output_data_size);
      if (rc == EOF)
	{
	  gnutls_assert ();
	  cdk_stream_close (s);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      *output_data_size = rc;
      if (*output_data_size != cdk_stream_get_length (s))
	{
	  *output_data_size = cdk_stream_get_length (s);
	  cdk_stream_close (s);
	  gnutls_assert ();
	  return GNUTLS_E_SHORT_MEMORY_BUFFER;
	}

      cdk_stream_close (s);
    }

  return 0;
}
Пример #9
0
/*-
 * gnutls_openpgp_get_key - Retrieve a key from the keyring.
 * @key: the destination context to save the key.
 * @keyring: the datum struct that contains all keyring information.
 * @attr: The attribute (keyid, fingerprint, ...).
 * @by: What attribute is used.
 *
 * This function can be used to retrieve keys by different pattern
 * from a binary or a file keyring.
 -*/
int
gnutls_openpgp_get_key (gnutls_datum_t * key,
			gnutls_openpgp_keyring_t keyring, key_attr_t by,
			opaque * pattern)
{
  cdk_kbnode_t knode = NULL;
  unsigned long keyid[2];
  unsigned char *buf;
  void *desc;
  size_t len;
  int rc = 0;
  cdk_keydb_search_t st;

  if (!key || !keyring || by == KEY_ATTR_NONE)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  memset (key, 0, sizeof *key);

  if (by == KEY_ATTR_SHORT_KEYID)
    {
      keyid[0] = _gnutls_read_uint32 (pattern);
      desc = keyid;
    }
  else if (by == KEY_ATTR_KEYID)
    {
      keyid[0] = _gnutls_read_uint32 (pattern);
      keyid[1] = _gnutls_read_uint32 (pattern + 4);
      desc = keyid;
    }
  else
    desc = pattern;
  rc = cdk_keydb_search_start (&st, keyring->db, by, desc);
  if (!rc)
    rc = cdk_keydb_search (st, keyring->db, &knode);

  cdk_keydb_search_release (st);

  if (rc)
    {
      rc = _gnutls_map_cdk_rc (rc);
      goto leave;
    }

  if (!cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY))
    {
      rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
      goto leave;
    }

  /* We let the function allocate the buffer to avoid
     to call the function twice. */
  rc = cdk_kbnode_write_to_mem_alloc (knode, &buf, &len);
  if (!rc)
    datum_append (key, buf, len);
  gnutls_free (buf);

leave:
  cdk_kbnode_release (knode);
  return rc;
}