Skip to content

Commit c5723d1

Browse files
committed
pkcs11: when getting attributes always get them into tmp buffer
this way we can check that the real buffer has room before copying the data there. also move logic for copying data up to populate_template(), this calls the get_attribute functions which can be static.
1 parent 43d695a commit c5723d1

File tree

2 files changed

+45
-60
lines changed

2 files changed

+45
-60
lines changed

pkcs11/util_pkcs11.c

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "debug_p11.h"
3838
#include "../common/util.h"
3939
#include "../common/openssl-compat.h"
40+
#include "../common/insecure_memzero.h"
4041

4142
#define ASN1_OID 0x06
4243
static const uint8_t oid_secp224r1[] = {ASN1_OID, 0x05, 0x2b, 0x81,
@@ -1452,33 +1453,22 @@ static CK_RV get_attribute_public_key(CK_ATTRIBUTE_TYPE type,
14521453
return CKR_OK;
14531454
}
14541455

1455-
CK_RV get_attribute(CK_ATTRIBUTE_TYPE type, yh_object_descriptor *object,
1456-
CK_VOID_PTR value, CK_ULONG_PTR length,
1457-
yh_session *session) {
1458-
1459-
CK_BYTE tmp[2048];
1460-
CK_VOID_PTR ptr;
1461-
if (value == NULL) {
1462-
// NOTE(adma): we just need the length, use a scratchpad for the data
1463-
ptr = tmp;
1464-
*length = sizeof(tmp);
1465-
} else {
1466-
// NOTE(adma): otherwise actually save the data
1467-
ptr = value;
1468-
}
1456+
static CK_RV get_attribute(CK_ATTRIBUTE_TYPE type, yh_object_descriptor *object,
1457+
CK_BYTE_PTR value, CK_ULONG_PTR length,
1458+
yh_session *session) {
14691459

14701460
switch (object->type) {
14711461
case YH_OPAQUE:
1472-
return get_attribute_opaque(type, object, ptr, length, session);
1462+
return get_attribute_opaque(type, object, value, length, session);
14731463

14741464
case YH_WRAP_KEY:
14751465
case YH_HMAC_KEY:
1476-
return get_attribute_secret_key(type, object, ptr, length);
1466+
return get_attribute_secret_key(type, object, value, length);
14771467

14781468
case YH_ASYMMETRIC_KEY:
1479-
return get_attribute_private_key(type, object, ptr, length, session);
1469+
return get_attribute_private_key(type, object, value, length, session);
14801470
case 0x80 | YH_ASYMMETRIC_KEY:
1481-
return get_attribute_public_key(type, object, ptr, length, session);
1471+
return get_attribute_public_key(type, object, value, length, session);
14821472

14831473
case YH_TEMPLATE:
14841474
case YH_AUTHENTICATION_KEY:
@@ -1490,50 +1480,43 @@ CK_RV get_attribute(CK_ATTRIBUTE_TYPE type, yh_object_descriptor *object,
14901480
return CKR_OK;
14911481
}
14921482

1493-
CK_RV get_attribute_ecsession_key(CK_ATTRIBUTE_TYPE type, ecdh_session_key *key,
1494-
CK_VOID_PTR value, CK_ULONG_PTR length) {
1495-
1496-
CK_BYTE tmp[2048];
1497-
CK_VOID_PTR ptr;
1498-
if (value == NULL) {
1499-
ptr = tmp;
1500-
*length = sizeof(tmp);
1501-
} else {
1502-
ptr = value;
1503-
}
1483+
static CK_RV get_attribute_ecsession_key(CK_ATTRIBUTE_TYPE type,
1484+
ecdh_session_key *key,
1485+
CK_BYTE_PTR value,
1486+
CK_ULONG_PTR length) {
15041487

15051488
switch (type) {
15061489
case CKA_CLASS:
1507-
*((CK_OBJECT_CLASS *) ptr) = CKO_SECRET_KEY;
1490+
*((CK_OBJECT_CLASS *) value) = CKO_SECRET_KEY;
15081491
*length = sizeof(CK_OBJECT_CLASS);
15091492
break;
15101493

15111494
case CKA_KEY_TYPE:
1512-
*((CK_KEY_TYPE *) ptr) = CKK_GENERIC_SECRET;
1495+
*((CK_KEY_TYPE *) value) = CKK_GENERIC_SECRET;
15131496
*length = sizeof(CK_KEY_TYPE);
15141497
break;
15151498

15161499
case CKA_ID: {
1517-
CK_OBJECT_HANDLE *id = ptr;
1500+
CK_OBJECT_HANDLE *id = (CK_OBJECT_HANDLE *) value;
15181501
*id = key->id;
15191502
*length = sizeof(CK_OBJECT_HANDLE);
15201503
break;
15211504
}
15221505

15231506
case CKA_LABEL:
15241507
*length = strlen(key->label);
1525-
memcpy(ptr, key->label, *length);
1508+
memcpy(value, key->label, *length);
15261509
break;
15271510

15281511
case CKA_LOCAL:
15291512
case CKA_TOKEN:
1530-
*((CK_BBOOL *) ptr) = CK_FALSE;
1513+
*((CK_BBOOL *) value) = CK_FALSE;
15311514
*length = sizeof(CK_BBOOL);
15321515
break;
15331516

15341517
case CKA_DESTROYABLE:
15351518
case CKA_EXTRACTABLE:
1536-
*((CK_BBOOL *) ptr) = CK_TRUE;
1519+
*((CK_BBOOL *) value) = CK_TRUE;
15371520
*length = sizeof(CK_BBOOL);
15381521
break;
15391522

@@ -1551,12 +1534,12 @@ CK_RV get_attribute_ecsession_key(CK_ATTRIBUTE_TYPE type, ecdh_session_key *key,
15511534
case CKA_WRAP_WITH_TRUSTED:
15521535
case CKA_VERIFY:
15531536
case CKA_ENCRYPT:
1554-
*((CK_BBOOL *) ptr) = CK_FALSE;
1537+
*((CK_BBOOL *) value) = CK_FALSE;
15551538
*length = sizeof(CK_BBOOL);
15561539
break;
15571540

15581541
case CKA_VALUE:
1559-
memcpy(ptr, key->ecdh_key, key->len);
1542+
memcpy(value, key->ecdh_key, key->len);
15601543
*length = key->len;
15611544
break;
15621545

@@ -3873,31 +3856,37 @@ CK_RV populate_template(int type, void *object, CK_ATTRIBUTE_PTR pTemplate,
38733856
CK_ULONG ulCount, yh_session *session) {
38743857

38753858
CK_RV rv = CKR_OK;
3859+
CK_BYTE tmp[8192];
38763860

38773861
for (CK_ULONG i = 0; i < ulCount; i++) {
38783862
DBG_INFO("Getting attribute 0x%lx", pTemplate[i].type);
3879-
3880-
CK_VOID_PTR object_ptr;
3881-
if (pTemplate[i].pValue == NULL) {
3882-
// NOTE(adma): just asking for the length
3883-
object_ptr = NULL;
3884-
DBG_INFO("Retrieving length");
3885-
} else {
3886-
// NOTE(adma): actually get the attribute
3887-
object_ptr = pTemplate[i].pValue;
3888-
DBG_INFO("Retrieving attribute");
3889-
}
3890-
3863+
CK_ULONG len = sizeof(tmp);
38913864
CK_RV attribute_rc;
3865+
38923866
if (type == ECDH_KEY_TYPE) {
38933867
ecdh_session_key *key = object;
38943868
attribute_rc =
3895-
get_attribute_ecsession_key(pTemplate[i].type, key, object_ptr,
3896-
&pTemplate[i].ulValueLen);
3869+
get_attribute_ecsession_key(pTemplate[i].type, key, tmp, &len);
38973870
} else {
38983871
yubihsm_pkcs11_object_desc *desc = object;
3899-
attribute_rc = get_attribute(pTemplate[i].type, &desc->object, object_ptr,
3900-
&pTemplate[i].ulValueLen, session);
3872+
attribute_rc =
3873+
get_attribute(pTemplate[i].type, &desc->object, tmp, &len, session);
3874+
}
3875+
3876+
if (attribute_rc == CKR_OK) {
3877+
if (pTemplate[i].pValue == NULL) {
3878+
DBG_INFO("Retrieving only length which is %lu", len);
3879+
pTemplate[i].ulValueLen = len;
3880+
} else if (len > pTemplate[i].ulValueLen) {
3881+
DBG_WARN("Skipping attribute, buffer to small %lu > %lu", len,
3882+
pTemplate[i].ulValueLen);
3883+
attribute_rc = CKR_BUFFER_TOO_SMALL;
3884+
pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
3885+
} else {
3886+
DBG_INFO("Retrieving attribute value, length is %lu", len);
3887+
memcpy(pTemplate[i].pValue, tmp, len);
3888+
pTemplate[i].ulValueLen = len;
3889+
}
39013890
}
39023891

39033892
if (attribute_rc != CKR_OK) {
@@ -3907,7 +3896,7 @@ CK_RV populate_template(int type, void *object, CK_ATTRIBUTE_PTR pTemplate,
39073896
} else if (attribute_rc == CKR_BUFFER_TOO_SMALL) {
39083897
DBG_ERR("Skipping attribute because buffer is too small");
39093898
} else {
3910-
DBG_ERR("Get attribute failed. %s", yh_strerror(attribute_rc));
3899+
DBG_ERR("Get attribute failed.");
39113900
}
39123901
} else {
39133902
DBG_INFO("Attribute/length successfully returned with length %lu",
@@ -3934,6 +3923,8 @@ CK_RV populate_template(int type, void *object, CK_ATTRIBUTE_PTR pTemplate,
39343923
* type having the CKF_ARRAY_ATTRIBUTE bit set.*/
39353924
}
39363925

3926+
insecure_memzero(tmp, sizeof(tmp));
3927+
39373928
return rv;
39383929
}
39393930

pkcs11/util_pkcs11.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ bool parse_hex(CK_UTF8CHAR_PTR hex, CK_ULONG hex_len, uint8_t *parsed);
3333

3434
void destroy_session(yubihsm_pkcs11_context *ctx, CK_SESSION_HANDLE hSession);
3535

36-
CK_RV get_attribute(CK_ATTRIBUTE_TYPE type, yh_object_descriptor *object,
37-
CK_VOID_PTR value, CK_ULONG_PTR length,
38-
yh_session *session);
39-
CK_RV get_attribute_ecsession_key(CK_ATTRIBUTE_TYPE type, ecdh_session_key *key,
40-
CK_VOID_PTR value, CK_ULONG_PTR length);
41-
4236
yubihsm_pkcs11_object_desc *get_object_desc(yh_session *session,
4337
yubihsm_pkcs11_object_desc *objects,
4438
CK_OBJECT_HANDLE objectHandle);

0 commit comments

Comments
 (0)