Merge pull request #211 from viktorTarasov/fix-206

Fix #206
This commit is contained in:
viktorTarasov 2014-02-21 13:09:57 +01:00
commit a399905d23
17 changed files with 404 additions and 309 deletions

View File

@ -44,6 +44,13 @@ AC_PROG_CC
PKG_PROG_PKG_CONFIG
AC_C_BIGENDIAN
AC_ARG_ENABLE(
[optimization],
[AS_HELP_STRING([--disable-optimization],[disable compile optimization @<:@enabled@:>@])],
,
[enable_optimization="yes"]
)
AC_ARG_WITH(
[cygwin-native],
[AS_HELP_STRING([--with-cygwin-native],[compile native win32])],
@ -51,9 +58,14 @@ AC_ARG_WITH(
[with_cygwin_native="no"]
)
if test "${enable_optimization}" = "no"; then
CFLAGS="-O0 -g"
fi
dnl Check for some target-specific stuff
test -z "${WIN32}" && WIN32="no"
test -z "${CYGWIN}" && CYGWIN="no"
case "${host}" in
*-*-solaris*)
CPPFLAGS="${CPPFLAGS} -I/usr/local/include"

View File

@ -1790,10 +1790,11 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
piv_private_data_t * priv = PIV_DATA(card);
u8 * opts; /* A or M, key_ref, alg_id */
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"cmd=%ld ptr=%p");
LOG_FUNC_CALLED(card->ctx);
sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr);
if (priv == NULL) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
}
switch(cmd) {
case SC_CARDCTL_PIV_AUTHENTICATE:
@ -1824,7 +1825,7 @@ static int piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
break;
}
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)

View File

@ -116,6 +116,6 @@ int sc_pkcs15emu_sc_hsm_encode_cvc(sc_pkcs15_card_t * p15card,
u8 ** buf, size_t *buflen);
void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc);
int sc_pkcs15emu_sc_hsm_get_curve(struct ec_curve **curve, u8 *oid, size_t oidlen);
int sc_pkcs15emu_sc_hsm_get_public_key(sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey);
int sc_pkcs15emu_sc_hsm_get_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey);
#endif /* SC_HSM_H_ */

View File

@ -65,7 +65,7 @@ parse_x509_cert(sc_context_t *ctx, struct sc_pkcs15_der *der, struct sc_pkcs15_c
{ "validity", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
{ "subject", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, &subject, &subject_len },
/* Use a callback to get the algorithm, parameters and pubkey into sc_pkcs15_pubkey */
{ "subjectPublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki, &pubkey },
{ "subjectPublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki_fields, &pubkey },
{ "extensions", SC_ASN1_STRUCT, SC_ASN1_CTX | 3 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_extensions, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};

View File

@ -120,7 +120,7 @@ typedef struct common_key_info_st {
*/
static int piv_get_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
char *out, size_t out_size)
unsigned char *out, size_t out_size)
{
struct sc_serial_number serialnr;
struct sc_pkcs15_id id;
@ -610,6 +610,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
memset(&serial, 0, sizeof(serial));
/* could read this off card if needed */
/* CSP does not like a - in the name */
@ -873,15 +875,13 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label);
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Adding pubkey from file %s",filename);
r = sc_pkcs15_pubkey_from_spki_filename(card->ctx,
filename,
&p15_key);
r = sc_pkcs15_pubkey_from_spki_file(card->ctx, filename, &p15_key);
if (r < 0)
continue;
/* Lets also try another method. */
sc_pkcs15_encode_pubkey_as_spki(card->ctx,p15_key,
&pubkey_obj.content.value, &pubkey_obj.content.len);
/* Lets also try another method. */
r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, p15_key, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
LOG_TEST_RET(card->ctx, r, "SPKI encode public key error");
/* Only get here if no cert, and the the above found the
* pub key file (actually the SPKI version). This only
@ -914,11 +914,11 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label);
pubkey_obj.emulated = p15_key;
p15_key = NULL;
}
else if (ckis[i].pubkey_from_cert && ckis[i].pubkey_from_cert->data.value) {
sc_pkcs15_encode_pubkey_as_spki(card->ctx,ckis[i].pubkey_from_cert,
&pubkey_obj.content.value, &pubkey_obj.content.len);
// sc_der_copy(&pubkey_obj.content, &ckis[i].pubkey_from_cert->data);
pubkey_obj.emulated = ckis[i].pubkey_from_cert;
else if (ckis[i].pubkey_from_cert) {
r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, ckis[i].pubkey_from_cert, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
LOG_TEST_RET(card->ctx, r, "SPKI encode public key error");
pubkey_obj.emulated = ckis[i].pubkey_from_cert;
}
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"adding pubkey for %d keyalg=%d",i, ckis[i].key_alg);

View File

@ -68,7 +68,7 @@ static const struct sc_asn1_entry c_asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_
#define C_ASN1_RSAKEY_VALUE_CHOICE_SIZE 3
static const struct sc_asn1_entry c_asn1_rsakey_value_choice[C_ASN1_RSAKEY_VALUE_CHOICE_SIZE] = {
{ "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
{ "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
{ "direct", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
@ -88,10 +88,11 @@ static const struct sc_asn1_entry c_asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_C
{ NULL, 0, 0, 0, NULL, NULL }
};
#define C_ASN1_ECKEY_ATTR_SIZE 4
#define C_ASN1_ECKEY_ATTR_SIZE 3
static const struct sc_asn1_entry c_asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE] = {
{ "value", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
{ "fieldSize", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
/* VTA: 'fieldSize' is not in PKCS#15 specification */
/* { "fieldSize", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, */
{ "keyInfo", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
@ -151,11 +152,59 @@ static const struct sc_asn1_entry c_asn1_pubkey[C_ASN1_PUBKEY_SIZE] = {
{ NULL, 0, 0, 0, NULL, NULL }
};
int sc_pkcs15_pubkey_from_spki_sequence(sc_context_t *ctx, const u8 *buf, size_t buflen, sc_pkcs15_pubkey_t ** outpubkey);
int
sc_pkcs15_decode_pubkey_direct_value(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_pubkey_info *info = (struct sc_pkcs15_pubkey_info *) obj->data;
LOG_FUNC_CALLED(ctx);
if (obj->content.value == NULL || obj->content.len == 0)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
if (*obj->content.value == (SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE)) {
/* RAW direct value */
sc_log(ctx, "Decoding 'RAW' direct value");
info->direct.raw.value = malloc(obj->content.len);
if (!info->direct.raw.value)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(info->direct.raw.value, obj->content.value, obj->content.len);
info->direct.raw.len = obj->content.len;
/* TODO: encode 'spki' direct value */
}
if (*obj->content.value == (SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_CONSTRUCTED | 0x01)) {
struct sc_pkcs15_pubkey *pubkey = NULL;
int rv;
/* SPKI direct value */
sc_log(ctx, "Decoding 'SPKI' direct value");
info->direct.spki.value = malloc(obj->content.len);
if (!info->direct.spki.value)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(info->direct.spki.value, obj->content.value, obj->content.len);
info->direct.spki.len = obj->content.len;
rv = sc_pkcs15_pubkey_from_spki_sequence(ctx, info->direct.spki.value, info->direct.spki.len, &pubkey);
LOG_TEST_RET(ctx, rv, "Failed to decode 'SPKI' direct value");
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &info->direct.raw.value, &info->direct.raw.len);
LOG_TEST_RET(ctx, rv, "Failed to endode 'RAW' direct value");
sc_pkcs15_free_pubkey(pubkey);
}
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_object *obj,
const u8 ** buf, size_t *buflen)
{
sc_context_t *ctx = p15card->card->ctx;
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_pubkey_info info;
int r, gostr3410_params[3];
struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
@ -221,7 +270,8 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
sc_format_asn1_entry(asn1_eckey_value_choice + 1, &der->value, &der->len, 0);
sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0);
sc_format_asn1_entry(asn1_eckey_attr + 1, &info.field_length, NULL, 0);
/* VTA: TODO 'fieldSize' is not in PKCS#15 specification */
/* sc_format_asn1_entry(asn1_eckey_attr + 1, &info.field_length, NULL, 0); */
sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0);
@ -268,13 +318,14 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0];
keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1];
keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2];
}
}
else if (asn1_pubkey_choice[3].flags & SC_ASN1_PRESENT) {
obj->type = SC_PKCS15_TYPE_PUBKEY_EC;
}
else {
obj->type = SC_PKCS15_TYPE_PUBKEY_DSA;
}
if (!p15card->app || !p15card->app->ddo.aid.len) {
r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
if (r < 0) {
@ -300,12 +351,16 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
}
memcpy(obj->data, &info, sizeof(info));
r = sc_pkcs15_decode_pubkey_direct_value(p15card, obj);
LOG_TEST_RET(ctx, r, "Decode public key direct value failed");
return 0;
}
int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
const struct sc_pkcs15_object *obj,
u8 **buf, size_t *buflen)
int
sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_object *obj,
unsigned char **buf, size_t *buflen)
{
struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE];
@ -322,11 +377,10 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE];
struct sc_asn1_entry asn1_pubkey[C_ASN1_PUBKEY_SIZE];
struct sc_pkcs15_pubkey_info *pubkey =
(struct sc_pkcs15_pubkey_info *) obj->data;
struct sc_asn1_pkcs15_object rsakey_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_key_attr,
asn1_com_pubkey_attr, asn1_rsa_type_attr };
struct sc_pkcs15_pubkey_info *pubkey = (struct sc_pkcs15_pubkey_info *) obj->data;
struct sc_asn1_pkcs15_object rsakey_obj = {
(struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_rsa_type_attr
};
struct sc_asn1_pkcs15_object eckey_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_key_attr,
asn1_com_pubkey_attr, asn1_ec_type_attr };
@ -339,6 +393,7 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
int r;
size_t af_len, usage_len;
unsigned char *spki_value = NULL;
sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice);
@ -360,14 +415,38 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 1);
sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 1);
if (pubkey->path.len || !obj->content.value)
if (pubkey->path.len) {
sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &pubkey->path, NULL, 1);
else
}
else if (pubkey->direct.raw.value && pubkey->direct.raw.len) {
/* In RSAPublicKeyChoice 'raw' value keep it's SEQUENCE tag */
sc_log(ctx, "Encode direct 'RAW' value");
sc_format_asn1_entry(asn1_rsakey_value_choice + 1, pubkey->direct.raw.value, (void *)&pubkey->direct.raw.len, 1);
}
else if (pubkey->direct.spki.value && pubkey->direct.spki.len) {
/* In RSAPublicKeyChoice 'spki' value changes initial SEQUENCE tag for
* CONTEXT [1] constructed SEQUENCE */
sc_log(ctx, "Encode direct 'SPKI' value");
spki_value = malloc(pubkey->direct.spki.len);
if (!spki_value)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(spki_value, pubkey->direct.spki.value, pubkey->direct.spki.len);
*spki_value = (SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_CONSTRUCTED | 0x01);
sc_format_asn1_entry(asn1_rsakey_value_choice + 1, spki_value, (void *)&pubkey->direct.spki.len, 1);
}
else if (obj->content.value && obj->content.len) {
sc_log(ctx, "Encode 'RAW' object content");
sc_format_asn1_entry(asn1_rsakey_value_choice + 1, obj->content.value, (void *)&obj->content.len, 1);
}
else {
sc_log(ctx, "Use empty path");
sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &pubkey->path, NULL, 1);
}
sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 1);
sc_format_asn1_entry(asn1_rsakey_attr + 1, &pubkey->modulus_length, NULL, 1);
break;
case SC_PKCS15_TYPE_PUBKEY_DSA:
sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 1);
@ -375,7 +454,6 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
sc_format_asn1_entry(asn1_dsakey_attr + 0, &pubkey->path, NULL, 1);
break;
case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 1);
@ -393,16 +471,28 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
}
break;
case SC_PKCS15_TYPE_PUBKEY_EC:
/* MyEID is a PKCS15 card with ECC */
sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 1);
sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 1);
if (pubkey->path.len || !obj->content.value)
if (pubkey->path.len) {
sc_format_asn1_entry(asn1_eckey_value_choice + 0, &pubkey->path, NULL, 1);
else
}
else if (pubkey->direct.spki.value) {
sc_format_asn1_entry(asn1_eckey_value_choice + 1, pubkey->direct.spki.value, (void *)&pubkey->direct.spki.len, 1);
}
else if (pubkey->direct.raw.value) {
sc_format_asn1_entry(asn1_eckey_value_choice + 1, pubkey->direct.raw.value, (void *)&pubkey->direct.raw.len, 1);
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "Needs KeyInfo with reference to algorithm in TokenInfo");
}
else if (obj->content.value) {
sc_format_asn1_entry(asn1_eckey_value_choice + 1, obj->content.value, (void *)&obj->content.len, 1);
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "Needs KeyInfo with reference to algorithm in TokenInfo");
}
sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 1);
sc_format_asn1_entry(asn1_eckey_attr + 1, &pubkey->field_length, NULL, 1);
/* VTA: TODO 'fieldSize' is not in PKCS#15 specification */
/* sc_format_asn1_entry(asn1_eckey_attr + 1, &pubkey->field_length, NULL, 1); */
break;
default:
@ -432,6 +522,9 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
r = sc_asn1_encode(ctx, asn1_pubkey, buf, buflen);
sc_log(ctx, "Key path %s", sc_print_path(&pubkey->path));
if (spki_value)
free(spki_value);
return r;
}
@ -626,18 +719,16 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx,
if (r < 0)
LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
if (*ecpoint_data != 0x04)
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value");
sc_log(ctx, "decode-EC key=%p, buf=%p, buflen=%d", key, buf, buflen);
key->ecpointQ.len = ecpoint_len;
key->ecpointQ.value = ecpoint_data;
/* An uncompressed ecpoint is of the form 04||x||y
* The 04 indicates uncompressed
* x and y are same size, and field_length = sizeof(x) in bits. */
/* TODO: -DEE support more then uncompressed */
key->params.field_length = (ecpoint_len - 1)/2 * 8;
LOG_FUNC_RETURN(ctx, r);
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
@ -648,6 +739,7 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key,
struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE];
int r;
LOG_FUNC_CALLED(ctx);
sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key->ecpointQ.len, 1);
@ -671,8 +763,9 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
return sc_pkcs15_encode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len);
if (key->algorithm == SC_ALGORITHM_EC)
return sc_pkcs15_encode_pubkey_ec(ctx, &key->u.ec, buf, len);
sc_log(ctx, "Encoding of public key type %u not supported", key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
@ -695,8 +788,7 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk
u8 **buf, size_t *len)
{
int r;
struct sc_asn1_entry asn1_spki_key[2],
asn1_spki_key_items[3];
struct sc_asn1_entry asn1_spki_key[2], asn1_spki_key_items[3];
struct sc_pkcs15_u8 pkey;
size_t key_len;
@ -714,12 +806,6 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk
pubkey->alg_id->algorithm = pubkey->algorithm;
}
/* make sure we have a der encoded value first */
if (pubkey->data.value == NULL){
r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pubkey->data.value, &pubkey->data.len);
LOG_TEST_RET(ctx, r, "public key encoding failed");
}
switch (pubkey->algorithm) {
case SC_ALGORITHM_EC:
/*
@ -781,24 +867,6 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
}
int sc_pkcs15_copy_pubkey_from_spki_object(sc_context_t *ctx, const u8 *buf, size_t buflen,sc_pkcs15_pubkey_t *pubkey);
int
sc_pkcs15_decode_pubkey_with_param(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
const u8 *buf, size_t len)
{
/* We assume all algrothims allow SPKI which starts with a sequence*/
if (*buf == 0x30)
/* Decode Public Key from SPKI */
return sc_pkcs15_copy_pubkey_from_spki_object(ctx, buf, len, key);
key->data.value = (u8 *)buf;
key->data.len = len;
return sc_pkcs15_decode_pubkey(ctx, key, buf, len);
}
/*
* Read public key.
*/
@ -815,6 +883,7 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj
assert(p15card != NULL && obj != NULL && out != NULL);
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "Public key type 0x%X", obj->type);
switch (obj->type) {
case SC_PKCS15_TYPE_PUBKEY_RSA:
@ -834,44 +903,52 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj
}
info = (const struct sc_pkcs15_pubkey_info *) obj->data;
sc_log(ctx, "Content (%p, %i)", obj->content.value, obj->content.len);
if (obj->content.value && obj->content.len) {
/* public key data is present as 'direct' value of pkcs#15 object */
/* For EC keys this can be either ECPoint or SPKI */
data = calloc(1, obj->content.len);
if (!data)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(data, obj->content.value, obj->content.len);
len = obj->content.len;
}
else if (p15card->card->ops->read_public_key) {
r = p15card->card->ops->read_public_key(p15card->card, algorithm,
(struct sc_path *)&info->path, info->key_reference, info->modulus_length,
&data, &len);
LOG_TEST_RET(ctx, r, "Card specific 'read-public' procedure failed.");
}
else if (info->path.len) {
r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
LOG_TEST_RET(ctx, r, "Failed to read public key file.");
}
else {
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "No way to get public key");
}
if (!data || !len)
LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);
pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
if (pubkey == NULL) {
free(data);
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
}
pubkey->algorithm = algorithm;
if (sc_pkcs15_decode_pubkey_with_param(ctx, pubkey, data, len)) {
free(data);
free(pubkey);
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT);
/* starting from SPKI direct value
in a compact form it presents complete public key data */
if (info->direct.spki.value && info->direct.spki.len) {
sc_log(ctx, "Using direct SPKI value, tag 0x%X", *(info->direct.spki.value));
r = sc_pkcs15_pubkey_from_spki_sequence(ctx, info->direct.spki.value, info->direct.spki.len, &pubkey);
LOG_TEST_RET(ctx, r, "Failed to decode 'SPKI' direct value");
}
else if (info->direct.raw.value && info->direct.raw.len) {
sc_log(ctx, "Using direct RAW value");
r = sc_pkcs15_decode_pubkey(ctx, pubkey, info->direct.raw.value, info->direct.raw.len);
LOG_TEST_RET(ctx, r, "Failed to decode 'RAW' direct value");
sc_log(ctx, "TODO: for EC keys 'raw' data needs to be completed with referenced algorithm from TokenInfo");
}
else if (obj->content.value && obj->content.len) {
sc_log(ctx, "Using object content");
r = sc_pkcs15_decode_pubkey(ctx, pubkey, obj->content.value, obj->content.len);
LOG_TEST_RET(ctx, r, "Failed to decode object content value");
sc_log(ctx, "TODO: for EC keys 'raw' data needs to be completed with referenced algorithm from TokenInfo");
}
else if (p15card->card->ops->read_public_key) {
sc_log(ctx, "Call card specific 'read-public-key' handle");
r = p15card->card->ops->read_public_key(p15card->card, algorithm,
(struct sc_path *)&info->path, info->key_reference, info->modulus_length,
&data, &len);
LOG_TEST_RET(ctx, r, "Card specific 'read-public' procedure failed.");
r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len);
LOG_TEST_RET(ctx, r, "Decode public key error");
}
else if (info->path.len) {
sc_log(ctx, "Read from EF and decode");
r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
LOG_TEST_RET(ctx, r, "Failed to read public key file.");
r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len);
LOG_TEST_RET(ctx, r, "Decode public key error");
}
else {
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "No way to get public key");
}
*out = pubkey;
@ -900,7 +977,7 @@ int
sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prvkey,
struct sc_pkcs15_pubkey **out)
{
struct sc_pkcs15_pubkey *pubkey;
struct sc_pkcs15_pubkey *pubkey = NULL;
int rv = SC_SUCCESS;
assert(prvkey && out);
@ -985,8 +1062,6 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
free(key->u.ec.ecpointQ.value);
break;
}
if (key->data.value)
free(key->data.value);
sc_mem_clear(key, sizeof(*key));
}
@ -1002,12 +1077,12 @@ sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key)
void
sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *key)
sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *info)
{
if (key->subject.value)
free(key->subject.value);
sc_pkcs15_free_key_params(&key->params);
free(key);
if (info->subject.value)
free(info->subject.value);
sc_pkcs15_free_key_params(&info->params);
free(info);
}
@ -1079,121 +1154,99 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename,
/*
* can be used as an SC_ASN1_CALLBACK while parsing a certificate,
* or can be called from the sc_pkcs15_pubkey_from_spki_filename
* or can be called from the sc_pkcs15_pubkey_from_spki_file
*/
int
sc_pkcs15_pubkey_from_spki(sc_context_t *ctx, sc_pkcs15_pubkey_t ** outpubkey,
u8 *buf, size_t buflen, int depth)
sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubkey **outpubkey,
unsigned char *buf, size_t buflen, int depth)
{
int r;
sc_pkcs15_pubkey_t * pubkey = NULL;
sc_pkcs15_der_t pk = { NULL, 0 };
struct sc_pkcs15_pubkey *pubkey = NULL;
struct sc_pkcs15_der pk = { NULL, 0 };
struct sc_algorithm_id pk_alg;
struct sc_asn1_entry asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE];
struct sc_asn1_entry asn1_ec_pointQ[2];
unsigned char *tmp_buf = NULL;
int r;
sc_log(ctx, "sc_pkcs15_pubkey_from_spki %p:%d", buf, buflen);
sc_log(ctx, "sc_pkcs15_pubkey_from_spki_fields %p:%d %s", buf, buflen, sc_dump_hex(buf, buflen));
tmp_buf = malloc(buflen);
if (!tmp_buf)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(tmp_buf, buf, buflen);
if ((*tmp_buf & SC_ASN1_TAG_CONTEXT))
*tmp_buf = SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE;
memset(&pk_alg, 0, sizeof(pk_alg));
pubkey = calloc(1, sizeof(sc_pkcs15_pubkey_t));
if (pubkey == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
if (pubkey == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
sc_copy_asn1_entry(c_asn1_pkinfo, asn1_pkinfo);
sc_format_asn1_entry(asn1_pkinfo + 0, &pk_alg, NULL, 0);
sc_format_asn1_entry(asn1_pkinfo + 1, &pk.value, &pk.len, 0);
r = sc_asn1_decode(ctx, asn1_pkinfo, buf, buflen, NULL, NULL);
if (r < 0)
goto err;
r = sc_asn1_decode(ctx, asn1_pkinfo, tmp_buf, buflen, NULL, NULL);
LOG_TEST_RET(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
if (pubkey->alg_id == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
if (pubkey->alg_id == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(pubkey->alg_id, &pk_alg, sizeof(struct sc_algorithm_id));
pubkey->algorithm = pk_alg.algorithm;
pk_alg.params = NULL;
sc_log(ctx, "DEE pk_alg.algorithm=%d", pk_alg.algorithm);
/* pk.len is in bits at this point */
switch (pk_alg.algorithm) {
case SC_ALGORITHM_EC:
/*
* TODO we really should only have params in one place!
* The alg_id may have the sc_ec_params,
* we want to get the curve OID into the
* u.ec.params and get the field length too.
*/
pk.len = (pk.len + 7)/8; /* convert number of bits to bytes */
if (pk_alg.algorithm == SC_ALGORITHM_EC) {
/* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */
if (pubkey->alg_id->params) {
struct sc_ec_params * ecp = (struct sc_ec_params *)pubkey->alg_id->params;
struct sc_ec_params *ecp = (struct sc_ec_params *)pubkey->alg_id->params;
pubkey->u.ec.params.der.value = malloc(ecp->der_len);
if (pubkey->u.ec.params.der.value) {
memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len);
pubkey->u.ec.params.der.len = ecp->der_len;
sc_pkcs15_fix_ec_parameters(ctx,&pubkey->u.ec.params);
}
if (pubkey->u.ec.params.der.value == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len);
pubkey->u.ec.params.der.len = ecp->der_len;
sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
}
/*
* For most keys, the above ASN.1 parsing of a key works, but for EC keys,
* the ec_pointQ in a certificate is stored in the bitstring, in its raw format.
* RSA for example is stored in the bitstring, as a ASN1 DER
* So we encoded the raw ecpointQ into ASN1 DER as the pubkey->data
* and let the sc_pkcs15_decode_pubkey below get the ecpointQ out later.
*/
pk.len >>= 3; /* Assume it is multiple of 8 */
if (pubkey->u.ec.params.field_length == 0)
pubkey->u.ec.params.field_length = (pk.len - 1)/2 * 8;
sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
sc_format_asn1_entry(&asn1_ec_pointQ[0], pk.value, &pk.len, 1);
r = sc_asn1_encode(ctx, asn1_ec_pointQ, &pubkey->data.value, &pubkey->data.len);
pk.value = NULL;
sc_log(ctx, "DEE r=%d data=%p:%d", r, pubkey->data.value, pubkey->data.len);
break;
default:
pk.len >>= 3; /* convert number of bits to bytes */
pubkey->data = pk; /* save in publey */
pk.value = NULL;
break;
pubkey->u.ec.params.field_length = (pk.len - 1)/2 * 8;
pubkey->u.ec.ecpointQ.value = malloc(pk.len);
if (pubkey->u.ec.ecpointQ.value == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len);
pubkey->u.ec.ecpointQ.len = pk.len;
}
else {
/* Public key is expected to be encapsulated into BIT STRING */
r = sc_pkcs15_decode_pubkey(ctx, pubkey, pk.value, pk.len);
LOG_TEST_RET(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
}
/* Now decode whatever is in pk as it depends on the key algorithm */
r = sc_pkcs15_decode_pubkey(ctx, pubkey, pubkey->data.value, pubkey->data.len);
if (r < 0)
goto err;
*outpubkey = pubkey;
pubkey = NULL;
return 0;
err:
if (pubkey)
free(pubkey);
if (pk.value)
free(pk.value);
if (tmp_buf)
free(tmp_buf);
LOG_TEST_RET(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
LOG_FUNC_RETURN(ctx, r);
*outpubkey = pubkey;
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
int
sc_pkcs15_pubkey_from_spki_object(sc_context_t *ctx, const u8 *buf, size_t buflen,
sc_pkcs15_pubkey_from_spki_sequence(sc_context_t *ctx, const u8 *buf, size_t buflen,
sc_pkcs15_pubkey_t ** outpubkey)
{
int r;
sc_pkcs15_pubkey_t * pubkey = NULL;
struct sc_asn1_entry asn1_spki[] = {
{ "PublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki, &pubkey},
{ "subjectPublicKeyInfo", SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki_fields, &pubkey},
{ NULL, 0, 0, 0, NULL, NULL } };
*outpubkey = NULL;
@ -1206,7 +1259,7 @@ sc_pkcs15_pubkey_from_spki_object(sc_context_t *ctx, const u8 *buf, size_t bufle
int
sc_pkcs15_pubkey_from_spki_filename(sc_context_t *ctx, char * filename,
sc_pkcs15_pubkey_from_spki_file(sc_context_t *ctx, char * filename,
sc_pkcs15_pubkey_t ** outpubkey)
{
int r;
@ -1217,7 +1270,7 @@ sc_pkcs15_pubkey_from_spki_filename(sc_context_t *ctx, char * filename,
if (r < 0)
return r;
r = sc_pkcs15_pubkey_from_spki_object(ctx, buf, buflen, outpubkey);
r = sc_pkcs15_pubkey_from_spki_sequence(ctx, buf, buflen, outpubkey);
if (buf)
free(buf);
@ -1226,22 +1279,6 @@ sc_pkcs15_pubkey_from_spki_filename(sc_context_t *ctx, char * filename,
}
int
sc_pkcs15_copy_pubkey_from_spki_object(sc_context_t *ctx, const u8 *buf, size_t buflen, sc_pkcs15_pubkey_t *pubkey)
{
int r;
sc_pkcs15_pubkey_t *outpubkey = NULL;
r = sc_pkcs15_pubkey_from_spki_object(ctx, buf, buflen, &outpubkey);
if (r < 0)
return r;
sc_pkcs15_erase_pubkey(pubkey);
*pubkey = *outpubkey;
return 0;
}
static struct ec_curve_info {
const char *name;
const char *oid_str;

View File

@ -329,7 +329,7 @@ int sc_pkcs15emu_sc_hsm_get_curve_oid(sc_cvc_t *cvc, const struct sc_lv_data **o
static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
{
pubkey->algorithm = SC_ALGORITHM_RSA;
@ -354,7 +354,7 @@ static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(sc_cvc_t *cvc, struct sc_pkcs1
static int sc_pkcs15emu_sc_hsm_get_ec_public_key(sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
static int sc_pkcs15emu_sc_hsm_get_ec_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
{
struct sc_ec_params *ecp;
const struct sc_lv_data *oid;
@ -390,21 +390,28 @@ static int sc_pkcs15emu_sc_hsm_get_ec_public_key(sc_cvc_t *cvc, struct sc_pkcs15
pubkey->u.ec.ecpointQ.value = malloc(cvc->publicPointlen);
if (!pubkey->u.ec.ecpointQ.value)
return SC_ERROR_OUT_OF_MEMORY;
memcpy(pubkey->u.ec.ecpointQ.value, cvc->publicPoint, cvc->publicPointlen);
pubkey->u.ec.ecpointQ.len = cvc->publicPointlen;
pubkey->u.ec.params.der.value = malloc(ecp->der_len);
if (!pubkey->u.ec.params.der.value)
return SC_ERROR_OUT_OF_MEMORY;
memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len);
pubkey->u.ec.params.der.len = ecp->der_len;
sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
return SC_SUCCESS;
}
int sc_pkcs15emu_sc_hsm_get_public_key(sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
int sc_pkcs15emu_sc_hsm_get_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
{
if (cvc->publicPoint || cvc->publicPointlen) {
return sc_pkcs15emu_sc_hsm_get_ec_public_key(cvc, pubkey);
return sc_pkcs15emu_sc_hsm_get_ec_public_key(ctx, cvc, pubkey);
} else {
return sc_pkcs15emu_sc_hsm_get_rsa_public_key(cvc, pubkey);
return sc_pkcs15emu_sc_hsm_get_rsa_public_key(ctx, cvc, pubkey);
}
}
@ -440,7 +447,9 @@ void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc)
static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *key_info, char *label) {
static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *key_info, char *label)
{
struct sc_context *ctx = p15card->card->ctx;
sc_card_t *card = p15card->card;
sc_pkcs15_pubkey_info_t pubkey_info;
sc_pkcs15_object_t pubkey_obj;
@ -453,23 +462,25 @@ static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_p
/* EF.CERT is selected */
r = sc_read_binary(p15card->card, 0, efbin, sizeof(efbin), 0);
LOG_TEST_RET(card->ctx, r, "Could not read CSR from EF");
LOG_TEST_RET(ctx, r, "Could not read CSR from EF");
cvcpo = efbin;
cvclen = r;
memset(&cvc, 0, sizeof(cvc));
r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&cvcpo, &cvclen, &cvc);
LOG_TEST_RET(card->ctx, r, "Could decode certificate signing request");
LOG_TEST_RET(ctx, r, "Could decode certificate signing request");
memset(&pubkey, 0, sizeof(pubkey));
r = sc_pkcs15emu_sc_hsm_get_public_key(&cvc, &pubkey);
r = sc_pkcs15emu_sc_hsm_get_public_key(ctx, &cvc, &pubkey);
LOG_TEST_RET(card->ctx, r, "Could not extract public key");
memset(&pubkey_info, 0, sizeof(pubkey_info));
memset(&pubkey_obj, 0, sizeof(pubkey_obj));
sc_pkcs15_encode_pubkey_as_spki(p15card->card->ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len);
sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len);
sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_info.direct.raw.value, &pubkey_info.direct.raw.len);
sc_pkcs15_encode_pubkey_as_spki(ctx, &pubkey, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
pubkey_info.id = key_info->id;
strlcpy(pubkey_obj.label, label, sizeof(pubkey_obj.label));
@ -481,7 +492,7 @@ static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_p
pubkey_info.field_length = cvc.primeOrModuluslen << 3;
r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
}
LOG_TEST_RET(card->ctx, r, "Could not add public key");
LOG_TEST_RET(ctx, r, "Could not add public key");
sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
sc_pkcs15_erase_pubkey(&pubkey);

View File

@ -221,7 +221,7 @@ struct sc_pkcs15_gost_parameters {
struct sc_pkcs15_pubkey_ec {
struct sc_pkcs15_ec_parameters params;
struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */
struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */
};
struct sc_pkcs15_prkey_ec {
@ -251,9 +251,6 @@ struct sc_pkcs15_pubkey {
struct sc_pkcs15_pubkey_ec ec;
struct sc_pkcs15_pubkey_gostr3410 gostr3410;
} u;
/* DER encoded raw key */
struct sc_pkcs15_der data;
};
typedef struct sc_pkcs15_pubkey sc_pkcs15_pubkey_t;
@ -474,6 +471,11 @@ struct sc_pkcs15_pubkey_info {
struct sc_pkcs15_key_params params;
struct sc_path path;
struct {
struct sc_pkcs15_der raw;
struct sc_pkcs15_der spki;
} direct;
};
typedef struct sc_pkcs15_pubkey_info sc_pkcs15_pubkey_info_t;
@ -739,9 +741,9 @@ int sc_pkcs15_pubkey_from_prvkey(struct sc_context *, struct sc_pkcs15_prkey *,
struct sc_pkcs15_pubkey **);
int sc_pkcs15_pubkey_from_cert(struct sc_context *, struct sc_pkcs15_der *,
struct sc_pkcs15_pubkey **);
int sc_pkcs15_pubkey_from_spki_filename(struct sc_context *,
int sc_pkcs15_pubkey_from_spki_file(struct sc_context *,
char *, struct sc_pkcs15_pubkey ** );
int sc_pkcs15_pubkey_from_spki(struct sc_context *,
int sc_pkcs15_pubkey_from_spki_fields(struct sc_context *,
struct sc_pkcs15_pubkey **, u8 *, size_t, int);
int sc_pkcs15_encode_prkey(struct sc_context *,
struct sc_pkcs15_prkey *, u8 **, size_t *);

View File

@ -2209,12 +2209,10 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
logprintf(pCardData, 1, "now read public key '%s'\n", cont->pubkey_obj->label);
rv = sc_pkcs15_read_pubkey(vs->p15card, cont->pubkey_obj, &pubkey);
if (!rv) {
if(pubkey->algorithm == SC_ALGORITHM_RSA) {
sc_der_copy(&pubkey_der, &pubkey->data);
ret = SCARD_S_SUCCESS;
}
else {
ret = SCARD_E_UNSUPPORTED_FEATURE;
rv = sc_pkcs15_encode_pubkey(vs->ctx, pubkey, &pubkey_der.value, &pubkey_der.len);
if (rv) {
logprintf(pCardData, 1, "encode public key error %d\n", rv);
ret = SCARD_F_INTERNAL_ERROR;
}
sc_pkcs15_free_pubkey(pubkey);
}
@ -2230,13 +2228,12 @@ DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData, __in BYTE bContaine
logprintf(pCardData, 1, "now read certificate '%s'\n", cont->cert_obj->label);
rv = sc_pkcs15_read_certificate(vs->p15card, (struct sc_pkcs15_cert_info *)(cont->cert_obj->data), &cert);
if(!rv) {
if(cert->key->algorithm == SC_ALGORITHM_RSA) {
sc_der_copy(&pubkey_der, &cert->key->data);
ret = SCARD_S_SUCCESS;
}
else {
ret = SCARD_E_UNSUPPORTED_FEATURE;
rv = sc_pkcs15_encode_pubkey(vs->ctx, cert->key, &pubkey_der.value, &pubkey_der.len);
if (rv) {
logprintf(pCardData, 1, "encode certificate public key error %d\n", rv);
ret = SCARD_F_INTERNAL_ERROR;
}
sc_pkcs15_free_certificate(cert);
}
else {

View File

@ -605,8 +605,8 @@ static int
__pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data,
struct sc_pkcs15_object *pubkey, struct pkcs15_any_object **pubkey_object)
{
struct pkcs15_pubkey_object *object;
struct sc_pkcs15_pubkey *p15_key;
struct pkcs15_pubkey_object *object = NULL;
struct sc_pkcs15_pubkey *p15_key = NULL;
int rv;
/* Read public key from card */
@ -615,15 +615,17 @@ __pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data,
* and saved as a file before the certificate has been created.
*/
if (pubkey->flags & SC_PKCS15_CO_FLAG_PRIVATE) { /* is the key private? */
sc_log(context, "No pubkey");
p15_key = NULL; /* will read key when needed */
}
else {
/* if emulation already created pubkey use it */
if (pubkey->emulated && (fw_data->p15_card->flags & SC_PKCS15_CARD_FLAG_EMULATED)) {
sc_log(context, "Use emulated pubkey");
p15_key = (struct sc_pkcs15_pubkey *) pubkey->emulated;
sc_log(context, "Using emulated pubkey %p", p15_key);
}
else {
sc_log(context, "Get pubkey from PKCS#15 object");
rv = sc_pkcs15_read_pubkey(fw_data->p15_card, pubkey, &p15_key);
if (rv < 0)
p15_key = NULL;
@ -2761,11 +2763,17 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
pub_args.key.algorithm = SC_ALGORITHM_GOSTR3410;
set_gost_params(&keygen_args.prkey_args.params.gost, &pub_args.params.gost,
pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt);
keybits = SC_PKCS15_GOSTR3410_KEYSIZE;
}
else if (keytype == CKK_RSA) {
/* default value (CKA_KEY_TYPE isn't set) or CKK_RSA is set */
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_RSA;
pub_args.key.algorithm = SC_ALGORITHM_RSA;
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS, &keybits, NULL);
if (rv != CKR_OK)
keybits = 1024; /* Default key size */
/* TODO: check allowed values of keybits */
}
else if (keytype == CKK_EC) {
struct sc_pkcs15_der *der = &keygen_args.prkey_args.params.ec.der;
@ -2785,20 +2793,9 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
rv = CKR_ATTRIBUTE_VALUE_INVALID;
goto kpgen_done;
}
if (keytype == CKK_GOSTR3410)
keybits = SC_PKCS15_GOSTR3410_KEYSIZE;
else if (keytype == CKK_RSA)
{
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS,
&keybits, NULL);
if (rv != CKR_OK)
keybits = 1024; /* Default key size */
/* TODO: check allowed values of keybits */
}
id.len = SC_PKCS15_MAX_ID_SIZE;
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_ID,
&id.value, &id.len);
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_ID, &id.value, &id.len);
if (rv == CKR_OK)
keygen_args.prkey_args.id = pub_args.id = id;
@ -2828,8 +2825,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
sc_pkcs15init_set_p15card(profile, fw_data->p15_card);
sc_log(context, "Try on-card key pair generation");
rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile,
&keygen_args, keybits, &priv_key_obj);
rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile, &keygen_args, keybits, &priv_key_obj);
if (rc >= 0) {
id = ((struct sc_pkcs15_prkey_info *) priv_key_obj->data)->id;
rc = sc_pkcs15_find_pubkey_by_id(fw_data->p15_card, &id, &pub_key_obj);
@ -3812,11 +3808,14 @@ static void
pkcs15_pubkey_release(void *object)
{
struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;
struct sc_pkcs15_pubkey *key_data = pubkey->pub_data;
if (__pkcs15_release_object((struct pkcs15_any_object *) object) == 0)
if (__pkcs15_release_object((struct pkcs15_any_object *) object) == 0) {
struct sc_pkcs15_pubkey *key_data = pubkey->pub_data;
if (key_data)
sc_pkcs15_free_pubkey(key_data);
pubkey->pub_data = NULL;
}
}
@ -3830,8 +3829,7 @@ pkcs15_pubkey_set_attribute(struct sc_pkcs11_session *session,
static CK_RV
pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,
void *object, CK_ATTRIBUTE_PTR attr)
pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr)
{
struct sc_pkcs11_card *p11card = session->slot->card;
struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;
@ -3950,24 +3948,29 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,
case CKA_PUBLIC_EXPONENT:
return get_public_exponent(pubkey->pub_data, attr);
case CKA_VALUE:
if (pubkey->pub_data) {
/* TODO: -DEE Not all pubkeys have CKA_VALUE attribute. RSA and EC
* for example don't. So why is this here?
* Why checking for cert in this pkcs15_pubkey_get_attribute?
*/
check_attribute_buffer(attr, pubkey->pub_data->data.len);
memcpy(attr->pValue, pubkey->pub_data->data.value,
pubkey->pub_data->data.len);
if (pubkey->pub_info->direct.raw.value && pubkey->pub_info->direct.raw.len) {
check_attribute_buffer(attr, pubkey->pub_info->direct.raw.len);
memcpy(attr->pValue, pubkey->pub_info->direct.raw.value, pubkey->pub_info->direct.raw.len);
}
else if (cert && cert->cert_data) {
else if (pubkey->pub_info->direct.spki.value && pubkey->pub_info->direct.spki.len) {
check_attribute_buffer(attr, pubkey->pub_info->direct.spki.len);
memcpy(attr->pValue, pubkey->pub_info->direct.spki.value, pubkey->pub_info->direct.spki.len);
}
else if (pubkey->base.p15_object->content.value && pubkey->base.p15_object->content.len) {
check_attribute_buffer(attr, pubkey->base.p15_object->content.len);
memcpy(attr->pValue, pubkey->base.p15_object->content.value, pubkey->base.p15_object->content.len);
}
else if (cert && cert->cert_data) {
check_attribute_buffer(attr, cert->cert_data->data.len);
memcpy(attr->pValue, cert->cert_data->data.value, cert->cert_data->data.len);
}
else {
return CKR_ATTRIBUTE_TYPE_INVALID;
}
break;
case CKA_GOSTR3410_PARAMS:
if (pubkey->pub_info && pubkey->pub_info->params.len)
return get_gostr3410_params(pubkey->pub_info->params.data,
pubkey->pub_info->params.len, attr);
return get_gostr3410_params(pubkey->pub_info->params.data, pubkey->pub_info->params.len, attr);
else
return CKR_ATTRIBUTE_TYPE_INVALID;
case CKA_EC_PARAMS:
@ -4383,6 +4386,7 @@ get_public_exponent(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
case SC_ALGORITHM_RSA:
return get_bignum(&key->u.rsa.exponent, attr);
}
return CKR_ATTRIBUTE_TYPE_INVALID;
}
@ -4395,44 +4399,50 @@ get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
return CKR_ATTRIBUTE_TYPE_INVALID;
if (key->alg_id == NULL)
return CKR_ATTRIBUTE_TYPE_INVALID;
ecp = (struct sc_ec_params *) key->alg_id->params;
switch (key->algorithm) {
case SC_ALGORITHM_EC:
/* TODO parms should not be in two places */
/* ec_params may be in key->alg_id or in key->u.ec */
if (key->u.ec.params.der.value) {
check_attribute_buffer(attr,key->u.ec.params.der.len);
memcpy(attr->pValue, key->u.ec.params.der.value, key->u.ec.params.der.len);
return CKR_OK;
check_attribute_buffer(attr,key->u.ec.params.der.len);
memcpy(attr->pValue, key->u.ec.params.der.value, key->u.ec.params.der.len);
return CKR_OK;
}
ecp = (struct sc_ec_params *) key->alg_id->params;
if (ecp && ecp->der && ecp->der_len) {
check_attribute_buffer(attr, ecp->der_len);
memcpy(attr->pValue, ecp->der, ecp->der_len);
return CKR_OK;
}
check_attribute_buffer(attr, ecp->der_len);
memcpy(attr->pValue, ecp->der, ecp->der_len);
return CKR_OK;
}
return CKR_ATTRIBUTE_TYPE_INVALID;
}
static CK_RV
get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
{
unsigned char *value = NULL;
size_t value_len = 0;
int rc;
if (key == NULL)
return CKR_ATTRIBUTE_TYPE_INVALID;
switch (key->algorithm) {
case SC_ALGORITHM_EC:
/*
* TODO Verify that pubkey->data is DER encoded ecpointQ
* It should be. If not we need to encode the ecpointQ to
* DER. But can not use sc_pkcs15_encode_pubkey as it
* needs ctx, and ctx is not available here.
* Original ECC code stored ecpointQ as DER, so there was
* no issue.
*/
check_attribute_buffer(attr, key->data.len);
memcpy(attr->pValue, key->data.value, key->data.len);
rc = sc_pkcs15_encode_pubkey_ec(context, &key->u.ec, &value, &value_len);
if (rc != SC_SUCCESS)
return sc_to_cryptoki_error(rc, NULL);
check_attribute_buffer(attr, value_len);
memcpy(attr->pValue, value, value_len);
free(value);
return CKR_OK;
}
return CKR_ATTRIBUTE_TYPE_INVALID;
}
@ -4444,8 +4454,7 @@ get_gostr3410_params(const u8 *params, size_t params_len, CK_ATTRIBUTE_PTR attr)
if (!params || params_len == sizeof(int))
return CKR_ATTRIBUTE_TYPE_INVALID;
for (i = 0; i < sizeof(gostr3410_param_oid)/
sizeof(gostr3410_param_oid[0]); ++i) {
for (i = 0; i < sizeof(gostr3410_param_oid)/sizeof(gostr3410_param_oid[0]); ++i) {
if (gostr3410_param_oid[i].param == ((int*)params)[0]) {
check_attribute_buffer(attr, sizeof(gostr3410_param_oid[i].oid));
memcpy(attr->pValue, gostr3410_param_oid[i].oid,

View File

@ -599,6 +599,8 @@ authentic_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15c
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
size_t keybits = key_info->modulus_length;
struct sc_authentic_sdo *sdo = NULL;
unsigned char *tmp = NULL;
size_t tmp_len;
unsigned long caps;
int rv;
@ -635,18 +637,20 @@ authentic_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15c
pubkey->u.rsa.exponent = sdo->data.prvkey->u.rsa.exponent;
sdo->data.prvkey = NULL;
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &pubkey->data.value, &pubkey->data.len);
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &tmp, &tmp_len);
LOG_TEST_RET(ctx, rv, "encode public key failed");
/* Here fix the key's supported algorithms, if these ones will be implemented
/*
* Here algorithms supported by key have to be fixed, if it will be implemented
* (see src/libopensc/pkcs15-prkey.c).
*/
authentic_free_sdo_data(sdo);
rv = sc_pkcs15_allocate_object_content(ctx, object, pubkey->data.value, pubkey->data.len);
rv = sc_pkcs15_allocate_object_content(ctx, object, tmp, tmp_len);
LOG_TEST_RET(ctx, rv, "Failed to allocate public key as object content");
free(tmp);
LOG_FUNC_RETURN(ctx, rv);
}

View File

@ -1088,6 +1088,8 @@ iasecc_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15card
struct iasecc_sdo *sdo_prvkey = NULL;
struct iasecc_sdo *sdo_pubkey = NULL;
struct sc_file *file = NULL;
unsigned char *tmp = NULL;
size_t tmp_len;
unsigned long caps;
int rv;
@ -1149,18 +1151,19 @@ iasecc_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15card
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(pubkey->u.rsa.exponent.data, sdo_pubkey->data.pub_key.e.value, pubkey->u.rsa.exponent.len);
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &pubkey->data.value, &pubkey->data.len);
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &tmp, &tmp_len);
LOG_TEST_RET(ctx, rv, "encode public key failed");
rv = iasecc_pkcs15_encode_supported_algos(p15card, object);
LOG_TEST_RET(ctx, rv, "encode private key access rules failed");
/* SDO PrvKey data replaced by public part of generated key */
rv = sc_pkcs15_allocate_object_content(ctx, object, pubkey->data.value, pubkey->data.len);
rv = sc_pkcs15_allocate_object_content(ctx, object, tmp, tmp_len);
LOG_TEST_RET(ctx, rv, "Failed to allocate public key as object content");
iasecc_sdo_free(card, sdo_pubkey);
free(tmp);
LOG_FUNC_RETURN(ctx, rv);
}

View File

@ -203,6 +203,7 @@ struct sc_pkcs15init_keyarg_gost_params {
};
struct sc_pkcs15init_prkeyargs {
/* TODO: member for private key algorithm: currently is used algorithm from 'key' member */
struct sc_pkcs15_id id;
struct sc_pkcs15_id auth_id;
char *label;

View File

@ -1318,7 +1318,11 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr
pubkey_args.label = keygen_args->pubkey_label ? keygen_args->pubkey_label : object->label;
pubkey_args.usage = keygen_args->prkey_args.usage;
pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage;
pubkey_args.params.gost = keygen_args->prkey_args.params.gost;
if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_GOSTR3410)
pubkey_args.params.gost = keygen_args->prkey_args.params.gost;
else if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_EC)
pubkey_args.params.ec = keygen_args->prkey_args.params.ec;
/* Generate the private key on card */
r = profile->ops->create_key(profile, p15card, object);
@ -1467,10 +1471,8 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil
* Store a public key
*/
int
sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
struct sc_profile *profile,
struct sc_pkcs15init_pubkeyargs *keyargs,
struct sc_pkcs15_object **res_obj)
sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15init_pubkeyargs *keyargs, struct sc_pkcs15_object **res_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_object *object;
@ -1505,8 +1507,12 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410;
break;
case SC_ALGORITHM_EC:
keybits = key.u.ec.params.field_length;
type = SC_PKCS15_TYPE_PUBKEY_EC;
key.u.ec.params = keyargs->params.ec;
sc_pkcs15_fix_ec_parameters(ctx, &key.u.ec.params);
keybits = key.u.ec.params.field_length;
break;
default:
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported key algorithm.");
@ -1537,15 +1543,16 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
key_info->params.data = malloc(key_info->params.len);
if (!key_info->params.data) {
/* FIXME free object with sc_pkcs15init_delete_object */
return SC_ERROR_OUT_OF_MEMORY;
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate GOST params");
}
keyinfo_gostparams = key_info->params.data;
keyinfo_gostparams->gostr3410 = keyargs->params.gost.gostr3410;
keyinfo_gostparams->gostr3411 = keyargs->params.gost.gostr3411;
keyinfo_gostparams->gost28147 = keyargs->params.gost.gost28147;
}
else if(key.algorithm == SC_ALGORITHM_EC)
else if (key.algorithm == SC_ALGORITHM_EC) {
key_info->field_length = keybits;
}
/* Select a intrinsic Key ID if the user didn't specify one */
r = sc_pkcs15init_select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &keyargs->id, &key);
@ -1566,10 +1573,16 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
key_info->id = keyargs->id;
/* DER encode public key components */
/* EC key are encoded as SPKI to preserve domain parameter */
r = sc_pkcs15_encode_pubkey_as_spki(p15card->card->ctx, &key, &object->content.value, &object->content.len);
r = sc_pkcs15_encode_pubkey(p15card->card->ctx, &key, &object->content.value, &object->content.len);
LOG_TEST_RET(ctx, r, "Encode public key error");
r = sc_pkcs15_encode_pubkey(p15card->card->ctx, &key, &key_info->direct.raw.value, &key_info->direct.raw.len);
LOG_TEST_RET(ctx, r, "RAW encode public key error");
/* EC key are encoded as SPKI to preserve domain parameter */
r = sc_pkcs15_encode_pubkey_as_spki(p15card->card->ctx, &key, &key_info->direct.spki.value, &key_info->direct.spki.len);
LOG_TEST_RET(ctx, r, "SPKI encode public key error");
/* Now create key file and store key */
r = sc_pkcs15init_store_data(p15card, profile, object, &object->content, &key_info->path);

View File

@ -421,6 +421,7 @@ myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
"Unsupported RSA key size");
break;
case SC_PKCS15_TYPE_PRKEY_EC:
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "20140202: waiting for cards and specification from Aventra. VTA");
if (sc_card_find_ec_alg(p15card->card, keybits) == NULL)
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
"Unsupported EC key size");
@ -481,6 +482,7 @@ myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size");
break;
case SC_PKCS15_TYPE_PRKEY_EC:
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "20140202: waiting for cards and specification from Aventra. VTA");
if (sc_card_find_ec_alg(p15card->card, keybits) == NULL)
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size");
if(key_info->field_length != 0)
@ -569,6 +571,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size");
break;
case SC_PKCS15_TYPE_PRKEY_EC:
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "20140202: waiting for cards and specification from Aventra. VTA");
if (sc_card_find_ec_alg(p15card->card, keybits) == NULL)
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size");
if(key_info->field_length != 0)
@ -664,12 +668,12 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
pubkey->u.ec.ecpointQ.value = malloc(data_obj.DataLen - 2);
pubkey->u.ec.ecpointQ.len = data_obj.DataLen - 2;
pubkey->data.value = malloc(data_obj.DataLen);
pubkey->data.len = data_obj.DataLen;
//pubkey->data.value = malloc(data_obj.DataLen);
//pubkey->data.len = data_obj.DataLen;
pubkey->u.ec.params.field_length = keybits;
/* Omit the first 2 bytes (0x86??) */
memcpy(pubkey->u.ec.ecpointQ.value, data_obj.Data + 2, data_obj.DataLen - 2);
memcpy(pubkey->data.value, data_obj.Data, data_obj.DataLen);
//memcpy(pubkey->data.value, data_obj.Data, data_obj.DataLen);
}
}

View File

@ -303,7 +303,7 @@ static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card
}
if (pubkey != NULL) {
r = sc_pkcs15emu_sc_hsm_get_public_key(&cvc, pubkey);
r = sc_pkcs15emu_sc_hsm_get_public_key(p15card->card->ctx, &cvc, pubkey);
}
out:

View File

@ -2571,6 +2571,7 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
unsigned char *bytes = NULL;
unsigned int n;
int ksize;
bytes = getEC_POINT(sess, obj, &size);
/*
* (We only support uncompressed for now)
@ -2586,10 +2587,10 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
else
ksize = (size - 5) * 4;
printf(" EC_POINT %d bits\n", ksize);
printf(" EC_POINT %d bits\n", ksize);
if (bytes) {
if ((CK_LONG)size > 0) { /* Will print the point here */
printf(" EC_POINT: ");
printf(" EC_POINT: ");
for (n = 0; n < size; n++)
printf("%02x", bytes[n]);
printf("\n");