From a8d0dfac3170e3cd92f964c8a51c61a15c96b20d Mon Sep 17 00:00:00 2001 From: Fredrik Thulin <fredrik@thulin.net> Date: Mon, 21 Jan 2013 13:21:06 +0100 Subject: [PATCH] C_InitToken: label is not NULL terminated PKCS#11 v2.2 is very clear that the 'label' argument provided to C_InitToken is *not* necessarily NULL-terminated, but rather of fixed size (32 bytes) and whitespace-padded. --- gck-rpc-dispatch.c | 34 +++++++++++++++++++++++++++++++++- gck-rpc-module.c | 6 +++++- gck-rpc-private.h | 4 ++-- p11proxy-mitm | 2 +- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/gck-rpc-dispatch.c b/gck-rpc-dispatch.c index 9bf2fa1..be1d7d9 100644 --- a/gck-rpc-dispatch.c +++ b/gck-rpc-dispatch.c @@ -601,6 +601,34 @@ static CK_RV proto_read_null_string(CallState * cs, CK_UTF8CHAR_PTR * val) return CKR_OK; } +static CK_RV proto_read_space_string(CallState * cs, CK_UTF8CHAR_PTR * val, CK_ULONG length) +{ + GckRpcMessage *msg; + const unsigned char *data; + size_t n_data; + + assert(cs); + assert(val); + + msg = cs->req; + + /* Check that we're supposed to have this at this point */ + assert(!msg->signature || gck_rpc_message_verify_part(msg, "s")); + + if (!egg_buffer_get_byte_array + (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data)) + return PARSE_ERROR; + + /* Allocate a block of memory for it. */ + *val = call_alloc(cs, n_data); + if (!*val) + return CKR_DEVICE_MEMORY; + + memcpy(*val, data, n_data); + + return CKR_OK; +} + static CK_RV proto_read_mechanism(CallState * cs, CK_MECHANISM_PTR mech) { GckRpcMessage *msg; @@ -781,6 +809,10 @@ static CK_RV proto_write_session_info(CallState * cs, CK_SESSION_INFO_PTR info) _ret = proto_read_null_string (cs, &val); \ if (_ret != CKR_OK) goto _cleanup; +#define IN_SPACE_STRING(val, len) \ + _ret = proto_read_space_string (cs, &val, len); \ + if (_ret != CKR_OK) goto _cleanup; + #define IN_BYTE_BUFFER(buffer, buffer_len_ptr) \ _ret = proto_read_byte_buffer (cs, &buffer, &buffer_len_ptr); \ if (_ret != CKR_OK) goto _cleanup; @@ -1033,7 +1065,7 @@ static CK_RV rpc_C_InitToken(CallState * cs) BEGIN_CALL(C_InitToken); IN_ULONG(slot_id); IN_BYTE_ARRAY(pin, pin_len); - IN_STRING(label); + IN_SPACE_STRING(label, 32); PROCESS_CALL((slot_id, pin, pin_len, label)); END_CALL; } diff --git a/gck-rpc-module.c b/gck-rpc-module.c index d858186..c3b62c1 100644 --- a/gck-rpc-module.c +++ b/gck-rpc-module.c @@ -1134,6 +1134,10 @@ proto_read_sesssion_info(GckRpcMessage * msg, CK_SESSION_INFO_PTR info) if (!gck_rpc_message_write_zero_string (_cs->req, val)) \ { _ret = CKR_HOST_MEMORY; goto _cleanup; } +#define IN_SPACE_STRING(val, len) \ + if (!gck_rpc_message_write_space_string (_cs->req, val, len)) \ + { _ret = CKR_HOST_MEMORY; goto _cleanup; } + #define IN_BYTE_BUFFER(arr, len) \ if (!gck_rpc_message_write_byte_buffer (_cs->req, arr, len)) \ { _ret = CKR_HOST_MEMORY; goto _cleanup; } @@ -1499,7 +1503,7 @@ rpc_C_InitToken(CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, BEGIN_CALL(C_InitToken); IN_ULONG(id); IN_BYTE_ARRAY(pin, pin_len); - IN_STRING(label); + IN_SPACE_STRING(label, 32); PROCESS_CALL; END_CALL; } diff --git a/gck-rpc-private.h b/gck-rpc-private.h index cf7f6ad..a3843e5 100644 --- a/gck-rpc-private.h +++ b/gck-rpc-private.h @@ -144,7 +144,7 @@ static const GckRpcCall gck_rpc_calls[] = { "ssssuuuuuuuuuuuvvs"}, {GCK_RPC_CALL_C_GetMechanismList, "C_GetMechanismList", "ufu", "au"}, {GCK_RPC_CALL_C_GetMechanismInfo, "C_GetMechanismInfo", "uu", "uuu"}, - {GCK_RPC_CALL_C_InitToken, "C_InitToken", "uayz", ""}, + {GCK_RPC_CALL_C_InitToken, "C_InitToken", "uays", ""}, {GCK_RPC_CALL_C_WaitForSlotEvent, "C_WaitForSlotEvent", "u", "u"}, {GCK_RPC_CALL_C_OpenSession, "C_OpenSession", "uu", "u"}, {GCK_RPC_CALL_C_CloseSession, "C_CloseSession", "u", ""}, @@ -216,7 +216,7 @@ static const GckRpcCall gck_rpc_calls[] = { #endif #define GCK_RPC_HANDSHAKE \ - "PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-2" + "PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-3" #define GCK_RPC_HANDSHAKE_LEN \ (sizeof (GCK_RPC_HANDSHAKE) - 1) diff --git a/p11proxy-mitm b/p11proxy-mitm index 013f161..a640150 100755 --- a/p11proxy-mitm +++ b/p11proxy-mitm @@ -95,7 +95,7 @@ request_list = [ (6, "C_GetTokenInfo", "u", "ssssuuuuuuuuuuuvvs"), (7, "C_GetMechanismList", "ufu", "au"), (8, "C_GetMechanismInfo", "uu", "uuu"), - (9, "C_InitToken", "uayz", ""), + (9, "C_InitToken", "uays", ""), (10, "C_WaitForSlotEvent", "u", "u"), (11, "C_OpenSession", "uu", "u"), (12, "C_CloseSession", "u", ""), -- GitLab