libopensc: parse content of the EF(ATR) file

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5059 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
vtarasov 2011-01-07 15:49:10 +00:00
parent 65cd456256
commit bf4aa793af
7 changed files with 194 additions and 2 deletions

View File

@ -19,7 +19,7 @@ INCLUDES = -I$(top_srcdir)/src
libopensc_la_SOURCES = \
sc.c ctx.c log.c errors.c \
asn1.c base64.c sec.c card.c iso7816.c dir.c padding.c apdu.c \
asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c padding.c apdu.c \
\
pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \
pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \

View File

@ -3,7 +3,7 @@ TOPDIR = ..\..
TARGET = opensc.dll opensc_a.lib
OBJECTS = \
sc.obj ctx.obj log.obj errors.obj \
asn1.obj base64.obj sec.obj card.obj iso7816.obj dir.obj padding.obj apdu.obj \
asn1.obj base64.obj sec.obj card.obj iso7816.obj dir.obj ef-atr.obj padding.obj apdu.obj \
\
pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \
pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-sec.obj \

View File

@ -87,6 +87,7 @@ static sc_card_t * sc_card_new(sc_context_t *ctx)
static void sc_card_free(sc_card_t *card)
{
sc_free_apps(card);
sc_free_ef_atr(card);
if (card->ef_dir != NULL)
sc_file_free(card->ef_dir);
free(card->ops);

152
src/libopensc/ef-atr.c Normal file
View File

@ -0,0 +1,152 @@
/*
* ef-atr.c: Stuff for handling EF(ATR)
*
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
* 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
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "internal.h"
#include "asn1.h"
#include "iso7816.h"
static int
sc_parse_ef_atr_content(struct sc_card *card, unsigned char *buf, size_t buflen)
{
struct sc_context *ctx = card->ctx;
const unsigned char *tag = NULL;
size_t taglen;
struct sc_ef_atr ef_atr;
LOG_FUNC_CALLED(ctx);
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_CARD_SERVICE, &taglen);
if (tag && taglen >= 1) {
ef_atr.card_service = *tag;
sc_log(ctx, "From EF.ATR: card service 0x%X", ef_atr.card_service);
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_PRE_ISSUING, &taglen);
if (tag && taglen >= 4) {
ef_atr.ic_manufacturer = *(tag + 0);
ef_atr.ic_type = *(tag + 1);
ef_atr.os_version = *(tag + 2);
ef_atr.iasecc_version = *(tag + 3);
sc_log(ctx, "From EF.ATR: IC manufacturer/type %X/%X, OS/IasEcc versions %X/%X",
ef_atr.ic_manufacturer, ef_atr.ic_type,
ef_atr.os_version, ef_atr.iasecc_version);
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_CARD_CAPABILITIES, &taglen);
if (tag && taglen >= 3) {
ef_atr.df_selection = *(tag + 0);
ef_atr.unit_size = *(tag + 1);
ef_atr.card_capabilities = *(tag + 2);
sc_log(ctx, "From EF.ATR: DF selection %X, unit_size %X, card caps %X",
ef_atr.df_selection, ef_atr.unit_size, ef_atr.card_capabilities);
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_AID, &taglen);
if (tag) {
if (taglen > sizeof(ef_atr.aid.value))
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid MF AID size");
memcpy(ef_atr.aid.value, tag, taglen);
ef_atr.aid.len = taglen;
sc_log(ctx, "From EF.ATR: AID(%i) %s", ef_atr.aid.len,
sc_dump_hex(ef_atr.aid.value, ef_atr.aid.len));
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_IO_BUFFER_SIZES, &taglen);
if (tag && taglen >= 0x10) {
ef_atr.max_size_send = *(tag + 2) * 0x100 + *(tag + 3);
ef_atr.max_size_send_sc = *(tag + 6) * 0x100 + *(tag + 7);
ef_atr.max_size_recv = *(tag + 10) * 0x100 + *(tag + 11);
ef_atr.max_size_recv_sc = *(tag + 14) * 0x100 + *(tag + 15);
/* FIXME: tell me why '-5' */
card->max_send_size = ef_atr.max_size_send - 5;
card->max_recv_size = ef_atr.max_size_recv;
sc_log(ctx, "From EF.ATR: mas send/recv size %X/%X", card->max_send_size, card->max_recv_size);
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_ALLOCATION_SCHEME, &taglen);
if (tag && taglen < sizeof(ef_atr.allocation_oid)) {
sc_log(ctx, "From EF.ATR: OID %s", sc_dump_hex(tag, sizeof(taglen)));
memcpy(ef_atr.allocation_oid.value, tag, taglen);
}
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_STATUS, &taglen);
if (tag && taglen == 2) {
ef_atr.status = *(tag + 0) * 0x100 + *(tag + 1);
sc_log(ctx, "From EF.ATR: status word 0x%X", ef_atr.status);
}
if (!card->ef_atr)
card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
if (!card->ef_atr)
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
memcpy(card->ef_atr, &ef_atr, sizeof(struct sc_ef_atr));
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
int sc_parse_ef_atr(struct sc_card *card)
{
struct sc_context *ctx = card->ctx;
struct sc_path path;
struct sc_file *file;
int rv;
unsigned char *buf = NULL;
LOG_FUNC_CALLED(ctx);
sc_format_path("3F002F01", &path);
rv = sc_select_file(card, &path, &file);
if (rv == SC_ERROR_FILE_NOT_FOUND)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
LOG_TEST_RET(ctx, rv, "Cannot select EF(ATR) file");
buf = malloc(file->size);
if (!buf)
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Memory allocation error");
rv = sc_read_binary(card, 0, buf, file->size, 0);
LOG_TEST_RET(ctx, rv, "Cannot read EF(ATR) file");
rv = sc_parse_ef_atr_content(card, buf, file->size);
LOG_TEST_RET(ctx, rv, "EF(ATR) parse error");
free(buf);
sc_file_free(file);
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
void sc_free_ef_atr(sc_card_t *card)
{
if (card->ef_atr)
free(card->ef_atr);
card->ef_atr = NULL;
}

View File

@ -15,6 +15,16 @@ extern "C" {
#define ISO7816_TAG_FCP_ID 0x83
#define ISO7816_TAG_FCP_ACLS 0x86
/* Interindustry data tags */
#define ISO7816_TAG_II_CARD_SERVICE 0x43
#define ISO7816_TAG_II_INITIAL_ACCESS_DATA 0x44
#define ISO7816_TAG_II_CARD_ISSUER_DATA 0x45
#define ISO7816_TAG_II_PRE_ISSUING 0x46
#define ISO7816_TAG_II_CARD_CAPABILITIES 0x47
#define ISO7816_TAG_II_AID 0x4F
#define ISO7816_TAG_II_IO_BUFFER_SIZES 0xE0
#define ISO7816_TAG_II_ALLOCATION_SCHEME 0x78
#define ISO7816_TAG_II_STATUS 0x82
#define ISO7816_FILE_TYPE_TRANSPARENT_EF 0x01
#define ISO7816_FILE_TYPE_DF 0x38

View File

@ -80,6 +80,7 @@ sc_disconnect_card
sc_do_log
_sc_debug
sc_enum_apps
sc_parse_ef_atr
sc_establish_context
sc_file_add_acl_entry
sc_file_clear_acl_entries
@ -98,6 +99,7 @@ sc_format_asn1_entry
sc_format_oid
sc_format_path
sc_free_apps
sc_free_ef_atr
sc_get_cache_dir
sc_get_challenge
sc_get_conf_block

View File

@ -217,6 +217,29 @@ typedef struct sc_app_info {
int rec_nr; /* -1, if EF(DIR) is transparent */
} sc_app_info_t;
struct sc_ef_atr {
unsigned char card_service;
unsigned char ic_manufacturer;
unsigned char ic_type;
unsigned char os_version;
unsigned char iasecc_version;
unsigned char df_selection;
size_t unit_size;
unsigned char card_capabilities;
struct sc_aid aid;
size_t max_size_send;
size_t max_size_send_sc;
size_t max_size_recv;
size_t max_size_recv_sc;
struct sc_object_id allocation_oid;
unsigned status;
};
struct sc_card_cache {
struct sc_path current_path;
@ -431,6 +454,8 @@ typedef struct sc_card {
int app_count;
struct sc_file *ef_dir;
struct sc_ef_atr *ef_atr;
struct sc_algorithm_info *algorithms;
int algorithm_count;
@ -1120,6 +1145,8 @@ int sc_make_cache_dir(sc_context_t *ctx);
int sc_enum_apps(sc_card_t *card);
void sc_free_apps(sc_card_t *card);
int sc_parse_ef_atr(sc_card_t *card);
void sc_free_ef_atr(sc_card_t *card);
int sc_update_dir(sc_card_t *card, sc_app_info_t *app);
struct sc_algorithm_info * sc_card_find_rsa_alg(sc_card_t *card,