Skip to content

Commit

Permalink
rpc: add support for recursive attributes
Browse files Browse the repository at this point in the history
Signed-off-by: Zoltan Fridrich <[email protected]>
  • Loading branch information
ZoltanFridrich committed Feb 28, 2024
1 parent 7756404 commit e571db2
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 110 deletions.
18 changes: 18 additions & 0 deletions common/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,24 @@ module_reset_objects (CK_SLOT_ID slot_id)
p11_dict_set (the_objects, handle_to_pointer (MOCK_PUBLIC_KEY_PREFIX), p11_attrs_dup (attrs));

}

{
CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY;
char *label = "Public prefix key 2";
char *value = "value";
CK_BBOOL bfalse = CK_FALSE;
CK_ATTRIBUTE wrap_template[] = {
{ CKA_LOCAL, &bfalse, sizeof (bfalse) },
};
CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &klass, sizeof (klass) },
{ CKA_LABEL, label, strlen (label) },
{ CKA_WRAP_TEMPLATE, &wrap_template, sizeof (wrap_template) },
{ CKA_VALUE, value, strlen (value) },
{ CKA_INVALID, NULL, 0 },
};
p11_dict_set (the_objects, handle_to_pointer (MOCK_PUBLIC_KEY_PREFIX_2), p11_attrs_dup (attrs));
}
}

void
Expand Down
1 change: 1 addition & 0 deletions common/mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum {
MOCK_PUBLIC_KEY_PREFIX = 6,
MOCK_PROFILE_OBJECT = 7,
MOCK_CERTIFICATE_OBJECT = 8,
MOCK_PUBLIC_KEY_PREFIX_2 = 9,

/*
* CKM_MOCK_CAPITALIZE (encrypt/decrypt)
Expand Down
8 changes: 2 additions & 6 deletions p11-kit/rpc-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,6 @@ proto_read_attribute_array (p11_rpc_message *msg,
return PARSE_ERROR;
}

if (IS_ATTRIBUTE_ARRAY (&temp)) {
p11_debug("recursive attribute array is not supported");
return PARSE_ERROR;
}

/* Try and stuff it in the output data */
if (arr) {
CK_ATTRIBUTE *attr = &(arr[i]);
Expand Down Expand Up @@ -277,6 +272,7 @@ proto_read_attribute_array (p11_rpc_message *msg,
msg->parsed = offset2;
return PARSE_ERROR;
}
offset = offset2;
}
} else {
attr->ulValueLen = temp.ulValueLen;
Expand Down Expand Up @@ -1262,7 +1258,7 @@ rpc_C_GetAttributeValue (CK_X_FUNCTION_LIST *self,
BEGIN_CALL_OR (C_GetAttributeValue, self, CKR_SESSION_HANDLE_INVALID);
IN_ULONG (session);
IN_ULONG (object);
IN_ATTRIBUTE_BUFFER (template, count);
IN_ATTRIBUTE_ARRAY (template, count);
PROCESS_CALL;
OUT_ATTRIBUTE_ARRAY (template, count);
END_CALL;
Expand Down
145 changes: 108 additions & 37 deletions p11-kit/rpc-message.c
Original file line number Diff line number Diff line change
Expand Up @@ -903,19 +903,69 @@ map_attribute_to_value_type (CK_ATTRIBUTE_TYPE type)
}
}

static bool
p11_rpc_message_get_byte_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
return p11_rpc_buffer_get_byte_value (buffer, offset, value, value_length);
}

static bool
p11_rpc_message_get_ulong_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
return p11_rpc_buffer_get_ulong_value (buffer, offset, value, value_length);
}

static bool
p11_rpc_message_get_mechanism_type_array_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
return p11_rpc_buffer_get_mechanism_type_array_value (buffer, offset, value, value_length);
}

static bool
p11_rpc_message_get_date_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
return p11_rpc_buffer_get_date_value (buffer, offset, value, value_length);
}

static bool
p11_rpc_message_get_byte_array_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
return p11_rpc_buffer_get_byte_array_value (buffer, offset, value, value_length);
}

typedef struct {
p11_rpc_value_type type;
p11_rpc_value_encoder encode;
p11_rpc_value_decoder decode;
p11_rpc_message_decoder decode;
} p11_rpc_attribute_serializer;

static p11_rpc_attribute_serializer p11_rpc_attribute_serializers[] = {
{ P11_RPC_VALUE_BYTE, p11_rpc_buffer_add_byte_value, p11_rpc_buffer_get_byte_value },
{ P11_RPC_VALUE_ULONG, p11_rpc_buffer_add_ulong_value, p11_rpc_buffer_get_ulong_value },
{ P11_RPC_VALUE_ATTRIBUTE_ARRAY, p11_rpc_buffer_add_attribute_array_value, p11_rpc_buffer_get_attribute_array_value },
{ P11_RPC_VALUE_MECHANISM_TYPE_ARRAY, p11_rpc_buffer_add_mechanism_type_array_value, p11_rpc_buffer_get_mechanism_type_array_value },
{ P11_RPC_VALUE_DATE, p11_rpc_buffer_add_date_value, p11_rpc_buffer_get_date_value },
{ P11_RPC_VALUE_BYTE_ARRAY, p11_rpc_buffer_add_byte_array_value, p11_rpc_buffer_get_byte_array_value }
{ P11_RPC_VALUE_BYTE, p11_rpc_buffer_add_byte_value, p11_rpc_message_get_byte_value },
{ P11_RPC_VALUE_ULONG, p11_rpc_buffer_add_ulong_value, p11_rpc_message_get_ulong_value },
{ P11_RPC_VALUE_ATTRIBUTE_ARRAY, p11_rpc_buffer_add_attribute_array_value, p11_rpc_message_get_attribute_array_value },
{ P11_RPC_VALUE_MECHANISM_TYPE_ARRAY, p11_rpc_buffer_add_mechanism_type_array_value, p11_rpc_message_get_mechanism_type_array_value },
{ P11_RPC_VALUE_DATE, p11_rpc_buffer_add_date_value, p11_rpc_message_get_date_value },
{ P11_RPC_VALUE_BYTE_ARRAY, p11_rpc_buffer_add_byte_array_value, p11_rpc_message_get_byte_array_value }
};

P11_STATIC_ASSERT(sizeof(CK_BYTE) <= sizeof(uint8_t));
Expand Down Expand Up @@ -977,6 +1027,12 @@ p11_rpc_buffer_add_attribute_array_value (p11_buffer *buffer,
return;
}

/* When value is NULL, write an empty attribute array */
if (attrs == NULL) {
p11_rpc_buffer_add_uint32 (buffer, 0);
return;
}

/* Write the number of items */
p11_rpc_buffer_add_uint32 (buffer, count);

Expand Down Expand Up @@ -1139,32 +1195,27 @@ p11_rpc_buffer_get_ulong_value (p11_buffer *buffer,
}

bool
p11_rpc_buffer_get_attribute_array_value (p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
p11_rpc_message_get_attribute_array_value (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length)
{
uint32_t count, i;
CK_ATTRIBUTE *attr, temp;
CK_ATTRIBUTE *attr = value;

if (!p11_rpc_buffer_get_uint32 (buffer, offset, &count))
return false;

if (!value) {
memset (&temp, 0, sizeof (CK_ATTRIBUTE));
attr = &temp;
} else
attr = value;
if (value_length != NULL)
*value_length = count * sizeof (CK_ATTRIBUTE);

for (i = 0; i < count; i++) {
if (!p11_rpc_buffer_get_attribute (buffer, offset, attr))
return false;
if (value)
attr++;
}
if (value == NULL)
return true;

if (value_length)
*value_length = count * sizeof (CK_ATTRIBUTE);
for (i = 0; i < count; ++i)
if (!p11_rpc_message_get_attribute (msg, buffer, offset, attr + i))
return false;

return true;
}
Expand Down Expand Up @@ -1252,11 +1303,13 @@ p11_rpc_buffer_get_byte_array_value (p11_buffer *buffer,
}

bool
p11_rpc_buffer_get_attribute (p11_buffer *buffer,
size_t *offset,
CK_ATTRIBUTE *attr)
p11_rpc_message_get_attribute (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
CK_ATTRIBUTE *attr)
{
uint32_t type, length, decode_length;
uint32_t type, length;
CK_ULONG decode_length;
unsigned char validity;
p11_rpc_attribute_serializer *serializer;
p11_rpc_value_type value_type;
Expand All @@ -1279,24 +1332,42 @@ p11_rpc_buffer_get_attribute (p11_buffer *buffer,
if (!p11_rpc_buffer_get_uint32 (buffer, offset, &length))
return false;

if (length == 0) {
attr->type = type;
attr->pValue = NULL;
attr->ulValueLen = 0;
return true;
}

/* Allocate memory for the attribute value */
if (msg != NULL) {
attr->pValue = p11_rpc_message_alloc_extra (msg, length);
if (attr->pValue == NULL)
return false;
}

/* Decode the attribute value */
value_type = map_attribute_to_value_type (type);
assert (value_type < ELEMS (p11_rpc_attribute_serializers));
serializer = &p11_rpc_attribute_serializers[value_type];
assert (serializer != NULL);
if (!serializer->decode (buffer, offset, attr->pValue, &attr->ulValueLen))
if (!serializer->decode (msg, buffer, offset, attr->pValue, &decode_length))
return false;
if (attr->pValue == NULL && decode_length > length)
return false;
if (!attr->pValue) {
decode_length = attr->ulValueLen;
attr->ulValueLen = length;
if (decode_length > length) {
return false;
}
}
attr->type = type;
attr->ulValueLen = length;
return true;
}

bool
p11_rpc_buffer_get_attribute (p11_buffer *buffer,
size_t *offset,
CK_ATTRIBUTE *attr)
{
return p11_rpc_message_get_attribute (NULL, buffer, offset, attr);
}

/* Used to override the supported mechanisms in tests */
CK_MECHANISM_TYPE *p11_rpc_mechanisms_override_supported = NULL;

Expand Down
21 changes: 17 additions & 4 deletions p11-kit/rpc-message.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ static const p11_rpc_call p11_rpc_calls[] = {
{ P11_RPC_CALL_C_CopyObject, "C_CopyObject", "uuaA", "u" },
{ P11_RPC_CALL_C_DestroyObject, "C_DestroyObject", "uu", "" },
{ P11_RPC_CALL_C_GetObjectSize, "C_GetObjectSize", "uu", "u" },
{ P11_RPC_CALL_C_GetAttributeValue, "C_GetAttributeValue", "uufA", "aAu" },
{ P11_RPC_CALL_C_GetAttributeValue, "C_GetAttributeValue", "uuaA", "aAu" },
{ P11_RPC_CALL_C_SetAttributeValue, "C_SetAttributeValue", "uuaA", "" },
{ P11_RPC_CALL_C_FindObjectsInit, "C_FindObjectsInit", "uaA", "" },
{ P11_RPC_CALL_C_FindObjects, "C_FindObjects", "ufu", "au" },
Expand Down Expand Up @@ -276,9 +276,6 @@ typedef enum _p11_rpc_value_type {
P11_RPC_VALUE_BYTE_ARRAY
} p11_rpc_value_type;

typedef void (*p11_rpc_value_encoder) (p11_buffer *, const void *, CK_ULONG);
typedef bool (*p11_rpc_value_decoder) (p11_buffer *, size_t *, void *, CK_ULONG *);

typedef enum _p11_rpc_message_type {
P11_RPC_REQUEST = 1,
P11_RPC_RESPONSE
Expand All @@ -295,6 +292,10 @@ typedef struct {
void *extra;
} p11_rpc_message;

typedef void (*p11_rpc_value_encoder) (p11_buffer *, const void *, CK_ULONG);
typedef bool (*p11_rpc_value_decoder) (p11_buffer *, size_t *, void *, CK_ULONG *);
typedef bool (*p11_rpc_message_decoder) (p11_rpc_message *msg, p11_buffer *, size_t *, void *, CK_ULONG *);

void p11_rpc_message_init (p11_rpc_message *msg,
p11_buffer *input,
p11_buffer *output);
Expand Down Expand Up @@ -441,6 +442,11 @@ bool p11_rpc_buffer_get_attribute (p11_buffer *buffer,
size_t *offset,
CK_ATTRIBUTE *attr);

bool p11_rpc_message_get_attribute (p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
CK_ATTRIBUTE *attr);

void p11_rpc_buffer_add_byte_value (p11_buffer *buffer,
const void *value,
CK_ULONG value_length);
Expand Down Expand Up @@ -470,6 +476,13 @@ bool p11_rpc_buffer_get_attribute_array_value
void *value,
CK_ULONG *value_length);

bool p11_rpc_message_get_attribute_array_value
(p11_rpc_message *msg,
p11_buffer *buffer,
size_t *offset,
void *value,
CK_ULONG *value_length);

void p11_rpc_buffer_add_mechanism_type_array_value
(p11_buffer *buffer,
const void *value,
Expand Down
36 changes: 3 additions & 33 deletions p11-kit/rpc-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,39 +327,9 @@ proto_read_attribute_array (p11_rpc_message *msg,
return CKR_DEVICE_MEMORY;

/* Now go through and fill in each one */
for (i = 0; i < n_attrs; ++i) {
size_t offset = msg->parsed;
CK_ATTRIBUTE temp;

/* Check the length needed to store the value */
memset (&temp, 0, sizeof (temp));
if (!p11_rpc_buffer_get_attribute (msg->input, &offset, &temp)) {
msg->parsed = offset;
return PARSE_ERROR;
}

if (IS_ATTRIBUTE_ARRAY (&temp)) {
p11_debug("recursive attribute array is not supported");
for (i = 0; i < n_attrs; ++i)
if (!p11_rpc_message_get_attribute (msg, msg->input, &msg->parsed, &attrs[i]))
return PARSE_ERROR;
}

attrs[i].type = temp.type;

/* Whether this one is valid or not */
if (temp.ulValueLen != ((CK_ULONG)-1)) {
size_t offset2 = msg->parsed;
attrs[i].pValue = p11_rpc_message_alloc_extra (msg, temp.ulValueLen);
if (!p11_rpc_buffer_get_attribute (msg->input, &offset2, &attrs[i])) {
msg->parsed = offset2;
return PARSE_ERROR;
}
} else {
attrs[i].pValue = NULL;
attrs[i].ulValueLen = -1;
}

msg->parsed = offset;
}

*result = attrs;
*n_result = n_attrs;
Expand Down Expand Up @@ -1175,7 +1145,7 @@ rpc_C_GetAttributeValue (CK_X_FUNCTION_LIST *self,
BEGIN_CALL (GetAttributeValue);
IN_ULONG (session);
IN_ULONG (object);
IN_ATTRIBUTE_BUFFER (template, count);
IN_ATTRIBUTE_ARRAY (template, count);
PROCESS_CALL ((self, session, object, template, count));
OUT_ATTRIBUTE_ARRAY (template, count);
END_CALL;
Expand Down
Loading

0 comments on commit e571db2

Please sign in to comment.