예제 #1
0
/* Reads an uint32 number from the buffer. If check is non zero it will also check whether
 * the number read, is less than the data in the buffer
 */
int
_gnutls_buffer_pop_prefix (gnutls_buffer_st * buf, size_t * data_size,
                           int check)
{
  size_t size;

  if (buf->length < 4)
    {
      gnutls_assert ();
      return GNUTLS_E_PARSING_ERROR;
    }

  size = _gnutls_read_uint32 (buf->data);
  if (check && size > buf->length - 4)
    {
      gnutls_assert ();
      return GNUTLS_E_PARSING_ERROR;
    }

  buf->data += 4;
  buf->length -= 4;

  *data_size = size;

  return 0;
}
예제 #2
0
static int
aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
		void *dst, size_t dst_size)
{
	struct aes_gcm_ctx *ctx = _ctx;
	int blocks = src_size / GCM_BLOCK_SIZE;
	int exp_blocks = blocks * GCM_BLOCK_SIZE;
	int rest = src_size - (exp_blocks);
	uint32_t counter;

	gcm_ghash(ctx, src, src_size);
	ctx->gcm.len.u[1] += src_size;

	if (blocks > 0) {
		ctr32_encrypt_blocks(src, dst,
				     blocks,
				     ALIGN16(&ctx->expanded_key),
				     ctx->gcm.Yi.c);

		counter = _gnutls_read_uint32(ctx->gcm.Yi.c + 12);
		counter += blocks;
		_gnutls_write_uint32(counter, ctx->gcm.Yi.c + 12);
	}

	if (rest > 0)		/* last incomplete block */
		ctr_encrypt_last(ctx, src, dst, exp_blocks, rest);

	return 0;
}
예제 #3
0
/**
 * gnutls_db_check_entry_time:
 * @entry: is a pointer to a #gnutls_datum_t structure.
 * @t: is the time of the session handshake
 *
 * This function returns the time that this entry was active.
 * It can be used for database entry expiration.
 *
 * Returns: The time this entry was created, or zero on error.
 **/
time_t gnutls_db_check_entry_time(gnutls_datum_t * entry)
{
	uint32_t t;
	uint32_t magic;

	if (entry->size < 8)
		return gnutls_assert_val(0);

	magic = _gnutls_read_uint32(entry->data);

	if (magic != PACKED_SESSION_MAGIC)
		return gnutls_assert_val(0);

	t = _gnutls_read_uint32(&entry->data[4]);

	return t;
}
예제 #4
0
파일: extras.c 프로젝트: GostCrypt/GnuTLS
/**
 * gnutls_openpgp_keyring_check_id:
 * @ring: holds the keyring to check against
 * @keyid: will hold the keyid to check for.
 * @flags: unused (should be 0)
 *
 * Check if a given key ID exists in the keyring.
 *
 * Returns: %GNUTLS_E_SUCCESS on success (if keyid exists) and a
 *   negative error code on failure.
 **/
int
gnutls_openpgp_keyring_check_id(gnutls_openpgp_keyring_t ring,
				const gnutls_openpgp_keyid_t keyid,
				unsigned int flags)
{
	cdk_pkt_pubkey_t pk;
	uint32_t id[2];

	id[0] = _gnutls_read_uint32(keyid);
	id[1] = _gnutls_read_uint32(&keyid[4]);

	if (!cdk_keydb_get_pk(ring->db, id, &pk)) {
		cdk_pk_release(pk);
		return 0;
	}

	_gnutls_debug_log("PGP: key not found %08lX\n",
			  (unsigned long) id[1]);
	return GNUTLS_E_NO_CERTIFICATE_FOUND;
}
예제 #5
0
static int parse_nst_extension(void *ctx, unsigned tls_id, const unsigned char *data, unsigned data_size)
{
	gnutls_session_t session = ctx;
	if (tls_id == ext_mod_early_data.tls_id) {
		if (data_size < 4)
			return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR);
		session->security_parameters.max_early_data_size =
			_gnutls_read_uint32(data);
	}
	return 0;
}
예제 #6
0
파일: mpi.c 프로젝트: ystk/debian-gnutls26
/* this function reads a (small) unsigned integer
 * from asn1 structs. Combines the read and the convertion
 * steps.
 */
int
_gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
{
  int len, result;
  opaque *tmpstr;

  len = 0;
  result = asn1_read_value (node, value, NULL, &len);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  tmpstr = gnutls_malloc (len);
  if (tmpstr == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  result = asn1_read_value (node, value, tmpstr, &len);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      gnutls_free (tmpstr);
      return _gnutls_asn2err (result);
    }

  if (len == 1)
    *ret = tmpstr[0];
  else if (len == 2)
    *ret = _gnutls_read_uint16 (tmpstr);
  else if (len == 3)
    *ret = _gnutls_read_uint24 (tmpstr);
  else if (len == 4)
    *ret = _gnutls_read_uint32 (tmpstr);
  else
    {
      gnutls_assert ();
      gnutls_free (tmpstr);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  gnutls_free (tmpstr);

  return 0;
}
예제 #7
0
static int
unpack_srp_auth_info (gnutls_session_t session,
		      const gnutls_datum_t * packed_session)
{
  size_t username_size;
  int ret;
  srp_server_auth_info_t info;

  if (packed_session->data[0] != GNUTLS_CRD_SRP)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  username_size =
    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);

  if (username_size == 0)
    return 0;			/* nothing to be done */

  /* a simple check for integrity */
  if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
			   sizeof (srp_server_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  memcpy (info->username,
	  &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
	  username_size);

  return 0;
}
예제 #8
0
/* Format: 
 *      4 bytes the total security data size
 *      1 byte the entity type (client/server)
 *      1 byte the key exchange algorithm used
 *      1 byte the read cipher algorithm
 *      1 byte the read mac algorithm
 *      1 byte the read compression algorithm
 *
 *      1 byte the write cipher algorithm
 *      1 byte the write mac algorithm
 *      1 byte the write compression algorithm
 *
 *      1 byte the certificate type
 *      1 byte the protocol version
 *
 *      2 bytes the cipher suite
 *
 *      48 bytes the master secret
 *
 *      32 bytes the client random
 *      32 bytes the server random
 *
 *      1 byte the session ID size
 *      x bytes the session ID (32 bytes max)
 *
 *      4 bytes a timestamp
 *            -------------------
 *                MAX: 165 bytes
 *
 *      EXTENSIONS:
 *      2 bytes the record send size
 *      2 bytes the record recv size
 *
 *      1 byte the SRP username size
 *      x bytes the SRP username (MAX_SRP_USERNAME)
 *
 *      2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
 *      1 byte the first name type
 *      2 bytes the size of the first name 
 *      x bytes the first name (MAX_SERVER_NAME_SIZE)
 *       and so on...
 *
 *           --------------------
 *                MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
 */
static int
pack_security_parameters (gnutls_session_t session,
			  gnutls_datum_t * packed_session)
{
  int pos = 0;
  size_t len, init, i;

  /* move after the auth info stuff.
   */
  init =
    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
    PACK_HEADER_SIZE;

  pos = init + 4;		/* make some space to write later the size */

  packed_session->data[pos++] = session->security_parameters.entity;
  packed_session->data[pos++] = session->security_parameters.kx_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.read_bulk_cipher_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.read_mac_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.read_compression_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.write_bulk_cipher_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.write_mac_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.write_compression_algorithm;
  packed_session->data[pos++] =
    session->security_parameters.current_cipher_suite.suite[0];
  packed_session->data[pos++] =
    session->security_parameters.current_cipher_suite.suite[1];

  packed_session->data[pos++] = session->security_parameters.cert_type;
  packed_session->data[pos++] = session->security_parameters.version;

  memcpy (&packed_session->data[pos],
	  session->security_parameters.master_secret, TLS_MASTER_SIZE);
  pos += TLS_MASTER_SIZE;

  memcpy (&packed_session->data[pos],
	  session->security_parameters.client_random, TLS_RANDOM_SIZE);
  pos += TLS_RANDOM_SIZE;
  memcpy (&packed_session->data[pos],
	  session->security_parameters.server_random, TLS_RANDOM_SIZE);
  pos += TLS_RANDOM_SIZE;

  packed_session->data[pos++] = session->security_parameters.session_id_size;
  memcpy (&packed_session->data[pos], session->security_parameters.session_id,
	  session->security_parameters.session_id_size);
  pos += session->security_parameters.session_id_size;

  _gnutls_write_uint32 (session->security_parameters.timestamp,
			&packed_session->data[pos]);
  pos += 4;

  /* Extensions */
  _gnutls_write_uint16 (session->security_parameters.max_record_send_size,
			&packed_session->data[pos]);
  pos += 2;

  _gnutls_write_uint16 (session->security_parameters.max_record_recv_size,
			&packed_session->data[pos]);
  pos += 2;

  /* SRP */
  len =
    strlen ((char *) session->security_parameters.extensions.srp_username);
  packed_session->data[pos++] = len;
  memcpy (&packed_session->data[pos],
	  session->security_parameters.extensions.srp_username, len);
  pos += len;

  _gnutls_write_uint16 (session->security_parameters.extensions.
			server_names_size, &packed_session->data[pos]);
  pos += 2;

  for (i = 0; i < session->security_parameters.extensions.server_names_size;
       i++)
    {
      packed_session->data[pos++] =
	session->security_parameters.extensions.server_names[i].type;
      _gnutls_write_uint16 (session->security_parameters.extensions.
			    server_names[i].name_length,
			    &packed_session->data[pos]);
      pos += 2;

      memcpy (&packed_session->data[pos],
	      session->security_parameters.extensions.server_names[i].name,
	      session->security_parameters.extensions.server_names[i].
	      name_length);
      pos +=
	session->security_parameters.extensions.server_names[i].name_length;
    }

  /* write the total size */
  _gnutls_write_uint32 (pos - init - 4, &packed_session->data[init]);
  packed_session->size += pos - init;

  return 0;
}
예제 #9
0
static int
unpack_psk_auth_info (gnutls_session_t session,
		      const gnutls_datum_t * packed_session)
{
  size_t username_size;
  size_t pack_size;
  int pos = 0, size, ret;
  psk_auth_info_t info;

  if (packed_session->data[0] != GNUTLS_CRD_PSK)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
  pos += PACK_HEADER_SIZE + 4;


  if (pack_size == 0)
    return 0;			/* nothing to be done */

  /* a simple check for integrity */
  if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* client and serer have the same auth_info here
   */
  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
			   sizeof (psk_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  username_size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;

  memcpy (info->username, &packed_session->data[pos], username_size);
  pos += username_size;

  info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
  pos += 2;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
		       size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  return 0;

error:
  _gnutls_free_datum (&info->dh.prime);
  _gnutls_free_datum (&info->dh.generator);
  _gnutls_free_datum (&info->dh.public_key);
  return ret;
}
예제 #10
0
/* Upack certificate info.
 */
static int
unpack_certificate_auth_info (gnutls_session_t session,
			      const gnutls_datum_t * packed_session)
{
  int pos = 0, size, ret;
  unsigned int i = 0, j;
  size_t pack_size;
  cert_auth_info_t info;

  if (packed_session->data[0] != GNUTLS_CRD_CERTIFICATE)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
  pos += PACK_HEADER_SIZE + 4;

  if (pack_size == 0)
    return 0;			/* nothing to be done */

  /* a simple check for integrity */
  if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* client and server have the same auth_info here
   */
  ret =
    _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
			   sizeof (cert_auth_info_st), 1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  info = _gnutls_get_auth_info (session);
  if (info == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
  pos += 2;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
		       size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->rsa_export.modulus,
		       &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;
  ret =
    _gnutls_set_datum (&info->rsa_export.exponent,
		       &packed_session->data[pos], size);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pos += size;

  info->ncerts = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;

  if (info->ncerts > 0)
    {
      info->raw_certificate_list =
	gnutls_calloc (1, sizeof (gnutls_datum_t) * info->ncerts);
      if (info->raw_certificate_list == NULL)
	{
	  gnutls_assert ();
	  ret = GNUTLS_E_MEMORY_ERROR;
	  goto error;
	}
    }

  for (i = 0; i < info->ncerts; i++)
    {
      size = _gnutls_read_uint32 (&packed_session->data[pos]);
      pos += sizeof (uint32_t);

      ret =
	_gnutls_set_datum (&info->raw_certificate_list[i],
			   &packed_session->data[pos], size);
      pos += size;

      if (ret < 0)
	{
	  gnutls_assert ();
	  goto error;
	}
    }


  return 0;

error:
  _gnutls_free_datum (&info->dh.prime);
  _gnutls_free_datum (&info->dh.generator);
  _gnutls_free_datum (&info->dh.public_key);

  _gnutls_free_datum (&info->rsa_export.modulus);
  _gnutls_free_datum (&info->rsa_export.exponent);

  for (j = 0; j < i; j++)
    _gnutls_free_datum (&info->raw_certificate_list[j]);

  gnutls_free (info->raw_certificate_list);

  return ret;

}
예제 #11
0
static int
unpack_security_parameters (gnutls_session_t session,
			    const gnutls_datum_t * packed_session)
{
  size_t pack_size, init, i;
  int pos = 0, len;
  time_t timestamp = time (0);


  /* skip the auth info stuff */
  init =
    _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
    PACK_HEADER_SIZE;

  pos = init;

  pack_size = _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;


  if (pack_size == 0)
    return GNUTLS_E_INVALID_REQUEST;

  /* a simple check for integrity */
  if (pack_size > MAX_SEC_PARAMS)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  session->internals.resumed_security_parameters.entity =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.kx_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.read_bulk_cipher_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.read_mac_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.read_compression_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.write_bulk_cipher_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.write_mac_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.write_compression_algorithm =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.current_cipher_suite.
    suite[0] = packed_session->data[pos++];
  session->internals.resumed_security_parameters.current_cipher_suite.
    suite[1] = packed_session->data[pos++];

  session->internals.resumed_security_parameters.cert_type =
    packed_session->data[pos++];
  session->internals.resumed_security_parameters.version =
    packed_session->data[pos++];

  memcpy (session->internals.resumed_security_parameters.master_secret,
	  &packed_session->data[pos], TLS_MASTER_SIZE);
  pos += TLS_MASTER_SIZE;

  memcpy (session->internals.resumed_security_parameters.client_random,
	  &packed_session->data[pos], TLS_RANDOM_SIZE);
  pos += TLS_RANDOM_SIZE;
  memcpy (session->internals.resumed_security_parameters.server_random,
	  &packed_session->data[pos], TLS_RANDOM_SIZE);
  pos += TLS_RANDOM_SIZE;

  session->internals.resumed_security_parameters.session_id_size =
    packed_session->data[pos++];
  memcpy (session->internals.resumed_security_parameters.session_id,
	  &packed_session->data[pos],
	  session->internals.resumed_security_parameters.session_id_size);
  pos += session->internals.resumed_security_parameters.session_id_size;

  session->internals.resumed_security_parameters.timestamp =
    _gnutls_read_uint32 (&packed_session->data[pos]);
  pos += 4;

  if (timestamp - session->internals.resumed_security_parameters.timestamp >
      session->internals.expire_time
      || session->internals.resumed_security_parameters.timestamp > timestamp)
    {
      gnutls_assert ();
      return GNUTLS_E_EXPIRED;
    }

  /* Extensions */
  session->internals.resumed_security_parameters.max_record_send_size =
    _gnutls_read_uint16 (&packed_session->data[pos]);
  pos += 2;

  session->internals.resumed_security_parameters.max_record_recv_size =
    _gnutls_read_uint16 (&packed_session->data[pos]);
  pos += 2;


  /* SRP */
  len = packed_session->data[pos++];	/* srp username length */
  memcpy (session->internals.resumed_security_parameters.extensions.
	  srp_username, &packed_session->data[pos], len);
  session->internals.resumed_security_parameters.extensions.
    srp_username[len] = 0;
  pos += len;

  session->internals.resumed_security_parameters.extensions.
    server_names_size = _gnutls_read_uint16 (&packed_session->data[pos]);
  pos += 2;
  for (i = 0;
       i <
       session->internals.resumed_security_parameters.extensions.
       server_names_size; i++)
    {
      session->internals.resumed_security_parameters.extensions.
	server_names[i].type = packed_session->data[pos++];
      session->internals.resumed_security_parameters.extensions.
	server_names[i].name_length =
	_gnutls_read_uint16 (&packed_session->data[pos]);
      pos += 2;

      memcpy (session->internals.resumed_security_parameters.extensions.
	      server_names[i].name, &packed_session->data[pos],
	      session->internals.resumed_security_parameters.extensions.
	      server_names[i].name_length);
      pos +=
	session->internals.resumed_security_parameters.extensions.
	server_names[i].name_length;
    }
  return 0;
}
예제 #12
0
static int
unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st *data)
{
	uint32_t age_add, lifetime;
	struct timespec creation_time;
	uint8_t resumption_master_secret[MAX_HASH_SIZE];
	size_t resumption_master_secret_size;
	uint8_t nonce[UINT8_MAX];
	size_t nonce_size;
	gnutls_datum_t state;
	gnutls_mac_algorithm_t kdf;
	const mac_entry_st *prf;
	uint8_t *p;
	ssize_t len;
	uint64_t v;
	int ret;

	if (unlikely(packed == NULL || data == NULL))
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	memset(data, 0, sizeof(*data));

	p = packed->data;
	len = packed->size;

	DECR_LEN(len, 2);
	kdf = _gnutls_read_uint16(p);
	p += 2;

	/* Check if the MAC ID we got is valid */
	prf = _gnutls_mac_to_entry(kdf);
	if (prf == NULL)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	/* Read the ticket age add and the ticket lifetime */
	DECR_LEN(len, 4);
	age_add = _gnutls_read_uint32(p);
	p += 4;

	DECR_LEN(len, 4);
	lifetime = _gnutls_read_uint32(p);
	p += 4;

	/*
	 * Check if the whole ticket is large enough,
	 * and read the resumption master secret
	 */
	DECR_LEN(len, 1);
	resumption_master_secret_size = *p;
	p += 1;

	/* Check if the size of resumption_master_secret matches the PRF */
	if (resumption_master_secret_size != prf->output_size)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	DECR_LEN(len, resumption_master_secret_size);
	memcpy(resumption_master_secret, p, resumption_master_secret_size);
	p += resumption_master_secret_size;

	/* Read the ticket nonce */
	DECR_LEN(len, 1);
	nonce_size = *p;
	p += 1;

	DECR_LEN(len, nonce_size);
	memcpy(nonce, p, nonce_size);
	p += nonce_size;

	DECR_LEN(len, 2);
	state.size = _gnutls_read_uint16(p);
	p += 2;

	DECR_LEN(len, state.size);
	state.data = p;
	p += state.size;

	DECR_LEN(len, 12);
	v = _gnutls_read_uint32(p);
	p += 4;
	creation_time.tv_sec = (v << 32) | _gnutls_read_uint32(p);
	p += 4;
	creation_time.tv_nsec = _gnutls_read_uint32(p);

	ret = _gnutls_session_unpack(session, &state);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* No errors - Now return all the data to the caller */
	data->prf = prf;
	memcpy(data->resumption_master_secret, resumption_master_secret,
	       resumption_master_secret_size);
	memcpy(data->nonce, nonce, nonce_size);
	data->nonce_size = nonce_size;
	data->age_add = age_add;
	data->lifetime = lifetime;
	memcpy(&data->creation_time, &creation_time, sizeof(struct timespec));

	return 0;
}
예제 #13
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;
}