int sc_pkcs15_decode_dodf_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_pkcs15_data_info info; struct sc_asn1_entry asn1_com_data_attr[3], asn1_type_data_attr[2], asn1_data[2]; struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL, asn1_type_data_attr }; size_t label_len = sizeof(info.app_label); int r; sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr); sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr); sc_copy_asn1_entry(c_asn1_data, asn1_data); sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0); sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0); sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0); /* Fill in defaults */ memset(&info, 0, sizeof(info)); sc_init_oid(&info.app_oid); r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) return r; } else { info.path.aid = p15card->app->ddo.aid; } obj->type = SC_PKCS15_TYPE_DATA_OBJECT; obj->data = malloc(sizeof(info)); if (obj->data == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return SC_SUCCESS; }
int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length, unsigned long flags, unsigned long ext_flags, struct sc_object_id *curve_oid) { sc_algorithm_info_t info; memset(&info, 0, sizeof(info)); sc_init_oid(&info.u._ec.params.id); info.algorithm = SC_ALGORITHM_EC; info.key_length = key_length; info.flags = flags; info.u._ec.ext_flags = ext_flags; if (curve_oid) info.u._ec.params.id = *curve_oid; return _sc_card_add_algorithm(card, &info); }
/* * Encode a pubkey as a SPKI, useful for pkcs15-tool, and for PKCS#15 files. */ int sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubkey, u8 **buf, size_t *len) { int r; struct sc_asn1_entry asn1_spki_key[2], asn1_spki_key_items[3]; struct sc_pkcs15_u8 pkey; size_t key_len; LOG_FUNC_CALLED(ctx); pkey.value = NULL; pkey.len = 0; sc_log(ctx, "Encoding public key with algorithm %i", pubkey->algorithm); if (!pubkey->alg_id) { pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id)); if (!pubkey->alg_id) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); sc_init_oid(&pubkey->alg_id->oid); 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: /* * most keys, but not EC have only one encoding. * For a SPKI, the ecpoint is placed directly in the * BIT STRING */ key_len = pubkey->u.ec.ecpointQ.len * 8; pkey.value = pubkey->u.ec.ecpointQ.value; pkey.len = 0; /* flag as do not delete */ /* TODO make sure algorithm params are available*/ /* if not can we copy them from the u.ec */ r = 0; break; case SC_ALGORITHM_GOSTR3410: /* TODO is this needed? does it cause mem leak? */ pubkey->alg_id->params = &pubkey->u.gostr3410.params; r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; break; default: r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len); key_len = pkey.len * 8; break; } if (r == 0) { sc_copy_asn1_entry(c_asn1_spki_key, asn1_spki_key); sc_copy_asn1_entry(c_asn1_spki_key_items, asn1_spki_key_items); sc_format_asn1_entry(asn1_spki_key + 0, asn1_spki_key_items, NULL, 1); sc_format_asn1_entry(asn1_spki_key_items + 0, pubkey->alg_id, NULL, 1); sc_format_asn1_entry(asn1_spki_key_items + 1, pkey.value, &key_len, 1); r = sc_asn1_encode(ctx, asn1_spki_key, buf, len); } if (pkey.len && pkey.value) free(pkey.value); LOG_FUNC_RETURN(ctx, r); }