commit
a399905d23
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue