Exemple #1
0
/**
 * gnutls_openpgp_privkey_get_subkey_id:
 * @key: the structure that contains the OpenPGP secret key.
 * @idx: the subkey index
 * @keyid: the buffer to save the keyid.
 *
 * Get the key-id for the subkey.
 *
 * Returns: the 64-bit keyID of the OpenPGP key.
 *
 * Since: 2.4.0
 **/
int
gnutls_openpgp_privkey_get_subkey_id(gnutls_openpgp_privkey_t key,
				     unsigned int idx,
				     gnutls_openpgp_keyid_t keyid)
{
	cdk_packet_t pkt;
	uint32_t kid[2];

	if (!key || !keyid) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
		return gnutls_openpgp_privkey_get_key_id(key, keyid);

	pkt = _get_secret_subkey(key, idx);
	if (!pkt)
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;

	cdk_sk_get_keyid(pkt->pkt.secret_key, kid);
	_gnutls_write_uint32(kid[0], keyid);
	_gnutls_write_uint32(kid[1], keyid + 4);

	return 0;
}
Exemple #2
0
static int
pack_ticket(gnutls_session_t session, tls13_ticket_st *ticket, gnutls_datum_t *packed)
{
	uint8_t *p;
	gnutls_datum_t state;
	int ret;

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

	packed->size = 2 + 4 + 4 +
		1 + ticket->prf->output_size +
		1 + ticket->nonce_size + 2 + state.size + 12;

	packed->data = gnutls_malloc(packed->size);
	if (!packed->data) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}

	p = packed->data;

	_gnutls_write_uint16(ticket->prf->id, p);
	p += 2;
	_gnutls_write_uint32(ticket->age_add, p);
	p += 4;
	_gnutls_write_uint32(ticket->lifetime, p);
	p += 4;
	*p = ticket->prf->output_size;
	p += 1;
	memcpy(p, ticket->resumption_master_secret, ticket->prf->output_size);
	p += ticket->prf->output_size;
	*p = ticket->nonce_size;

	p += 1;
	memcpy(p, ticket->nonce, ticket->nonce_size);
	p += ticket->nonce_size;

	_gnutls_write_uint16(state.size, p);
	p += 2;

	memcpy(p, state.data, state.size);
	p += state.size;

	_gnutls_write_uint32((uint64_t) ticket->creation_time.tv_sec >> 32, p);
	p += 4;
	_gnutls_write_uint32(ticket->creation_time.tv_sec & 0xFFFFFFFF, p);
	p += 4;
	_gnutls_write_uint32(ticket->creation_time.tv_nsec, p);

	ret = 0;

 cleanup:
	gnutls_free(state.data);
	return ret;
}
Exemple #3
0
int
_gnutls_buffer_append_prefix (gnutls_buffer_st * buf, int pfx_size, size_t data_size)
{
  opaque ss[4];

  if (pfx_size == 32)
    {
      _gnutls_write_uint32 (data_size, ss);
      pfx_size = 4;
    }
  else if (pfx_size == 24)
    {
      _gnutls_write_uint24 (data_size, ss);
      pfx_size = 3;
    }
  else if (pfx_size == 16)
    {
      _gnutls_write_uint16 (data_size, ss);
      pfx_size = 2;
    }
  else if (pfx_size == 8)
    {
      ss[0] = data_size;
      pfx_size = 1;
    }
  else
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

  return _gnutls_buffer_append_data (buf, ss, pfx_size);
}
Exemple #4
0
void
_gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat)
{
  _gnutls_write_uint32 (dat.size, dest);
  if (dat.data != NULL)
    memcpy (&dest[4], dat.data, dat.size);
}
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;
}
Exemple #6
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_anon_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  int cur_size, ret;
  anon_auth_info_t info = _gnutls_get_auth_info (session);
  int size_offset;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  if (info)
    {
      BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
      BUFFER_APPEND_PFX (ps, info->dh.prime.data, info->dh.prime.size);
      BUFFER_APPEND_PFX (ps, info->dh.generator.data,
                         info->dh.generator.size);
      BUFFER_APPEND_PFX (ps, info->dh.public_key.data,
                         info->dh.public_key.size);
    }

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
int _gnutls_ext_pack(gnutls_session_t session, gnutls_buffer_st * packed)
{
	unsigned int i;
	int ret;
	extension_priv_data_t data;
	int cur_size;
	int size_offset;
	int total_exts_pos;
	int exts = 0;

	total_exts_pos = packed->length;
	BUFFER_APPEND_NUM(packed, 0);

	for (i = 0; i < extfunc_size; i++) {
		ret =
		    _gnutls_ext_get_session_data(session, extfunc[i].type,
						 &data);
		if (ret >= 0 && extfunc[i].pack_func != NULL) {
			BUFFER_APPEND_NUM(packed, extfunc[i].type);

			size_offset = packed->length;
			BUFFER_APPEND_NUM(packed, 0);

			cur_size = packed->length;

			ret = extfunc[i].pack_func(data, packed);
			if (ret < 0) {
				gnutls_assert();
				return ret;
			}

			exts++;
			/* write the actual size */
			_gnutls_write_uint32(packed->length - cur_size,
					     packed->data + size_offset);
		}
	}

	_gnutls_write_uint32(exts, packed->data + total_exts_pos);

	return 0;
}
Exemple #8
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_anon_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
{
  anon_auth_info_t info = _gnutls_get_auth_info (session);
  int pos = 0;
  size_t pack_size;

  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info)
    pack_size = 2 + 4 * 3 + info->dh.prime.size +
      info->dh.generator.size + info->dh.public_key.size;
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  packed_session->data[0] = GNUTLS_CRD_ANON;
  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
  pos += 4 + PACK_HEADER_SIZE;

  if (pack_size > 0)
    {
      _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
      pos += 2;

      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
      pos += 4 + info->dh.prime.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
      pos += 4 + info->dh.generator.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
      pos += 4 + info->dh.public_key.size;

    }

  return 0;
}
Exemple #9
0
/**
 * gnutls_openpgp_privkey_get_key_id:
 * @key: the structure that contains the OpenPGP secret key.
 * @keyid: the buffer to save the keyid.
 *
 * Get key-id.
 *
 * Returns: the 64-bit keyID of the OpenPGP key.
 *
 * Since: 2.4.0
 **/
int
gnutls_openpgp_privkey_get_key_id(gnutls_openpgp_privkey_t key,
				  gnutls_openpgp_keyid_t keyid)
{
	cdk_packet_t pkt;
	uint32_t kid[2];

	if (!key || !keyid) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY);
	if (!pkt)
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;

	cdk_sk_get_keyid(pkt->pkt.secret_key, kid);
	_gnutls_write_uint32(kid[0], keyid);
	_gnutls_write_uint32(kid[1], keyid + 4);

	return 0;
}
Exemple #10
0
/* Writes the specified integer into the specified node.
 */
int
_gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
{
  opaque tmpstr[4];
  int result;

  _gnutls_write_uint32 (num, tmpstr);

  result = asn1_write_value (node, value, tmpstr, 4);

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

  return 0;
}
Exemple #11
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the SRP username (x)
 *      x bytes the SRP username
 */
static int
pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
{
  srp_server_auth_info_t info = _gnutls_get_auth_info (session);
  int pack_size;

  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info && info->username)
    pack_size = strlen (info->username) + 1;	/* include the terminating null */
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  packed_session->data[0] = GNUTLS_CRD_SRP;
  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);

  if (pack_size > 0)
    memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
	    info->username, pack_size + 1);

  return 0;
}
Exemple #12
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *        DH stuff
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 *        RSA stuff
 *      4 bytes the size of the modulus
 *      x bytes the modulus
 *      4 bytes the size of the exponent
 *      x bytes the exponent
 *        CERTIFICATES
 *      4 bytes the length of the certificate list
 *      4 bytes the size of first certificate
 *      x bytes the certificate
 *       and so on...
 */
static int
pack_certificate_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  unsigned int i;
  int cur_size, ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);
  int size_offset;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  if (info)
    {

      BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
      BUFFER_APPEND_PFX (ps, info->dh.prime.data, info->dh.prime.size);
      BUFFER_APPEND_PFX (ps, info->dh.generator.data,
                         info->dh.generator.size);
      BUFFER_APPEND_PFX (ps, info->dh.public_key.data,
                         info->dh.public_key.size);
      BUFFER_APPEND_PFX (ps, info->rsa_export.modulus.data,
                         info->rsa_export.modulus.size);
      BUFFER_APPEND_PFX (ps, info->rsa_export.exponent.data,
                         info->rsa_export.exponent.size);

      BUFFER_APPEND_NUM (ps, info->ncerts);

      for (i = 0; i < info->ncerts; i++)
        BUFFER_APPEND_PFX (ps, info->raw_certificate_list[i].data,
                           info->raw_certificate_list[i].size);
    }

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #13
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *
 *      4 bytes the size of the PSK username (x)
 *      x bytes the PSK username
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  psk_auth_info_t info;
  int username_len;
  int hint_len, ret;
  int size_offset;
  size_t cur_size;

  info = _gnutls_get_auth_info (session);

  if (info && info->username)
    username_len = strlen (info->username) + 1; /* include the terminating null */
  else
    username_len = 0;

  if (info && info->hint)
    hint_len = strlen (info->hint) + 1; /* include the terminating null */
  else
    hint_len = 0;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  BUFFER_APPEND_PFX (ps, info->username, username_len);
  BUFFER_APPEND_PFX (ps, info->hint, hint_len);

  BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
  BUFFER_APPEND_PFX (ps, info->dh.prime.data, info->dh.prime.size);
  BUFFER_APPEND_PFX (ps, info->dh.generator.data, info->dh.generator.size);
  BUFFER_APPEND_PFX (ps, info->dh.public_key.data, info->dh.public_key.size);

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #14
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the SRP username (x)
 *      x bytes the SRP username
 */
static int
pack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
{
  srp_server_auth_info_t info = _gnutls_get_auth_info (session);
  int len, ret;
  int size_offset;
  size_t cur_size;

  if (info && info->username)
    len = strlen (info->username) + 1;  /* include the terminating null */
  else
    len = 0;

  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;

  BUFFER_APPEND_PFX (ps, info->username, len);

  /* write the real size */
  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}
Exemple #15
0
int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
{
    mbuffer_st *bufel = NULL;
    uint8_t *data = NULL, *p;
    int data_size = 0;
    int ret;
    struct ticket_st ticket;
    uint16_t ticket_len;
    session_ticket_ext_st *priv = NULL;
    extension_priv_data_t epriv;
    uint16_t epoch_saved = session->security_parameters.epoch_write;

    if (again == 0) {
        ret =
            _gnutls_ext_get_session_data(session,
                                         GNUTLS_EXTENSION_SESSION_TICKET,
                                         &epriv);
        if (ret < 0)
            return 0;
        priv = epriv;

        if (!priv->session_ticket_renew)
            return 0;

        /* XXX: Temporarily set write algorithms to be used.
           _gnutls_write_connection_state_init() does this job, but it also
           triggers encryption, while NewSessionTicket should not be
           encrypted in the record layer. */
        ret =
            _gnutls_epoch_set_keys(session,
                                   session->security_parameters.
                                   epoch_next);
        if (ret < 0) {
            gnutls_assert();
            return ret;
        }

        session->security_parameters.epoch_write =
            session->security_parameters.epoch_next;

        ret = encrypt_ticket(session, priv, &ticket);
        session->security_parameters.epoch_write = epoch_saved;
        if (ret < 0) {
            gnutls_assert();
            return ret;
        }

        ticket_len =
            KEY_NAME_SIZE + IV_SIZE + 2 +
            ticket.encrypted_state_len + MAC_SIZE;

        bufel =
            _gnutls_handshake_alloc(session,
                                    4 + 2 + ticket_len);
        if (!bufel) {
            gnutls_assert();
            gnutls_free(ticket.encrypted_state);
            return GNUTLS_E_MEMORY_ERROR;
        }

        data = _mbuffer_get_udata_ptr(bufel);
        p = data;

        _gnutls_write_uint32(session->internals.expire_time, p);
        p += 4;

        _gnutls_write_uint16(ticket_len, p);
        p += 2;

        memcpy(p, ticket.key_name, KEY_NAME_SIZE);
        p += KEY_NAME_SIZE;

        memcpy(p, ticket.IV, IV_SIZE);
        p += IV_SIZE;

        _gnutls_write_uint16(ticket.encrypted_state_len, p);
        p += 2;

        memcpy(p, ticket.encrypted_state, ticket.encrypted_state_len);
        gnutls_free(ticket.encrypted_state);
        p += ticket.encrypted_state_len;

        memcpy(p, ticket.mac, MAC_SIZE);
        p += MAC_SIZE;

        data_size = p - data;

        session->internals.ticket_sent = 1;
    }
    return _gnutls_send_handshake(session, data_size ? bufel : NULL,
                                  GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);
}
Exemple #16
0
/*
 * Return zero if session tickets haven't been enabled.
 */
int _gnutls_send_new_session_ticket(gnutls_session_t session, int again)
{
	mbuffer_st *bufel = NULL;
	uint8_t *data = NULL, *p;
	int data_size = 0;
	int ret;
	gnutls_datum_t state = { NULL, 0 };
	uint16_t epoch_saved = session->security_parameters.epoch_write;
	gnutls_datum_t ticket_data;

	if (again == 0) {
		if (session->internals.flags & GNUTLS_NO_TICKETS)
			return 0;
		if (!session->internals.session_ticket_renew)
			return 0;

		_gnutls_handshake_log
		    ("HSK[%p]: sending session ticket\n", session);

		/* XXX: Temporarily set write algorithms to be used.
		   _gnutls_write_connection_state_init() does this job, but it also
		   triggers encryption, while NewSessionTicket should not be
		   encrypted in the record layer. */
		ret =
		    _gnutls_epoch_set_keys(session,
					   session->security_parameters.
					   epoch_next, 0);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		/* Under TLS1.2 with session tickets, the session ID is used for different
		 * purposes than the TLS1.0 session ID. Ensure that there is an internally
		 * set value which the server will see on the original and resumed sessions */
		if (session->internals.resumed != RESUME_TRUE) {
			ret = _gnutls_generate_session_id(session->security_parameters.
							  session_id,
							  &session->security_parameters.
							  session_id_size);
			if (ret < 0) {
				gnutls_assert();
				return ret;
			}
		}

		session->security_parameters.epoch_write =
		    session->security_parameters.epoch_next;

		/* Pack security parameters. */
		ret = _gnutls_session_pack(session, &state);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		/* Generate an encrypted ticket */
		ret = _gnutls_encrypt_session_ticket(session, &state, &ticket_data);
		session->security_parameters.epoch_write = epoch_saved;
		_gnutls_free_datum(&state);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		bufel =
		    _gnutls_handshake_alloc(session, 
					    4 + 2 + ticket_data.size);
		if (!bufel) {
			gnutls_assert();
			_gnutls_free_datum(&ticket_data);
			return GNUTLS_E_MEMORY_ERROR;
		}

		data = _mbuffer_get_udata_ptr(bufel);
		p = data;

		_gnutls_write_uint32(session->internals.expire_time, p);
		p += 4;

		_gnutls_write_uint16(ticket_data.size, p);
		p += 2;

		memcpy(p, ticket_data.data, ticket_data.size);
		p += ticket_data.size;

		_gnutls_free_datum(&ticket_data);

		data_size = p - data;

		session->internals.hsk_flags |= HSK_TLS12_TICKET_SENT;
	}
	return _gnutls_send_handshake(session, data_size ? bufel : NULL,
				      GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);
}
Exemple #17
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *        DH stuff
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 *        RSA stuff
 *      4 bytes the size of the modulus
 *      x bytes the modulus
 *      4 bytes the size of the exponent
 *      x bytes the exponent
 *        CERTIFICATES
 *      4 bytes the length of the certificate list
 *      4 bytes the size of first certificate
 *      x bytes the certificate
 *       and so on...
 */
static int
pack_certificate_auth_info (gnutls_session_t session,
			    gnutls_datum_t * packed_session)
{
  unsigned int pos = 0, i;
  int cert_size, pack_size;
  cert_auth_info_t info = _gnutls_get_auth_info (session);


  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info)
    {
      cert_size = 4;

      for (i = 0; i < info->ncerts; i++)
	cert_size += 4 + info->raw_certificate_list[i].size;

      pack_size = 2 + 4 + info->dh.prime.size +
	4 + info->dh.generator.size + 4 + info->dh.public_key.size +
	4 + info->rsa_export.modulus.size +
	4 + info->rsa_export.exponent.size + cert_size;
    }
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  packed_session->data[0] = GNUTLS_CRD_CERTIFICATE;
  _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
  pos += 4 + PACK_HEADER_SIZE;


  if (pack_size > 0)
    {

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

      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
      pos += 4 + info->dh.prime.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
      pos += 4 + info->dh.generator.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
      pos += 4 + info->dh.public_key.size;

      _gnutls_write_datum32 (&packed_session->data[pos],
			     info->rsa_export.modulus);
      pos += 4 + info->rsa_export.modulus.size;
      _gnutls_write_datum32 (&packed_session->data[pos],
			     info->rsa_export.exponent);
      pos += 4 + info->rsa_export.exponent.size;

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

      for (i = 0; i < info->ncerts; i++)
	{
	  _gnutls_write_datum32 (&packed_session->data[pos],
				 info->raw_certificate_list[i]);
	  pos += sizeof (uint32_t) + info->raw_certificate_list[i].size;
	}
    }

  return 0;
}
Exemple #18
0
/* Format: 
 *      1 byte the credentials type
 *      4 bytes the size of the whole structure
 *      4 bytes the size of the PSK username (x)
 *      x bytes the PSK username
 *      2 bytes the size of secret key in bits
 *      4 bytes the size of the prime
 *      x bytes the prime
 *      4 bytes the size of the generator
 *      x bytes the generator
 *      4 bytes the size of the public key
 *      x bytes the public key
 */
static int
pack_psk_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
{
  psk_auth_info_t info;
  int pack_size, username_size = 0, pos;

  info = _gnutls_get_auth_info (session);

  if (info == NULL && session->key->auth_info_size != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (info)
    {
      username_size = strlen (info->username) + 1;	/* include the terminating null */
      pack_size = username_size +
	2 + 4 * 3 + info->dh.prime.size + info->dh.generator.size +
	info->dh.public_key.size;
    }
  else
    pack_size = 0;

  packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);

  /* calculate the size and allocate the data.
   */
  packed_session->data =
    gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);

  if (packed_session->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  pos = 0;

  packed_session->data[pos] = GNUTLS_CRD_PSK;
  pos++;

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


  if (pack_size > 0)
    {
      _gnutls_write_uint32 (username_size, &packed_session->data[pos]);
      pos += 4;

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

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

      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
      pos += 4 + info->dh.prime.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
      pos += 4 + info->dh.generator.size;
      _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
      pos += 4 + info->dh.public_key.size;

    }


  return 0;
}
Exemple #19
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;
}
Exemple #20
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
 *
 */
static int
pack_security_parameters (gnutls_session_t session, gnutls_buffer_st * ps)
{

  int ret;
  int size_offset;
  size_t cur_size;
  record_parameters_st *params;

  if (session->security_parameters.epoch_read
      != session->security_parameters.epoch_write)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &params);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* move after the auth info stuff.
   */
  size_offset = ps->length;
  BUFFER_APPEND_NUM (ps, 0);
  cur_size = ps->length;


  BUFFER_APPEND (ps, &session->security_parameters.entity, 1);
  BUFFER_APPEND (ps, &session->security_parameters.kx_algorithm, 1);
  BUFFER_APPEND (ps,
                 &session->security_parameters.current_cipher_suite.suite[0],
                 1);
  BUFFER_APPEND (ps,
                 &session->security_parameters.current_cipher_suite.suite[1],
                 1);
  BUFFER_APPEND (ps, &params->compression_algorithm, 1);
  BUFFER_APPEND (ps, &session->security_parameters.cert_type, 1);
  BUFFER_APPEND (ps, &session->security_parameters.version, 1);

  BUFFER_APPEND (ps, session->security_parameters.master_secret,
                 GNUTLS_MASTER_SIZE);
  BUFFER_APPEND (ps, session->security_parameters.client_random,
                 GNUTLS_RANDOM_SIZE);
  BUFFER_APPEND (ps, session->security_parameters.server_random,
                 GNUTLS_RANDOM_SIZE);

  BUFFER_APPEND_NUM (ps, session->security_parameters.session_id_size);
  BUFFER_APPEND (ps, session->security_parameters.session_id,
                 session->security_parameters.session_id_size);

  BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_send_size);
  BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_recv_size);
  BUFFER_APPEND_NUM (ps, session->security_parameters.timestamp);

  _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);

  return 0;
}