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

Add support for CKA_EC_POINT as not DER encoded #483

Merged
merged 2 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
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
86 changes: 64 additions & 22 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,53 @@ static int fetch_rsa_key(P11PROV_CTX *ctx, P11PROV_SESSION *session,
return CKR_OK;
}

static CK_RV decode_ec_point(CK_KEY_TYPE key_type, CK_ATTRIBUTE *attr,
struct data_buffer *ec_point)
{
ASN1_OCTET_STRING *octet;
const unsigned char *val;
CK_RV ret = CKR_GENERAL_ERROR;
int err;

/* in d2i functions 'in' is overwritten to return the remainder of
* the buffer after parsing, so we always need to avoid passing in
* our pointer holders, to avoid having them clobbered */
val = attr->pValue;
octet = d2i_ASN1_OCTET_STRING(NULL, (const unsigned char **)&val,
attr->ulValueLen);
if (!octet) {
/* 3.1 spec says CKA_EC_POINT is not DER encoded for Edwards and
* Montgomery curves so do not fail in that case and just take
* the value as is */
if (key_type == CKK_EC) {
return CKR_KEY_INDIGESTIBLE;
} else {
octet = ASN1_OCTET_STRING_new();
if (!octet) {
return CKR_HOST_MEMORY;
}
/* makes a copy of the value */
err = ASN1_OCTET_STRING_set(octet, attr->pValue, attr->ulValueLen);
if (err != RET_OSSL_OK) {
ret = CKR_HOST_MEMORY;
goto done;
}
}
}

ec_point->data = octet->data;
ec_point->length = octet->length;

/* moved octet data, do not free it */
octet->data = NULL;
octet->length = 0;

ret = CKR_OK;
done:
ASN1_OCTET_STRING_free(octet);
return ret;
}

const CK_BYTE ed25519_ec_params[] = { ED25519_EC_PARAMS };
const CK_BYTE ed448_ec_params[] = { ED448_EC_PARAMS };

Expand All @@ -679,7 +726,8 @@ static CK_RV pre_process_ec_key_data(P11PROV_OBJ *key)
int buffer_size;
const char *curve_name = NULL;
int curve_nid;
ASN1_OCTET_STRING *octet;
struct data_buffer ec_point = { 0 };
CK_RV ret;

attr = p11prov_obj_get_attr(key, CKA_EC_PARAMS);
if (!attr) {
Expand Down Expand Up @@ -778,21 +826,15 @@ static CK_RV pre_process_ec_key_data(P11PROV_OBJ *key)
return CKR_OK;
}

val = attr->pValue;
octet = d2i_ASN1_OCTET_STRING(NULL, (const unsigned char **)&val,
attr->ulValueLen);
if (!octet) {
return CKR_KEY_INDIGESTIBLE;
ret = decode_ec_point(type, attr, &ec_point);
if (ret != CKR_OK) {
return ret;
}

CKATTR_ASSIGN(key->attrs[key->numattrs], CKA_P11PROV_PUB_KEY, octet->data,
octet->length);
/* takes the data allocated in ec_point */
CKATTR_ASSIGN(key->attrs[key->numattrs], CKA_P11PROV_PUB_KEY, ec_point.data,
ec_point.length);
key->numattrs++;

/* moved octet data to attrs, do not free it */
octet->data = NULL;
octet->length = 0;
ASN1_OCTET_STRING_free(octet);
return CKR_OK;
}

Expand Down Expand Up @@ -2228,29 +2270,29 @@ CK_ATTRIBUTE *p11prov_obj_get_ec_public_raw(P11PROV_OBJ *key)

ec_point = p11prov_obj_get_attr(key, CKA_EC_POINT);
if (ec_point) {
const unsigned char *val;
ASN1_OCTET_STRING *octet;
struct data_buffer data = { 0 };
void *tmp_ptr;
CK_RV ret;

val = ec_point->pValue;
octet = d2i_ASN1_OCTET_STRING(NULL, (const unsigned char **)&val,
ec_point->ulValueLen);
if (!octet) {
P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE,
"Failed to decode CKA_EC_POINT");
ret = decode_ec_point(key->data.key.type, ec_point, &data);
if (ret != CKR_OK) {
P11PROV_raise(key->ctx, ret, "Failed to decode EC_POINT");
return NULL;
}

tmp_ptr = OPENSSL_realloc(key->attrs, sizeof(CK_ATTRIBUTE)
* (key->numattrs + 1));
if (!tmp_ptr) {
P11PROV_raise(key->ctx, CKR_HOST_MEMORY,
"Failed to allocate memory key attributes");
OPENSSL_free(data.data);
return NULL;
}
key->attrs = tmp_ptr;

/* takes the data allocated in data */
CKATTR_ASSIGN(key->attrs[key->numattrs], CKA_P11PROV_PUB_KEY,
octet->data, octet->length);
data.data, data.length);
key->numattrs++;

pub_key = &key->attrs[key->numattrs - 1];
Expand Down
4 changes: 4 additions & 0 deletions tests/kryoptic-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ pkcs11-tool --module "${P11LIB}" --so-pin "${PINVALUE}" \
export TOKENCONFIGVARS="export KRYOPTIC_CONF=$TOKDIR/kryoptic.sql"

export TESTPORT="34000"

# Older versions of certtool do not support non-DER encoded CKA_EC_POINT
# so set the kryoptic env var to enforce compatibility for the setup phase
export KRYOPTIC_EC_POINT_ENCODING="DER"
Loading