Skip to content

Commit 07b6bf2

Browse files
authored
Merge pull request #362 from bigbrett/client-id-alias
client ID fixes
2 parents d80da11 + f563fc8 commit 07b6bf2

8 files changed

Lines changed: 85 additions & 8 deletions

File tree

docs/src-ja/chapter03.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ whCommClientConfig commClientCfg = {
4646
.transport_cb = transportMemClientCb,
4747
.transport_context = (void*)transportMemClientCtx,
4848
.transport_config = (void*)transportMemCfg,
49-
.client_id = 123, /* 一意のクライアント識別子 */
49+
.client_id = 1, /* 一意のクライアント識別子。1-15(WOLFHSM_CFG_GLOBAL_KEYSなしでは0-15) */
5050
};
5151

5252
/* 手順3: クライアント設定の割り当てと初期化 */

docs/src-ja/chapter05.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ whCommClientConfig commClientCfg[1] = {{
8888
.transport_cb = transportMemClientCb,
8989
.transport_context = (void*)transportMemClientCtx,
9090
.transport_config = (void*)transportMemCfg,
91-
.client_id = 123, /* 一意のクライアント識別子 */
91+
.client_id = 1, /* 一意のクライアント識別子。1-15(WOLFHSM_CFG_GLOBAL_KEYSなしでは0-15) */
9292
}};
9393

9494
/* ステップ3: クライアント設定の割り当てと初期化 */
@@ -150,7 +150,7 @@ whCommClientConfig commClientCfg = {{
150150
.transport_cb = posixTransportTcpCb,
151151
.transport_context = (void*)posixTransportTcpCtx,
152152
.transport_config = (void*)posixTransportTcpCfg,
153-
.client_id = 123, /* 一意のクライアント識別子 */
153+
.client_id = 1, /* 一意のクライアント識別子。1-15(WOLFHSM_CFG_GLOBAL_KEYSなしでは0-15) */
154154
}};
155155

156156
/* 以降のステップは同じ... */

docs/src/chapter03.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ whCommClientConfig commClientCfg = {
4545
.transport_cb = transportMemClientCb,
4646
.transport_context = (void*)transportMemClientCtx,
4747
.transport_config = (void*)transportMemCfg,
48-
.client_id = 123, /* unique client identifier */
48+
.client_id = 1, /* unique client identifier, 1-15 (or 0-15 without WOLFHSM_CFG_GLOBAL_KEYS) */
4949
};
5050

5151
/* Step 3: Allocate and initialize the client configuration */

docs/src/chapter05.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ whCommClientConfig commClientCfg[1] = {{
9090
.transport_cb = transportMemClientCb,
9191
.transport_context = (void*)transportMemClientCtx,
9292
.transport_config = (void*)transportMemCfg,
93-
.client_id = 123, /* unique client identifier */
93+
.client_id = 1, /* unique client identifier, 1-15 (or 0-15 without WOLFHSM_CFG_GLOBAL_KEYS) */
9494
}};
9595

9696
/* Step 3: Allocate and initialize the client configuration */
@@ -149,7 +149,7 @@ whCommClientConfig commClientCfg = {{
149149
.transport_cb = posixTransportTcpCb,
150150
.transport_context = (void*)posixTransportTcpCtx,
151151
.transport_config = (void*)posixTransportTcpCfg,
152-
.client_id = 123, /* unique client identifier */
152+
.client_id = 1, /* unique client identifier, 1-15 (or 0-15 without WOLFHSM_CFG_GLOBAL_KEYS) */
153153
}};
154154

155155
/* Subsequent steps remain the same... */

src/wh_server.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ static int _wh_Server_HandleCommRequest(whServerContext* server,
204204
wh_MessageComm_TranslateInitRequest(magic,
205205
(whMessageCommInitRequest*)req_packet, &req);
206206

207+
if (req.client_id > WH_CLIENT_ID_MAX) {
208+
*out_resp_size = 0;
209+
return WH_ERROR_BADARGS;
210+
}
207211
#ifdef WOLFHSM_CFG_GLOBAL_KEYS
208212
/* USER=0 is reserved for global keys, client_id must be non-zero */
209213
if (req.client_id == WH_KEYUSER_GLOBAL) {

test/wh_test_clientserver.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,49 @@ static int _clientServerSequentialTestConnectCb(void* context,
516516
connected);
517517
}
518518

519+
/* Drive one INIT cycle on an already-initialized client/server pair to verify
520+
* the server enforces the [0, WH_CLIENT_ID_MAX] bound on client_id (so values
521+
* that would be silently truncated by the 4-bit USER field of whKeyId — e.g.
522+
* 16 aliasing the USER=0 global namespace, 17 aliasing client 1 — are
523+
* rejected at INIT instead of breaking per-client key isolation). Mutates
524+
* client->comm->client_id; caller is responsible for restoring it.
525+
*
526+
* Note: boundary coverage is limited to [0, 255] because
527+
* client->comm->client_id is uint8_t; values above 255 are truncated by the
528+
* host-side comm field before reaching the wire. */
529+
static int _testInitClientIdBoundary(whClientContext* client,
530+
whServerContext* server,
531+
uint32_t client_id, int expect_ok)
532+
{
533+
uint32_t resp_client_id = 0;
534+
uint32_t resp_server_id = 0;
535+
int rc;
536+
uint8_t prior_server_client_id = server->comm->client_id;
537+
538+
client->comm->client_id = (uint8_t)client_id;
539+
540+
WH_TEST_RETURN_ON_FAIL(wh_Client_CommInitRequest(client));
541+
WH_TEST_RETURN_ON_FAIL(wh_Server_HandleRequestMessage(server));
542+
rc = wh_Client_CommInitResponse(client, &resp_client_id, &resp_server_id);
543+
544+
if (expect_ok) {
545+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);
546+
WH_TEST_ASSERT_RETURN(resp_client_id == client_id);
547+
}
548+
else {
549+
/* Server returns BADARGS with size=0; client decodes that as ABORTED.
550+
*/
551+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED);
552+
/* Rejection must not corrupt server-side identity: a regression that
553+
* moved the assignment in _wh_Server_HandleCommRequest above the
554+
* bound check would still produce ABORTED on the wire but would
555+
* leave server->comm->client_id holding the rejected value. */
556+
WH_TEST_ASSERT_RETURN(server->comm->client_id ==
557+
prior_server_client_id);
558+
}
559+
return WH_ERROR_OK;
560+
}
561+
519562
static int _testOutOfBoundsNvmReads(whClientContext* client,
520563
whServerContext* server, whNvmId id)
521564
{
@@ -739,6 +782,24 @@ int whTest_ClientServerSequential(whTestNvmBackendType nvmType)
739782
WH_TEST_RETURN_ON_FAIL(wh_Client_CommInitResponse(client, &client_id, &server_id));
740783
WH_TEST_ASSERT_RETURN(client_id == client->comm->client_id);
741784

785+
/* Verify INIT rejects out-of-range client_id values that would otherwise
786+
* be silently truncated by the 4-bit USER field of whKeyId. */
787+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 16, 0));
788+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 17, 0));
789+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 32, 0));
790+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 255, 0));
791+
#ifdef WOLFHSM_CFG_GLOBAL_KEYS
792+
/* USER=0 is reserved for global keys */
793+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 0, 0));
794+
#else
795+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(client, server, 0, 1));
796+
#endif
797+
WH_TEST_RETURN_ON_FAIL(
798+
_testInitClientIdBoundary(client, server, WH_CLIENT_ID_MAX, 1));
799+
/* Restore default client_id so the rest of the sequential test runs with
800+
* the expected per-client identity on both ends. */
801+
WH_TEST_RETURN_ON_FAIL(_testInitClientIdBoundary(
802+
client, server, WH_TEST_DEFAULT_CLIENT_ID, 1));
742803

743804
/* Send the comm info message */
744805
WH_TEST_RETURN_ON_FAIL(wh_Client_CommInfoRequest(client));

test/wh_test_posix_threadsafe_stress.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ static int initClientServerPair(StressTestContext* ctx, int pairIndex)
629629
pair->clientCommConfig.transport_cb = &clientTransportCb;
630630
pair->clientCommConfig.transport_context = &pair->clientTransportCtx;
631631
pair->clientCommConfig.transport_config = &pair->tmConfig;
632-
pair->clientCommConfig.client_id = (uint16_t)(100 + pairIndex);
632+
/* client_id must fit in WH_CLIENT_ID_MAX (4-bit USER field) */
633+
pair->clientCommConfig.client_id = (uint8_t)(1 + pairIndex);
633634

634635
/* Configure client */
635636
pair->clientConfig.comm = &pair->clientCommConfig;

wolfhsm/wh_keyid.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ typedef uint16_t whKeyId;
4646
#define WH_KEYTYPE_MASK 0xF000
4747
#define WH_KEYTYPE_SHIFT 12
4848

49+
/* Maximum valid client_id. The USER field of whKeyId is 4 bits, so client_id
50+
* must fit in [0, WH_CLIENT_ID_MAX]. Values outside this range would be
51+
* silently truncated by WH_MAKE_KEYID, breaking per-client key isolation, so
52+
* the server rejects them at WH_MESSAGE_COMM_ACTION_INIT. With
53+
* WOLFHSM_CFG_GLOBAL_KEYS enabled, value 0 is reserved for the global-keys
54+
* namespace and is also rejected. Derived from WH_KEYUSER_MASK so the bound
55+
* stays in sync if the USER field is ever widened. */
56+
#define WH_CLIENT_ID_MAX (WH_KEYUSER_MASK >> WH_KEYUSER_SHIFT)
57+
4958
/*
5059
* Client-facing key flags (temporary, stripped by server during translation)
5160
*
@@ -110,7 +119,9 @@ typedef uint16_t whKeyId;
110119
* @param type Key type to use as the TYPE field. Input value is ignored and
111120
* WH_KEYTYPE_WRAPPED is used if the input clientId has the
112121
* WH_CLIENT_KEYID_WRAPPED flag set.
113-
* @param clientId Client identifier to use as USER field
122+
* @param clientId Client identifier to use as USER field. Must be in
123+
* [0, WH_CLIENT_ID_MAX]; the server enforces this at INIT so callers may
124+
* assume the value fits in the 4-bit USER field.
114125
* @param reqId Requested keyId from client (may include flags)
115126
* @return Server-internal keyId with TYPE, USER, and ID fields properly set.
116127
*/

0 commit comments

Comments
 (0)