#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include "../libopensc/log.h"
#include "../libopensc/opensc.h"
#include "../libopensc/cardctl.h"
#include "../libopensc/asn1.h"
#include "pkcs15-init.h"
#include "profile.h"
#include "../libopensc/card-gids.h"
static int
gids_select_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
sc_pkcs15_prkey_info_t *key_info)
{
sc_card_t *card = p15card->card;
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_SELECT_KEY_REFERENCE, key_info));
}
static int
gids_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj)
{
sc_card_t *card = p15card->card;
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_CREATE_KEY, obj));
}
static int
gids_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
sc_pkcs15_object_t *obj,
sc_pkcs15_pubkey_t *pubkey)
{
sc_card_t *card = p15card->card;
struct sc_cardctl_gids_genkey call = {obj, pubkey};
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_GENERATE_KEY, &call));
}
static int
gids_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *object,
sc_pkcs15_prkey_t *key)
{
sc_card_t *card = p15card->card;
struct sc_cardctl_gids_importkey call = {object, key};
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_IMPORT_KEY, &call));
}
static int
gids_delete_object(struct sc_profile *profile, struct sc_pkcs15_card * p15card,
struct sc_pkcs15_object *object, const struct sc_path *path) {
sc_card_t *card = p15card->card;
switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PRKEY:
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_DELETE_KEY, object));
break;
case SC_PKCS15_TYPE_CERT:
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_DELETE_CERT, object));
break;
case SC_PKCS15_TYPE_PUBKEY:
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
default:
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
}
static int gids_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
unsigned op, struct sc_pkcs15_object *object)
{
LOG_FUNC_CALLED(p15card->card->ctx);
LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
}
static int gids_save_certificate(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_path *path) {
int r;
sc_card_t *card = p15card->card;
struct sc_cardctl_gids_save_cert call = {object, NULL, path};
struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
r = sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, &cert_info->id , &(call.privkeyobject));
if (r == SC_ERROR_OBJECT_NOT_FOUND) {
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
LOG_TEST_RET(card->ctx, r, "unable to find the private key associated to the certificate");
LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_SAVE_CERT, &call));
}
static int gids_emu_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *object, struct sc_pkcs15_der *content,
struct sc_path *path) {
sc_card_t *card = p15card->card;
int r;
LOG_FUNC_CALLED(card->ctx);
switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PRKEY:
case SC_PKCS15_TYPE_PUBKEY:
r = SC_SUCCESS;
break;
case SC_PKCS15_TYPE_CERT:
r = gids_save_certificate(p15card, object, path);
break;
default:
r = SC_ERROR_NOT_IMPLEMENTED;
break;
}
LOG_FUNC_RETURN(card->ctx, r);
}
static int gids_emu_update_tokeninfo(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
sc_pkcs15_tokeninfo_t *tokeninfo)
{
LOG_FUNC_CALLED(p15card->card->ctx);
LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
}
static struct sc_pkcs15init_operations sc_pkcs15init_gids_operations =
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
gids_select_key_reference,
gids_create_key,
gids_store_key,
gids_generate_key,
NULL, NULL,
NULL,
gids_delete_object,
NULL,
gids_emu_update_any_df,
gids_emu_update_tokeninfo,
NULL,
gids_emu_store_data,
NULL,
};
struct
sc_pkcs15init_operations *sc_pkcs15init_get_gids_ops(void)
{
return &sc_pkcs15init_gids_operations;
}