- added sc_update_binary(), sc_append_binary() and
sc_write_binary() with their corresponding ISO 7816-4 reference functions git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@216 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
e78dc96440
commit
d2a36c88fd
|
@ -761,6 +761,45 @@ int sc_read_record(struct sc_card *card, unsigned int rec_nr, u8 *buf,
|
|||
SC_FUNC_RETURN(card->ctx, 2, r);
|
||||
}
|
||||
|
||||
int sc_write_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf,
|
||||
size_t count, unsigned long flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(card != NULL);
|
||||
SC_FUNC_CALLED(card->ctx, 2);
|
||||
if (card->ops->write_record == NULL)
|
||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
|
||||
r = card->ops->write_record(card, rec_nr, buf, count, flags);
|
||||
SC_FUNC_RETURN(card->ctx, 2, r);
|
||||
}
|
||||
|
||||
int sc_append_record(struct sc_card *card, const u8 * buf, size_t count,
|
||||
unsigned long flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(card != NULL);
|
||||
SC_FUNC_CALLED(card->ctx, 2);
|
||||
if (card->ops->append_record == NULL)
|
||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
|
||||
r = card->ops->append_record(card, buf, count, flags);
|
||||
SC_FUNC_RETURN(card->ctx, 2, r);
|
||||
}
|
||||
|
||||
int sc_update_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf,
|
||||
size_t count, unsigned long flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(card != NULL);
|
||||
SC_FUNC_CALLED(card->ctx, 2);
|
||||
if (card->ops->update_record == NULL)
|
||||
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
|
||||
r = card->ops->update_record(card, rec_nr, buf, count, flags);
|
||||
SC_FUNC_RETURN(card->ctx, 2, r);
|
||||
}
|
||||
|
||||
inline int sc_card_valid(const struct sc_card *card) {
|
||||
#ifndef NDEBUG
|
||||
assert(card != NULL);
|
||||
|
|
|
@ -123,8 +123,8 @@ static int iso7816_read_record(struct sc_card *card,
|
|||
int r;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, rec_nr, 0);
|
||||
apdu.p2 = (flags & SC_READ_RECORD_EF_ID_MASK) << 3;
|
||||
if (flags & SC_READ_RECORD_BY_REC_NR)
|
||||
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
|
||||
if (flags & SC_RECORD_BY_REC_NR)
|
||||
apdu.p2 |= 0x04;
|
||||
|
||||
apdu.le = count;
|
||||
|
@ -140,6 +140,85 @@ static int iso7816_read_record(struct sc_card *card,
|
|||
SC_FUNC_RETURN(card->ctx, 3, apdu.resplen);
|
||||
}
|
||||
|
||||
static int iso7816_write_record(struct sc_card *card, unsigned int rec_nr,
|
||||
const u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct sc_apdu apdu;
|
||||
int r;
|
||||
|
||||
if (count > 256) {
|
||||
error(card->ctx, "Trying to send too many bytes\n");
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD2, rec_nr, 0);
|
||||
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
|
||||
if (flags & SC_RECORD_BY_REC_NR)
|
||||
apdu.p2 |= 0x04;
|
||||
|
||||
apdu.lc = count;
|
||||
apdu.datalen = count;
|
||||
apdu.data = buf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
|
||||
"Card returned error");
|
||||
SC_FUNC_RETURN(card->ctx, 3, count);
|
||||
}
|
||||
|
||||
static int iso7816_append_record(struct sc_card *card,
|
||||
const u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct sc_apdu apdu;
|
||||
int r;
|
||||
|
||||
if (count > 256) {
|
||||
error(card->ctx, "Trying to send too many bytes\n");
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE2, 0, 0);
|
||||
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
|
||||
|
||||
apdu.lc = count;
|
||||
apdu.datalen = count;
|
||||
apdu.data = buf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
|
||||
"Card returned error");
|
||||
SC_FUNC_RETURN(card->ctx, 3, count);
|
||||
}
|
||||
|
||||
static int iso7816_update_record(struct sc_card *card, unsigned int rec_nr,
|
||||
const u8 *buf, size_t count,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct sc_apdu apdu;
|
||||
int r;
|
||||
|
||||
if (count > 256) {
|
||||
error(card->ctx, "Trying to send too many bytes\n");
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0);
|
||||
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
|
||||
if (flags & SC_RECORD_BY_REC_NR)
|
||||
apdu.p2 |= 0x04;
|
||||
|
||||
apdu.lc = count;
|
||||
apdu.datalen = count;
|
||||
apdu.data = buf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
|
||||
"Card returned error");
|
||||
SC_FUNC_RETURN(card->ctx, 3, count);
|
||||
}
|
||||
|
||||
static int iso7816_write_binary(struct sc_card *card,
|
||||
unsigned int idx, const u8 *buf,
|
||||
size_t count, unsigned long flags)
|
||||
|
@ -766,6 +845,9 @@ const struct sc_card_driver * sc_get_iso7816_driver(void)
|
|||
iso_ops.match_card = no_match;
|
||||
iso_ops.read_binary = iso7816_read_binary;
|
||||
iso_ops.read_record = iso7816_read_record;
|
||||
iso_ops.write_record = iso7816_write_record;
|
||||
iso_ops.append_record = iso7816_append_record;
|
||||
iso_ops.update_record = iso7816_update_record;
|
||||
iso_ops.write_binary = iso7816_write_binary;
|
||||
iso_ops.update_binary = iso7816_update_binary;
|
||||
iso_ops.select_file = iso7816_select_file;
|
||||
|
|
|
@ -138,11 +138,11 @@ extern "C" {
|
|||
|
||||
#define SC_MAX_AC_OPS 7
|
||||
|
||||
/* sc_read_record() flags */
|
||||
#define SC_READ_RECORD_EF_ID_MASK 0x0001F
|
||||
#define SC_READ_RECORD_BY_REC_ID 0x00000
|
||||
#define SC_READ_RECORD_BY_REC_NR 0x00100
|
||||
#define SC_READ_RECORD_CURRENT 0
|
||||
/* sc_*_record() flags */
|
||||
#define SC_RECORD_EF_ID_MASK 0x0001F
|
||||
#define SC_RECORD_BY_REC_ID 0x00000
|
||||
#define SC_RECORD_BY_REC_NR 0x00100
|
||||
#define SC_RECORD_CURRENT 0
|
||||
|
||||
/* various maximum values */
|
||||
#define SC_MAX_CARD_DRIVERS 16
|
||||
|
@ -327,8 +327,15 @@ struct sc_card_operations {
|
|||
const u8 * buf, size_t count, unsigned long flags);
|
||||
int (*erase_binary)(struct sc_card *card, unsigned int idx,
|
||||
size_t count, unsigned long flags);
|
||||
|
||||
int (*read_record)(struct sc_card *card, unsigned int rec_nr,
|
||||
u8 * buf, size_t count, unsigned long flags);
|
||||
int (*write_record)(struct sc_card *card, unsigned int rec_nr,
|
||||
const u8 * buf, size_t count, unsigned long flags);
|
||||
int (*append_record)(struct sc_card *card, const u8 * buf,
|
||||
size_t count, unsigned long flags);
|
||||
int (*update_record)(struct sc_card *card, unsigned int rec_nr,
|
||||
const u8 * buf, size_t count, unsigned long flags);
|
||||
|
||||
/* select_file: Does the equivalent of SELECT FILE command specified
|
||||
* in ISO7816-4. Stores information about the selected file to
|
||||
|
@ -545,6 +552,13 @@ int sc_update_binary(struct sc_card *card, unsigned int idx, const u8 * buf,
|
|||
*/
|
||||
int sc_read_record(struct sc_card *card, unsigned int rec_nr, u8 * buf,
|
||||
size_t count, unsigned long flags);
|
||||
int sc_write_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf,
|
||||
size_t count, unsigned long flags);
|
||||
int sc_append_record(struct sc_card *card, const u8 * buf, size_t count,
|
||||
unsigned long flags);
|
||||
int sc_update_record(struct sc_card *card, unsigned int rec_nr, const u8 * buf,
|
||||
size_t count, unsigned long flags);
|
||||
|
||||
int sc_get_challenge(struct sc_card *card, u8 * rndout, size_t len);
|
||||
|
||||
/* ISO 7816-8 related functions */
|
||||
|
|
Loading…
Reference in New Issue