Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PKCS11: Add support for CKA_KEY_TYPE when searching for objects #358

Merged
merged 5 commits into from
Sep 25, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions pkcs11/yubihsm_pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,18 @@
return true;
}

static CK_RV set_object_type(uint8_t *type, uint8_t expected_type) {
if (*type == 0) {
*type = expected_type;
return CKR_OK;
}
if (*type != expected_type) {
DBG_ERR("Mismatch in attribute values");
return CKR_TEMPLATE_INCONSISTENT;
}
return CKR_OK;
}

CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) {

Expand Down Expand Up @@ -2343,144 +2355,188 @@
DBG_INFO("find with %lu attributes", ulCount);
if (ulCount != 0) {
for (CK_ULONG i = 0; i < ulCount; i++) {
switch (pTemplate[i].type) {
case CKA_ID:
template_id_len = pTemplate[i].ulValueLen;
memcpy(template_id, pTemplate[i].pValue, template_id_len);
break;

case CKA_CLASS: {
uint32_t value = *((CK_ULONG_PTR)(pTemplate[i].pValue));
uint8_t class_type = 0;
switch (value) {
case CKO_CERTIFICATE:
DBG_INFO("Filtering for certificate");
algorithm =
YH_ALGO_OPAQUE_X509_CERTIFICATE; // TODO: handle other certs?
case CKO_DATA:
type = YH_OPAQUE;
class_type = YH_OPAQUE;
break;

case CKO_PUBLIC_KEY:
pub = true;
type = YH_ASYMMETRIC_KEY;
class_type = YH_ASYMMETRIC_KEY;
break;

case CKO_PRIVATE_KEY:
session->operation.op.find.only_private = true;
type = YH_ASYMMETRIC_KEY;
class_type = YH_ASYMMETRIC_KEY;
break;

case CKO_SECRET_KEY:
secret_key = true;
break;

default:
unknown = true;
DBG_INFO("Asking for unknown class %x, returning empty set. %x",
(uint32_t) pTemplate[i].type, value);
}
rv = set_object_type(&type, class_type);
if (rv != CKR_OK) {
goto c_foi_out;
}
} break;
case CKA_LABEL:
template_label_len = pTemplate[i].ulValueLen;
memcpy(template_label, pTemplate[i].pValue, template_label_len);
break;

case CKA_SIGN:
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
session->operation.op.find.only_private = true;
rc = yh_string_to_capabilities(
"sign-pkcs,sign-pss,sign-ecdsa,sign-hmac", &capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_DECRYPT:
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
session->operation.op.find.only_private = true;
rc =
yh_string_to_capabilities("decrypt-pkcs,decrypt-oaep,derive-ecdh,"
"unwrap-data,decrypt-ecb,decrypt-cbc",
&capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_ENCRYPT:
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
rc = yh_string_to_capabilities("wrap-data,encrypt-ecb,encrypt-cbc",
&capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_WRAP:
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
type = YH_WRAP_KEY;
rv = set_object_type(&type, YH_WRAP_KEY);
if (rv != CKR_OK) {
goto c_foi_out;
}
rc = yh_string_to_capabilities("export-wrapped", &capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_UNWRAP:
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
type = YH_WRAP_KEY;
rv = set_object_type(&type, YH_WRAP_KEY);
if (rv != CKR_OK) {
goto c_foi_out;
}
rc = yh_string_to_capabilities("import-wrapped", &capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_EXTRACTABLE:
extractable_set = true;
if (*((CK_BBOOL *) pTemplate[i].pValue) == CK_TRUE) {
session->operation.op.find.only_private = true;
rc =
yh_string_to_capabilities("exportable-under-wrap", &capabilities);
if (rc != YHR_SUCCESS) {
rv = yrc_to_rv(rc);
goto c_foi_out;
}
}
break;

case CKA_VALUE:
template_value_len = pTemplate[i].ulValueLen;
template_value = malloc(template_value_len * sizeof(uint8_t));
memcpy(template_value, pTemplate[i].pValue, template_value_len);
break;

case CKA_KEY_TYPE: {
uint32_t value = *((CK_ULONG_PTR)(pTemplate[i].pValue));
uint8_t key_type = 0;
switch (value) {
case CKK_YUBICO_AES128_CCM_WRAP:
case CKK_YUBICO_AES192_CCM_WRAP:
case CKK_YUBICO_AES256_CCM_WRAP:
key_type = YH_WRAP_KEY;
break;
case CKK_SHA_1_HMAC:
case CKK_SHA256_HMAC:
case CKK_SHA384_HMAC:
case CKK_SHA512_HMAC:
key_type = YH_HMAC_KEY;
break;
case CKK_AES:
key_type = YH_SYMMETRIC_KEY;
break;
case CKK_RSA:
case CKK_EC:
key_type = YH_ASYMMETRIC_KEY;
break;
default:
unknown = true;
DBG_INFO("Asking for unknown key type %x, returning empty set. "
"%x",
(uint32_t) pTemplate[i].type, value);
}
rv = set_object_type(&type, key_type);
if (rv != CKR_OK) {
goto c_foi_out;
}
} break;

case CKA_TOKEN:
case CKA_PRIVATE:
case CKA_SENSITIVE:
case CKA_ALWAYS_SENSITIVE:
case CKA_DESTROYABLE:
case CKA_KEY_TYPE:
case CKA_APPLICATION:
case CKA_CERTIFICATE_TYPE:
DBG_INFO("Got type %x, ignoring it for results",
(uint32_t) pTemplate[i].type);
break;

default:
unknown = true;
DBG_INFO("Got type %x, returning empty set",
(uint32_t) pTemplate[i].type);
break;
}

Check notice

Code scanning / CodeQL

Long switch case Note

Switch has at least one case that is too long:
0 (35 lines)
.
Switch has at least one case that is too long:
256 (33 lines)
.
}
}

Expand All @@ -2492,7 +2548,7 @@
yh_object_descriptor
tmp_objects[YH_MAX_ITEMS_COUNT + MAX_ECDH_SESSION_KEYS] = {0};
size_t tmp_n_objects = YH_MAX_ITEMS_COUNT + MAX_ECDH_SESSION_KEYS;
rc = yh_util_list_objects(session->slot->device_session, 0, 0, domains,
rc = yh_util_list_objects(session->slot->device_session, 0, type, domains,
&capabilities, algorithm, label, tmp_objects,
&tmp_n_objects);
if (rc != YHR_SUCCESS) {
Expand Down
Loading