Update TLS alert

This commit is contained in:
Zhi Guan
2026-06-15 12:21:52 +08:00
parent 40b8d67110
commit cc8cb67c29
6 changed files with 249 additions and 53 deletions

View File

@@ -764,7 +764,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1049") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1050")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -1639,6 +1639,11 @@ int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentle
int tls_send_alert(TLS_CONNECT *conn, int alert); int tls_send_alert(TLS_CONNECT *conn, int alert);
int tls_send_warning(TLS_CONNECT *conn, int alert); int tls_send_warning(TLS_CONNECT *conn, int alert);
int tls12_send_alert(TLS_CONNECT *conn, int alert);
int tls12_send_warning(TLS_CONNECT *conn, int alert);
int tlcp_send_alert(TLS_CONNECT *conn, int alert);
int tlcp_send_warning(TLS_CONNECT *conn, int alert);
int tls13_send_alert(TLS_CONNECT *conn, int alert); int tls13_send_alert(TLS_CONNECT *conn, int alert);

View File

@@ -18,7 +18,7 @@ extern "C" {
#define GMSSL_VERSION_NUM 30200 #define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1049" #define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1050"
int gmssl_version_num(void); int gmssl_version_num(void);
const char *gmssl_version_str(void); const char *gmssl_version_str(void);

View File

@@ -606,7 +606,7 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
@@ -616,7 +616,7 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
case TLS_extension_status_request: case TLS_extension_status_request:
if (ext_data) { if (ext_data) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
break; break;
@@ -624,7 +624,7 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
case TLS_extension_application_layer_protocol_negotiation: case TLS_extension_application_layer_protocol_negotiation:
if (!ext_data) { if (!ext_data) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
break; break;
@@ -680,7 +680,7 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
case TLS_extension_supported_groups: case TLS_extension_supported_groups:
if (supported_groups) { if (supported_groups) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
supported_groups = ext_data; supported_groups = ext_data;
@@ -695,7 +695,7 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
} }
if (application_layer_protocol_negotiation) { if (application_layer_protocol_negotiation) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
application_layer_protocol_negotiation = ext_data; application_layer_protocol_negotiation = ext_data;
@@ -1224,7 +1224,7 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, verify_data) != 1) { if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, verify_data) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -1233,7 +1233,7 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
verify_data, sizeof(verify_data)) != 1) { verify_data, sizeof(verify_data)) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -1252,7 +1252,7 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
conn->record, &conn->recordlen) != 1) { conn->record, &conn->recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -1294,7 +1294,7 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) { if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tlcp_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
@@ -1303,7 +1303,7 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
conn->server_seq_num, conn->record, conn->recordlen, conn->server_seq_num, conn->record, conn->recordlen,
conn->plain_record, &conn->plain_recordlen) != 1) { conn->plain_record, &conn->plain_recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_record_mac); tlcp_send_alert(conn, TLS_alert_bad_record_mac);
return -1; return -1;
} }
tls_seq_num_incr(conn->server_seq_num); tls_seq_num_incr(conn->server_seq_num);
@@ -1314,24 +1314,24 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tlcp_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
if (verify_data_len != sizeof(local_verify_data)) { if (verify_data_len != sizeof(local_verify_data)) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tlcp_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, local_verify_data) != 1) { if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, local_verify_data) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_decrypt_error); tlcp_send_alert(conn, TLS_alert_decrypt_error);
return -1; return -1;
} }
@@ -1530,7 +1530,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
@@ -1547,7 +1547,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_server_name: case TLS_extension_server_name:
if (server_name) { if (server_name) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
server_name = ext_data; server_name = ext_data;
@@ -1557,13 +1557,13 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_trusted_ca_keys: case TLS_extension_trusted_ca_keys:
if (trusted_ca_keys) { if (trusted_ca_keys) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
if (tls_trusted_authorities_from_bytes(&trusted_authorities, if (tls_trusted_authorities_from_bytes(&trusted_authorities,
&trusted_authorities_len, ext_data, ext_datalen) != 1) { &trusted_authorities_len, ext_data, ext_datalen) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
trusted_ca_keys = 1; trusted_ca_keys = 1;
@@ -1572,7 +1572,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_status_request: case TLS_extension_status_request:
if (status_request) { if (status_request) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
status_request = ext_data; status_request = ext_data;
@@ -1582,7 +1582,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_supported_groups: case TLS_extension_supported_groups:
if (supported_groups) { if (supported_groups) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
supported_groups = ext_data; supported_groups = ext_data;
@@ -1592,7 +1592,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_signature_algorithms: case TLS_extension_signature_algorithms:
if (signature_algorithms) { if (signature_algorithms) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
signature_algorithms = ext_data; signature_algorithms = ext_data;
@@ -1602,7 +1602,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_application_layer_protocol_negotiation: case TLS_extension_application_layer_protocol_negotiation:
if (application_layer_protocol_negotiation) { if (application_layer_protocol_negotiation) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
application_layer_protocol_negotiation = ext_data; application_layer_protocol_negotiation = ext_data;
@@ -1612,7 +1612,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
case TLS_extension_client_id: case TLS_extension_client_id:
if (client_id) { if (client_id) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
} }
client_id = ext_data; client_id = ext_data;
@@ -2344,7 +2344,7 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished",
&conn->dgst_ctx, verify_data) != 1) { &conn->dgst_ctx, verify_data) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -2353,7 +2353,7 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
verify_data, sizeof(verify_data)) != 1) { verify_data, sizeof(verify_data)) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
@@ -2363,7 +2363,7 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
conn->server_seq_num, conn->plain_record, conn->plain_recordlen, conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
conn->record, &conn->recordlen) != 1) { conn->record, &conn->recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tlcp_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
tls_seq_num_incr(conn->server_seq_num); tls_seq_num_incr(conn->server_seq_num);
@@ -2491,6 +2491,98 @@ int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentle
return 1; return 1;
} }
static int tlcp_send_encrypted_alert(TLS_CONNECT *conn, int level, int alert)
{
const HMAC_CTX *hmac;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
int ret;
if (!conn) {
error_print();
return -1;
}
if (!tls_alert_level_name(level) || !tls_alert_description_text(alert)) {
error_print();
return -1;
}
if (conn->send_state && conn->send_state != TLS_state_send_record) {
error_print();
return -1;
}
if (conn->send_state == TLS_state_send_record
&& tls_record_type(conn->record) != TLS_record_alert) {
error_print();
return -1;
}
if (!conn->send_state) {
tls_clean_record(conn);
conn->plain_recordlen = 0;
if (conn->is_client) {
hmac = &conn->client_write_mac_ctx;
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
hmac = &conn->server_write_mac_ctx;
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
tls_record_set_protocol(conn->plain_record, conn->protocol);
if (tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, level, alert) != 1) {
error_print();
return -1;
}
if (conn->verbose) {
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
}
if (tlcp_record_encrypt(conn->cipher_suite, hmac, key, iv, seq_num,
conn->plain_record, conn->plain_recordlen,
conn->record, &conn->recordlen) != 1) {
error_print();
conn->plain_recordlen = 0;
tls_clean_record(conn);
return -1;
}
tls_seq_num_incr(seq_num);
conn->record_offset = 0;
conn->send_state = TLS_state_send_record;
if (conn->verbose) {
tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0);
}
}
ret = tls_send_record(conn);
if (ret != 1) {
if (ret != TLS_ERROR_SEND_AGAIN) {
error_print();
}
return ret;
}
conn->send_state = 0;
conn->plain_recordlen = 0;
tls_clean_record(conn);
return 1;
}
int tlcp_send_alert(TLS_CONNECT *conn, int alert)
{
return tlcp_send_encrypted_alert(conn, TLS_alert_level_fatal, alert);
}
int tlcp_send_warning(TLS_CONNECT *conn, int alert)
{
return tlcp_send_encrypted_alert(conn, TLS_alert_level_warning, alert);
}
/* /*
Client Server Client Server

View File

@@ -2381,8 +2381,6 @@ int tls_send_warning(TLS_CONNECT *conn, int alert)
return 1; return 1;
} }
int tls_decrypt_recv(TLS_CONNECT *conn) int tls_decrypt_recv(TLS_CONNECT *conn)
{ {
int ret; int ret;

View File

@@ -850,7 +850,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
&protocol, &client_random, &session_id, &session_id_len, &protocol, &client_random, &session_id, &session_id_len,
&cipher_suites, &cipher_suites_len, &exts, &extslen)) < 0) { &cipher_suites, &cipher_suites_len, &exts, &extslen)) < 0) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} else if (ret == 0) { } else if (ret == 0) {
error_print(); error_print();
@@ -874,7 +874,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
@@ -1078,7 +1078,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
} else { } else {
if (!conn->ctx->signature_algorithms_cnt) { if (!conn->ctx->signature_algorithms_cnt) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_handshake_failure); tls_send_alert(conn, TLS_alert_handshake_failure);
return -1; return -1;
} }
memcpy(common_signature_algorithms, conn->ctx->signature_algorithms, memcpy(common_signature_algorithms, conn->ctx->signature_algorithms,
@@ -1109,7 +1109,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
if (server_name) { if (server_name) {
if (tls_server_name_from_bytes(&host_name, &host_name_len, server_name, server_name_len) != 1) { if (tls_server_name_from_bytes(&host_name, &host_name_len, server_name, server_name_len) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_decode_error); tls_send_alert(conn, TLS_alert_decode_error);
return -1; return -1;
} }
conn->server_name = 1; conn->server_name = 1;
@@ -1132,7 +1132,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
if (tls12_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) { if (tls12_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) {
error_print(); error_print();
tls13_send_alert(conn, TLS_alert_internal_error); tls_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -1310,6 +1310,7 @@ int tls_recv_server_hello(TLS_CONNECT *conn)
// session_id // session_id
memcpy(conn->session_id, session_id, session_id_len); memcpy(conn->session_id, session_id, session_id_len);
conn->session_id_len = session_id_len;
// cipher_suite // cipher_suite
if (tls_type_is_in_list(cipher_suite, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) { if (tls_type_is_in_list(cipher_suite, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) {
@@ -1955,7 +1956,7 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
error_print(); error_print();
return -1; return -1;
} }
if (server_key_exchange_len > sizeof(conn->peer_key_exchange)) { if (server_key_exchange_len != sizeof(conn->peer_key_exchange)) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_illegal_parameter); tls_send_alert(conn, TLS_alert_illegal_parameter);
return -1; return -1;
@@ -1970,10 +1971,6 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
conn->peer_key_exchange_len = server_key_exchange_len; conn->peer_key_exchange_len = server_key_exchange_len;
// xxxx
// 这里的签名错了肯定是sign_ctx就是不对的因此是不可能正确的
// 现在要做的是必须确定server_key_exchange中都包括了哪些被签名的消息
return 1; return 1;
} }
@@ -2486,8 +2483,16 @@ int tls_send_change_cipher_spec(TLS_CONNECT *conn)
int tls_recv_change_cipher_spec(TLS_CONNECT *conn) int tls_recv_change_cipher_spec(TLS_CONNECT *conn)
{ {
int ret; int ret;
int (*send_alert)(TLS_CONNECT *conn, int alert) = tls_send_alert;
if(conn->verbose) tls_trace("recv [ChangeCipherSpec]\n"); if(conn->verbose) tls_trace("recv [ChangeCipherSpec]\n");
if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) {
if (conn->protocol == TLS_protocol_tlcp) {
send_alert = tlcp_send_alert;
} else {
send_alert = tls12_send_alert;
}
}
if ((ret = tls_recv_record(conn)) != 1) { if ((ret = tls_recv_record(conn)) != 1) {
if (ret != TLS_ERROR_RECV_AGAIN) { if (ret != TLS_ERROR_RECV_AGAIN) {
error_print(); error_print();
@@ -2497,14 +2502,14 @@ int tls_recv_change_cipher_spec(TLS_CONNECT *conn)
if (tls_record_protocol(conn->record) != conn->protocol) { if (tls_record_protocol(conn->record) != conn->protocol) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0); if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
if (tls_record_get_change_cipher_spec(conn->record) != 1) { if (tls_record_get_change_cipher_spec(conn->record) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
return 1; return 1;
@@ -2523,7 +2528,7 @@ int tls_send_client_finished(TLS_CONNECT *conn)
if (tls_compute_verify_data(conn->digest, conn->master_secret, if (tls_compute_verify_data(conn->digest, conn->master_secret,
"client finished", &conn->dgst_ctx, local_verify_data) != 1) { "client finished", &conn->dgst_ctx, local_verify_data) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -2532,7 +2537,7 @@ int tls_send_client_finished(TLS_CONNECT *conn)
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
local_verify_data, sizeof(local_verify_data)) != 1) { local_verify_data, sizeof(local_verify_data)) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -2550,7 +2555,7 @@ int tls_send_client_finished(TLS_CONNECT *conn)
conn->record, &conn->recordlen) != 1) { conn->record, &conn->recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
tls_seq_num_incr(conn->client_seq_num); tls_seq_num_incr(conn->client_seq_num);
@@ -2677,6 +2682,7 @@ int tls_send_server_finished(TLS_CONNECT *conn)
if (tls_compute_verify_data(conn->digest, conn->master_secret, if (tls_compute_verify_data(conn->digest, conn->master_secret,
"server finished", &conn->dgst_ctx, local_verify_data) != 1) { "server finished", &conn->dgst_ctx, local_verify_data) != 1) {
error_print(); error_print();
tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
@@ -2687,7 +2693,7 @@ int tls_send_server_finished(TLS_CONNECT *conn)
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
local_verify_data, sizeof(local_verify_data)) != 1) { local_verify_data, sizeof(local_verify_data)) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0);
@@ -2697,7 +2703,7 @@ int tls_send_server_finished(TLS_CONNECT *conn)
conn->server_seq_num, conn->plain_record, conn->plain_recordlen, conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
conn->record, &conn->recordlen) != 1) { conn->record, &conn->recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
tls_seq_num_incr(conn->server_seq_num); tls_seq_num_incr(conn->server_seq_num);
@@ -2727,7 +2733,7 @@ int tls_recv_server_finished(TLS_CONNECT *conn)
if (tls_compute_verify_data(conn->digest, conn->master_secret, if (tls_compute_verify_data(conn->digest, conn->master_secret,
"server finished", &conn->dgst_ctx, local_verify_data) != 1) { "server finished", &conn->dgst_ctx, local_verify_data) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_internal_error); tls12_send_alert(conn, TLS_alert_internal_error);
return -1; return -1;
} }
if (conn->verbose >= 5) { if (conn->verbose >= 5) {
@@ -2745,7 +2751,7 @@ int tls_recv_server_finished(TLS_CONNECT *conn)
} }
if (tls_record_protocol(conn->record) != conn->protocol) { if (tls_record_protocol(conn->record) != conn->protocol) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tls12_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
@@ -2761,7 +2767,7 @@ int tls_recv_server_finished(TLS_CONNECT *conn)
conn->server_write_iv, conn->server_seq_num, conn->record, conn->recordlen, conn->server_write_iv, conn->server_seq_num, conn->record, conn->recordlen,
conn->plain_record, &conn->plain_recordlen) != 1) { conn->plain_record, &conn->plain_recordlen) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_bad_record_mac); tls12_send_alert(conn, TLS_alert_bad_record_mac);
return -1; return -1;
} }
if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); if(conn->verbose) tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0);
@@ -2770,19 +2776,19 @@ int tls_recv_server_finished(TLS_CONNECT *conn)
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) { if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tls12_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
if (verify_data_len != sizeof(local_verify_data)) { if (verify_data_len != sizeof(local_verify_data)) {
error_print(); error_print();
tls_send_alert(conn, TLS_alert_unexpected_message); tls12_send_alert(conn, TLS_alert_unexpected_message);
return -1; return -1;
} }
if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
error_puts("server_finished.verify_data verification failure"); error_puts("server_finished.verify_data verification failure");
tls_send_alert(conn, TLS_alert_decrypt_error); tls12_send_alert(conn, TLS_alert_decrypt_error);
return -1; return -1;
} }
@@ -2914,6 +2920,101 @@ int tls12_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentl
return 1; return 1;
} }
static int tls12_send_encrypted_alert(TLS_CONNECT *conn, int level, int alert)
{
const HMAC_CTX *hmac;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
int ret;
if (!conn) {
error_print();
return -1;
}
if (conn->protocol == TLS_protocol_tls13) {
error_print();
return -1;
}
if (!tls_alert_level_name(level) || !tls_alert_description_text(alert)) {
error_print();
return -1;
}
if (conn->send_state && conn->send_state != TLS_state_send_record) {
error_print();
return -1;
}
if (conn->send_state == TLS_state_send_record
&& tls_record_type(conn->record) != TLS_record_alert) {
error_print();
return -1;
}
if (!conn->send_state) {
tls_clean_record(conn);
conn->plain_recordlen = 0;
if (conn->is_client) {
hmac = &conn->client_write_mac_ctx;
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
hmac = &conn->server_write_mac_ctx;
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
tls_record_set_protocol(conn->plain_record, conn->protocol);
if (tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, level, alert) != 1) {
error_print();
return -1;
}
if (conn->verbose) {
tls12_record_print(stderr, conn->plain_record, conn->plain_recordlen, 0, 0);
}
if (tls_record_encrypt(conn->cipher_suite, hmac, key, iv, seq_num,
conn->plain_record, conn->plain_recordlen,
conn->record, &conn->recordlen) != 1) {
error_print();
conn->plain_recordlen = 0;
tls_clean_record(conn);
return -1;
}
tls_seq_num_incr(seq_num);
conn->record_offset = 0;
conn->send_state = TLS_state_send_record;
if (conn->verbose) {
tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0);
}
}
ret = tls_send_record(conn);
if (ret != 1) {
if (ret != TLS_ERROR_SEND_AGAIN) {
error_print();
}
return ret;
}
conn->send_state = 0;
conn->plain_recordlen = 0;
tls_clean_record(conn);
return 1;
}
int tls12_send_alert(TLS_CONNECT *conn, int alert)
{
return tls12_send_encrypted_alert(conn, TLS_alert_level_fatal, alert);
}
int tls12_send_warning(TLS_CONNECT *conn, int alert)
{
return tls12_send_encrypted_alert(conn, TLS_alert_level_warning, alert);
}
/* /*