示例#1
0
int
_gnutls_recv_server_certificate_request (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;

  if (session->internals.
      auth_struct->gnutls_process_server_certificate_request != NULL)
    {

      ret =
        _gnutls_recv_handshake (session, 
                                GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
                                OPTIONAL_PACKET, &buf);
      if (ret < 0)
        return ret;

      if (ret == 0 && buf.length == 0)
        {
          _gnutls_buffer_clear(&buf);
          return 0;               /* ignored */
        }

      ret =
        session->internals.
        auth_struct->gnutls_process_server_certificate_request (session, buf.data,
                                                                buf.length);
      _gnutls_buffer_clear (&buf);
      if (ret < 0)
        return ret;

    }
  return ret;
}
示例#2
0
/**
 * gnutls_deinit:
 * @session: is a #gnutls_session_t structure.
 *
 * This function clears all buffers associated with the @session.
 * This function will also remove session data from the session
 * database if the session was terminated abnormally.
 **/
void
gnutls_deinit (gnutls_session_t session)
{
  unsigned int i;

  if (session == NULL)
    return;

  _gnutls_rnd_refresh();

  /* remove auth info firstly */
  _gnutls_free_auth_info (session);

  _gnutls_handshake_internal_state_clear (session);
  _gnutls_handshake_io_buffer_clear (session);
  _gnutls_ext_free_session_data (session);

  for (i = 0; i < MAX_EPOCH_INDEX; i++)
    if (session->record_parameters[i] != NULL)
      {
        _gnutls_epoch_free (session, session->record_parameters[i]);
        session->record_parameters[i] = NULL;
      }

  _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
  _gnutls_buffer_clear (&session->internals.hb_remote_data);
  _gnutls_buffer_clear (&session->internals.hb_local_data);
  _gnutls_buffer_clear (&session->internals.record_presend_buffer);

  _mbuffer_head_clear (&session->internals.record_buffer);
  _mbuffer_head_clear (&session->internals.record_recv_buffer);
  _mbuffer_head_clear (&session->internals.record_send_buffer);

  gnutls_credentials_clear (session);
  _gnutls_selected_certs_deinit (session);

  gnutls_pk_params_release(&session->key.ecdh_params);
  _gnutls_mpi_release (&session->key.ecdh_x);
  _gnutls_mpi_release (&session->key.ecdh_y);

  _gnutls_mpi_release (&session->key.KEY);
  _gnutls_mpi_release (&session->key.client_Y);
  _gnutls_mpi_release (&session->key.client_p);
  _gnutls_mpi_release (&session->key.client_g);

  _gnutls_mpi_release (&session->key.u);
  _gnutls_mpi_release (&session->key.a);
  _gnutls_mpi_release (&session->key.x);
  _gnutls_mpi_release (&session->key.A);
  _gnutls_mpi_release (&session->key.B);
  _gnutls_mpi_release (&session->key.b);

  /* RSA */
  _gnutls_mpi_release (&session->key.rsa[0]);
  _gnutls_mpi_release (&session->key.rsa[1]);

  _gnutls_mpi_release (&session->key.dh_secret);
  
  gnutls_free (session);
}
示例#3
0
文件: kx.c 项目: GostCrypt/GnuTLS
int _gnutls_recv_server_kx_message(gnutls_session_t session)
{
	gnutls_buffer_st buf;
	int ret = 0;
	unsigned int optflag = 0;

	if (session->internals.auth_struct->gnutls_process_server_kx !=
	    NULL) {
		/* Server key exchange packet is optional for PSK. */
		if (_gnutls_session_is_psk(session))
			optflag = 1;

		ret =
		    _gnutls_recv_handshake(session,
					   GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
					   optflag, &buf);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		ret =
		    session->internals.auth_struct->
		    gnutls_process_server_kx(session, buf.data,
					     buf.length);
		_gnutls_buffer_clear(&buf);

		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

	}
	return ret;
}
示例#4
0
文件: kx.c 项目: GostCrypt/GnuTLS
/* This is called when we want send our certificate
 */
int _gnutls_send_server_certificate(gnutls_session_t session, int again)
{
	gnutls_buffer_st data;
	int ret = 0;


	if (session->internals.auth_struct->
	    gnutls_generate_server_certificate == NULL)
		return 0;

	_gnutls_buffer_init(&data);

	if (again == 0) {
		ret =
		    session->internals.auth_struct->
		    gnutls_generate_server_certificate(session, &data);

		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}
	ret = send_handshake(session, data.data, data.length,
			     GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
	if (ret < 0) {
		gnutls_assert();
	}

      cleanup:
	_gnutls_buffer_clear(&data);
	return ret;
}
示例#5
0
/* This is the function for the client to send the key
 * exchange message 
 */
int
_gnutls_send_client_kx_message (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;

  if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
    return 0;

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      ret =
        session->internals.auth_struct->gnutls_generate_client_kx (session,
                                                                   &data);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }
    }
  ret = send_handshake (session, data.data, data.length,
                        GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
  if (ret < 0)
    {
      gnutls_assert ();
    }
  
cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
示例#6
0
int
_gnutls_recv_client_kx_message (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;


  /* Do key exchange only if the algorithm permits it */
  if (session->internals.auth_struct->gnutls_process_client_kx != NULL)
    {

      ret =
        _gnutls_recv_handshake (session, 
                                GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
                                MANDATORY_PACKET, &buf);
      if (ret < 0)
        return ret;

      ret =
        session->internals.auth_struct->gnutls_process_client_kx (session,
                                                                  buf.data,
                                                                  buf.length);
      _gnutls_buffer_clear (&buf);
      if (ret < 0)
        return ret;

    }

  return ret;
}
示例#7
0
int
_gnutls_recv_server_certificate (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;

  if (session->internals.auth_struct->gnutls_process_server_certificate !=
      NULL)
    {

      ret =
        _gnutls_recv_handshake (session, 
                                GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
                                MANDATORY_PACKET, &buf);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      ret =
        session->internals.
        auth_struct->gnutls_process_server_certificate (session, buf.data,
                                                        buf.length);
      _gnutls_buffer_clear(&buf);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
    }

  return ret;
}
示例#8
0
/* converts the buffer to a datum if possible. After this call the buffer
 * is at an usable state and might not be used or deinitialized */
int
_gnutls_buffer_to_datum (gnutls_buffer_st * str, gnutls_datum_t * data)
{

  if (str->length == 0)
    {
      data->data = NULL;
      data->size = 0;
      return 0;
    }

  if (str->allocd != str->data)
    {
      data->data = gnutls_malloc (str->length);
      if (data->data == NULL)
        {
          gnutls_assert ();
          return GNUTLS_E_MEMORY_ERROR;
        }
      memcpy (data->data, str->data, str->length);
      data->size = str->length;
      _gnutls_buffer_clear (str);
    }
  else
    {
      data->data = str->data;
      data->size = str->length;
    }

  return 0;
}
示例#9
0
/* This is called when we want send our certificate
 */
int
_gnutls_send_client_certificate (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;


  if (session->key->certificate_requested == 0)
    return 0;

  if (session->internals.auth_struct->gnutls_generate_client_certificate ==
      NULL)
    return 0;

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
          session->internals.selected_cert_list_length > 0)
        {
          /* TLS 1.0 or SSL 3.0 with a valid certificate 
           */
          ret =
            session->internals.
            auth_struct->gnutls_generate_client_certificate (session, &data);

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

  /* In the SSL 3.0 protocol we need to send a
   * no certificate alert instead of an
   * empty certificate.
   */
  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
      session->internals.selected_cert_list_length == 0)
    {
      ret =
        gnutls_alert_send (session, GNUTLS_AL_WARNING,
                           GNUTLS_A_SSL3_NO_CERTIFICATE);

    }
  else
    {                           /* TLS 1.0 or SSL 3.0 with a valid certificate 
                                 */
      ret = send_handshake (session, data.data, data.length,
                            GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
    }

cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
示例#10
0
/**
 * gnutls_deinit:
 * @session: is a #gnutls_session_t structure.
 *
 * This function clears all buffers associated with the @session.
 * This function will also remove session data from the session
 * database if the session was terminated abnormally.
 **/
void
gnutls_deinit (gnutls_session_t session)
{
  unsigned int i;

  if (session == NULL)
    return;

  /* remove auth info firstly */
  _gnutls_free_auth_info (session);

  _gnutls_handshake_internal_state_clear (session);
  _gnutls_handshake_io_buffer_clear (session);
  _gnutls_ext_free_session_data (session);

  for (i = 0; i < MAX_EPOCH_INDEX; i++)
    if (session->record_parameters[i] != NULL)
      {
        _gnutls_epoch_free (session, session->record_parameters[i]);
        session->record_parameters[i] = NULL;
      }

  _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
  _mbuffer_head_clear (&session->internals.record_buffer);
  _mbuffer_head_clear (&session->internals.record_recv_buffer);
  _mbuffer_head_clear (&session->internals.record_send_buffer);

  gnutls_credentials_clear (session);
  _gnutls_selected_certs_deinit (session);

  if (session->key != NULL)
    {
      _gnutls_mpi_release (&session->key->KEY);
      _gnutls_mpi_release (&session->key->client_Y);
      _gnutls_mpi_release (&session->key->client_p);
      _gnutls_mpi_release (&session->key->client_g);

      _gnutls_mpi_release (&session->key->u);
      _gnutls_mpi_release (&session->key->a);
      _gnutls_mpi_release (&session->key->x);
      _gnutls_mpi_release (&session->key->A);
      _gnutls_mpi_release (&session->key->B);
      _gnutls_mpi_release (&session->key->b);

      /* RSA */
      _gnutls_mpi_release (&session->key->rsa[0]);
      _gnutls_mpi_release (&session->key->rsa[1]);

      _gnutls_mpi_release (&session->key->dh_secret);
      gnutls_free (session->key);

      session->key = NULL;
    }

  memset (session, 0, sizeof (struct gnutls_session_int));
  gnutls_free (session);
}
示例#11
0
int
_gnutls_handshake_buffer_clear (gnutls_session_t session)
{

    _gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");

    _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);

    return 0;
}
示例#12
0
/* This is the function for the client to send the certificate
 * verify message
 */
int
_gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;

  /* This is a packet that is only sent by the client
   */
  if (session->security_parameters.entity == GNUTLS_SERVER)
    return 0;

  /* if certificate verify is not needed just exit 
   */
  if (session->key->certificate_requested == 0)
    return 0;


  if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy ==
      NULL)
    {
      gnutls_assert ();
      return 0;                 /* this algorithm does not support cli_cert_vrfy 
                                 */
    }

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      ret =
        session->internals.
        auth_struct->gnutls_generate_client_cert_vrfy (session, &data);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }

      if (ret == 0)
          goto cleanup;

    }
  ret = send_handshake (session, data.data, data.length,
                        GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);

  if (ret < 0)
    {
      gnutls_assert ();
    }
  
cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
示例#13
0
文件: state.c 项目: GostCrypt/GnuTLS
/**
 * gnutls_deinit:
 * @session: is a #gnutls_session_t type.
 *
 * This function clears all buffers associated with the @session.
 * This function will also remove session data from the session
 * database if the session was terminated abnormally.
 **/
void gnutls_deinit(gnutls_session_t session)
{
	unsigned int i;

	if (session == NULL)
		return;

	/* remove auth info firstly */
	_gnutls_free_auth_info(session);

	_gnutls_handshake_internal_state_clear(session);
	_gnutls_handshake_io_buffer_clear(session);
	_gnutls_ext_free_session_data(session);

	for (i = 0; i < MAX_EPOCH_INDEX; i++)
		if (session->record_parameters[i] != NULL) {
			_gnutls_epoch_free(session,
					   session->record_parameters[i]);
			session->record_parameters[i] = NULL;
		}

	_gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
	_gnutls_buffer_clear(&session->internals.hb_remote_data);
	_gnutls_buffer_clear(&session->internals.hb_local_data);
	_gnutls_buffer_clear(&session->internals.record_presend_buffer);

	_mbuffer_head_clear(&session->internals.record_buffer);
	_mbuffer_head_clear(&session->internals.record_recv_buffer);
	_mbuffer_head_clear(&session->internals.record_send_buffer);

	_gnutls_free_datum(&session->internals.resumption_data);

	gnutls_free(session->internals.rexts);

	gnutls_free(session->internals.rsup);

	gnutls_credentials_clear(session);
	_gnutls_selected_certs_deinit(session);

	gnutls_free(session);
}
示例#14
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn,
		    unsigned flags)
{
	gnutls_buffer_st out_str;
	int i, k1, result;

	_gnutls_buffer_init(&out_str);

	result = asn1_number_of_elements(asn1_struct, asn1_rdn_name, &k1);
	if (result != ASN1_SUCCESS) {
		if (result == ASN1_ELEMENT_NOT_FOUND || result == ASN1_VALUE_NOT_FOUND) {
			result = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
		} else {
			gnutls_assert();
			result = _gnutls_asn2err(result);
		}
		goto cleanup;
	}

	if (k1 == 0) {
		gnutls_assert();
		result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		goto cleanup;
	}

	if (flags & GNUTLS_X509_DN_FLAG_COMPAT) {
		for (i=0;i<k1;i++) {
			result = append_elements(asn1_struct, asn1_rdn_name, &out_str, i+1, (i==(k1-1))?1:0);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}
	} else {
		while (k1 > 0) {
			result = append_elements(asn1_struct, asn1_rdn_name, &out_str, k1, k1==1?1:0);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
			k1--;
		}
	}

	return _gnutls_buffer_to_datum(&out_str, dn, 1);

 cleanup:
	_gnutls_buffer_clear(&out_str);
	return result;

}
示例#15
0
int
_gnutls_recv_server_kx_message (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;
  optional_t optflag = MANDATORY_PACKET;

  if (session->internals.auth_struct->gnutls_process_server_kx != NULL)
    {

      /* EXCEPTION FOR RSA_EXPORT cipher suite 
       */
      if (_gnutls_session_is_export (session) != 0 &&
          _gnutls_peers_cert_less_512 (session) != 0)
        {
          gnutls_assert ();
          return 0;
        }

      /* Server key exchange packet is optional for PSK. */
      if (_gnutls_session_is_psk (session))
        optflag = OPTIONAL_PACKET;

      ret =
        _gnutls_recv_handshake (session, 
                                GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
                                optflag, &buf);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      ret =
        session->internals.auth_struct->gnutls_process_server_kx (session,
                                                                  buf.data,
                                                                  buf.length);
      _gnutls_buffer_clear(&buf);

      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

    }
  return ret;
}
示例#16
0
文件: krb5.c 项目: GostCrypt/GnuTLS
int _gnutls_krb5_der_to_principal(const gnutls_datum_t * der,
				  gnutls_datum_t * name)
{
	int ret, result;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	gnutls_buffer_st str;

	_gnutls_buffer_init(&str);

	result =
	    asn1_create_element(_gnutls_get_gnutls_asn(),
				"GNUTLS.KRB5PrincipalName", &c2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	result = asn1_der_decoding(&c2, der->data, der->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	ret = principal_to_str(c2, &str);
	if (ret < 0) {
		/* for some reason we cannot convert to a human readable string
		 * the principal. Then we use the #HEX format.
		 */
		_gnutls_buffer_reset(&str);
		ret = _gnutls_buffer_append_data(&str, "#", 1);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		_gnutls_buffer_hexprint(&str, der->data, der->size);
	}

	asn1_delete_structure(&c2);
	return _gnutls_buffer_to_datum(&str, name, 1);

 cleanup:
	_gnutls_buffer_clear(&str);
	asn1_delete_structure(&c2);
	return ret;
}
示例#17
0
文件: tpm.c 项目: gnutls/gnutls
static int
unescape_string(char *output, const char *input, size_t * size,
		char terminator)
{
	gnutls_buffer_st str;
	int ret = 0;
	char *p;
	int len;

	_gnutls_buffer_init(&str);

	/* find terminator */
	p = strchr(input, terminator);
	if (p != NULL)
		len = p - input;
	else
		len = strlen(input);

	ret = _gnutls_buffer_append_data(&str, input, len);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_buffer_unescape(&str);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_buffer_append_data(&str, "", 1);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_buffer_pop_data(&str, output, str.length);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	_gnutls_buffer_clear(&str);

	return ret;
}
示例#18
0
/* Recv the client certificate verify. This packet may not
 * arrive if the peer did not send us a certificate.
 */
int
_gnutls_recv_client_certificate_verify_message (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;


  if (session->internals.auth_struct->gnutls_process_client_cert_vrfy == NULL)
    return 0;

  if (session->internals.send_cert_req == 0 ||
      session->key->certificate_requested == 0)
    {
      return 0;
    }

  ret =
    _gnutls_recv_handshake (session, 
                            GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
                            OPTIONAL_PACKET, &buf);
  if (ret < 0)
    return ret;

  if (ret == 0 && buf.length == 0
      && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
    {
      /* certificate was required */
      gnutls_assert ();
      ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
      goto cleanup;
    }

  ret =
    session->internals.
    auth_struct->gnutls_process_client_cert_vrfy (session, buf.data,
                                                  buf.length);

cleanup:
  _gnutls_buffer_clear(&buf);
  return ret;
}
示例#19
0
/*
 * Return zero if session tickets haven't been enabled.
 */
int _gnutls_recv_new_session_ticket(gnutls_session_t session)
{
	uint8_t *p;
	int data_size;
	gnutls_buffer_st buf;
	uint16_t ticket_len;
	int ret;
	session_ticket_ext_st *priv = NULL;
	gnutls_ext_priv_data_t epriv;

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

	/* This is the last flight and peer cannot be sure
	 * we have received it unless we notify him. So we
	 * wait for a message and retransmit if needed. */
	if (IS_DTLS(session) && !_dtls_is_async(session)) {
		unsigned have;
		mbuffer_st *bufel = NULL;

		have = gnutls_record_check_pending(session) +
		       record_check_unprocessed(session);

		if (have != 0) {
			bufel = _mbuffer_head_get_first(&session->internals.record_buffer, NULL);
		}

		if (have == 0 || (bufel && bufel->type != GNUTLS_HANDSHAKE)) {
			ret = _dtls_wait_and_retransmit(session);
			if (ret < 0)
				return gnutls_assert_val(ret);
		}
	}

	ret = _gnutls_recv_handshake(session,
				     GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
				     0, &buf);
	if (ret < 0)
		return gnutls_assert_val_fatal(ret);

	p = buf.data;
	data_size = buf.length;

	DECR_LENGTH_COM(data_size, 4, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	/* skip over lifetime hint */
	p += 4;

	DECR_LENGTH_COM(data_size, 2, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	ticket_len = _gnutls_read_uint16(p);
	p += 2;

	DECR_LENGTH_COM(data_size, ticket_len, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);

	priv = gnutls_calloc(1, sizeof(*priv));
	if (!priv) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto error;
	}
	priv->session_ticket =
	    gnutls_realloc_fast(priv->session_ticket, ticket_len);
	if (!priv->session_ticket) {
		gnutls_free(priv);
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto error;
	}
	memcpy(priv->session_ticket, p, ticket_len);
	priv->session_ticket_len = ticket_len;
	epriv = priv;

	/* Discard the current session ID.  (RFC5077 3.4) */
	ret =
	    _gnutls_generate_session_id(session->security_parameters.
					session_id,
					&session->security_parameters.
					session_id_size);
	if (ret < 0) {
		gnutls_assert();
		session_ticket_deinit_data(epriv);
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto error;
	}
	ret = 0;

	_gnutls_handshake_log
		    ("HSK[%p]: received session ticket\n", session);
	session->internals.hsk_flags |= HSK_TICKET_RECEIVED;

	_gnutls_hello_ext_set_priv(session,
			GNUTLS_EXTENSION_SESSION_TICKET,
			epriv);

      error:
	_gnutls_buffer_clear(&buf);

	return ret;
}
示例#20
0
int
_gnutls_recv_client_certificate (gnutls_session_t session)
{
  gnutls_buffer_st buf;
  int ret = 0;
  int optional;

  if (session->internals.auth_struct->gnutls_process_client_certificate ==
      NULL)
    return 0;

  /* if we have not requested a certificate then just return
   */
  if (session->internals.send_cert_req == 0)
    {
      return 0;
    }

  if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
    optional = MANDATORY_PACKET;
  else
    optional = OPTIONAL_PACKET;

  ret =
    _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT, 
      optional, &buf);

  if (ret < 0)
    {
      /* Handle the case of old SSL3 clients who send
       * a warning alert instead of an empty certificate to indicate
       * no certificate.
       */
      if (optional == OPTIONAL_PACKET &&
          ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
          gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
          gnutls_alert_get (session) == GNUTLS_A_SSL3_NO_CERTIFICATE)
        {

          /* SSL3 does not send an empty certificate,
           * but this alert. So we just ignore it.
           */
          gnutls_assert ();
          return 0;
        }

      /* certificate was required 
       */
      if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
           || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
          && optional == MANDATORY_PACKET)
        {
          gnutls_assert ();
          return GNUTLS_E_NO_CERTIFICATE_FOUND;
        }

      return ret;
    }

  if (ret == 0 && buf.length == 0 && optional == OPTIONAL_PACKET)
    {
      /* Client has not sent the certificate message.
       * well I'm not sure we should accept this
       * behaviour.
       */
      gnutls_assert ();
      ret = 0;
      goto cleanup;
    }
  ret =
    session->internals.
    auth_struct->gnutls_process_client_certificate (session, buf.data,
                                                    buf.length);

  if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND)
    {
      gnutls_assert ();
      goto cleanup;
    }

  /* ok we should expect a certificate verify message now 
   */
  if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional == OPTIONAL_PACKET)
    ret = 0;
  else
    session->key->certificate_requested = 1;

cleanup:
  _gnutls_buffer_clear(&buf);
  return ret;
}
示例#21
0
int _gnutls_recv_server_certificate_status(gnutls_session_t session)
{
	uint8_t *data;
	int data_size;
	size_t r_size;
	gnutls_buffer_st buf;
	int ret;
	status_request_ext_st *priv = NULL;
	extension_priv_data_t epriv;

	ret =
	    _gnutls_ext_get_session_data(session,
					 GNUTLS_EXTENSION_STATUS_REQUEST,
					 &epriv);
	if (ret < 0)
		return 0;

	priv = epriv.ptr;

	if (!priv->expect_cstatus)
		return 0;

	ret = _gnutls_recv_handshake(session,
				     GNUTLS_HANDSHAKE_CERTIFICATE_STATUS,
				     0, &buf);
	if (ret < 0)
		return gnutls_assert_val_fatal(ret);

	priv->expect_cstatus = 0;

	data = buf.data;
	data_size = buf.length;

	/* minimum message is type (1) + response (3) + data */
	if (data_size == 0)
		return 0;
	else if (data_size < 4)
		return
		    gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);

	if (data[0] != 0x01) {
		gnutls_assert();
		_gnutls_handshake_log("EXT[%p]: unknown status_type %d\n",
				      session, data[0]);
		return 0;
	}
	DECR_LENGTH_COM(data_size, 1, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	data++;

	DECR_LENGTH_COM(data_size, 3, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	r_size = _gnutls_read_uint24(data);
	data += 3;

	DECR_LENGTH_COM(data_size, r_size, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);

	ret = _gnutls_set_datum(&priv->response, data, r_size);
	if (ret < 0)
		goto error;

	ret = 0;

      error:
	_gnutls_buffer_clear(&buf);

	return ret;
}
示例#22
0
/* Since auth_info structures contain malloced data, this function
 * is required in order to pack these structures in a vector in
 * order to store them to the DB.
 *
 * packed_session will contain the session data.
 *
 * The data will be in a platform independent format.
 */
int
_gnutls_session_pack (gnutls_session_t session,
                      gnutls_datum_t * packed_session)
{
  int ret;
  gnutls_buffer_st sb;
  opaque id;

  if (packed_session == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  _gnutls_buffer_init (&sb);

  id = gnutls_auth_get_type (session);
  BUFFER_APPEND (&sb, &id, 1);

  switch (id)
    {
#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      ret = pack_srp_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
#ifdef ENABLE_PSK
    case GNUTLS_CRD_PSK:
      ret = pack_psk_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
#ifdef ENABLE_ANON
    case GNUTLS_CRD_ANON:
      ret = pack_anon_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
    case GNUTLS_CRD_CERTIFICATE:
      ret = pack_certificate_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
    default:
      return GNUTLS_E_INTERNAL_ERROR;

    }

  /* Auth_info structures copied. Now copy security_parameters_st. 
   * packed_session must have allocated space for the security parameters.
   */
  ret = pack_security_parameters (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_buffer_clear (&sb);
      return ret;
    }

  ret = _gnutls_ext_pack (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_buffer_clear (&sb);
      return ret;
    }

  ret = _gnutls_buffer_to_datum (&sb, packed_session);

  return ret;
}
示例#23
0
文件: keys-win.c 项目: gnutls/gnutls
static
int get_win_urls(const CERT_CONTEXT * cert, char **cert_url, char **key_url,
		 char **label, gnutls_datum_t * der)
{
	BOOL r;
	int ret;
	DWORD tl_size;
	gnutls_datum_t tmp_label = { NULL, 0 };
	char name[MAX_CN * 2];
	char hex[MAX_WID_SIZE * 2 + 1];
	gnutls_buffer_st str;
#ifdef WORDS_BIGENDIAN
	const unsigned bigendian = 1;
#else
	const unsigned bigendian = 0;
#endif

	if (cert == NULL)
		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);

	if (der) {
		der->data = gnutls_malloc(cert->cbCertEncoded);
		if (der->data == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

		memcpy(der->data, cert->pbCertEncoded, cert->cbCertEncoded);
		der->size = cert->cbCertEncoded;
	}

	_gnutls_buffer_init(&str);
	if (label)
		*label = NULL;
	if (key_url)
		*key_url = NULL;
	if (cert_url)
		*cert_url = NULL;

	tl_size = sizeof(name);
	r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
					      name, &tl_size);
	if (r != 0) {		/* optional */
		ret =
		    _gnutls_ucs2_to_utf8(name, tl_size, &tmp_label, bigendian);
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
		if (label)
			*label = (char *)tmp_label.data;
	}

	tl_size = sizeof(name);
	r = CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID,
					      name, &tl_size);
	if (r == 0) {
		gnutls_assert();
		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		goto fail;
	}

	if (_gnutls_bin2hex(name, tl_size, hex, sizeof(hex), 0) == NULL) {
		ret = gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
		goto fail;
	}

	ret =
	    _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=cert", hex);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (tmp_label.data) {
		ret = _gnutls_buffer_append_str(&str, ";name=");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}

		ret =
		    _gnutls_buffer_append_escape(&str, tmp_label.data,
						 tmp_label.size, " ");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
	}

	ret = _gnutls_buffer_append_data(&str, "\x00", 1);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (cert_url)
		*cert_url = (char *)str.data;
	_gnutls_buffer_init(&str);

	ret =
	    _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=privkey",
					 hex);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (tmp_label.data) {
		ret = _gnutls_buffer_append_str(&str, ";name=");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}

		ret =
		    _gnutls_buffer_append_escape(&str, tmp_label.data,
						 tmp_label.size, " ");
		if (ret < 0) {
			gnutls_assert();
			goto fail;
		}
	}

	ret = _gnutls_buffer_append_data(&str, "\x00", 1);
	if (ret < 0) {
		gnutls_assert();
		goto fail;
	}

	if (key_url)
		*key_url = (char *)str.data;
	_gnutls_buffer_init(&str);

	ret = 0;
	goto cleanup;

 fail:
	if (der)
		gnutls_free(der->data);
	if (cert_url)
		gnutls_free(*cert_url);
	if (key_url)
		gnutls_free(*key_url);
	if (label)
		gnutls_free(*label);
 cleanup:
	_gnutls_buffer_clear(&str);
	return ret;
}
示例#24
0
int _gnutls13_send_certificate(gnutls_session_t session, unsigned again)
{
	int ret;
	gnutls_pcert_st *apr_cert_list = NULL;
	gnutls_privkey_t apr_pkey = NULL;
	int apr_cert_list_length = 0;
	mbuffer_st *bufel = NULL;
	gnutls_buffer_st buf;
	unsigned pos_mark, ext_pos_mark;
	unsigned i;
	struct ocsp_req_ctx_st ctx;
	gnutls_certificate_credentials_t cred;

	if (again == 0) {
		if (!session->internals.initial_negotiation_completed &&
		    session->internals.hsk_flags & HSK_PSK_SELECTED)
			return 0;

		if (session->security_parameters.entity == GNUTLS_SERVER &&
		    session->internals.resumed)
			return 0;

		cred = (gnutls_certificate_credentials_t)
		    _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
		if (cred == NULL) {
			gnutls_assert();
			return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
		}

		if (session->security_parameters.entity == GNUTLS_CLIENT &&
		    !(session->internals.hsk_flags & HSK_CRT_ASKED)) {
			return 0;
		}

		ret = _gnutls_get_selected_cert(session, &apr_cert_list,
						&apr_cert_list_length, &apr_pkey);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
		if (ret < 0)
			return gnutls_assert_val(ret);

		if (session->security_parameters.entity == GNUTLS_CLIENT) {
			ret = _gnutls_buffer_append_data_prefix(&buf, 8,
								session->internals.post_handshake_cr_context.data,
								session->internals.post_handshake_cr_context.size);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

		} else {
			ret = _gnutls_buffer_append_prefix(&buf, 8, 0);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}

		/* mark total size */
		pos_mark = buf.length;
		ret = _gnutls_buffer_append_prefix(&buf, 24, 0);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		for (i=0;i<(unsigned)apr_cert_list_length;i++) {
			ret = _gnutls_buffer_append_data_prefix(&buf, 24,
								apr_cert_list[i].cert.data,
								apr_cert_list[i].cert.size);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

#ifdef ENABLE_OCSP
			if ((session->internals.selected_ocsp_length > 0 ||
			     session->internals.selected_ocsp_func) &&
			    _gnutls_hello_ext_is_present(session, GNUTLS_EXTENSION_STATUS_REQUEST)) {
				/* append status response if available */
				ret = _gnutls_extv_append_init(&buf);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}
				ext_pos_mark = ret;

				ctx.pcert = &apr_cert_list[i];
				ctx.cert_index = i;
				ctx.session = session;
				ctx.cred = cred;
				ret = _gnutls_extv_append(&buf, STATUS_REQUEST_TLS_ID,
							  &ctx, append_status_request);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}

				ret = _gnutls_extv_append_final(&buf, ext_pos_mark, 0);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}
			} else
#endif
			{
				ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}
			}
		}

		_gnutls_write_uint24(buf.length-pos_mark-3, &buf.data[pos_mark]);

		bufel = _gnutls_buffer_to_mbuffer(&buf);
	}

	return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);

 cleanup:
	_gnutls_buffer_clear(&buf);
	return ret;
}
示例#25
0
/**
  * gnutls_deinit - clear all buffers associated with a session
  * @session: is a #gnutls_session_t structure.
  *
  * This function clears all buffers associated with the @session.
  * This function will also remove session data from the session
  * database if the session was terminated abnormally.
  **/
void
gnutls_deinit (gnutls_session_t session)
{

  if (session == NULL)
    return;

  /* remove auth info firstly */
  _gnutls_free_auth_info (session);

  _gnutls_handshake_internal_state_clear (session);
  _gnutls_handshake_io_buffer_clear (session);

  _gnutls_free_datum (&session->connection_state.read_mac_secret);
  _gnutls_free_datum (&session->connection_state.write_mac_secret);

  _gnutls_buffer_clear (&session->internals.ia_data_buffer);
  _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
  _gnutls_buffer_clear (&session->internals.handshake_data_buffer);
  _gnutls_buffer_clear (&session->internals.application_data_buffer);
  _gnutls_buffer_clear (&session->internals.record_recv_buffer);
  _gnutls_buffer_clear (&session->internals.record_send_buffer);

  gnutls_credentials_clear (session);
  _gnutls_selected_certs_deinit (session);

  _gnutls_cipher_deinit (&session->connection_state.read_cipher_state);
  _gnutls_cipher_deinit (&session->connection_state.write_cipher_state);

  if (session->connection_state.read_compression_state != NULL)
    _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
  if (session->connection_state.write_compression_state != NULL)
    _gnutls_comp_deinit (session->connection_state.write_compression_state,
			 0);

  _gnutls_free_datum (&session->cipher_specs.server_write_mac_secret);
  _gnutls_free_datum (&session->cipher_specs.client_write_mac_secret);
  _gnutls_free_datum (&session->cipher_specs.server_write_IV);
  _gnutls_free_datum (&session->cipher_specs.client_write_IV);
  _gnutls_free_datum (&session->cipher_specs.server_write_key);
  _gnutls_free_datum (&session->cipher_specs.client_write_key);

  if (session->key != NULL)
    {
      _gnutls_mpi_release (&session->key->KEY);
      _gnutls_mpi_release (&session->key->client_Y);
      _gnutls_mpi_release (&session->key->client_p);
      _gnutls_mpi_release (&session->key->client_g);

      _gnutls_mpi_release (&session->key->u);
      _gnutls_mpi_release (&session->key->a);
      _gnutls_mpi_release (&session->key->x);
      _gnutls_mpi_release (&session->key->A);
      _gnutls_mpi_release (&session->key->B);
      _gnutls_mpi_release (&session->key->b);

      /* RSA */
      _gnutls_mpi_release (&session->key->rsa[0]);
      _gnutls_mpi_release (&session->key->rsa[1]);

      _gnutls_mpi_release (&session->key->dh_secret);
      gnutls_free (session->key);

      session->key = NULL;
    }

  gnutls_free (session->internals.srp_username);

  if (session->internals.srp_password)
    {
      memset (session->internals.srp_password, 0,
	      strlen (session->internals.srp_password));
      gnutls_free (session->internals.srp_password);
    }

  memset (session, 0, sizeof (struct gnutls_session_int));
  gnutls_free (session);
}
示例#26
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn)
{
	gnutls_buffer_st out_str;
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	uint8_t value[MAX_STRING_LEN];
	gnutls_datum_t td = { NULL, 0 }, tvd = {
	NULL, 0};
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	int len;

	_gnutls_buffer_init(&out_str);

	k1 = 0;
	do {
		k1++;
		/* create a string like "tbsCertList.issuer.rdnSequence.?1"
		 */
		if (asn1_rdn_name[0] != 0)
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
				 asn1_rdn_name, k1);
		else
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
				 k1);

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

		if (result == ASN1_ELEMENT_NOT_FOUND) {
			if (k1 == 1) {
				gnutls_assert();
				result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
				goto cleanup;
			}
			break;
		}

		if (result != ASN1_VALUE_NOT_FOUND) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		k2 = 0;

		do {		/* Move to the attibute type and values
				 */
			k2++;

			if (tmpbuffer1[0] != 0)
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "%s.?%u", tmpbuffer1, k2);
			else
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "?%u", k2);

			/* Try to read the RelativeDistinguishedName attributes.
			 */

			len = sizeof(value) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer2, value,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			if (result != ASN1_VALUE_NOT_FOUND) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the OID 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".type");

			len = sizeof(oid) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer3, oid,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			else if (result != ASN1_SUCCESS) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the Value 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".value");

			len = 0;

			result =
			    _gnutls_x509_read_value(asn1_struct,
						    tmpbuffer3, &tvd);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
			/*   The encodings of adjoining RelativeDistinguishedNames are separated
			 *   by a comma character (',' ASCII 44).
			 */

			/*   Where there is a multi-valued RDN, the outputs from adjoining
			 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
			 *   character.
			 */
			if (k1 != 1) {	/* the first time do not append a comma */
				if (k2 != 1) {	/* adjoining multi-value RDN */
					STR_APPEND("+");
				} else {
					STR_APPEND(",");
				}
			}

			ldap_desc =
			    gnutls_x509_dn_oid_name(oid,
						    GNUTLS_X509_DN_OID_RETURN_OID);

			STR_APPEND(ldap_desc);
			STR_APPEND("=");

			result =
			    _gnutls_x509_dn_to_string(oid, tvd.data,
						      tvd.size, &td);
			if (result < 0) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Cannot parse OID: '%s' with value '%s'\n",
				     oid, _gnutls_bin2hex(tvd.data,
							  tvd.size,
							  tmpbuffer3,
							  sizeof
							  (tmpbuffer3),
							  NULL));
				goto cleanup;
			}

			DATA_APPEND(td.data, td.size);
			_gnutls_free_datum(&td);
			_gnutls_free_datum(&tvd);
		}
		while (1);
	}
	while (1);

	result = _gnutls_buffer_to_datum(&out_str, dn, 1);
	if (result < 0)
		gnutls_assert();

	goto cleanup1;

      cleanup:
	_gnutls_buffer_clear(&out_str);
      cleanup1:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;

}
示例#27
0
static int
compute_psk_binder(gnutls_session_t session,
		   const mac_entry_st *prf, unsigned binders_length,
		   int exts_length, int ext_offset,
		   const gnutls_datum_t *psk, const gnutls_datum_t *client_hello,
		   bool resuming, void *out)
{
	int ret;
	unsigned client_hello_pos, extensions_len_pos;
	gnutls_buffer_st handshake_buf;
	uint8_t binder_key[MAX_HASH_SIZE];

	_gnutls_buffer_init(&handshake_buf);

	if (session->security_parameters.entity == GNUTLS_CLIENT) {
		if (session->internals.hsk_flags & HSK_HRR_RECEIVED) {
			ret = gnutls_buffer_append_data(&handshake_buf,
							(const void *) session->internals.handshake_hash_buffer.data,
							session->internals.handshake_hash_buffer.length);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}
		}

		client_hello_pos = handshake_buf.length;
		ret = gnutls_buffer_append_data(&handshake_buf, client_hello->data,
						client_hello->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		/* This is a ClientHello message */
		handshake_buf.data[client_hello_pos] = GNUTLS_HANDSHAKE_CLIENT_HELLO;

		/* At this point we have not yet added the binders to the ClientHello,
		 * but we have to overwrite the size field, pretending as if binders
		 * of the correct length were present.
		 */
		_gnutls_write_uint24(handshake_buf.length - client_hello_pos + binders_length - 2, &handshake_buf.data[client_hello_pos + 1]);
		_gnutls_write_uint16(handshake_buf.length - client_hello_pos + binders_length - ext_offset,
				     &handshake_buf.data[client_hello_pos + ext_offset]);
		extensions_len_pos = handshake_buf.length - client_hello_pos - exts_length - 2;
		_gnutls_write_uint16(exts_length + binders_length + 2,
				     &handshake_buf.data[client_hello_pos + extensions_len_pos]);
	} else {
		if (session->internals.hsk_flags & HSK_HRR_SENT) {
			if (unlikely(session->internals.handshake_hash_buffer.length <= client_hello->size)) {
				ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
				goto error;
			}

			ret = gnutls_buffer_append_data(&handshake_buf,
							session->internals.handshake_hash_buffer.data,
							session->internals.handshake_hash_buffer.length - client_hello->size);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}
		}

		if (unlikely(client_hello->size <= binders_length)) {
			ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
			goto error;
		}

		ret = gnutls_buffer_append_data(&handshake_buf,
						(const void *) client_hello->data,
						client_hello->size - binders_length);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	}

	ret = compute_binder_key(prf,
				 psk->data, psk->size, resuming,
				 binder_key);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls13_compute_finished(prf, binder_key,
					 &handshake_buf,
					 out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = 0;
error:
	_gnutls_buffer_clear(&handshake_buf);
	return ret;
}
示例#28
0
文件: tpm.c 项目: randombit/hacrypto
static int encode_tpmkey_url(char **url, const TSS_UUID * uuid,
			     TSS_FLAG storage)
{
	size_t size = (UUID_SIZE * 2 + 4) * 2 + 32;
	uint8_t u1[UUID_SIZE];
	gnutls_buffer_st buf;
	gnutls_datum_t dret;
	int ret;

	*url = gnutls_malloc(size);
	if (*url == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	_gnutls_buffer_init(&buf);

	memcpy(u1, &uuid->ulTimeLow, 4);
	memcpy(&u1[4], &uuid->usTimeMid, 2);
	memcpy(&u1[6], &uuid->usTimeHigh, 2);
	u1[8] = uuid->bClockSeqHigh;
	u1[9] = uuid->bClockSeqLow;
	memcpy(&u1[10], uuid->rgbNode, 6);

	ret = _gnutls_buffer_append_str(&buf, "tpmkey:uuid=");
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_printf(&buf,
					 "%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
					 (unsigned int) u1[0],
					 (unsigned int) u1[1],
					 (unsigned int) u1[2],
					 (unsigned int) u1[3],
					 (unsigned int) u1[4],
					 (unsigned int) u1[5],
					 (unsigned int) u1[6],
					 (unsigned int) u1[7],
					 (unsigned int) u1[8],
					 (unsigned int) u1[9],
					 (unsigned int) u1[10],
					 (unsigned int) u1[11],
					 (unsigned int) u1[12],
					 (unsigned int) u1[13],
					 (unsigned int) u1[14],
					 (unsigned int) u1[15]);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_buffer_append_printf(&buf, ";storage=%s",
					 (storage ==
					  TSS_PS_TYPE_USER) ? "user" :
					 "system");
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_buffer_to_datum(&buf, &dret);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	*url = (char *) dret.data;

	return 0;
      cleanup:
	_gnutls_buffer_clear(&buf);
	return ret;
}
示例#29
0
int _gnutls13_recv_certificate(gnutls_session_t session)
{
	int ret;
	gnutls_buffer_st buf;
	unsigned optional = 0;

	if (!session->internals.initial_negotiation_completed &&
	    session->internals.hsk_flags & HSK_PSK_SELECTED)
		return 0;

	if (session->security_parameters.entity == GNUTLS_SERVER) {
		/* if we didn't request a certificate, there will not be any */
		if (session->internals.send_cert_req == 0)
			return 0;

		if (session->internals.send_cert_req != GNUTLS_CERT_REQUIRE)
			optional = 1;
	}

	ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT, 0, &buf);
	if (ret < 0) {
		if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET && session->internals.send_cert_req)
			return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);

		return gnutls_assert_val(ret);
	}

	if (buf.length == 0) {
		gnutls_assert();
		ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
		goto cleanup;
	}

	if (session->internals.initial_negotiation_completed &&
	    session->internals.post_handshake_cr_context.size > 0) {
		gnutls_datum_t context;

		/* verify whether the context matches */
		ret = _gnutls_buffer_pop_datum_prefix8(&buf, &context);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		if (context.size != session->internals.post_handshake_cr_context.size ||
		    memcmp(context.data, session->internals.post_handshake_cr_context.data,
		           context.size) != 0) {
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			gnutls_assert();
			goto cleanup;
		}
	} else {
		if (buf.data[0] != 0) {
			/* The context field must be empty during handshake */
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto cleanup;
		}

		/* buf.length is positive */
		buf.data++;
		buf.length--;
	}

	_gnutls_handshake_log("HSK[%p]: parsing certificate message\n", session);

	ret = parse_cert_list(session, buf.data, buf.length);
	if (ret < 0) {
		if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) {
			if (optional)
				ret = 0;
			else if (session->security_parameters.entity ==
				 GNUTLS_SERVER)
				ret = GNUTLS_E_CERTIFICATE_REQUIRED;
		}
		gnutls_assert();
		goto cleanup;
	}

	session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;

	ret = 0;
cleanup:

	_gnutls_buffer_clear(&buf);
	return ret;
}
示例#30
0
/* Load session data from a buffer.
 */
int
_gnutls_session_unpack (gnutls_session_t session,
                        const gnutls_datum_t * packed_session)
{
  int ret;
  gnutls_buffer_st sb;
  opaque id;

  _gnutls_buffer_init (&sb);

  if (packed_session == NULL || packed_session->size == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret =
    _gnutls_buffer_append_data (&sb, packed_session->data,
                                packed_session->size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (_gnutls_get_auth_info (session) != NULL)
    {
      _gnutls_free_auth_info (session);
    }

  BUFFER_POP (&sb, &id, 1);

  switch (id)
    {
#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      ret = unpack_srp_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
#endif
#ifdef ENABLE_PSK
    case GNUTLS_CRD_PSK:
      ret = unpack_psk_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
#endif
#ifdef ENABLE_ANON
    case GNUTLS_CRD_ANON:
      ret = unpack_anon_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }
      break;
#endif
    case GNUTLS_CRD_CERTIFICATE:
      ret = unpack_certificate_auth_info (session, &sb);
      if (ret < 0)
        {
          gnutls_assert ();
          goto error;
        }
      break;
    default:
      gnutls_assert ();
      ret = GNUTLS_E_INTERNAL_ERROR;
      goto error;

    }

  /* Auth_info structures copied. Now copy security_parameters_st. 
   * packed_session must have allocated space for the security parameters.
   */
  ret = unpack_security_parameters (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = _gnutls_ext_unpack (session, &sb);
  if (ret < 0)
    {
      gnutls_assert ();
      goto error;
    }

  ret = 0;

error:
  _gnutls_buffer_clear (&sb);

  return ret;
}