- continued improving ASN.1 decoding

- improved debug levels
- added some PC/SC Lite workarounds


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@87 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
jey 2001-12-21 23:34:47 +00:00
parent 41416437e5
commit c17ff3ebdf
14 changed files with 290 additions and 309 deletions

View File

@ -354,6 +354,7 @@ static int decode_bit_string(const u8 * inbuf, int inlen, void *outbuf,
int octets_left = inlen - 1;
int i, count = 0;
memset(outbuf, 0, outlen);
in++;
if (outlen < octets_left)
return SC_ERROR_BUFFER_TOO_SMALL;
@ -527,7 +528,7 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
int *len = entry->len;
int r = 0;
if (ctx->debug > 2) {
if (ctx->debug >= 3) {
u8 line[128], *linep = line;
int i;
@ -556,6 +557,7 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
}
break;
case SC_ASN1_INTEGER:
case SC_ASN1_ENUMERATED:
if (parm != NULL)
r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm);
break;
@ -627,7 +629,7 @@ static int asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
struct sc_asn1_struct *entry = asn1;
int left = len, objlen;
if (ctx->debug > 2)
if (ctx->debug >= 3)
debug(ctx, "called, depth %d%s\n", depth, choice ? ", choice" : "");
if (left < 2)
return SC_ERROR_ASN1_END_OF_CONTENTS;
@ -640,8 +642,12 @@ static int asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
if (obj == NULL) {
if (choice)
continue;
if (entry->flags & SC_ASN1_OPTIONAL)
if (entry->flags & SC_ASN1_OPTIONAL) {
if (ctx->debug >= 3)
debug(ctx, "optional ASN.1 object '%s' not present\n",
entry->name);
continue;
}
error(ctx, "mandatory ASN.1 object '%s' not found\n", entry->name);
if (ctx->debug && left) {
u8 line[128], *linep = line;
@ -654,7 +660,7 @@ static int asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
}
debug(ctx, "next tag: %s\n", line);
}
SC_FUNC_RETURN(ctx, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
SC_FUNC_RETURN(ctx, 3, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
}
r = asn1_decode_entry(ctx, entry, obj, objlen, depth);
if (r)
@ -663,14 +669,14 @@ static int asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
break;
}
if (choice && asn1[idx].name == NULL) /* No match */
SC_FUNC_RETURN(ctx, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
SC_FUNC_RETURN(ctx, 3, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
if (newp != NULL)
*newp = p;
if (len_left != NULL)
*len_left = left;
if (choice)
SC_FUNC_RETURN(ctx, idx);
SC_FUNC_RETURN(ctx, 0);
SC_FUNC_RETURN(ctx, 3, idx);
SC_FUNC_RETURN(ctx, 3, 0);
}
int sc_asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,

View File

@ -32,16 +32,7 @@ void error(struct sc_context *ctx, const char *format, ...)
va_list ap;
va_start(ap, format);
do_log2(ctx, SC_LOG_ERROR, "", format, ap);
va_end(ap);
}
void log(struct sc_context *ctx, const char *format, ...)
{
va_list ap;
va_start(ap, format);
do_log2(ctx, SC_LOG_NORMAL, "", format, ap);
do_log2(ctx, SC_LOG_TYPE_ERROR, "", format, ap);
va_end(ap);
}
@ -50,7 +41,7 @@ void debug(struct sc_context *ctx, const char *format, ...)
va_list ap;
va_start(ap, format);
do_log2(ctx, SC_LOG_DEBUG, "", format, ap);
do_log2(ctx, SC_LOG_TYPE_DEBUG, "", format, ap);
va_end(ap);
}
@ -79,12 +70,11 @@ void do_log2(struct sc_context *ctx, int type, const char *file,
assert(ctx != NULL);
if (ctx->use_std_output) {
switch (type) {
case SC_LOG_ERROR:
case SC_LOG_TYPE_ERROR:
outf = stderr;
break;
case SC_LOG_NORMAL:
case SC_LOG_DEBUG:
case SC_LOG_DEBUG2:
case SC_LOG_TYPE_DEBUG:
outf = stdout;
}
if (outf == NULL)
@ -122,14 +112,15 @@ void do_log2(struct sc_context *ctx, int type, const char *file,
if (do_color) {
color_sfx = "\e[0m";
switch (type) {
case SC_LOG_ERROR:
case SC_LOG_TYPE_ERROR:
color_pfx = "\e[01;31m";
break;
case SC_LOG_NORMAL:
#if 0
case SC_LOG_TYPE_NORMAL:
color_pfx = "\e[01;33m";
break;
case SC_LOG_DEBUG:
case SC_LOG_DEBUG2:
#endif
case SC_LOG_TYPE_DEBUG:
color_pfx = "\e[00;32m";
break;
}

View File

@ -24,34 +24,29 @@
#include "opensc.h"
#include <stdarg.h>
#define SC_LOG_ERROR 0
#define SC_LOG_NORMAL 1
#define SC_LOG_VERBOSE 2
#define SC_LOG_DEBUG 3
#define SC_LOG_DEBUG2 4
#define SC_LOG_TYPE_ERROR 0
#define SC_LOG_TYPE_VERBOSE 1
#define SC_LOG_TYPE_DEBUG 2
#ifdef __GNUC__
#define error(ctx, format, args...) do_log(ctx, SC_LOG_ERROR, __FILE__, __LINE__, __FUNCTION__ , format , ## args)
#define log(ctx, format, args...) do_log(ctx, SC_LOG_NORMAL, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define debug(ctx, format, args...) do_log(ctx, SC_LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define debug2(ctx, format, args...) do_log(ctx, SC_LOG_DEBUG2, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define error(ctx, format, args...) do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__ , format , ## args)
#define debug(ctx, format, args...) do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#else
void error(struct sc_context *ctx, const char *format, ...);
void log(struct sc_context *ctx, const char *format, ...);
void debug(struct sc_context *ctx, const char *format, ...);
void debug2(struct sc_context *ctx, const char *format, ...);
#endif
#define SC_FUNC_CALLED(ctx) {\
if ((ctx)->debug > 2)\
#define SC_FUNC_CALLED(ctx, level) {\
if ((ctx)->debug >= level)\
debug(ctx, "called\n"); }
#define SC_FUNC_RETURN(ctx, r) {\
#define SC_FUNC_RETURN(ctx, level, r) {\
int _ret = r;\
if (_ret < 0) {\
error(ctx, "returning with: %s\n", sc_strerror(_ret));\
} else if ((ctx)->debug > 2) {\
} else if ((ctx)->debug >= level) {\
debug(ctx, "returning with: %d\n", _ret);\
}\
return _ret; }

View File

@ -58,6 +58,7 @@ struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id;
int reference;
int flags, type;
int min_length, stored_length;
u8 pad_char;
@ -129,7 +130,7 @@ struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */
int usage, access_flags;
int usage, access_flags, native;
int key_reference;
struct sc_path file_id;
@ -173,9 +174,12 @@ struct sc_pkcs15_defaults {
int arg;
};
int sc_pkcs15_init(struct sc_card *card,
/* Binds a card object to a PKCS#15 card object and initializes
* a new PKCS#15 card object */
int sc_pkcs15_bind(struct sc_card *card,
struct sc_pkcs15_card **pkcs15_card);
int sc_pkcs15_destroy(struct sc_pkcs15_card *card);
int sc_pkcs15_unbind(struct sc_pkcs15_card *card);
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_prkey_info *prkey,

View File

@ -42,7 +42,7 @@ extern "C" {
#define SC_ERROR_OUT_OF_MEMORY -1009
#define SC_ERROR_NO_READERS_FOUND -1010
#define SC_ERROR_OBJECT_NOT_VALID -1011
#define SC_ERROR_UNKNOWN_RESPONSE -1012
#define SC_ERROR_ILLEGAL_RESPONSE -1012
#define SC_ERROR_PIN_CODE_INCORRECT -1013
#define SC_ERROR_SECURITY_STATUS_NOT_SATISFIED -1014
#define SC_ERROR_CONNECTING_TO_RES_MGR -1015
@ -106,7 +106,6 @@ extern "C" {
#define SC_ASN1_MAX_OBJECT_ID_OCTETS 16
typedef unsigned char u8;
typedef unsigned int uint32;
struct sc_object_id {
int value[SC_ASN1_MAX_OBJECT_ID_OCTETS];
@ -132,6 +131,9 @@ struct sc_file {
unsigned int magic;
};
#define SC_SEC_OPERATION_DECIPHER 0
#define SC_SEC_OPERATION_SIGN 1
struct sc_security_env {
int algorithm_ref;
struct sc_path key_file_id;
@ -146,19 +148,19 @@ struct sc_card_operations {
int (*init)(struct sc_card *card);
int (*finish)(struct sc_card *card);
int (*read_binary)(struct sc_card *card, uint32 idx,
int (*read_binary)(struct sc_card *card, unsigned int idx,
u8 * buf, size_t count);
int (*write_binary)(struct sc_card *card, uint32 idx,
int (*write_binary)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count);
int (*update_binary)(struct sc_card *card, uint32 idx,
int (*update_binary)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count);
int (*erase_binary)(struct sc_card *card, uint32 idx,
int (*erase_binary)(struct sc_card *card, unsigned int idx,
size_t count);
int (*read_binary_large)(struct sc_card *card, uint32 idx,
int (*read_binary_large)(struct sc_card *card, unsigned int idx,
u8 * buf, size_t count);
int (*write_binary_large)(struct sc_card *card, uint32 idx,
int (*write_binary_large)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count);
int (*update_binary_large)(struct sc_card *card, uint32 idx,
int (*update_binary_large)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count);
/* possibly TODO: record handling */
int (*select_file)(struct sc_card *card, struct sc_file *file,

View File

@ -224,7 +224,7 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_cert *cert;
assert(p15card != NULL && info != NULL && cert_out != NULL);
SC_FUNC_CALLED(p15card->card->ctx);
SC_FUNC_CALLED(p15card->card->ctx, 1);
r = find_cached_cert(p15card, info, &data, &len);
if (r) {
r = sc_select_file(p15card->card, &file, &info->path,
@ -290,7 +290,7 @@ static int parse_x509_cert_info(struct sc_context *ctx,
struct sc_pkcs15_object cert_obj = { &cert->com_attr, asn1_com_cert_attr, NULL,
asn1_type_cert_attr };
struct sc_asn1_struct asn1_cert[] = {
{ "x509Certificate", SC_ASN1_PKCS15_OBJECT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, &cert_obj, },
{ "x509Certificate", SC_ASN1_PKCS15_OBJECT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, &cert_obj },
{ NULL }
};
@ -332,15 +332,17 @@ static int get_certs_from_file(struct sc_pkcs15_card *card,
return r;
bytes_left = r;
do {
if (card->cert_count >= SC_PKCS15_MAX_CERTS)
return SC_ERROR_TOO_MANY_OBJECTS;
struct sc_pkcs15_cert_info tmp;
r = parse_x509_cert_info(card->card->ctx,
&card->cert_info[card->cert_count],
&p, &bytes_left);
&tmp, &p, &bytes_left);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
break;
if (r)
return r;
if (card->cert_count >= SC_PKCS15_MAX_CERTS)
return SC_ERROR_TOO_MANY_OBJECTS;
card->cert_info[card->cert_count] = tmp;
card->cert_count++;
} while (bytes_left);

View File

@ -27,73 +27,49 @@
#include <stdlib.h>
#include <stdio.h>
static int decode_pin_info(const u8 *buf,
int buflen, struct sc_pkcs15_pin_info *pin)
static int parse_pin_info(struct sc_context *ctx,
struct sc_pkcs15_pin_info *pin,
const u8 ** buf, int *buflen)
{
const u8 *tag, *p = buf;
int taglen, left = buflen;
int r;
struct sc_asn1_struct asn1_com_ao_attr[] = {
{ "authId", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, &pin->auth_id },
{ NULL }
};
int flags_len = sizeof(pin->flags);
int padchar_len = 1;
struct sc_asn1_struct asn1_pin_attr[] = {
{ "pinFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, &pin->flags, &flags_len},
{ "pinType", SC_ASN1_ENUMERATED, ASN1_ENUMERATED, 0, &pin->type },
{ "minLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &pin->min_length },
{ "storedLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &pin->stored_length },
{ "maxLength", SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ "pinReference", SC_ASN1_INTEGER, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, &pin->reference },
{ "padChar", SC_ASN1_OCTET_STRING, ASN1_OCTET_STRING, SC_ASN1_OPTIONAL, &pin->pad_char, &padchar_len },
{ "lastPinChange",SC_ASN1_GENERALIZEDTIME, ASN1_GENERALIZEDTIME, SC_ASN1_OPTIONAL, NULL },
{ "path", SC_ASN1_PATH, ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, &pin->path },
{ NULL }
};
struct sc_asn1_struct asn1_type_pin_attr[] = {
{ "pinAttributes", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, asn1_pin_attr},
{ NULL }
};
struct sc_pkcs15_object pin_obj = { &pin->com_attr, asn1_com_ao_attr, NULL,
asn1_type_pin_attr };
struct sc_asn1_struct asn1_pin[] = {
{ "pin", SC_ASN1_PKCS15_OBJECT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, &pin_obj },
{ NULL }
};
pin->reference = 0;
memset(pin, 0, sizeof(*pin));
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* SEQUENCE */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
sc_pkcs15_parse_common_object_attr(&pin->com_attr, tag, taglen);
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* SEQUENCE */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
tag = sc_asn1_verify_tag(tag, taglen, 0x04, &taglen); /* OCTET STRING */
if (tag == NULL || taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
if (taglen > SC_PKCS15_MAX_ID_SIZE)
taglen = SC_PKCS15_MAX_ID_SIZE;
memcpy(pin->auth_id.value, tag, taglen);
pin->auth_id.len = taglen;
r = sc_asn1_parse(ctx, asn1_pin, *buf, *buflen, buf, buflen);
if (r == 0)
pin->magic = SC_PKCS15_PIN_MAGIC;
p = sc_asn1_verify_tag(p, left, 0xA1, &left); /* CONS */
if (left == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
p = sc_asn1_verify_tag(p, left, 0x30, &left);
if (left == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
tag = sc_asn1_skip_tag(&p, &left, 0x03, &taglen);
if (taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
sc_asn1_decode_bit_string(tag, taglen, &pin->flags,
sizeof(pin->flags));
tag = sc_asn1_skip_tag(&p, &left, 0x0A, &taglen);
if (taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
pin->type = tag[0];
tag = sc_asn1_skip_tag(&p, &left, 0x02, &taglen);
if (taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
pin->min_length = tag[0];
tag = sc_asn1_skip_tag(&p, &left, 0x02, &taglen);
if (taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
pin->stored_length = tag[0];
tag = sc_asn1_find_tag(p, left, 0x04, &taglen);
if (taglen == 0)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
pin->pad_char = tag[0];
tag = sc_asn1_find_tag(p, left, 0x30, &taglen);
if (taglen != 0) {
tag = sc_asn1_find_tag(tag, taglen, 0x04, &taglen);
if (taglen >= 0) {
memcpy(pin->path.value, tag, taglen);
pin->path.len = taglen;
}
}
pin->magic = SC_PKCS15_PIN_MAGIC;
return 0;
return r;
}
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *pin)
@ -120,36 +96,40 @@ void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *pin)
printf("\n");
}
static int get_pins_from_file(struct sc_pkcs15_card *p15card,
static int get_pins_from_file(struct sc_pkcs15_card *card,
struct sc_file *file)
{
int r, taglen, left;
const u8 *p, *tag;
u8 buf[MAX_BUFFER_SIZE];
int r, bytes_left;
u8 buf[2048];
const u8 *p = buf;
r = sc_select_file(p15card->card, file, &file->path,
r = sc_select_file(card->card, file, &file->path,
SC_SELECT_FILE_BY_PATH);
if (r)
return r;
if (file->size > sizeof(buf))
return SC_ERROR_BUFFER_TOO_SMALL;
r = sc_read_binary(p15card->card, 0, buf, file->size);
r = sc_read_binary(card->card, 0, buf, file->size);
if (r < 0)
return r;
bytes_left = r;
do {
struct sc_pkcs15_pin_info tmp;
left = r;
p = buf;
while ((tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen)) != NULL) {
if (p15card->pin_count >= SC_PKCS15_MAX_PINS)
return SC_ERROR_TOO_MANY_OBJECTS;
r = decode_pin_info(tag, taglen,
&p15card->pin_info[p15card->pin_count]);
r = parse_pin_info(card->card->ctx,
&tmp, &p, &bytes_left);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
break;
if (r)
return r;
if (card->pin_count >= SC_PKCS15_MAX_CERTS)
return SC_ERROR_TOO_MANY_OBJECTS;
card->pin_info[card->pin_count] = tmp;
card->pin_count++;
} while (bytes_left);
p15card->pin_count++;
}
return 0;
}
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *p15card)
@ -158,7 +138,7 @@ int sc_pkcs15_enum_pins(struct sc_pkcs15_card *p15card)
struct sc_context *ctx = p15card->card->ctx;
assert(p15card != NULL);
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
if (p15card->pin_count) {
for (i = 0; i < p15card->pin_count; i++) {
if (p15card->pin_info[i].magic != SC_PKCS15_PIN_MAGIC)
@ -167,6 +147,7 @@ int sc_pkcs15_enum_pins(struct sc_pkcs15_card *p15card)
if (i == p15card->pin_count)
return i; /* Already enumerated */
}
p15card->pin_count = 0;
for (i = 0; i < p15card->aodf_count; i++) {
r = get_pins_from_file(p15card, &p15card->file_aodf[i]);
SC_TEST_RET(ctx, r, "Failed to read PINs from AODF");

View File

@ -47,105 +47,97 @@ void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey)
printf("\n");
}
static int parse_prkey_info(const u8 * buf,
int buflen, struct sc_pkcs15_prkey_info *prkey)
static int parse_rsa_prkey_info(struct sc_context *ctx,
struct sc_pkcs15_prkey_info *prkey,
const u8 **buf, int *buflen)
{
const u8 *tag, *p;
int taglen, left;
int r;
int usage_len = sizeof(prkey->usage);
int af_len = sizeof(prkey->access_flags);
struct sc_asn1_struct asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, &prkey->id, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, &prkey->usage, &usage_len },
{ "native", SC_ASN1_BOOLEAN, ASN1_BOOLEAN, SC_ASN1_OPTIONAL, &prkey->native },
{ "accessFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, &prkey->access_flags, &af_len },
{ "keyReference",SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, &prkey->key_reference },
{ NULL }
};
struct sc_asn1_struct asn1_com_prkey_attr[] = {
{ NULL }
};
struct sc_asn1_struct asn1_rsakey_attr[] = {
{ "value", SC_ASN1_PATH, ASN1_SEQUENCE | SC_ASN1_CONS, 0, &prkey->file_id },
{ "modulusLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &prkey->modulus_length },
{ "keyInfo", SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
struct sc_asn1_struct asn1_type_attr[] = {
{ "publicRSAKeyAttributes", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, asn1_rsakey_attr },
{ NULL }
};
tag = sc_asn1_skip_tag(&buf, &buflen, 0x30, &taglen); /* SEQUENCE */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
sc_pkcs15_parse_common_object_attr(&prkey->com_attr, tag, taglen);
struct sc_pkcs15_object prkey_obj = { &prkey->com_attr, asn1_com_key_attr,
asn1_com_prkey_attr, asn1_type_attr };
struct sc_asn1_struct asn1_prkey[] = {
{ "privateRSAKey", SC_ASN1_PKCS15_OBJECT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, &prkey_obj },
{ NULL }
};
p = sc_asn1_skip_tag(&buf, &buflen, 0x30, &left); /* SEQUENCE */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
prkey->key_reference = -1;
prkey->native = 1;
tag = sc_asn1_skip_tag(&p, &left, 0x04, &taglen); /* OCTET STRING */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
memcpy(prkey->id.value, tag, taglen);
prkey->id.len = taglen;
r = sc_asn1_parse(ctx, asn1_prkey, *buf, *buflen, buf, buflen);
tag = sc_asn1_skip_tag(&p, &left, 0x03, &taglen); /* BIT STRING */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
sc_asn1_decode_bit_string(tag, taglen, &prkey->usage,
sizeof(prkey->usage));
return r;
}
tag = sc_asn1_skip_tag(&p, &left, 0x01, &taglen); /* BOOLEAN */
if (tag != NULL) {
/* FIXME */
}
static int get_prkeys_from_file(struct sc_pkcs15_card *card,
struct sc_file *file)
{
int r, bytes_left;
u8 buf[2048];
const u8 *p = buf;
tag = sc_asn1_skip_tag(&p, &left, 0x03, &taglen); /* BIT STRING */
if (tag != NULL) {
sc_asn1_decode_bit_string(tag, taglen,
&prkey->access_flags,
sizeof(prkey->access_flags));
} else
prkey->access_flags = 0;
r = sc_select_file(card->card, file, &file->path,
SC_SELECT_FILE_BY_PATH);
if (r)
return r;
if (file->size > sizeof(buf))
return SC_ERROR_BUFFER_TOO_SMALL;
r = sc_read_binary(card->card, 0, buf, file->size);
if (r < 0)
return r;
bytes_left = r;
do {
struct sc_pkcs15_prkey_info tmp;
tag = sc_asn1_skip_tag(&p, &left, 0x02, &taglen); /* INTEGER */
if (tag != NULL && taglen) {
prkey->key_reference = tag[0];
} else
prkey->key_reference = -1;
/* FIXME */
p = sc_asn1_find_tag(buf, buflen, 0xA1, &left);
if (p == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
p = sc_asn1_verify_tag(p, left, 0x30, &left); /* SEQUENCE 1 */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* SEQUENCE 2 */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
tag = sc_asn1_verify_tag(tag, taglen, 0x04, &taglen); /* OCTET STRING */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
memcpy(prkey->file_id.value, tag, taglen);
prkey->file_id.len = taglen;
tag = sc_asn1_skip_tag(&p, &left, 0x02, &taglen); /* INTEGER */
if (tag == NULL)
return SC_ERROR_REQUIRED_PARAMETER_NOT_FOUND;
sc_asn1_decode_integer(tag, taglen, &prkey->modulus_length);
r = parse_rsa_prkey_info(card->card->ctx,
&tmp, &p, &bytes_left);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
break;
if (r)
return r;
if (card->prkey_count >= SC_PKCS15_MAX_PRKEYS)
return SC_ERROR_TOO_MANY_OBJECTS;
card->prkey_info[card->prkey_count] = tmp;
card->prkey_count++;
} while (bytes_left);
return 0;
}
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card)
{
int r, left, taglen;
const u8 *p, *tag;
u8 buf[1024];
int r, i;
assert(card != NULL);
if (card->prkey_count)
return card->prkey_count; /* already enumerated */
card->prkey_count = 0;
r = sc_select_file(card->card, &card->file_prkdf,
&card->file_prkdf.path, SC_SELECT_FILE_BY_PATH);
if (r)
return r;
r = sc_read_binary(card->card, 0, buf, card->file_prkdf.size);
if (r < 0)
return r;
left = r;
p = buf;
while ((tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen)) != NULL) {
struct sc_pkcs15_prkey_info *prkey =
&card->prkey_info[card->prkey_count];
if (parse_prkey_info(tag, taglen, prkey))
break;
card->prkey_count++;
for (i = 0; i < 1; i++) {
r = get_prkeys_from_file(card, &card->file_prkdf);
if (r != 0)
return r;
}
return card->prkey_count;
}

View File

@ -40,13 +40,14 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
senv.operation = 0;
senv.key_ref = prkey->key_reference;
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
r = sc_select_file(p15card->card, &p15card->file_app,
&p15card->file_app.path, SC_SELECT_FILE_BY_PATH);
SC_TEST_RET(ctx, r, "sc_select_file() failed");
r = sc_select_file(p15card->card, &p15card->file_app,
&p15card->file_app.path, SC_SELECT_FILE_BY_PATH);
SC_TEST_RET(ctx, r, "sc_select_file() failed");
usleep(100*1000); /* PC/SC Lite quirks */
r = sc_restore_security_env(p15card->card, 0); /* empty SE */
SC_TEST_RET(ctx, r, "sc_restore_security_env() failed");
r = sc_set_security_env(p15card->card, &senv);
@ -78,10 +79,11 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
senv.operation = 1;
senv.key_ref = prkey->key_reference;
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
r = sc_select_file(p15card->card, &p15card->file_app,
&p15card->file_app.path, SC_SELECT_FILE_BY_PATH);
SC_TEST_RET(ctx, r, "sc_select_file() failed");
usleep(100*1000); /* PC/SC Lite quirks */
r = sc_restore_security_env(p15card->card, 0); /* empty SE */
SC_TEST_RET(ctx, r, "sc_restore_security_env() failed");
r = sc_set_security_env(p15card->card, &senv);

View File

@ -236,7 +236,7 @@ static const struct sc_pkcs15_defaults * find_defaults(u8 *dir, int dirlen)
return match;
}
int sc_pkcs15_init(struct sc_card *card,
int sc_pkcs15_bind(struct sc_card *card,
struct sc_pkcs15_card **p15card_out)
{
unsigned char buf[MAX_BUFFER_SIZE];
@ -324,7 +324,7 @@ error:
return err;
}
int sc_pkcs15_destroy(struct sc_pkcs15_card *p15card)
int sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
{
free(p15card->label);
free(p15card->serial_number);

View File

@ -58,6 +58,7 @@ struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id;
int reference;
int flags, type;
int min_length, stored_length;
u8 pad_char;
@ -129,7 +130,7 @@ struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */
int usage, access_flags;
int usage, access_flags, native;
int key_reference;
struct sc_path file_id;
@ -173,9 +174,12 @@ struct sc_pkcs15_defaults {
int arg;
};
int sc_pkcs15_init(struct sc_card *card,
/* Binds a card object to a PKCS#15 card object and initializes
* a new PKCS#15 card object */
int sc_pkcs15_bind(struct sc_card *card,
struct sc_pkcs15_card **pkcs15_card);
int sc_pkcs15_destroy(struct sc_pkcs15_card *card);
int sc_pkcs15_unbind(struct sc_pkcs15_card *card);
int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_prkey_info *prkey,

View File

@ -24,34 +24,29 @@
#include "opensc.h"
#include <stdarg.h>
#define SC_LOG_ERROR 0
#define SC_LOG_NORMAL 1
#define SC_LOG_VERBOSE 2
#define SC_LOG_DEBUG 3
#define SC_LOG_DEBUG2 4
#define SC_LOG_TYPE_ERROR 0
#define SC_LOG_TYPE_VERBOSE 1
#define SC_LOG_TYPE_DEBUG 2
#ifdef __GNUC__
#define error(ctx, format, args...) do_log(ctx, SC_LOG_ERROR, __FILE__, __LINE__, __FUNCTION__ , format , ## args)
#define log(ctx, format, args...) do_log(ctx, SC_LOG_NORMAL, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define debug(ctx, format, args...) do_log(ctx, SC_LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define debug2(ctx, format, args...) do_log(ctx, SC_LOG_DEBUG2, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define error(ctx, format, args...) do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__ , format , ## args)
#define debug(ctx, format, args...) do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#else
void error(struct sc_context *ctx, const char *format, ...);
void log(struct sc_context *ctx, const char *format, ...);
void debug(struct sc_context *ctx, const char *format, ...);
void debug2(struct sc_context *ctx, const char *format, ...);
#endif
#define SC_FUNC_CALLED(ctx) {\
if ((ctx)->debug > 2)\
#define SC_FUNC_CALLED(ctx, level) {\
if ((ctx)->debug >= level)\
debug(ctx, "called\n"); }
#define SC_FUNC_RETURN(ctx, r) {\
#define SC_FUNC_RETURN(ctx, level, r) {\
int _ret = r;\
if (_ret < 0) {\
error(ctx, "returning with: %s\n", sc_strerror(_ret));\
} else if ((ctx)->debug > 2) {\
} else if ((ctx)->debug >= level) {\
debug(ctx, "returning with: %d\n", _ret);\
}\
return _ret; }

View File

@ -118,28 +118,28 @@ int sc_check_apdu(struct sc_context *ctx, const struct sc_apdu *apdu)
switch (apdu->cse) {
case SC_APDU_CASE_1:
if (apdu->datalen)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
break;
case SC_APDU_CASE_2_SHORT:
if (apdu->datalen)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
if (apdu->resplen < apdu->le)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
break;
case SC_APDU_CASE_3_SHORT:
if (apdu->datalen == 0 || apdu->data == NULL)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
break;
case SC_APDU_CASE_4_SHORT:
if (apdu->datalen == 0 || apdu->data == NULL)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
if (apdu->resplen < apdu->le)
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
break;
case SC_APDU_CASE_2_EXT:
case SC_APDU_CASE_3_EXT:
case SC_APDU_CASE_4_EXT:
SC_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
}
return 0;
}
@ -196,7 +196,7 @@ static int sc_transceive_t0(struct sc_card *card, struct sc_apdu *apdu)
dwRecvLength = apdu->resplen + 2;
if (dwRecvLength > 255) /* FIXME: PC/SC Lite quirk */
dwRecvLength = 255;
if (card->ctx->debug > 3) {
if (card->ctx->debug >= 5) {
char buf[2048];
sc_hex_dump(card->ctx, s, dwSendLength, buf, sizeof(buf));
@ -221,7 +221,7 @@ static int sc_transceive_t0(struct sc_card *card, struct sc_apdu *apdu)
}
}
if (dwRecvLength < 2)
return SC_ERROR_UNKNOWN_RESPONSE;
return SC_ERROR_ILLEGAL_RESPONSE;
apdu->sw1 = r[dwRecvLength-2];
apdu->sw2 = r[dwRecvLength-1];
dwRecvLength -= 2;
@ -239,12 +239,12 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
{
int r;
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 4);
r = sc_check_apdu(card->ctx, apdu);
SC_TEST_RET(card->ctx, r, "APDU sanity check failed");
r = sc_transceive_t0(card, apdu);
SC_TEST_RET(card->ctx, r, "transceive_t0() failed");
if (card->ctx->debug > 3) {
if (card->ctx->debug >= 5) {
char buf[2048];
buf[0] = 0;
@ -273,7 +273,7 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
sc_strerror(r));
return r;
}
if (card->ctx->debug > 3) {
if (card->ctx->debug >= 5) {
char buf[2048];
buf[0] = 0;
if (rspapdu.resplen) {
@ -315,7 +315,7 @@ int sc_detect_card(struct sc_context *ctx, int reader)
SCARD_READERSTATE_A rgReaderStates[SC_MAX_READERS];
assert(ctx != NULL);
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
if (reader >= ctx->reader_count || reader < 0)
return SC_ERROR_INVALID_ARGUMENTS;
@ -324,11 +324,16 @@ int sc_detect_card(struct sc_context *ctx, int reader)
ret = SCardGetStatusChange(ctx->pcsc_ctx, 0, rgReaderStates, 1);
if (ret != 0) {
error(ctx, "SCardGetStatusChange failed: %s\n", pcsc_stringify_error(ret));
SC_FUNC_RETURN(ctx, -1); /* FIXME */
SC_FUNC_RETURN(ctx, 1, -1); /* FIXME */
}
if (rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT)
SC_FUNC_RETURN(ctx, 1);
SC_FUNC_RETURN(ctx, 0);
if (rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT) {
if (ctx->debug >= 1)
debug(ctx, "card present\n");
return 1;
}
if (ctx->debug >= 1)
debug(ctx, "card absent\n");
return 0;
}
int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout)
@ -338,13 +343,13 @@ int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout)
int count = 0, i;
assert(ctx != NULL);
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
if (reader >= ctx->reader_count)
return SC_ERROR_INVALID_ARGUMENTS;
SC_FUNC_RETURN(ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
if (reader < 0) {
if (ctx->reader_count == 0)
SC_FUNC_RETURN(ctx, SC_ERROR_NO_READERS_FOUND);
SC_FUNC_RETURN(ctx, 1, SC_ERROR_NO_READERS_FOUND);
for (i = 0; i < ctx->reader_count; i++) {
rgReaderStates[i].szReader = ctx->readers[i];
rgReaderStates[i].dwCurrentState =
@ -360,13 +365,13 @@ int sc_wait_for_card(struct sc_context *ctx, int reader, int timeout)
count);
if (ret != 0) {
error(ctx, "SCardGetStatusChange failed: %s\n", pcsc_stringify_error(ret));
SC_FUNC_RETURN(ctx, -1);
SC_FUNC_RETURN(ctx, 1, -1);
}
for (i = 0; i < count; i++) {
if (rgReaderStates[i].dwEventState & SCARD_STATE_CHANGED)
SC_FUNC_RETURN(ctx, 1);
SC_FUNC_RETURN(ctx, 1, 1);
}
SC_FUNC_RETURN(ctx, 0);
SC_FUNC_RETURN(ctx, 1, 0);
}
int sc_establish_context(struct sc_context **ctx_out)
@ -417,7 +422,7 @@ int sc_destroy_context(struct sc_context *ctx)
int i;
assert(ctx != NULL);
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
for (i = 0; i < ctx->reader_count; i++)
free(ctx->readers[i]);
free(ctx);
@ -462,23 +467,23 @@ int sc_connect_card(struct sc_context *ctx,
const struct sc_defaults *defaults;
assert(card_out != NULL);
SC_FUNC_CALLED(ctx);
SC_FUNC_CALLED(ctx, 1);
if (reader >= ctx->reader_count || reader < 0)
SC_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND);
SC_FUNC_RETURN(ctx, 1, SC_ERROR_OBJECT_NOT_FOUND);
rgReaderStates[0].szReader = ctx->readers[reader];
rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
rv = SCardGetStatusChange(ctx->pcsc_ctx, 0, rgReaderStates, 1);
if (rv != 0) {
error(ctx, "SCardGetStatusChange failed: %s\n", pcsc_stringify_error(rv));
SC_FUNC_RETURN(ctx, SC_ERROR_RESOURCE_MANAGER); /* FIXME */
SC_FUNC_RETURN(ctx, 1, SC_ERROR_RESOURCE_MANAGER); /* FIXME */
}
if (!(rgReaderStates[0].dwEventState & SCARD_STATE_PRESENT))
SC_FUNC_RETURN(ctx, SC_ERROR_CARD_NOT_PRESENT);
SC_FUNC_RETURN(ctx, 1, SC_ERROR_CARD_NOT_PRESENT);
card = malloc(sizeof(struct sc_card));
if (card == NULL)
SC_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
SC_FUNC_RETURN(ctx, 1, SC_ERROR_OUT_OF_MEMORY);
memset(card, 0, sizeof(struct sc_card));
rv = SCardConnect(ctx->pcsc_ctx, ctx->readers[reader],
SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0,
@ -506,17 +511,18 @@ int sc_connect_card(struct sc_context *ctx,
pthread_mutex_init(&card->mutex, NULL);
*card_out = card;
return 0;
SC_FUNC_RETURN(ctx, 1, 0);
}
int sc_disconnect_card(struct sc_card *card)
{
struct sc_context *ctx = card->ctx;
assert(card != NULL);
SC_FUNC_CALLED(ctx, 1);
SCardDisconnect(card->pcsc_card, SCARD_LEAVE_CARD);
pthread_mutex_destroy(&card->mutex);
free(card);
return 0;
SC_FUNC_RETURN(ctx, 1, 0);
}
const char *sc_strerror(int error)
@ -578,8 +584,9 @@ int _sc_lock_int(struct sc_card *card)
int sc_lock(struct sc_card *card)
{
SC_FUNC_CALLED(card->ctx, 2);
pthread_mutex_lock(&card->mutex);
return _sc_lock_int(card);
SC_FUNC_RETURN(card->ctx, 2, _sc_lock_int(card));
}
int _sc_unlock_int(struct sc_card *card)
@ -596,22 +603,23 @@ int _sc_unlock_int(struct sc_card *card)
int sc_unlock(struct sc_card *card)
{
SC_FUNC_CALLED(card->ctx, 2);
pthread_mutex_unlock(&card->mutex);
return _sc_unlock_int(card);
SC_FUNC_RETURN(card->ctx, 2, _sc_unlock_int(card));
}
int sc_list_files(struct sc_card *card, u8 *buf, int buflen)
{
struct sc_apdu apdu;
int r;
SC_FUNC_CALLED(card->ctx, 2);
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xAA, 0, 0);
apdu.resp = buf;
apdu.resplen = buflen;
apdu.le = 0;
r = sc_transmit_apdu(card, &apdu);
if (r)
return r;
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.resplen == 0)
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
return apdu.resplen;
@ -658,10 +666,10 @@ int sc_create_file(struct sc_card *card, const struct sc_file *file)
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
struct sc_apdu apdu;
SC_FUNC_CALLED(card->ctx, 1);
len = SC_MAX_APDU_BUFFER_SIZE;
r = construct_fci(file, sbuf, &len);
if (r)
return r;
SC_TEST_RET(card->ctx, r, "construct_fci() failed");
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
apdu.lc = len;
@ -671,9 +679,8 @@ int sc_create_file(struct sc_card *card, const struct sc_file *file)
apdu.resp = rbuf;
r = sc_transmit_apdu(card, &apdu);
if (r)
return r;
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
SC_FUNC_RETURN(card->ctx, 1, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_delete_file(struct sc_card *card, int file_id)
@ -683,6 +690,7 @@ int sc_delete_file(struct sc_card *card, int file_id)
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
struct sc_apdu apdu;
SC_FUNC_CALLED(card->ctx, 1);
sbuf[0] = (file_id >> 8) & 0xFF;
sbuf[1] = file_id & 0xFF;
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
@ -693,11 +701,10 @@ int sc_delete_file(struct sc_card *card, int file_id)
apdu.resp = rbuf;
r = sc_transmit_apdu(card, &apdu);
if (r)
return r;
if (apdu.resplen != 2)
return -1;
return sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.resplen != 0)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_ILLEGAL_RESPONSE);
SC_FUNC_RETURN(card->ctx, 1, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_file_valid(const struct sc_file *file)

View File

@ -33,7 +33,7 @@ int sc_set_security_env(struct sc_card *card,
int r;
assert(card != NULL && env != NULL);
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 2);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
if (env->operation == 1) {
apdu.p1 = 0x81;
@ -61,7 +61,7 @@ int sc_set_security_env(struct sc_card *card,
apdu.resplen = 0;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_restore_security_env(struct sc_card *card, int num)
@ -71,13 +71,13 @@ int sc_restore_security_env(struct sc_card *card, int num)
u8 rbuf[MAX_BUFFER_SIZE];
assert(card != NULL);
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 2);
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, num);
apdu.resplen = sizeof(rbuf) > 250 ? 250 : sizeof(rbuf);
apdu.resp = rbuf;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_decipher(struct sc_card *card,
@ -89,9 +89,9 @@ int sc_decipher(struct sc_card *card,
u8 sbuf[MAX_BUFFER_SIZE];
assert(card != NULL && crgram != NULL && out != NULL);
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 2);
if (crgram_len > 255)
SC_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86);
apdu.resp = rbuf;
@ -108,9 +108,9 @@ int sc_decipher(struct sc_card *card,
int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len);
SC_FUNC_RETURN(card->ctx, len);
SC_FUNC_RETURN(card->ctx, 2, len);
}
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_compute_signature(struct sc_card *card,
@ -123,9 +123,9 @@ int sc_compute_signature(struct sc_card *card,
u8 sbuf[MAX_BUFFER_SIZE];
assert(card != NULL && data != NULL && out != NULL);
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 2);
if (datalen > 255)
SC_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x9E,
0x9A);
@ -142,9 +142,9 @@ int sc_compute_signature(struct sc_card *card,
int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len);
SC_FUNC_RETURN(card->ctx, len);
SC_FUNC_RETURN(card->ctx, 2, len);
}
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_verify(struct sc_card *card, int ref, const u8 *pin, int pinlen,
@ -154,9 +154,9 @@ int sc_verify(struct sc_card *card, int ref, const u8 *pin, int pinlen,
u8 sbuf[MAX_BUFFER_SIZE];
int r;
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 2);
if (pinlen >= MAX_BUFFER_SIZE)
SC_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0, ref);
memcpy(sbuf, pin, pinlen);
apdu.lc = pinlen;
@ -170,9 +170,9 @@ int sc_verify(struct sc_card *card, int ref, const u8 *pin, int pinlen,
if (apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) {
if (tries_left != NULL)
*tries_left = apdu.sw2 & 0x0F;
SC_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_PIN_CODE_INCORRECT);
}
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 2, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_change_reference_data(struct sc_card *card, int ref, const u8 *old,
@ -183,9 +183,9 @@ int sc_change_reference_data(struct sc_card *card, int ref, const u8 *old,
u8 sbuf[MAX_BUFFER_SIZE];
int r, p1 = 0, len = oldlen + newlen;
SC_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, 1);
if (len >= MAX_BUFFER_SIZE)
SC_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
if (oldlen == 0)
p1 = 1;
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, p1, ref);
@ -202,9 +202,9 @@ int sc_change_reference_data(struct sc_card *card, int ref, const u8 *old,
if (apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) {
if (tries_left != NULL)
*tries_left = apdu.sw2 & 0x0F;
SC_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_PIN_CODE_INCORRECT);
}
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 1, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}
int sc_reset_retry_counter(struct sc_card *card, int ref, const u8 *puk,
@ -215,7 +215,7 @@ int sc_reset_retry_counter(struct sc_card *card, int ref, const u8 *puk,
int r, p1 = 0, len = puklen + newlen;
if (len >= MAX_BUFFER_SIZE)
SC_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
if (puklen == 0) {
if (newlen == 0)
p1 = 3;
@ -238,5 +238,5 @@ int sc_reset_retry_counter(struct sc_card *card, int ref, const u8 *puk,
r = sc_transmit_apdu(card, &apdu);
memset(sbuf, 0, len);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
SC_FUNC_RETURN(card->ctx, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 1, sc_sw_to_errorcode(card, apdu.sw1, apdu.sw2));
}