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 Mar 6, 2024
1 parent 7756404 commit 4f7b1f0
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 199 deletions.
6 changes: 3 additions & 3 deletions common/attrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ attrs_build (CK_ATTRIBUTE *attrs,
/* The attribute exists and we're not overriding */
} else if (!override) {
if (take_values)
free (add->pValue);
p11_attr_clear (add);
continue;

/* The attribute exists but we're overriding */
} else {
free (attr->pValue);
p11_attr_clear (attr);
}

if (take_values) {
Expand Down Expand Up @@ -432,7 +432,7 @@ p11_attrs_purge (CK_ATTRIBUTE *attrs)

for (in = 0, out = 0; !p11_attrs_terminator (attrs + in); in++) {
if (attrs[in].ulValueLen == (CK_ULONG)-1) {
free (attrs[in].pValue);
p11_attr_clear (attrs + in);
attrs[in].pValue = NULL;
attrs[in].ulValueLen = 0;
} else {
Expand Down
72 changes: 68 additions & 4 deletions common/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,17 +286,24 @@ module_reset_objects (CK_SLOT_ID slot_id)
{
CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY;
char *label = "Public prefix key";
char *label2 = "Wrapped label";
char *value = "value";
CK_MECHANISM_TYPE type = CKM_MOCK_PREFIX;
CK_BBOOL btrue = CK_TRUE;
CK_BBOOL bfalse = CK_FALSE;
CK_ATTRIBUTE wrap_template[] = {
{ CKA_LABEL, label2, strlen (label2) },
{ CKA_VERIFY, &btrue, sizeof (btrue) },
{ CKA_ENCRYPT, &btrue, sizeof (btrue) },
};
CK_ATTRIBUTE attrs[] = {
{ CKA_CLASS, &klass, sizeof (klass) },
{ CKA_LABEL, label, strlen (label) },
{ CKA_ALLOWED_MECHANISMS, &type, sizeof (type) },
{ CKA_VERIFY, &btrue, sizeof (btrue) },
{ CKA_PRIVATE, &bfalse, sizeof (bfalse) },
{ CKA_ALWAYS_AUTHENTICATE, &btrue, sizeof (btrue) },
{ CKA_WRAP_TEMPLATE, &wrap_template, sizeof (wrap_template) },
{ CKA_VALUE, value, strlen (value) },
{ CKA_INVALID, NULL, 0 },
};
Expand Down Expand Up @@ -1618,6 +1625,51 @@ mock_X_GetObjectSize__invalid_handle (CK_X_FUNCTION_LIST *self,
return CKR_SESSION_HANDLE_INVALID;
}

static CK_RV
get_recursive_attribute_value (CK_ATTRIBUTE_PTR dest,
CK_ATTRIBUTE_PTR src,
CK_ULONG count)
{
CK_RV rv, ret = CKR_OK;
CK_ULONG i;
CK_ATTRIBUTE *result, *attr;

for (i = 0; i < count; ++i) {
result = dest + i;
attr = src + i;

result->type = attr->type;

if (result->pValue == NULL) {
result->ulValueLen = attr->ulValueLen;
continue;
}

if (result->ulValueLen < attr->ulValueLen) {
result->ulValueLen = (CK_ULONG)-1;
ret = CKR_BUFFER_TOO_SMALL;
continue;
}

if (IS_ATTRIBUTE_ARRAY (attr)) {
rv = get_recursive_attribute_value (result->pValue,
attr->pValue, attr->ulValueLen / sizeof (CK_ATTRIBUTE));
if (rv != CKR_OK) {
result->ulValueLen = (CK_ULONG)-1;
ret = rv;
continue;
}
result->ulValueLen = attr->ulValueLen;
continue;
}

memcpy (result->pValue, attr->pValue, attr->ulValueLen);
result->ulValueLen = attr->ulValueLen;
}

return ret;
}

CK_RV
mock_C_GetAttributeValue (CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE object,
Expand Down Expand Up @@ -1654,14 +1706,26 @@ mock_C_GetAttributeValue (CK_SESSION_HANDLE session,
continue;
}

if (result->ulValueLen >= attr->ulValueLen) {
memcpy (result->pValue, attr->pValue, attr->ulValueLen);
if (result->ulValueLen < attr->ulValueLen) {
result->ulValueLen = (CK_ULONG)-1;
ret = CKR_BUFFER_TOO_SMALL;
continue;
}

if (IS_ATTRIBUTE_ARRAY (attr)) {
rv = get_recursive_attribute_value (result->pValue,
attr->pValue, attr->ulValueLen / sizeof (CK_ATTRIBUTE));
if (rv != CKR_OK) {
result->ulValueLen = (CK_ULONG)-1;
ret = rv;
continue;
}
result->ulValueLen = attr->ulValueLen;
continue;
}

result->ulValueLen = (CK_ULONG)-1;
ret = CKR_BUFFER_TOO_SMALL;
memcpy (result->pValue, attr->pValue, attr->ulValueLen);
result->ulValueLen = attr->ulValueLen;
}

return ret;
Expand Down
7 changes: 7 additions & 0 deletions common/persist.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,13 @@ field_to_attribute (p11_persist *persist,
return false;
}

/* Ignore recursive attributes */
if (IS_ATTRIBUTE_ARRAY (&attr)) {
free (attr.pValue);
attr.pValue = NULL;
attr.ulValueLen = 0;
}

*attrs = p11_attrs_take (*attrs, attr.type,
attr.pValue, attr.ulValueLen);
return true;
Expand Down
54 changes: 53 additions & 1 deletion p11-kit/iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,50 @@ p11_kit_iter_get_attributes (P11KitIter *iter,
templ, count);
}

static CK_RV
prepare_recursive_attribute (P11KitIter *iter,
CK_ATTRIBUTE *templ)
{
CK_RV rv;
CK_ULONG count, i;
CK_ATTRIBUTE *attr;

return_val_if_fail (iter != NULL, CKR_GENERAL_ERROR);
return_val_if_fail (templ != NULL, CKR_GENERAL_ERROR);
return_val_if_fail (templ->pValue != NULL, CKR_GENERAL_ERROR);
return_val_if_fail (templ->ulValueLen != 0, CKR_GENERAL_ERROR);
return_val_if_fail (IS_ATTRIBUTE_ARRAY (templ), CKR_GENERAL_ERROR);

memset (templ->pValue, 0, templ->ulValueLen);
rv = (iter->module->C_GetAttributeValue) (iter->session, iter->object, templ, 1);

switch (rv) {
case CKR_OK:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_ATTRIBUTE_SENSITIVE:
break;
default:
return_val_if_fail (rv != CKR_BUFFER_TOO_SMALL, rv);
return rv;
}

attr = templ->pValue;
count = templ->ulValueLen / sizeof (CK_ATTRIBUTE);

for (i = 0; i < count; ++i, ++attr) {
/* Currently we don't support nested recursive attributes */
return_val_if_fail (!IS_ATTRIBUTE_ARRAY (attr), CKR_FUNCTION_NOT_SUPPORTED);
return_val_if_fail (attr->type != CKA_INVALID, CKR_GENERAL_ERROR);
return_val_if_fail (attr->ulValueLen != 0, CKR_GENERAL_ERROR);
return_val_if_fail (attr->ulValueLen != (CK_ULONG)-1, CKR_GENERAL_ERROR);

attr->pValue = malloc (attr->ulValueLen);
return_val_if_fail (attr->pValue != NULL, CKR_HOST_MEMORY);
}

return CKR_OK;
}

/**
* p11_kit_iter_load_attributes:
* @iter: the iterator
Expand Down Expand Up @@ -1081,7 +1125,7 @@ p11_kit_iter_load_attributes (P11KitIter *iter,
for (i = 0; i < count; i++) {
if (templ[i].ulValueLen == (CK_ULONG)-1 ||
templ[i].ulValueLen == 0) {
free (original[i].pValue);
p11_attr_clear (original + i);

} else if (original[i].pValue != NULL &&
templ[i].ulValueLen == original[i].ulValueLen) {
Expand All @@ -1090,6 +1134,14 @@ p11_kit_iter_load_attributes (P11KitIter *iter,
} else {
templ[i].pValue = realloc (original[i].pValue, templ[i].ulValueLen);
return_val_if_fail (templ[i].pValue != NULL, CKR_HOST_MEMORY);

if (IS_ATTRIBUTE_ARRAY (templ + i)) {
rv = prepare_recursive_attribute (iter, templ + i);
if (rv != CKR_OK) {
free (original);
return rv;
}
}
}
}

Expand Down
17 changes: 3 additions & 14 deletions p11-kit/rpc-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,11 @@ proto_read_attribute_array (p11_rpc_message *msg,
CK_ATTRIBUTE temp;

memset (&temp, 0, sizeof (temp));
if (!p11_rpc_buffer_get_attribute (msg->input, &offset, &temp)) {
if (!p11_rpc_message_get_attribute (msg, msg->input, &offset, &temp)) {
msg->parsed = offset;
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 All @@ -273,7 +268,7 @@ proto_read_attribute_array (p11_rpc_message *msg,
/* Wants attribute data, enough space */
} else {
size_t offset2 = msg->parsed;
if (!p11_rpc_buffer_get_attribute (msg->input, &offset2, attr)) {
if (!p11_rpc_message_get_attribute (NULL, msg->input, &offset2, attr)) {
msg->parsed = offset2;
return PARSE_ERROR;
}
Expand Down Expand Up @@ -627,12 +622,6 @@ proto_read_sesssion_info (p11_rpc_message *msg,
if (!p11_rpc_message_write_ulong_array (&_msg, arr, len)) \
{ _ret = CKR_HOST_MEMORY; goto _cleanup; }

#define IN_ATTRIBUTE_BUFFER(arr, num) \
if (num != 0 && arr == NULL) \
{ _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
if (!p11_rpc_message_write_attribute_buffer (&_msg, (arr), (num))) \
{ _ret = CKR_HOST_MEMORY; goto _cleanup; }

#define IN_ATTRIBUTE_ARRAY(arr, num) \
if (num != 0 && arr == NULL) \
{ _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
Expand Down Expand Up @@ -1262,7 +1251,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
Loading

0 comments on commit 4f7b1f0

Please sign in to comment.