00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include <list.h>
00009 #include <emv.h>
00010 #include <ber.h>
00011 #include "emv-internal.h"
00012
00013 static int bop_adfname(const uint8_t *ptr, size_t len, void *priv)
00014 {
00015 struct _emv_app *a = priv;
00016 assert(len >= EMV_RID_LEN && len <= EMV_AID_LEN);
00017 a->a_id_sz = len;
00018 memcpy(a->a_id, ptr, sizeof(a->a_id));
00019 return 1;
00020 }
00021
00022 static int bop_label(const uint8_t *ptr, size_t len, void *priv)
00023 {
00024 struct _emv_app *a = priv;
00025 snprintf(a->a_name, sizeof(a->a_name), "%.*s", len, ptr);
00026 return 1;
00027 }
00028
00029 static int bop_pname(const uint8_t *ptr, size_t len, void *priv)
00030 {
00031 struct _emv_app *a = priv;
00032 snprintf(a->a_pname, sizeof(a->a_pname), "%.*s", len, ptr);
00033 return 1;
00034 }
00035
00036 static int bop_prio(const uint8_t *ptr, size_t len, void *priv)
00037 {
00038 struct _emv_app *a = priv;
00039 assert(1U == len);
00040 a->a_prio = *ptr;
00041 return 1;
00042 }
00043
00044 static int bop_dtemp(const uint8_t *ptr, size_t len, void *priv)
00045 {
00046 struct _emv *e = priv;
00047 struct _emv_app *app;
00048 static const struct ber_tag tags[] = {
00049 { .tag = "\x4f", .tag_len = 1, .op = bop_adfname },
00050 { .tag = "\x50", .tag_len = 1, .op = bop_label },
00051 { .tag = "\x87", .tag_len = 1, .op = bop_prio },
00052 { .tag = "\x9f\x12", .tag_len = 2, .op = bop_pname },
00053 };
00054
00055 app = calloc(1, sizeof(*app));
00056 if ( NULL == app )
00057 return 0;
00058
00059 if ( ber_decode(tags, sizeof(tags)/sizeof(*tags), ptr, len, app) ) {
00060 list_add_tail(&app->a_list, &e->e_apps);
00061 e->e_num_apps++;
00062 return 1;
00063 }else{
00064 _emv_error(e, EMV_ERR_DATA_ELEMENT_NOT_FOUND);
00065 free(app);
00066 return 0;
00067 }
00068 }
00069
00070 static int bop_psd(const uint8_t *ptr, size_t len, void *priv)
00071 {
00072 static const struct ber_tag tags[] = {
00073 { .tag = "\x61", .tag_len = 1, .op = bop_dtemp },
00074 };
00075 return ber_decode(tags, sizeof(tags)/sizeof(*tags), ptr, len, priv);
00076 }
00077
00078 static int add_app(emv_t e)
00079 {
00080 const uint8_t *res;
00081 size_t len;
00082 static const struct ber_tag tags[] = {
00083 { .tag = "\x70", .tag_len = 1, .op = bop_psd },
00084 };
00085
00086 res = xfr_rx_data(e->e_xfr, &len);
00087 if ( NULL == res )
00088 return 0;
00089
00090 if ( !ber_decode(tags, sizeof(tags)/sizeof(*tags), res, len, e) ) {
00091 _emv_error(e, EMV_ERR_DATA_ELEMENT_NOT_FOUND);
00092 return 0;
00093 }else
00094 return 1;
00095 }
00096
00097 void _emv_free_applist(emv_t e)
00098 {
00099 struct _emv_app *a, *t;
00100 list_for_each_entry_safe(a, t, &e->e_apps, a_list) {
00101 list_del(&a->a_list);
00102 free(a);
00103 }
00104 }
00105
00106 void emv_app_rid(emv_app_t a, emv_rid_t ret)
00107 {
00108 memcpy(ret, a->a_id, EMV_RID_LEN);
00109 }
00110
00111 void emv_app_aid(emv_app_t a, uint8_t *ret, size_t *len)
00112 {
00113 memcpy(ret, a->a_id, a->a_id_sz);
00114 *len = a->a_id_sz;
00115 }
00116
00117 const char *emv_app_label(emv_app_t a)
00118 {
00119 return a->a_name;
00120 }
00121
00122 const char *emv_app_pname(emv_app_t a)
00123 {
00124 if ( '\0' != *a->a_pname )
00125 return a->a_pname;
00126 return a->a_name;
00127 }
00128
00129 uint8_t emv_app_prio(emv_app_t a)
00130 {
00131 return a->a_prio & 0x7f;
00132 }
00133
00134 int emv_app_confirm(emv_app_t a)
00135 {
00136 return a->a_prio >> 7;
00137 }
00138
00139 int emv_appsel_pse(emv_t e)
00140 {
00141 static const char * const pse = "1PAY.SYS.DDF01";
00142 struct _emv_app *a, *tmp;
00143 unsigned int i;
00144
00145 if ( !_emv_select(e, (uint8_t *)pse, strlen(pse)) )
00146 return 0;
00147
00148 list_for_each_entry_safe(a, tmp, &e->e_apps, a_list) {
00149 list_del(&a->a_list);
00150 free(a);
00151 }
00152
00153 for (i = 1; ; i++) {
00154 if ( !_emv_read_record(e, 1, i) )
00155 break;
00156 add_app(e);
00157 }
00158
00159
00160
00161 _emv_success(e);
00162 return 1;
00163 }
00164
00165 emv_app_t emv_appsel_pse_first(emv_t e)
00166 {
00167 return list_entry(e->e_apps.next, struct _emv_app, a_list);
00168 }
00169
00170 emv_app_t emv_appsel_pse_next(emv_t e, emv_app_t app)
00171 {
00172 if ( app->a_list.next == &e->e_apps )
00173 return NULL;
00174 return list_entry(app->a_list.next, struct _emv_app, a_list);
00175 }
00176
00177 _public void emv_app_delete(emv_app_t a)
00178 {
00179 list_del(&a->a_list);
00180 free(a);
00181 }
00182
00183 static int bop_fci2(const uint8_t *ptr, size_t len, void *priv)
00184 {
00185 static const struct ber_tag tags[] = {
00186 { .tag = "\x50", .tag_len = 1, .op = bop_label},
00187 { .tag = "\x87", .tag_len = 1, .op = bop_prio},
00188 { .tag = "\x5f\x2d", .tag_len = 2, .op = NULL},
00189 { .tag = "\x9f\x11", .tag_len = 2, .op = NULL},
00190 { .tag = "\x9f\x12", .tag_len = 2, .op = bop_pname},
00191 { .tag = "\xbf\x0c", .tag_len = 2, .op = NULL},
00192
00193 };
00194 return ber_decode(tags, sizeof(tags)/sizeof(*tags), ptr, len, priv);
00195 }
00196
00197 static int bop_fci(const uint8_t *ptr, size_t len, void *priv)
00198 {
00199 static const struct ber_tag tags[] = {
00200 { .tag = "\x84", .tag_len = 1, .op = bop_adfname},
00201 { .tag = "\xa5", .tag_len = 1, .op = bop_fci2},
00202 };
00203 return ber_decode(tags, sizeof(tags)/sizeof(*tags), ptr, len, priv);
00204 }
00205
00206 static int set_app(emv_t e)
00207 {
00208 static const struct ber_tag tags[] = {
00209 { .tag = "\x6f", .tag_len = 1, .op = bop_fci},
00210 };
00211 struct _emv_app *cur;
00212 const uint8_t *fci;
00213 size_t len;
00214
00215 fci = xfr_rx_data(e->e_xfr, &len);
00216 if ( NULL == fci )
00217 return 0;
00218
00219 cur = calloc(1, sizeof(*cur));
00220 if ( NULL == cur )
00221 return 0;
00222
00223 if ( !ber_decode(tags, BER_NUM_TAGS(tags), fci, len, cur) ) {
00224 free(cur);
00225 return 0;
00226 }
00227
00228 e->e_app = cur;
00229 return 1;
00230 }
00231
00232 int emv_app_select_pse(emv_t e, emv_app_t a)
00233 {
00234 if ( !_emv_select(e, a->a_id, a->a_id_sz) )
00235 return 0;
00236 return set_app(e);
00237 }
00238
00239 int emv_app_select_aid(emv_t e, const uint8_t *aid, size_t aid_len)
00240 {
00241 if ( !_emv_select(e, aid, aid_len) )
00242 return 0;
00243 return set_app(e);
00244 }
00245
00246 int emv_app_select_aid_next(emv_t e, const uint8_t *aid, size_t aid_len)
00247 {
00248 if ( !_emv_select_next(e, aid, aid_len) )
00249 return 0;
00250 return set_app(e);
00251 }