iasecc: SM add related procedures
This commit is contained in:
parent
cfd5aaba7d
commit
ea5a19e27e
@ -37,7 +37,7 @@ libopensc_la_SOURCES = \
|
|||||||
card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \
|
card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \
|
||||||
card-rtecp.c card-westcos.c card-myeid.c card-ias.c \
|
card-rtecp.c card-westcos.c card-myeid.c card-ias.c \
|
||||||
card-javacard.c card-itacns.c card-authentic.c \
|
card-javacard.c card-itacns.c card-authentic.c \
|
||||||
card-iasecc.c iasecc-sdo.c \
|
card-iasecc.c iasecc-sdo.c iasecc-sm.c \
|
||||||
\
|
\
|
||||||
pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \
|
pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \
|
||||||
pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \
|
pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \
|
||||||
|
@ -21,7 +21,7 @@ OBJECTS = \
|
|||||||
card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \
|
card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \
|
||||||
card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \
|
card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \
|
||||||
card-javacard.obj card-itacns.obj card-authentic.obj \
|
card-javacard.obj card-itacns.obj card-authentic.obj \
|
||||||
card-iasecc.obj iasecc-sdo.obj \
|
card-iasecc.obj iasecc-sdo.obj iasecc-sm.obj \
|
||||||
\
|
\
|
||||||
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
|
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
|
||||||
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
|
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -116,7 +116,7 @@ enum {
|
|||||||
SC_CARD_TYPE_OBERTHUR_32K_BIO,
|
SC_CARD_TYPE_OBERTHUR_32K_BIO,
|
||||||
SC_CARD_TYPE_OBERTHUR_64K,
|
SC_CARD_TYPE_OBERTHUR_64K,
|
||||||
/* Oberthur 'COSMO v7' with applet 'AuthentIC v3.2' */
|
/* Oberthur 'COSMO v7' with applet 'AuthentIC v3.2' */
|
||||||
SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2 = 11100,
|
SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2 = 11100,
|
||||||
|
|
||||||
/* belpic driver */
|
/* belpic driver */
|
||||||
SC_CARD_TYPE_BELPIC_BASE = 12000,
|
SC_CARD_TYPE_BELPIC_BASE = 12000,
|
||||||
@ -130,12 +130,12 @@ enum {
|
|||||||
/* PIV-II type cards */
|
/* PIV-II type cards */
|
||||||
SC_CARD_TYPE_PIV_II_BASE = 14000,
|
SC_CARD_TYPE_PIV_II_BASE = 14000,
|
||||||
SC_CARD_TYPE_PIV_II_GENERIC,
|
SC_CARD_TYPE_PIV_II_GENERIC,
|
||||||
|
|
||||||
/* MuscleApplet */
|
/* MuscleApplet */
|
||||||
SC_CARD_TYPE_MUSCLE_BASE = 15000,
|
SC_CARD_TYPE_MUSCLE_BASE = 15000,
|
||||||
SC_CARD_TYPE_MUSCLE_GENERIC,
|
SC_CARD_TYPE_MUSCLE_GENERIC,
|
||||||
SC_CARD_TYPE_MUSCLE_V1,
|
SC_CARD_TYPE_MUSCLE_V1,
|
||||||
SC_CARD_TYPE_MUSCLE_V2,
|
SC_CARD_TYPE_MUSCLE_V2,
|
||||||
SC_CARD_TYPE_MUSCLE_ETOKEN_72K,
|
SC_CARD_TYPE_MUSCLE_ETOKEN_72K,
|
||||||
SC_CARD_TYPE_MUSCLE_JCOP241,
|
SC_CARD_TYPE_MUSCLE_JCOP241,
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ enum {
|
|||||||
/* MyEID cards */
|
/* MyEID cards */
|
||||||
SC_CARD_TYPE_MYEID_BASE = 20000,
|
SC_CARD_TYPE_MYEID_BASE = 20000,
|
||||||
SC_CARD_TYPE_MYEID_GENERIC,
|
SC_CARD_TYPE_MYEID_GENERIC,
|
||||||
|
|
||||||
/* GemsafeV1 cards */
|
/* GemsafeV1 cards */
|
||||||
SC_CARD_TYPE_GEMSAFEV1_BASE = 21000,
|
SC_CARD_TYPE_GEMSAFEV1_BASE = 21000,
|
||||||
SC_CARD_TYPE_GEMSAFEV1_GENERIC,
|
SC_CARD_TYPE_GEMSAFEV1_GENERIC,
|
||||||
@ -169,7 +169,7 @@ enum {
|
|||||||
/* IAS cards */
|
/* IAS cards */
|
||||||
SC_CARD_TYPE_IAS_BASE = 22000,
|
SC_CARD_TYPE_IAS_BASE = 22000,
|
||||||
SC_CARD_TYPE_IAS_PTEID,
|
SC_CARD_TYPE_IAS_PTEID,
|
||||||
|
|
||||||
/* Italian CNS cards */
|
/* Italian CNS cards */
|
||||||
SC_CARD_TYPE_ITACNS_BASE = 23000,
|
SC_CARD_TYPE_ITACNS_BASE = 23000,
|
||||||
SC_CARD_TYPE_ITACNS_GENERIC,
|
SC_CARD_TYPE_ITACNS_GENERIC,
|
||||||
@ -186,6 +186,7 @@ enum {
|
|||||||
SC_CARD_TYPE_IASECC_GEMALTO,
|
SC_CARD_TYPE_IASECC_GEMALTO,
|
||||||
SC_CARD_TYPE_IASECC_OBERTHUR,
|
SC_CARD_TYPE_IASECC_OBERTHUR,
|
||||||
SC_CARD_TYPE_IASECC_SAGEM,
|
SC_CARD_TYPE_IASECC_SAGEM,
|
||||||
|
SC_CARD_TYPE_IASECC_AMOS
|
||||||
};
|
};
|
||||||
|
|
||||||
extern sc_card_driver_t *sc_get_default_driver(void);
|
extern sc_card_driver_t *sc_get_default_driver(void);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#define IASECC_DOCP_TAG_TRIES_REMAINING 0x9B
|
#define IASECC_DOCP_TAG_TRIES_REMAINING 0x9B
|
||||||
#define IASECC_DOCP_TAG_USAGE_MAXIMUM 0x9C
|
#define IASECC_DOCP_TAG_USAGE_MAXIMUM 0x9C
|
||||||
#define IASECC_DOCP_TAG_USAGE_REMAINING 0x9D
|
#define IASECC_DOCP_TAG_USAGE_REMAINING 0x9D
|
||||||
#define IASECC_DOCP_TAG_NON_REPUDATION 0x9E
|
#define IASECC_DOCP_TAG_NON_REPUDATION 0x9E
|
||||||
#define IASECC_DOCP_TAG_SIZE 0x80
|
#define IASECC_DOCP_TAG_SIZE 0x80
|
||||||
#define IASECC_DOCP_TAG_ACLS 0xA1
|
#define IASECC_DOCP_TAG_ACLS 0xA1
|
||||||
#define IASECC_DOCP_TAG_ACLS_CONTACT 0x8C
|
#define IASECC_DOCP_TAG_ACLS_CONTACT 0x8C
|
||||||
@ -218,7 +218,7 @@ struct iasecc_sdo_keyset {
|
|||||||
struct iasecc_extended_tlv enc;
|
struct iasecc_extended_tlv enc;
|
||||||
struct iasecc_extended_tlv compulsory;
|
struct iasecc_extended_tlv compulsory;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iasecc_sdo {
|
struct iasecc_sdo {
|
||||||
unsigned char sdo_class;
|
unsigned char sdo_class;
|
||||||
unsigned char sdo_ref;
|
unsigned char sdo_ref;
|
||||||
@ -244,8 +244,6 @@ struct iasecc_sdo_update {
|
|||||||
|
|
||||||
struct iasecc_extended_tlv fields[IASECC_SDO_TAGS_UPDATE_MAX];
|
struct iasecc_extended_tlv fields[IASECC_SDO_TAGS_UPDATE_MAX];
|
||||||
|
|
||||||
unsigned char acl_method, acl_ref;
|
|
||||||
|
|
||||||
unsigned magic;
|
unsigned magic;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -294,6 +292,16 @@ enum IASECC_KEY_TYPE {
|
|||||||
IASECC_SDO_CLASS_RSA_PUB = 0x20
|
IASECC_SDO_CLASS_RSA_PUB = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct iasecc_sm_cmd_update_binary {
|
||||||
|
const unsigned char *data;
|
||||||
|
size_t offs, count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iasecc_sm_cmd_create_file {
|
||||||
|
const unsigned char *data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
struct sc_card;
|
struct sc_card;
|
||||||
int iasecc_sdo_convert_acl(struct sc_card *, struct iasecc_sdo *, unsigned char, unsigned *, unsigned *);
|
int iasecc_sdo_convert_acl(struct sc_card *, struct iasecc_sdo *, unsigned char, unsigned *, unsigned *);
|
||||||
void iasecc_sdo_free_fields(struct sc_card *, struct iasecc_sdo *);
|
void iasecc_sdo_free_fields(struct sc_card *, struct iasecc_sdo *);
|
||||||
@ -303,12 +311,24 @@ int iasecc_sdo_parse(struct sc_card *, unsigned char *, size_t, struct iasecc_sd
|
|||||||
int iasecc_sdo_allocate_and_parse(struct sc_card *, unsigned char *, size_t, struct iasecc_sdo **);
|
int iasecc_sdo_allocate_and_parse(struct sc_card *, unsigned char *, size_t, struct iasecc_sdo **);
|
||||||
int iasecc_encode_size(size_t, unsigned char *);
|
int iasecc_encode_size(size_t, unsigned char *);
|
||||||
int iasecc_sdo_encode_create(struct sc_context*, struct iasecc_sdo *, unsigned char **);
|
int iasecc_sdo_encode_create(struct sc_context*, struct iasecc_sdo *, unsigned char **);
|
||||||
int iasecc_sdo_encode_update_field(struct sc_context *, unsigned char, unsigned char,
|
int iasecc_sdo_encode_update_field(struct sc_context *, unsigned char, unsigned char,
|
||||||
struct iasecc_extended_tlv *, unsigned char **);
|
struct iasecc_extended_tlv *, unsigned char **);
|
||||||
int iasecc_se_get_crt(struct sc_card *, struct iasecc_se_info *, struct sc_crt *);
|
int iasecc_se_get_crt(struct sc_card *, struct iasecc_se_info *, struct sc_crt *);
|
||||||
int iasecc_se_get_crt_by_usage(struct sc_card *, struct iasecc_se_info *,
|
int iasecc_se_get_crt_by_usage(struct sc_card *, struct iasecc_se_info *,
|
||||||
unsigned char, unsigned char, struct sc_crt *);
|
unsigned char, unsigned char, struct sc_crt *);
|
||||||
int iasecc_sdo_encode_rsa_update(struct sc_context *, struct iasecc_sdo *, struct sc_pkcs15_prkey_rsa *, struct iasecc_sdo_update *);
|
int iasecc_sdo_encode_rsa_update(struct sc_context *, struct iasecc_sdo *, struct sc_pkcs15_prkey_rsa *, struct iasecc_sdo_update *);
|
||||||
int iasecc_sdo_parse_card_answer(struct sc_context *, unsigned char *, size_t, struct iasecc_sm_card_answer *);
|
int iasecc_sdo_parse_card_answer(struct sc_context *, unsigned char *, size_t, struct iasecc_sm_card_answer *);
|
||||||
int iasecc_docp_copy(struct sc_context *, struct iasecc_sdo_docp *, struct iasecc_sdo_docp *);
|
int iasecc_docp_copy(struct sc_context *, struct iasecc_sdo_docp *, struct iasecc_sdo_docp *);
|
||||||
|
int iasecc_se_get_info(struct sc_card *card, struct iasecc_se_info *se);
|
||||||
|
|
||||||
|
int iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *tries_left);
|
||||||
|
int iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data, int *tries_left);
|
||||||
|
int iasecc_sm_pin_reset(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data);
|
||||||
|
int iasecc_sm_update_binary(struct sc_card *card, unsigned se_num, size_t offs, const unsigned char *buff, size_t count);
|
||||||
|
int iasecc_sm_read_binary(struct sc_card *card, unsigned se_num, size_t offs, unsigned char *buff, size_t count);
|
||||||
|
int iasecc_sm_create_file(struct sc_card *card, unsigned se_num, unsigned char *fcp, size_t fcp_len);
|
||||||
|
int iasecc_sm_delete_file(struct sc_card *card, unsigned se_num, unsigned int file_id);
|
||||||
|
int iasecc_sm_rsa_generate(struct sc_card *card, unsigned se_num, struct iasecc_sdo *sdo);
|
||||||
|
int iasecc_sm_rsa_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_rsa_update *udata);
|
||||||
|
int iasecc_sm_sdo_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_update *update);
|
||||||
#endif
|
#endif
|
||||||
|
728
src/libopensc/iasecc-sm.c
Normal file
728
src/libopensc/iasecc-sm.c
Normal file
@ -0,0 +1,728 @@
|
|||||||
|
/*
|
||||||
|
* iasecc.h Support for IAS/ECC smart cards
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Viktor Tarasov <vtarasov@opentrust.com>
|
||||||
|
* OpenTrust <www.opentrust.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "asn1.h"
|
||||||
|
#include "cardctl.h"
|
||||||
|
|
||||||
|
#ifndef ENABLE_OPENSSL
|
||||||
|
#error "Need OpenSSL"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sm.h"
|
||||||
|
#include "iasecc.h"
|
||||||
|
#include "authentic.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
static int
|
||||||
|
sm_save_sc_context (struct sc_card *card, struct sm_info *sm_info)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
struct sc_card_cache *cache = &card->cache;
|
||||||
|
|
||||||
|
if (!card || !sm_info)
|
||||||
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
sc_log(ctx, "SM save context: cache(valid:%i,current_df:%p)", cache->valid, cache->current_df);
|
||||||
|
if (cache->valid && cache->current_df) {
|
||||||
|
sm_info->current_path_df = cache->current_df->path;
|
||||||
|
if (cache->current_df->path.type == SC_PATH_TYPE_DF_NAME) {
|
||||||
|
if (cache->current_df->path.aid.len) {
|
||||||
|
sm_info->current_aid = cache->current_df->path.aid;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(sm_info->current_aid.value, cache->current_df->path.value, cache->current_df->path.len);
|
||||||
|
sm_info->current_aid.len = cache->current_df->path.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->valid && cache->current_ef)
|
||||||
|
sm_info->current_path_ef = cache->current_ef->path;
|
||||||
|
|
||||||
|
return SC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
sm_restore_sc_context(struct sc_card *card, struct sm_info *sm_info)
|
||||||
|
{
|
||||||
|
int rv = SC_SUCCESS;
|
||||||
|
|
||||||
|
if (sm_info->current_path_df.type == SC_PATH_TYPE_DF_NAME && sm_info->current_path_df.len)
|
||||||
|
rv = sc_select_file(card, &sm_info->current_path_df, NULL);
|
||||||
|
|
||||||
|
if (sm_info->current_path_ef.len && rv == SC_SUCCESS)
|
||||||
|
rv = sc_select_file(card, &sm_info->current_path_ef, NULL);
|
||||||
|
|
||||||
|
memset(&sm_info->current_path_df, 0, sizeof(sm_info->current_path_df));
|
||||||
|
memset(&sm_info->current_path_ef, 0, sizeof(sm_info->current_path_ef));
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
iasecc_sm_transmit_apdus(struct sc_card *card, struct sc_remote_data *rdata,
|
||||||
|
unsigned char *out, size_t *out_len)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sc_remote_apdu *rapdu = rdata->data;
|
||||||
|
int rv = SC_SUCCESS, offs = 0;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_transmit_apdus() rdata-length %i", rdata->length);
|
||||||
|
|
||||||
|
while (rapdu) {
|
||||||
|
sc_log(ctx, "iasecc_sm_transmit_apdus() rAPDU flags 0x%X", rapdu->apdu.flags);
|
||||||
|
rv = sc_transmit_apdu(card, &rapdu->apdu);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_transmit_apdus() failed to execute r-APDU");
|
||||||
|
rv = sc_check_sw(card, rapdu->apdu.sw1, rapdu->apdu.sw2);
|
||||||
|
if (rv < 0 && !(rapdu->flags & SC_REMOTE_APDU_FLAG_NOT_FATAL))
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_transmit_apdus() fatal error %i");
|
||||||
|
|
||||||
|
if (out && out_len && (rapdu->flags & SC_REMOTE_APDU_FLAG_RETURN_ANSWER)) {
|
||||||
|
int len = rapdu->apdu.resplen > (*out_len - offs) ? (*out_len - offs) : rapdu->apdu.resplen;
|
||||||
|
|
||||||
|
memcpy(out + offs, rapdu->apdu.resp, len);
|
||||||
|
offs += len;
|
||||||
|
/* TODO: decode and gather data answers */
|
||||||
|
}
|
||||||
|
|
||||||
|
rapdu = rapdu->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_len)
|
||||||
|
*out_len = offs;
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of SM and External Authentication");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Big TODO: do SM release in all handles, clean the saved card context -- current DF, EF, etc. */
|
||||||
|
static int
|
||||||
|
sm_release (struct sc_card *card, struct sc_remote_data *rdata,
|
||||||
|
unsigned char *out, size_t out_len)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
if (!card->sm_ctx.module.ops.finalize)
|
||||||
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||||
|
|
||||||
|
rv = card->sm_ctx.module.ops.finalize(ctx, sm_info, rdata, out, out_len);
|
||||||
|
|
||||||
|
sm_restore_sc_context(card, sm_info);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of SM and External Authentication");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *tries_left)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
struct sc_apdu apdu;
|
||||||
|
unsigned char sbuf[0x100];
|
||||||
|
int rv, offs;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_external_authentication(): SKey ref %i", skey_ref);
|
||||||
|
|
||||||
|
if (card->sm_ctx.sm_mode == SM_MODE_NONE)
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot do 'External Authentication' without SM activated ");
|
||||||
|
|
||||||
|
strncpy(sm_info->config_section, card->sm_ctx.config_section, sizeof(sm_info->config_section));
|
||||||
|
sm_info->cmd = SM_CMD_EXTERNAL_AUTH;
|
||||||
|
sm_info->serialnr = card->serialnr;
|
||||||
|
sm_info->card_type = card->type;
|
||||||
|
sm_info->sm_type = SM_TYPE_CWA14890;
|
||||||
|
sm_info->sm_params.cwa.crt_at.usage = IASECC_UQB_AT_EXTERNAL_AUTHENTICATION;
|
||||||
|
sm_info->sm_params.cwa.crt_at.algo = IASECC_ALGORITHM_ROLE_AUTH;
|
||||||
|
sm_info->sm_params.cwa.crt_at.refs[0] = skey_ref;
|
||||||
|
|
||||||
|
offs = 0;
|
||||||
|
sbuf[offs++] = IASECC_CRT_TAG_ALGO;
|
||||||
|
sbuf[offs++] = 0x01;
|
||||||
|
sbuf[offs++] = IASECC_ALGORITHM_ROLE_AUTH;
|
||||||
|
sbuf[offs++] = IASECC_CRT_TAG_REFERENCE;
|
||||||
|
sbuf[offs++] = 0x01;
|
||||||
|
sbuf[offs++] = skey_ref;
|
||||||
|
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x81, 0xA4);
|
||||||
|
apdu.data = sbuf;
|
||||||
|
apdu.datalen = offs;
|
||||||
|
apdu.lc = offs;
|
||||||
|
|
||||||
|
rv = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): APDU transmit failed");
|
||||||
|
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
|
||||||
|
|
||||||
|
rv = sc_get_challenge(card, sm_info->schannel.card_challenge, sizeof(sm_info->schannel.card_challenge));
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
|
||||||
|
if (!card->sm_ctx.module.ops.initialize)
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_SM_NOT_INITIALIZED, "No SM module");
|
||||||
|
rv = card->sm_ctx.module.ops.initialize(ctx, sm_info, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "SM: INITIALIZE failed");
|
||||||
|
|
||||||
|
sc_log(ctx, "sm_iasecc_external_authentication(): rdata length %i\n", rdata.length);
|
||||||
|
|
||||||
|
rv = iasecc_sm_transmit_apdus (card, &rdata, NULL, 0);
|
||||||
|
if (rv == SC_ERROR_PIN_CODE_INCORRECT && tries_left)
|
||||||
|
*tries_left = (rdata.data + rdata.length - 1)->apdu.sw2 & 0x0F;
|
||||||
|
LOG_TEST_RET(ctx, rv, "sm_iasecc_external_authentication(): execute failed");
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of SM and External Authentication");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct iasecc_se_info se;
|
||||||
|
struct sc_crt *crt = &sm_info->sm_params.cwa.crt_at;
|
||||||
|
struct sc_apdu apdu;
|
||||||
|
unsigned char sbuf[0x100];
|
||||||
|
int rv, offs;
|
||||||
|
|
||||||
|
memset(&se, 0, sizeof(se));
|
||||||
|
|
||||||
|
se.reference = se_num;
|
||||||
|
crt->usage = IASECC_UQB_AT_MUTUAL_AUTHENTICATION;
|
||||||
|
crt->tag = IASECC_CRT_TAG_AT;
|
||||||
|
|
||||||
|
rv = iasecc_se_get_info(card, &se);
|
||||||
|
LOG_TEST_RET(ctx, rv, "Get SE info error");
|
||||||
|
|
||||||
|
rv = iasecc_se_get_crt(card, &se, crt);
|
||||||
|
LOG_TEST_RET(ctx, rv, "Cannot get authentication CRT");
|
||||||
|
|
||||||
|
if (se.df)
|
||||||
|
sc_file_free(se.df);
|
||||||
|
|
||||||
|
/* MSE SET Mutual Authentication SK scheme */
|
||||||
|
offs = 0;
|
||||||
|
sbuf[offs++] = IASECC_CRT_TAG_ALGO;
|
||||||
|
sbuf[offs++] = 0x01;
|
||||||
|
sbuf[offs++] = crt->algo;
|
||||||
|
sbuf[offs++] = IASECC_CRT_TAG_REFERENCE;
|
||||||
|
sbuf[offs++] = 0x01;
|
||||||
|
sbuf[offs++] = crt->refs[0];
|
||||||
|
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0xA4);
|
||||||
|
apdu.data = sbuf;
|
||||||
|
apdu.datalen = offs;
|
||||||
|
apdu.lc = offs;
|
||||||
|
|
||||||
|
rv = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(ctx, rv, "SM set SE mutual auth.: APDU transmit failed");
|
||||||
|
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||||
|
LOG_TEST_RET(ctx, rv, "SM set SE mutual auth.: set SE error");
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
iasecc_sm_get_challenge(struct sc_card *card, unsigned char *out, size_t len)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
struct sc_apdu apdu;
|
||||||
|
unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
sc_log(ctx, "SM get challenge: length %i",len);
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0, 0);
|
||||||
|
apdu.le = len;
|
||||||
|
apdu.resplen = len;
|
||||||
|
apdu.resp = rbuf;
|
||||||
|
|
||||||
|
rv = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(ctx, rv, "APDU transmit failed");
|
||||||
|
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||||
|
LOG_TEST_RET(ctx, rv, "Command failed");
|
||||||
|
|
||||||
|
memcpy(out, rbuf, apdu.resplen);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, apdu.resplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sm_cwa_session *cwa_session = &sm_info->schannel.session.cwa;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
|
||||||
|
strncpy(sm_info->config_section, card->sm_ctx.config_section, sizeof(sm_info->config_section));
|
||||||
|
sm_info->cmd = cmd;
|
||||||
|
sm_info->serialnr = card->serialnr;
|
||||||
|
sm_info->card_type = card->type;
|
||||||
|
sm_info->sm_type = SM_TYPE_CWA14890;
|
||||||
|
|
||||||
|
rv = iasecc_sm_se_mutual_authentication(card, se_num);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() MUTUAL AUTHENTICATION failed");
|
||||||
|
|
||||||
|
rv = iasecc_sm_get_challenge(card, sm_info->schannel.card_challenge, SM_SMALL_CHALLENGE_LEN);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() GET CHALLENGE failed");
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
|
||||||
|
rv = sm_save_sc_context(card, sm_info);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() cannot save current context");
|
||||||
|
|
||||||
|
if (!card->sm_ctx.module.ops.initialize)
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_SM_NOT_INITIALIZED, "iasecc_sm_initialize() no SM module");
|
||||||
|
rv = card->sm_ctx.module.ops.initialize(ctx, sm_info, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() INITIALIZE failed");
|
||||||
|
|
||||||
|
|
||||||
|
if (rdata.length == 1) {
|
||||||
|
rdata.data->flags |= SC_REMOTE_APDU_FLAG_RETURN_ANSWER;
|
||||||
|
rdata.data->apdu.flags &= ~SC_APDU_FLAGS_NO_GET_RESP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "TODO: SM init with more then one APDU");
|
||||||
|
}
|
||||||
|
|
||||||
|
cwa_session->mdata_len = sizeof(cwa_session->mdata);
|
||||||
|
rv = iasecc_sm_transmit_apdus (card, &rdata, cwa_session->mdata, &cwa_session->mdata_len);
|
||||||
|
if (rv == SC_ERROR_PIN_CODE_INCORRECT)
|
||||||
|
sc_log(ctx, "SM initialization failed, %i tries left", (rdata.data + rdata.length - 1)->apdu.sw2 & 0x0F);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() trasmit APDUs failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
|
||||||
|
sc_log(ctx, "MA data(len:%i) '%s'", cwa_session->mdata_len, sc_dump_hex(cwa_session->mdata, cwa_session->mdata_len));
|
||||||
|
if (sm_info->schannel.session.cwa.mdata_len != 0x48)
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "iasecc_sm_initialize() invalid MUTUAL AUTHENTICATE result data");
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
iasecc_sm_cmd(struct sc_card *card, struct sc_remote_data *rdata)
|
||||||
|
{
|
||||||
|
#define AUTH_SM_APDUS_MAX 12
|
||||||
|
#define ENCODED_APDUS_MAX_LENGTH (AUTH_SM_APDUS_MAX * (SC_MAX_APDU_BUFFER_SIZE * 2 + 64) + 32)
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sm_cwa_session *session = &sm_info->schannel.session.cwa;
|
||||||
|
struct sc_remote_apdu *rapdu = NULL;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
if (!card->sm_ctx.module.ops.get_apdus)
|
||||||
|
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
rv = card->sm_ctx.module.ops.get_apdus(ctx, sm_info, session->mdata, session->mdata_len, rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_cmd() 'GET APDUS' failed");
|
||||||
|
|
||||||
|
sc_log(ctx, "iasecc_sm_cmd() %i remote APDUs to transmit", rdata->length);
|
||||||
|
for (rapdu = rdata->data; rapdu; rapdu = rapdu->next) {
|
||||||
|
struct sc_apdu *apdu = &rapdu->apdu;
|
||||||
|
|
||||||
|
sc_log(ctx, "iasecc_sm_cmd() apdu->ins:0x%X, resplen %i", apdu->ins, apdu->resplen);
|
||||||
|
if (!apdu->ins)
|
||||||
|
break;
|
||||||
|
rv = sc_transmit_apdu(card, apdu);
|
||||||
|
if (rv < 0) {
|
||||||
|
sc_log(ctx, "iasecc_sm_cmd() APDU transmit error rv:%i", rv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = sc_check_sw(card, apdu->sw1, apdu->sw2);
|
||||||
|
if (rv < 0 && !(rapdu->flags & SC_REMOTE_APDU_FLAG_NOT_FATAL)) {
|
||||||
|
sc_log(ctx, "iasecc_sm_cmd() APDU error rv:%i", rv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sc_log(ctx, "iasecc_sm_cmd() apdu->resplen %i", apdu->resplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_rsa_generate(struct sc_card *card, unsigned se_num, struct iasecc_sdo *sdo)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_rsa_generate() SE#%i, SDO(class:%X,ref:%X)", se_num, sdo->sdo_class, sdo->sdo_ref);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_RSA_GENERATE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM initialize failed");
|
||||||
|
|
||||||
|
sm_info->cmd_data = sdo;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM cmd failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_rsa_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_rsa_update *udata)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "SM update RSA: SE#: 0x%X, SDO(class:0x%X:ref:%X)", se_num,
|
||||||
|
udata->sdo_prv_key->sdo_class, udata->sdo_prv_key->sdo_ref);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_RSA_UPDATE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM initialize failed");
|
||||||
|
|
||||||
|
sm_info->cmd_data = udata;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM cmd failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data, int *tries_left)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_pin_verify() SE#%i, PIN(ref:%i,len:%i)", se_num, data->pin_reference, data->pin1.len);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_PIN_VERIFY);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
sm_info->cmd_data = data;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
if (rv && rdata.length && tries_left)
|
||||||
|
if (rdata.data->apdu.sw1 == 0x63 && (rdata.data->apdu.sw2 & 0xF0) == 0xC0)
|
||||||
|
*tries_left = rdata.data->apdu.sw2 & 0x0F;
|
||||||
|
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM 'PIN VERIFY' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_sdo_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_update *update)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_sdo_update() SE#%i, SDO(class:0x%X,ref:%i)", se_num, update->sdo_class, update->sdo_ref);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_SDO_UPDATE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
sc_log(ctx, "current DF '%s'", sc_print_path(&sm_info->current_path_df));
|
||||||
|
|
||||||
|
sm_info->cmd_data = update;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM 'SDO UPDATE' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_pin_reset(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_pin_reset() SE#%i, PIN(ref:%i,len:%i)", se_num, data->pin_reference, data->pin2.len);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_PIN_RESET);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
sm_info->cmd_data = data;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM 'PIN RESET' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_create_file(struct sc_card *card, unsigned se_num, unsigned char *fcp, size_t fcp_len)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
struct iasecc_sm_cmd_create_file cmd_data;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "iasecc_sm_create_file() SE#%i, fcp(%i) '%s'", se_num, fcp_len, sc_dump_hex(fcp, fcp_len));
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_CREATE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
cmd_data.data = fcp;
|
||||||
|
cmd_data.size = fcp_len;
|
||||||
|
sm_info->cmd_data = &cmd_data;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv= iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM 'UPDATE BINARY' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_read_binary(struct sc_card *card, unsigned se_num, size_t offs, unsigned char *buff, size_t count)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
struct iasecc_sm_cmd_update_binary cmd_data;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "SM read binary: acl:%X, offs:%i, count:%i", se_num, offs, count);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_READ);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
cmd_data.offs = offs;
|
||||||
|
cmd_data.count = count;
|
||||||
|
sm_info->cmd_data = &cmd_data;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM 'READ BINARY' failed");
|
||||||
|
|
||||||
|
sc_log(ctx, "IAS/ECC decode answer() rdata length %i", rdata.length);
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, buff, count);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_update_binary(struct sc_card *card, unsigned se_num, size_t offs,
|
||||||
|
const unsigned char *buff, size_t count)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
struct iasecc_sm_cmd_update_binary cmd_data;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "SM update binary: acl:%X, offs:%i, count:%i", se_num, offs, count);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_UPDATE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
cmd_data.offs = offs;
|
||||||
|
cmd_data.count = count;
|
||||||
|
cmd_data.data = buff;
|
||||||
|
sm_info->cmd_data = &cmd_data;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM 'UPDATE BINARY' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, count);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
iasecc_sm_delete_file(struct sc_card *card, unsigned se_num, unsigned int file_id)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
|
struct sm_info *sm_info = &card->sm_ctx.info;
|
||||||
|
struct sc_remote_data rdata;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
sc_log(ctx, "SM delete file: SE#:%X, file-id:%X", se_num, file_id);
|
||||||
|
|
||||||
|
rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_DELETE);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM INITIALIZE failed");
|
||||||
|
|
||||||
|
sm_info->cmd_data = (void *)file_id;
|
||||||
|
|
||||||
|
sc_remote_data_init(&rdata);
|
||||||
|
rv = iasecc_sm_cmd(card, &rdata);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM 'FILE DELETE' failed");
|
||||||
|
|
||||||
|
rv = sm_release (card, &rdata, NULL, 0);
|
||||||
|
LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM release failed");
|
||||||
|
|
||||||
|
rdata.free(&rdata);
|
||||||
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
|
#else
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
|
||||||
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -302,3 +302,14 @@ sc_crc32
|
|||||||
sc_pkcs15_convert_prkey
|
sc_pkcs15_convert_prkey
|
||||||
sc_pkcs15_convert_pubkey
|
sc_pkcs15_convert_pubkey
|
||||||
sc_perform_pace
|
sc_perform_pace
|
||||||
|
iasecc_sdo_encode_update_field
|
||||||
|
iasecc_sm_create_file
|
||||||
|
iasecc_sm_delete_file
|
||||||
|
iasecc_sm_external_authentication
|
||||||
|
iasecc_sm_pin_reset
|
||||||
|
iasecc_sm_pin_verify
|
||||||
|
iasecc_sm_read_binary
|
||||||
|
iasecc_sm_rsa_generate
|
||||||
|
iasecc_sm_rsa_update
|
||||||
|
iasecc_sm_update_binary
|
||||||
|
iasecc_sm_sdo_update
|
||||||
|
Loading…
Reference in New Issue
Block a user