mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-08-07 06:42:56 +03:00
Wrap lines which exceed 80 chars in ssl_tls13_client.c
Signed-off-by: Xiaokang Qian <xiaokang.qian@arm.com>
This commit is contained in:
@@ -227,8 +227,8 @@ static int ssl_tls13_get_default_group_id(mbedtls_ssl_context *ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (; *group_list != 0; group_list++) {
|
for (; *group_list != 0; group_list++) {
|
||||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(*group_list,
|
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||||
NULL, NULL) == PSA_SUCCESS) &&
|
*group_list, NULL, NULL) == PSA_SUCCESS) &&
|
||||||
mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
|
mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
|
||||||
*group_id = *group_list;
|
*group_id = *group_list;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -402,8 +402,8 @@ static int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl,
|
|||||||
* then the client MUST abort the handshake with an "illegal_parameter" alert.
|
* then the client MUST abort the handshake with an "illegal_parameter" alert.
|
||||||
*/
|
*/
|
||||||
for (; *group_list != 0; group_list++) {
|
for (; *group_list != 0; group_list++) {
|
||||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(*group_list,
|
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||||
NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
|
*group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
|
||||||
*group_list != selected_group) {
|
*group_list != selected_group) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -472,9 +472,9 @@ static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl,
|
|||||||
/* Check that the chosen group matches the one we offered. */
|
/* Check that the chosen group matches the one we offered. */
|
||||||
offered_group = ssl->handshake->offered_group_id;
|
offered_group = ssl->handshake->offered_group_id;
|
||||||
if (offered_group != group) {
|
if (offered_group != group) {
|
||||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
("Invalid server key share, our group %u, their group %u",
|
1, ("Invalid server key share, our group %u, their group %u",
|
||||||
(unsigned) offered_group, (unsigned) group));
|
(unsigned) offered_group, (unsigned) group));
|
||||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||||
@@ -1410,8 +1410,8 @@ static int ssl_server_hello_is_hrr(mbedtls_ssl_context *ssl,
|
|||||||
* } ServerHello;
|
* } ServerHello;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end,
|
MBEDTLS_SSL_CHK_BUF_READ_PTR(
|
||||||
2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
|
buf, end, 2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
|
||||||
|
|
||||||
if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
|
if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
|
||||||
sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) {
|
sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) {
|
||||||
@@ -1464,9 +1464,9 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
|||||||
*/
|
*/
|
||||||
ssl->keep_current_message = 1;
|
ssl->keep_current_message = 1;
|
||||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||||
MBEDTLS_SSL_HS_SERVER_HELLO,
|
ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
|
||||||
buf, (size_t) (end - buf)));
|
buf, (size_t) (end - buf)));
|
||||||
|
|
||||||
if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
|
if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
|
||||||
ret = ssl_tls13_reset_key_share(ssl);
|
ret = ssl_tls13_reset_key_share(ssl);
|
||||||
@@ -1492,15 +1492,16 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
|||||||
break;
|
break;
|
||||||
case SSL_SERVER_HELLO_HRR:
|
case SSL_SERVER_HELLO_HRR:
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message"));
|
MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message"));
|
||||||
/* If a client receives a second
|
/* If a client receives a second HelloRetryRequest in the same
|
||||||
* HelloRetryRequest in the same connection (i.e., where the ClientHello
|
* connection (i.e., where the ClientHello was itself in response
|
||||||
* was itself in response to a HelloRetryRequest), it MUST abort the
|
* to a HelloRetryRequest), it MUST abort the handshake with an
|
||||||
* handshake with an "unexpected_message" alert.
|
* "unexpected_message" alert.
|
||||||
*/
|
*/
|
||||||
if (handshake->hello_retry_request_count > 0) {
|
if (handshake->hello_retry_request_count > 0) {
|
||||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
|
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
|
||||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||||
|
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||||
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -1861,20 +1862,25 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
|||||||
* exchange mode is EPHEMERAL-only.
|
* exchange mode is EPHEMERAL-only.
|
||||||
*/
|
*/
|
||||||
switch (handshake->received_extensions &
|
switch (handshake->received_extensions &
|
||||||
(MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
|
(MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
|
||||||
|
MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
|
||||||
/* Only the pre_shared_key extension was received */
|
/* Only the pre_shared_key extension was received */
|
||||||
case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY):
|
case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY):
|
||||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
handshake->key_exchange_mode =
|
||||||
|
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Only the key_share extension was received */
|
/* Only the key_share extension was received */
|
||||||
case MBEDTLS_SSL_EXT_MASK(KEY_SHARE):
|
case MBEDTLS_SSL_EXT_MASK(KEY_SHARE):
|
||||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
handshake->key_exchange_mode =
|
||||||
|
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Both the pre_shared_key and key_share extensions were received */
|
/* Both the pre_shared_key and key_share extensions were received */
|
||||||
case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
|
case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
|
||||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
|
||||||
|
handshake->key_exchange_mode =
|
||||||
|
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Neither pre_shared_key nor key_share extension was received */
|
/* Neither pre_shared_key nor key_share extension was received */
|
||||||
@@ -1917,15 +1923,15 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
|||||||
if (!mbedtls_ssl_conf_tls13_check_kex_modes(
|
if (!mbedtls_ssl_conf_tls13_check_kex_modes(
|
||||||
ssl, handshake->key_exchange_mode)) {
|
ssl, handshake->key_exchange_mode)) {
|
||||||
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2,
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
("Key exchange mode(%s) is not supported.",
|
2, ("Key exchange mode(%s) is not supported.",
|
||||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG(3,
|
MBEDTLS_SSL_DEBUG_MSG(
|
||||||
("Selected key exchange mode: %s",
|
3, ("Selected key exchange mode: %s",
|
||||||
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
|
||||||
|
|
||||||
/* Start the TLS 1.3 key scheduling if not already done.
|
/* Start the TLS 1.3 key scheduling if not already done.
|
||||||
*
|
*
|
||||||
@@ -2009,9 +2015,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
|
MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||||
MBEDTLS_SSL_HS_SERVER_HELLO,
|
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
|
||||||
&buf, &buf_len));
|
|
||||||
|
|
||||||
ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len);
|
ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -2032,9 +2037,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||||
MBEDTLS_SSL_HS_SERVER_HELLO, buf,
|
ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, buf_len));
|
||||||
buf_len));
|
|
||||||
|
|
||||||
if (is_hrr) {
|
if (is_hrr) {
|
||||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
|
MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
|
||||||
@@ -2043,8 +2047,8 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
|||||||
* immediately before its second flight. This may either be before
|
* immediately before its second flight. This may either be before
|
||||||
* its second ClientHello or before its encrypted handshake flight.
|
* its second ClientHello or before its encrypted handshake flight.
|
||||||
*/
|
*/
|
||||||
mbedtls_ssl_handshake_set_state(ssl,
|
mbedtls_ssl_handshake_set_state(
|
||||||
MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
|
ssl, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
|
||||||
#else
|
#else
|
||||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
||||||
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
|
||||||
@@ -2124,7 +2128,8 @@ static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
|
|||||||
case MBEDTLS_TLS_EXT_ALPN:
|
case MBEDTLS_TLS_EXT_ALPN:
|
||||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
|
MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
|
||||||
|
|
||||||
if ((ret = ssl_tls13_parse_alpn_ext(ssl, p, (size_t) extension_data_len)) != 0) {
|
if ((ret = ssl_tls13_parse_alpn_ext(
|
||||||
|
ssl, p, (size_t) extension_data_len)) != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2148,10 +2153,12 @@ static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
|
|||||||
case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
|
case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
|
||||||
MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
|
MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
|
||||||
|
|
||||||
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(ssl, p, p + extension_data_len);
|
ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
|
||||||
|
ssl, p, p + extension_data_len);
|
||||||
|
|
||||||
/* TODO: Return unconditionally here until we handle the record size limit correctly.
|
/* TODO: Return unconditionally here until we handle the record
|
||||||
* Once handled correctly, only return in case of errors. */
|
* size limit correctly. Once handled correctly, only return in
|
||||||
|
* case of errors. */
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2190,9 +2197,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
|||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));
|
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||||
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||||
&buf, &buf_len));
|
&buf, &buf_len));
|
||||||
|
|
||||||
/* Process the message contents */
|
/* Process the message contents */
|
||||||
MBEDTLS_SSL_PROC_CHK(
|
MBEDTLS_SSL_PROC_CHK(
|
||||||
@@ -2205,9 +2212,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||||
MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
|
||||||
buf, buf_len));
|
buf, buf_len));
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||||
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
|
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
|
||||||
@@ -2443,16 +2450,16 @@ static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl)
|
|||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
size_t buf_len;
|
size_t buf_len;
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
|
||||||
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||||
&buf, &buf_len));
|
&buf, &buf_len));
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(ssl,
|
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(
|
||||||
buf, buf + buf_len));
|
ssl, buf, buf + buf_len));
|
||||||
|
|
||||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl,
|
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
|
||||||
MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
|
||||||
buf, buf_len));
|
buf, buf_len));
|
||||||
} else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
|
} else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -2614,8 +2621,8 @@ static int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl)
|
|||||||
|
|
||||||
ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
|
ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
MBEDTLS_SSL_DEBUG_RET(1,
|
MBEDTLS_SSL_DEBUG_RET(
|
||||||
"mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
|
1, "mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2995,7 +3002,8 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
|||||||
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
|
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
|
||||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
mbedtls_ssl_handshake_set_state(
|
||||||
|
ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user