已合并
feat: enforce record boundary on TLS1.3 read key switches #1014
feat: enforce record boundary on TLS1.3 read key switches #1014
已合并
pi_ixeL创建于 1月20日
5 个文件变更+286-2
@@ -246,6 +246,7 @@ typedef enum {
246 HITLS_REC_DECODE_ERROR, /**< Decoding failed. */246 HITLS_REC_DECODE_ERROR, /**< Decoding failed. */
247 HITLS_REC_RECORD_OVERFLOW, /**< Record is too long. */247 HITLS_REC_RECORD_OVERFLOW, /**< Record is too long. */
248 HITLS_REC_ERR_RECV_UNEXPECTED_MSG, /**< Record: unexpected message */248 HITLS_REC_ERR_RECV_UNEXPECTED_MSG, /**< Record: unexpected message */
249+ HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY, /**< TLS1.3: read key change not on record boundary */
249 HITLS_REC_ERR_GENERATE_MAC, /**< Failed to generate the MAC address. */250 HITLS_REC_ERR_GENERATE_MAC, /**< Failed to generate the MAC address. */
250 HITLS_REC_NORMAL_IO_EOF, /**< IO object has reached EOF. */251 HITLS_REC_NORMAL_IO_EOF, /**< IO object has reached EOF. */
251 HITLS_REC_ENCRYPTED_NUMBER_OVERFLOW, /**< The number of AES-GCM encryption times cannot exceed 2^24.5. */252 HITLS_REC_ENCRYPTED_NUMBER_OVERFLOW, /**< The number of AES-GCM encryption times cannot exceed 2^24.5. */
@@ -35,6 +35,7 @@
35#include "conn_init.h"35#include "conn_init.h"
36#include "alert.h"36#include "alert.h"
37#include "hs_kx.h"37#include "hs_kx.h"
38+#include "rec_wrapper.h"
38/* END_HEADER */39/* END_HEADER */
39 40 
40#define MAX_RECORD_LENTH (20 * 1024)41#define MAX_RECORD_LENTH (20 * 1024)
@@ -2556,4 +2557,259 @@ EXIT:
2556 FRAME_FreeLink(client);2557 FRAME_FreeLink(client);
2557 FRAME_FreeLink(server);2558 FRAME_FreeLink(server);
2558}2559}
2560+/* END_CASE */
2561+ 
2562+static void AppendKeyUpdateAfterRecord(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user)
2563+{
2564+ (void)ctx;
2565+ (void)user;
2566+ 
2567+ const uint8_t ku[5] = { 0x18, 0x00, 0x00, 0x01, 0x00 };
2568+ 
2569+ if (*len + (uint32_t)sizeof(ku) > bufSize) {
2570+ return;
2571+ }
2572+ (void)memcpy_s(data + *len, bufSize - *len, ku, sizeof(ku));
2573+ *len += (uint32_t)sizeof(ku);
2574+}
2575+ 
2576+static void AppendFinishedAfterRecord(HITLS_Ctx *ctx, uint8_t *data, uint32_t *len, uint32_t bufSize, void *user)
2577+{
2578+ (void)ctx;
2579+ (void)user;
2580+ 
2581+ /* Finished handshake: type=0x14, length=0 (empty verify_data as placeholder) */
2582+ const uint8_t finished[4] = { 0x14, 0x00, 0x00, 0x00 };
2583+ 
2584+ if (*len + (uint32_t)sizeof(finished) > bufSize) {
2585+ return;
2586+ }
2587+ (void)memcpy_s(data + *len, bufSize - *len, finished, sizeof(finished));
2588+ *len += (uint32_t)sizeof(finished);
2589+}
2590+ 
2591+/**
2592+ * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC001
2593+ * @spec -
2594+ * @title ServerHello not on record boundary - Client read key switch
2595+ * @precon nan
2596+ * @brief Server sends ServerHello with KeyUpdate appended in same record.
2597+ * Client should reject with fatal unexpected_message.
2598+ * @expect Client returns HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY and ALERT_UNEXPECTED_MESSAGE
2599+ * @prior Level 1
2600+ * @auto TRUE
2601+ */
2602+/* BEGIN_CASE */
2603+void UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC001(void)
2604+{
2605+ FRAME_Init();
2606+ HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config();
2607+ ASSERT_TRUE(tlsConfig != NULL);
2608+ 
2609+ RecWrapper wrapper = { TRY_SEND_SERVER_HELLO, REC_TYPE_HANDSHAKE, false, NULL, AppendKeyUpdateAfterRecord };
2610+ RegisterWrapper(wrapper);
2611+ 
2612+ FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2613+ FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2614+ ASSERT_TRUE(client != NULL);
2615+ ASSERT_TRUE(server != NULL);
2616+ 
2617+ int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT);
2618+ ASSERT_EQ(ret, HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
2619+ 
2620+ ALERT_Info alert = {0};
2621+ ALERT_GetInfo(client->ssl, &alert);
2622+ ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL);
2623+ ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE);
2624+ 
2625+EXIT:
2626+ ClearWrapper();
2627+ HITLS_CFG_FreeConfig(tlsConfig);
2628+ FRAME_FreeLink(client);
2629+ FRAME_FreeLink(server);
2630+}
2631+/* END_CASE */
2632+ 
2633+/**
2634+ * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC002
2635+ * @spec -
2636+ * @title Server Finished not on record boundary - Client read key switch
2637+ * @precon nan
2638+ * @brief Server sends Finished with KeyUpdate appended in same record.
2639+ * Client should reject with fatal unexpected_message.
2640+ * @expect Client returns HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY and ALERT_UNEXPECTED_MESSAGE
2641+ * @prior Level 1
2642+ * @auto TRUE
2643+ */
2644+/* BEGIN_CASE */
2645+void UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC002(void)
2646+{
2647+ FRAME_Init();
2648+ HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config();
2649+ ASSERT_TRUE(tlsConfig != NULL);
2650+ 
2651+ RecWrapper wrapper = { TRY_SEND_FINISH, REC_TYPE_HANDSHAKE, false, NULL, AppendKeyUpdateAfterRecord };
2652+ RegisterWrapper(wrapper);
2653+ 
2654+ FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2655+ FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2656+ ASSERT_TRUE(client != NULL);
2657+ ASSERT_TRUE(server != NULL);
2658+ 
2659+ int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT);
2660+ ASSERT_EQ(ret, HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
2661+ 
2662+ ALERT_Info alert = {0};
2663+ ALERT_GetInfo(client->ssl, &alert);
2664+ ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL);
2665+ ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE);
2666+ 
2667+EXIT:
2668+ ClearWrapper();
2669+ HITLS_CFG_FreeConfig(tlsConfig);
2670+ FRAME_FreeLink(client);
2671+ FRAME_FreeLink(server);
2672+}
2673+/* END_CASE */
2674+ 
2675+/**
2676+ * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC003
2677+ * @spec -
2678+ * @title Client Finished not on record boundary - Server read key switch
2679+ * @precon nan
2680+ * @brief Client sends Finished with KeyUpdate appended in same record.
2681+ * Server should reject with fatal unexpected_message.
2682+ * @expect Server returns HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY and ALERT_UNEXPECTED_MESSAGE
2683+ * @prior Level 1
2684+ * @auto TRUE
2685+ */
2686+/* BEGIN_CASE */
2687+void UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC003(void)
2688+{
2689+ FRAME_Init();
2690+ HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config();
2691+ ASSERT_TRUE(tlsConfig != NULL);
2692+ 
2693+ RecWrapper wrapper = { TRY_SEND_FINISH, REC_TYPE_HANDSHAKE, false, NULL, AppendKeyUpdateAfterRecord };
2694+ RegisterWrapper(wrapper);
2695+ 
2696+ FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2697+ FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2698+ ASSERT_TRUE(client != NULL);
2699+ ASSERT_TRUE(server != NULL);
2700+ 
2701+ int32_t ret = FRAME_CreateConnection(client, server, true, HS_STATE_BUTT);
2702+ ASSERT_EQ(ret, HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
2703+ 
2704+ ALERT_Info alert = {0};
2705+ ALERT_GetInfo(client->ssl, &alert);
2706+ ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL);
2707+ ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE);
2708+ 
2709+EXIT:
2710+ ClearWrapper();
2711+ HITLS_CFG_FreeConfig(tlsConfig);
2712+ FRAME_FreeLink(client);
2713+ FRAME_FreeLink(server);
2714+}
2715+/* END_CASE */
2716+ 
2717+/**
2718+ * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC004
2719+ * @spec -
2720+ * @title KeyUpdate not on record boundary - Server to Client
2721+ * @precon nan
2722+ * @brief Server sends KeyUpdate with another KeyUpdate appended in same record.
2723+ * Client should reject with fatal unexpected_message.
2724+ * @expect Client returns HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY and ALERT_UNEXPECTED_MESSAGE
2725+ * @prior Level 1
2726+ * @auto TRUE
2727+ */
2728+/* BEGIN_CASE */
2729+void UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC004(void)
2730+{
2731+ FRAME_Init();
2732+ HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config();
2733+ ASSERT_TRUE(tlsConfig != NULL);
2734+ 
2735+ FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2736+ FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2737+ ASSERT_TRUE(client != NULL);
2738+ ASSERT_TRUE(server != NULL);
2739+ 
2740+ ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS);
2741+ 
2742+ RecWrapper wrapper = { TRY_SEND_KEY_UPDATE, REC_TYPE_HANDSHAKE, false, NULL, AppendFinishedAfterRecord };
2743+ RegisterWrapper(wrapper);
2744+ 
2745+ ASSERT_TRUE(HITLS_KeyUpdate(server->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS);
2746+ ASSERT_TRUE(HITLS_Accept(server->ssl) == HITLS_SUCCESS);
2747+ ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(server, client) == HITLS_SUCCESS);
2748+ 
2749+ uint8_t readBuf[READ_BUF_SIZE] = {0};
2750+ uint32_t readLen = 0;
2751+ int32_t ret = HITLS_Read(client->ssl, readBuf, READ_BUF_SIZE, &readLen);
2752+ ASSERT_EQ(ret, HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
2753+ 
2754+ ALERT_Info alert = {0};
2755+ ALERT_GetInfo(client->ssl, &alert);
2756+ ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL);
2757+ ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE);
2758+ 
2759+EXIT:
2760+ ClearWrapper();
2761+ HITLS_CFG_FreeConfig(tlsConfig);
2762+ FRAME_FreeLink(client);
2763+ FRAME_FreeLink(server);
2764+}
2765+/* END_CASE */
2766+ 
2767+/**
2768+ * @test UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC005
2769+ * @spec -
2770+ * @title KeyUpdate not on record boundary - Client to Server
2771+ * @precon nan
2772+ * @brief Client sends KeyUpdate with Finished appended in same record.
2773+ * Server should reject with fatal unexpected_message.
2774+ * @expect Server returns HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY and ALERT_UNEXPECTED_MESSAGE
2775+ * @prior Level 1
2776+ * @auto TRUE
2777+ */
2778+/* BEGIN_CASE */
2779+void UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC005(void)
2780+{
2781+ FRAME_Init();
2782+ HITLS_Config *tlsConfig = HITLS_CFG_NewTLS13Config();
2783+ ASSERT_TRUE(tlsConfig != NULL);
2784+ 
2785+ FRAME_LinkObj *client = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2786+ FRAME_LinkObj *server = FRAME_CreateLink(tlsConfig, BSL_UIO_TCP);
2787+ ASSERT_TRUE(client != NULL);
2788+ ASSERT_TRUE(server != NULL);
2789+ 
2790+ ASSERT_TRUE(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT) == HITLS_SUCCESS);
2791+ 
2792+ RecWrapper wrapper = { TRY_SEND_KEY_UPDATE, REC_TYPE_HANDSHAKE, false, NULL, AppendFinishedAfterRecord };
2793+ RegisterWrapper(wrapper);
2794+ 
2795+ ASSERT_TRUE(HITLS_KeyUpdate(client->ssl, HITLS_UPDATE_REQUESTED) == HITLS_SUCCESS);
2796+ ASSERT_TRUE(HITLS_Connect(client->ssl) == HITLS_SUCCESS);
2797+ ASSERT_TRUE(FRAME_TrasferMsgBetweenLink(client, server) == HITLS_SUCCESS);
2798+ 
2799+ uint8_t readBuf[READ_BUF_SIZE] = {0};
2800+ uint32_t readLen = 0;
2801+ int32_t ret = HITLS_Read(server->ssl, readBuf, READ_BUF_SIZE, &readLen);
2802+ ASSERT_EQ(ret, HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
2803+ 
2804+ ALERT_Info alert = {0};
2805+ ALERT_GetInfo(server->ssl, &alert);
2806+ ASSERT_EQ(alert.level, ALERT_LEVEL_FATAL);
2807+ ASSERT_EQ(alert.description, ALERT_UNEXPECTED_MESSAGE);
2808+ 
2809+EXIT:
2810+ ClearWrapper();
2811+ HITLS_CFG_FreeConfig(tlsConfig);
2812+ FRAME_FreeLink(client);
2813+ FRAME_FreeLink(server);
2814+}
2559/* END_CASE */2815/* END_CASE */
@@ -107,4 +107,19 @@ UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002
107UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002:107UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC002:
108 108 
109UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003109UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003
110-UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003:110+UT_TLS_TLS13_RFC8446_CONSISTENCY_SEQUENCE_NUMBER_FUNC_TC003:
111+ 
112+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC001
113+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC001:
114+ 
115+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC002
116+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC002:
117+ 
118+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC003
119+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC003:
120+ 
121+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC004
122+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC004:
123+ 
124+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC005
125+UT_TLS_TLS13_RFC8446_CONSISTENCY_NOT_ON_RECORD_BOUNDARY_FUNC_TC005:
@@ -501,7 +501,8 @@ enum TLS_BINLOG_ID {
501 BINLOG_ID17336, BINLOG_ID17337, BINLOG_ID17338, BINLOG_ID17339, BINLOG_ID17340,501 BINLOG_ID17336, BINLOG_ID17337, BINLOG_ID17338, BINLOG_ID17339, BINLOG_ID17340,
502 BINLOG_ID17341, BINLOG_ID17342, BINLOG_ID17343, BINLOG_ID17344, BINLOG_ID17345,502 BINLOG_ID17341, BINLOG_ID17342, BINLOG_ID17343, BINLOG_ID17344, BINLOG_ID17345,
503 BINLOG_ID17346, BINLOG_ID17347, BINLOG_ID17348, BINLOG_ID17349, BINLOG_ID17350,503 BINLOG_ID17346, BINLOG_ID17347, BINLOG_ID17348, BINLOG_ID17349, BINLOG_ID17350,
504- BINLOG_ID17351, BINLOG_ID17352, BINLOG_ID17353, BINLOG_ID17354, BINLOG_ID17355504+ BINLOG_ID17351, BINLOG_ID17352, BINLOG_ID17353, BINLOG_ID17354, BINLOG_ID17355,
505+ BINLOG_ID17356
505};506};
506 507 
507#ifdef HITLS_BSL_LOG508#ifdef HITLS_BSL_LOG
@@ -474,6 +474,17 @@ int32_t REC_TLS13InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *p
474int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut)474int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut)
475{475{
476 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;476 RecCtx *recordCtx = (RecCtx *)ctx->recCtx;
477+ 
478+ if (!isOut) {
479+ if ((recordCtx->hsRecList != NULL && !RecBufListEmpty(recordCtx->hsRecList))) {
480+ ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
481+ BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17356, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
482+ "Record: read key change not on record boundary.", 0, 0, 0, 0);
483+ BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY);
484+ return HITLS_REC_ERR_NOT_ON_RECORD_BOUNDARY;
485+ }
486+ }
487+ 
477 RecConnStates *states = (isOut == true) ? &recordCtx->writeStates : &recordCtx->readStates;488 RecConnStates *states = (isOut == true) ? &recordCtx->writeStates : &recordCtx->readStates;
478 489 
479 if (states->pendingState == NULL) {490 if (states->pendingState == NULL) {