Change (X)EDDSA EC_PARAMS encoding to OID

This is the current interpretation of the specs after talking with
several members of PKCS #11 TC.
This commit is contained in:
Jakub Jelen 2020-08-28 19:49:15 +02:00
parent c39e31b274
commit 56af7de137
3 changed files with 99 additions and 52 deletions

View File

@ -4253,7 +4253,7 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj,
struct pkcs15_fw_data *fw_data = NULL;
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
struct pkcs15_any_object *targetKeyObj = (struct pkcs15_any_object *) targetKey;
int rv;
int rv;
sc_log(context, "Initiating unwrapping with private key.");
@ -5541,8 +5541,9 @@ static CK_RV
get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
{
struct sc_ec_parameters *ecp;
unsigned long expected_size = 0;
char *curve_name = NULL;
unsigned long value_len = 0;
unsigned char *value = NULL;
int r;
if (key == NULL)
@ -5553,26 +5554,23 @@ get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
switch (key->algorithm) {
case SC_ALGORITHM_EDDSA:
case SC_ALGORITHM_XEDDSA:
/* TODO key->alg_id->oid contains OID which we need to convert to curve name */
/* For now, using hardcoded curve names */
if (key->algorithm == SC_ALGORITHM_EDDSA) {
curve_name = "edwards25519";
} else if (key->algorithm == SC_ALGORITHM_XEDDSA) {
curve_name = "curve25519";
} else {
return CKR_GENERAL_ERROR;
}
r = sc_asn1_put_tag(0x13, (u8 *)curve_name, strlen(curve_name), NULL, 0, NULL);
if (r <= 0) {
return CKR_GENERAL_ERROR;
}
expected_size = r;
check_attribute_buffer(attr, expected_size);
/* Tag PrintableString */
r = sc_asn1_put_tag(0x13, (u8 *)curve_name, strlen(curve_name), attr->pValue, expected_size, NULL);
r = sc_encode_oid(context, &key->alg_id->oid, &value, (size_t *)&value_len);
if (r != SC_SUCCESS) {
return sc_to_cryptoki_error(r, NULL);
}
attr->ulValueLen = value_len;
if (attr->pValue == NULL_PTR) {
free(value);
return CKR_OK;
}
if (attr->ulValueLen < value_len) {
free(value);
return CKR_BUFFER_TOO_SMALL;
}
memcpy(attr->pValue, value, value_len);
free(value);
return CKR_OK;
case SC_ALGORITHM_EC:

View File

@ -435,40 +435,65 @@ int callback_public_keys(test_certs_t *objects,
|| o->key_type == CKK_EC_MONTGOMERY) {
EVP_PKEY *key = NULL;
ASN1_PRINTABLESTRING *curve = NULL;
ASN1_OBJECT *obj = NULL;
const unsigned char *a;
ASN1_OCTET_STRING *os;
int evp_type;
a = template[6].pValue;
if (!d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)template[6].ulValueLen)) {
if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)template[6].ulValueLen) != NULL) {
switch (o->key_type) {
case CKK_EC_EDWARDS:
if (strcmp((char *)curve->data, "edwards25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected edwards25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_ED25519;
break;
case CKK_EC_MONTGOMERY:
if (strcmp((char *)curve->data, "curve25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected curve25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_X25519;
break;
default:
debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type);
return -1;
}
ASN1_PRINTABLESTRING_free(curve);
} else if (d2i_ASN1_OBJECT(&obj, &a, (long)template[6].ulValueLen) != NULL) {
int nid = OBJ_obj2nid(obj);
switch (o->key_type) {
case CKK_EC_EDWARDS:
if (nid != NID_ED25519) {
debug_print(" [WARN %s ] Unknown OID. "
" expected NID_ED25519 (%d), got %d", o->id_str, NID_ED25519, nid);
return -1;
}
evp_type = EVP_PKEY_ED25519;
break;
case CKK_EC_MONTGOMERY:
if (nid != NID_X25519) {
debug_print(" [WARN %s ] Unknown OID. "
" expected NID_X25519 (%d), got %d", o->id_str, NID_X25519, nid);
return -1;
}
evp_type = EVP_PKEY_X25519;
break;
default:
debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type);
return -1;
}
ASN1_OBJECT_free(obj);
} else {
debug_print(" [WARN %s ] Failed to convert EC_PARAMS"
" to curve name", o->id_str);
" to curve name or object id", o->id_str);
return -1;
}
switch (o->key_type) {
case CKK_EC_EDWARDS:
if (strcmp((char *)curve->data, "edwards25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected edwards25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_ED25519;
break;
case CKK_EC_MONTGOMERY:
if (strcmp((char *)curve->data, "curve25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected curve25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_X25519;
break;
default:
debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type);
return -1;
}
ASN1_PRINTABLESTRING_free(curve);
/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */
a = template[7].pValue;
os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)template[7].ulValueLen);

View File

@ -59,6 +59,7 @@
#include "pkcs11/pkcs11.h"
#include "pkcs11/pkcs11-opensc.h"
#include "libopensc/asn1.h"
#include "libopensc/log.h"
#include "common/compat_strlcat.h"
#include "common/compat_strlcpy.h"
#include "common/libpkcs11.h"
@ -4199,10 +4200,23 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
bytes = getEC_PARAMS(sess, obj, &size);
if (bytes){
if ((CK_LONG)size > 0) {
struct sc_object_id oid;
printf(" EC_PARAMS: ");
for (n = 0; n < size; n++)
printf("%02x", bytes[n]);
sc_init_oid(&oid);
if (size > 2 && sc_asn1_decode_object_id(bytes + 2, size - 2, &oid) == SC_SUCCESS) {
printf(" (OID %i", oid.value[0]);
if (oid.value[0] >= 0)
for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS)
&& (oid.value[n] >= 0); n++)
printf(".%i", oid.value[n]);
printf(")");
}
printf("\n");
}
free(bytes);
}
@ -4768,13 +4782,28 @@ static int read_object(CK_SESSION_HANDLE session)
} else if (type == CKK_EC_EDWARDS) {
EVP_PKEY *key = NULL;
CK_BYTE *params = NULL;
ASN1_PRINTABLESTRING *curve = NULL;
const unsigned char *a;
ASN1_OCTET_STRING *os;
if ((params = getEC_PARAMS(session, obj, &len))) {
ASN1_PRINTABLESTRING *curve = NULL;
ASN1_OBJECT *obj = NULL;
a = params;
if (!d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len)) {
if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) {
if (strcmp((char *)curve->data, "edwards25519")) {
util_fatal("Unknown curve name, expected edwards25519, got %s",
curve->data);
}
ASN1_PRINTABLESTRING_free(curve);
} else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) {
int nid = OBJ_obj2nid(obj);
if (nid != NID_ED25519) {
util_fatal("Unknown curve OID, expected NID_ED25519 (%d), got %d",
NID_ED25519, nid);
}
ASN1_OBJECT_free(obj);
} else {
util_fatal("cannot parse curve name from EC_PARAMS");
}
free(params);
@ -4782,11 +4811,6 @@ static int read_object(CK_SESSION_HANDLE session)
util_fatal("cannot obtain EC_PARAMS");
}
if (strcmp((char *)curve->data, "edwards25519")) {
util_fatal("Unknown curve name, expeced edwards25519, got %s",
curve->data);
}
ASN1_PRINTABLESTRING_free(curve);
value = getEC_POINT(session, obj, &len);
/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */