00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include <emv.h>
00009
00010 #include <stdio.h>
00011
00012 #include "ca_pubkeys.h"
00013
00014 struct t_app {
00015 const uint8_t *aid;
00016 size_t aid_len;
00017 uint8_t asi;
00018 };
00019
00020 static const struct t_app apps[] = {
00021 {.aid = (uint8_t *)"\xa0\x00\x00\x00\x03", .aid_len = 5, .asi = 1},
00022 {.aid = (uint8_t *)"\xa0\x00\x00\x00\x29", .aid_len = 5, .asi = 1},
00023 };
00024
00025 static int app_cmp(emv_app_t a, const struct t_app *b)
00026 {
00027 if ( b->asi ) {
00028 emv_rid_t rid;
00029 emv_app_rid(a, rid);
00030 return memcmp(rid, b->aid, EMV_RID_LEN);
00031 }else{
00032 uint8_t aid[EMV_AID_LEN];
00033 size_t sz;
00034 emv_app_aid(a, aid, &sz);
00035 if ( sz < b->aid_len )
00036 return -1;
00037 if ( sz > b->aid_len )
00038 return 1;
00039 return memcmp(aid, b->aid, sz);
00040 }
00041 }
00042
00043 static int app_supported(emv_app_t a)
00044 {
00045 unsigned int i;
00046
00047 for(i = 0; i < sizeof(apps)/sizeof(*apps); i++) {
00048 if ( !app_cmp(a, apps + i) )
00049 return 1;
00050 }
00051
00052 return 0;
00053 }
00054
00055
00056 static int select_app(emv_t e)
00057 {
00058 emv_app_t app;
00059 unsigned int i;
00060
00061
00062 if ( emv_appsel_pse(e) ) {
00063 for(app = emv_appsel_pse_first(e); app; ) {
00064 if ( !app_supported(app) ) {
00065 printf("emvtool: unsupported PSE app: %s\n",
00066 emv_app_pname(app));
00067 emv_app_t f = app;
00068 app = emv_appsel_pse_next(e, app);
00069 emv_app_delete(f);
00070 continue;
00071 }
00072 printf("emvtool: PSE app: %s\n",
00073 emv_app_pname(app));
00074 app = emv_appsel_pse_next(e, app);
00075 }
00076
00077 for(app = emv_appsel_pse_first(e); app;
00078 app = emv_appsel_pse_next(e, app)) {
00079 if ( emv_app_select_pse(e, app) ) {
00080 printf("emvtool: Selected PSE app: %s\n",
00081 emv_app_pname(app));
00082 return 1;
00083 }
00084 }
00085 }
00086
00087
00088 for(i = 0; i < sizeof(apps)/sizeof(*apps); i++) {
00089 if ( !emv_app_select_aid(e, apps[i].aid, apps[i].aid_len) )
00090 continue;
00091
00092 app = emv_current_app(e);
00093 if ( !app_cmp(app, apps + i) ) {
00094 printf("emvtool: Selected AID app: %s\n",
00095 emv_app_pname(app));
00096 return 1;
00097 }
00098
00099 while ( emv_app_select_aid_next(e, apps[i].aid,
00100 apps[i].aid_len) ) {
00101 app = emv_current_app(e);
00102 if ( app_cmp(app, apps + i) )
00103 continue;
00104 printf("emvtool: Selected partial AID app: %s\n",
00105 emv_app_pname(app));
00106 return 1;
00107 }
00108 }
00109
00110 return 0;
00111 }
00112
00113 static const struct {
00114 const uint8_t *mod, *exp;
00115 size_t mod_len, exp_len;
00116 }ca_keys[] = {
00117 [7] = {.mod = visa1152_mod,
00118 .mod_len = sizeof(visa1152_mod),
00119 .exp = visa1152_exp,
00120 .exp_len = sizeof(visa1152_exp)},
00121 };
00122
00123 static const uint8_t *get_mod(void *priv, unsigned int idx, size_t *len)
00124 {
00125 if ( idx >= sizeof(ca_keys)/sizeof(*ca_keys) )
00126 return NULL;
00127 *len = ca_keys[idx].mod_len;
00128 return ca_keys[idx].mod;
00129 }
00130
00131 static const uint8_t *get_exp(void *priv, unsigned int idx, size_t *len)
00132 {
00133 if ( idx >= sizeof(ca_keys)/sizeof(*ca_keys) )
00134 return NULL;
00135 *len = ca_keys[idx].exp_len;
00136 return ca_keys[idx].exp;
00137 }
00138
00139 static int trm(emv_t e)
00140 {
00141 int atc, oatc;
00142 atc = emv_trm_atc(e);
00143 oatc = emv_trm_last_online_atc(e);
00144 printf("emvtool: app transaction counter: %u\n", atc);
00145 printf("emvtool: last online transaction: %u\n", oatc);
00146 return 1;
00147 }
00148
00149 static int do_emv_stuff(chipcard_t cc)
00150 {
00151 emv_t e;
00152
00153 e = emv_init(cc);
00154 if ( NULL == e ) {
00155 fprintf(stderr, "emv: init error\n");
00156 return 0;
00157 }
00158
00159 if ( !select_app(e) )
00160 goto end;
00161
00162
00163
00164 if ( !emv_app_init(e) )
00165 goto end;
00166
00167 printf("emvtool: application initiated\n");
00168
00169
00170 if ( !emv_read_app_data(e) )
00171 goto end;
00172
00173 printf("emvtool: application data retrieved\n");
00174
00175
00176
00177
00178 if ( !emv_authenticate_dynamic(e, get_mod, get_exp, NULL) )
00179 goto end;
00180
00181 printf("emvtool: card data authenticated\n");
00182
00183
00184 #if 0
00185 if ( !emv_cvm_pin(e, "1337") )
00186 goto end;
00187
00188 printf("emvtool: card holder verified\n");
00189
00190
00191 if ( !trm(e) )
00192 goto end;
00193
00194
00195 #endif
00196
00197 end:
00198 emv_fini(e);
00199 return 1;
00200 }
00201
00202 static int found_cci(ccidev_t dev)
00203 {
00204 chipcard_t cc;
00205 cci_t cci;
00206 int ret = 0;
00207
00208 cci = cci_probe(dev, "./emvtool.log");
00209 if ( NULL == cci )
00210 goto out;
00211
00212 cc = cci_get_slot(cci, 0);
00213 if ( NULL == cc ) {
00214 fprintf(stderr, "ccid: error: no slots on CCI\n");
00215 goto out_close;
00216 }
00217
00218 if ( !chipcard_wait_for_card(cc) )
00219 goto out_close;
00220
00221 if ( !chipcard_slot_on(cc, CHIPCARD_AUTO_VOLTAGE, NULL) )
00222 goto out_close;
00223
00224 if ( !do_emv_stuff(cc) )
00225 goto out_close;
00226
00227 ret = 1;
00228
00229 chipcard_slot_off(cc);
00230 out_close:
00231 cci_close(cci);
00232 out:
00233 return ret;
00234 }
00235
00236 int main(int argc, char **argv)
00237 {
00238 ccidev_t *dev;
00239 size_t num_dev, i;
00240
00241 dev = ccid_get_device_list(&num_dev);
00242 if ( NULL == dev )
00243 return EXIT_FAILURE;
00244
00245 for(i = 0; i < num_dev; i++)
00246 found_cci(dev[i]);
00247
00248 ccid_free_device_list(dev);
00249
00250 return EXIT_SUCCESS;
00251 }