00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include <emv.h>
00009 #include <Python.h>
00010 #include <structmember.h>
00011 #include "py_ccid.h"
00012
00013 struct cp_emv {
00014 PyObject_HEAD;
00015 emv_t emv;
00016 PyObject *applist;
00017 struct cp_app *current;
00018 };
00019
00020 struct cp_app {
00021 PyObject_HEAD;
00022 emv_app_t app;
00023 int cur;
00024 int dirty;
00025 struct cp_emv *owner;
00026 };
00027
00028 struct cp_data {
00029 PyObject_HEAD;
00030 emv_data_t data;
00031 struct cp_emv *owner;
00032 };
00033
00034 static PyObject *data_dict(struct cp_emv *, emv_data_t *, unsigned int);
00035
00036 static void set_err(emv_t e)
00037 {
00038 PyObject *ex, *tup;
00039 unsigned int type, code;
00040 const char *str;
00041 emv_err_t err;
00042
00043 err = emv_error(e);
00044 str = emv_error_string(err);
00045 type = emv_error_type(err);
00046 code = emv_error_additional(err);
00047
00048 switch(type) {
00049 case EMV_ERR_SYSTEM:
00050 ex = PyExc_SystemError;
00051 break;
00052 case EMV_ERR_CCID:
00053 ex = PyExc_IOError;
00054 break;
00055 default:
00056 ex = PyExc_Exception;
00057 break;
00058 }
00059
00060 tup = PyTuple_New(3);
00061 if ( NULL == tup )
00062 return;
00063
00064 if ( NULL == str ) {
00065 PyTuple_SetItem(tup, 0, PyString_FromString(""));
00066 }else{
00067 PyTuple_SetItem(tup, 0, PyString_FromString(str));
00068 }
00069 PyTuple_SetItem(tup, 1, PyInt_FromLong(type));
00070 PyTuple_SetItem(tup, 2, PyInt_FromLong(code));
00071
00072 PyErr_SetObject(ex, tup);
00073 }
00074
00075 static PyObject *bcd_convert(const uint8_t *ptr, size_t len)
00076 {
00077 char buf[len * 2 + len / 2 + 1];
00078 size_t i;
00079 char *p;
00080
00081 for(i = 0, p = buf; i < len; i++, p += 2) {
00082 if ( i && 0 == (i % 2) )
00083 sprintf(p, "-"), ++p;
00084 sprintf(p, "%.2x", ptr[i]);
00085 }
00086
00087 return PyString_FromString(buf);
00088 }
00089
00090 static PyObject *binary_convert(const uint8_t *ptr, size_t len)
00091 {
00092 char buf[len * 3 + len / 16 + 1];
00093 size_t i;
00094 char *p;
00095
00096 for(i = 0, p = buf; i < len; i++, p += 3) {
00097 if ( i && 0 == (i & 0xf) )
00098 sprintf(p, "\n"), ++p;
00099 sprintf(p, "%.2x ", ptr[i]);
00100 }
00101 p--;
00102 *p = '\0';
00103
00104 return PyString_FromString(buf);
00105 }
00106
00107 static PyObject *date_convert(const uint8_t *ptr, size_t len)
00108 {
00109 char buf[11];
00110 snprintf(buf, sizeof(buf), "%.2u%.2x-%.2x-%.2x",
00111 (ptr[0] < 70) ? 20 : 19, ptr[0], ptr[1], ptr[2]);
00112 return PyString_FromString(buf);
00113 }
00114
00115 static PyObject *cp_data_repr(struct cp_data *self)
00116 {
00117 const uint8_t *ptr;
00118 size_t len;
00119
00120 ptr = emv_data(self->data, &len);
00121
00122 switch(emv_data_type(self->data)) {
00123 case EMV_DATA_BINARY:
00124 return binary_convert(ptr, len);
00125 case EMV_DATA_TEXT:
00126 return PyString_FromStringAndSize((const char *)ptr, len);
00127 case EMV_DATA_INT:
00128 do {
00129 PyObject *ret;
00130 ret = PyInt_FromLong(emv_data_int(self->data));
00131 return ret->ob_type->tp_repr(ret);
00132 }while(0);
00133 case EMV_DATA_BCD:
00134 return bcd_convert(ptr, len);
00135 case EMV_DATA_DATE:
00136 return date_convert(ptr, len);
00137 default:
00138 return NULL;
00139 }
00140 }
00141
00142 static PyObject *cp_data_value(struct cp_data *self, PyObject *args)
00143 {
00144 const uint8_t *ptr;
00145 size_t len;
00146
00147 ptr = emv_data(self->data, &len);
00148 return PyString_FromStringAndSize((const char *)ptr, len);
00149 }
00150
00151 static PyObject *cp_data_children(struct cp_data *self, PyObject *args)
00152 {
00153 emv_data_t *rec;
00154 unsigned int num_rec;
00155
00156 rec = emv_data_children(self->data, &num_rec);
00157 return data_dict(self->owner, rec, num_rec);
00158 }
00159
00160 static PyObject *cp_data_type(struct cp_data *self, PyObject *args)
00161 {
00162 return Py_BuildValue("i", emv_data_type(self->data));
00163 }
00164
00165 static PyObject *cp_data_tag(struct cp_data *self, PyObject *args)
00166 {
00167 return Py_BuildValue("i", emv_data_tag(self->data));
00168 }
00169
00170 static PyObject *cp_data_tag_label(struct cp_data *self, PyObject *args)
00171 {
00172 const char *label;
00173 label = emv_data_tag_label(self->data);
00174 if ( label ) {
00175 return PyString_FromString(label);
00176 }else{
00177 Py_INCREF(Py_None);
00178 return Py_None;
00179 }
00180 }
00181
00182 static PyObject *cp_data_sda(struct cp_data *self, PyObject *args)
00183 {
00184 if ( emv_data_sda(self->data) ) {
00185 Py_INCREF(Py_True);
00186 return Py_True;
00187 }else{
00188 Py_INCREF(Py_False);
00189 return Py_False;
00190 }
00191 }
00192
00193 static void cp_data_dealloc(struct cp_data *self)
00194 {
00195 Py_DECREF(self->owner);
00196 self->ob_type->tp_free((PyObject*)self);
00197 }
00198
00199 static PyMethodDef cp_data_methods[] = {
00200 {"type",(PyCFunction)cp_data_type, METH_NOARGS,
00201 "data.type() - Data element type"},
00202 {"tag",(PyCFunction)cp_data_tag, METH_NOARGS,
00203 "data.type() - Data element BER tag"},
00204 {"tag_label",(PyCFunction)cp_data_tag_label, METH_NOARGS,
00205 "data.type() - Data element tag name if known, None if not"},
00206 {"children",(PyCFunction)cp_data_children, METH_NOARGS,
00207 "data.children() - Returns dictionary of child elements"},
00208 {"value",(PyCFunction)cp_data_value, METH_NOARGS,
00209 "data.value() - Retrieve value of data element"},
00210 {"sda",(PyCFunction)cp_data_sda, METH_NOARGS,
00211 "data.sda() - Returns True if SDA protected"},
00212 {NULL,},
00213 };
00214
00215 static PyTypeObject data_pytype = {
00216 PyObject_HEAD_INIT(NULL)
00217 .tp_name = "emv.data",
00218 .tp_basicsize = sizeof(struct cp_data),
00219 .tp_flags = Py_TPFLAGS_DEFAULT,
00220 .tp_new = PyType_GenericNew,
00221 .tp_dealloc = (destructor)cp_data_dealloc,
00222 .tp_methods = cp_data_methods,
00223 .tp_repr = (reprfunc)cp_data_repr,
00224 .tp_doc = "EMV data element",
00225 };
00226
00227 static PyObject *data_dict(struct cp_emv *owner, emv_data_t *elem,
00228 unsigned int nmemb)
00229 {
00230 PyObject *dict;
00231 unsigned int i;
00232
00233 dict = PyDict_New();
00234 for(i = 0; i < nmemb; i++) {
00235 PyObject *key;
00236 struct cp_data *val;
00237
00238 val = (struct cp_data *)_PyObject_New(&data_pytype);
00239 val->data = elem[i];
00240 val->owner = owner;
00241 Py_INCREF(owner);
00242
00243 key = PyInt_FromLong(emv_data_tag(elem[i]));
00244
00245 PyDict_SetItem(dict, key, (PyObject *)val);
00246 }
00247
00248 return dict;
00249 }
00250
00251 static void cp_app_dealloc(struct cp_app *self)
00252 {
00253 Py_DECREF(self->owner);
00254 if ( !self->cur && !self->dirty )
00255 emv_app_delete(self->app);
00256 self->ob_type->tp_free((PyObject*)self);
00257 }
00258
00259 static PyObject *cp_app_rid(struct cp_app *self, PyObject *args)
00260 {
00261 emv_rid_t ret;
00262 if ( self->dirty ) {
00263 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00264 return NULL;
00265 }
00266 emv_app_rid(self->app, ret);
00267 return Py_BuildValue("s#", ret, EMV_RID_LEN);
00268 }
00269
00270 static PyObject *cp_app_aid(struct cp_app *self, PyObject *args)
00271 {
00272 uint8_t ret[EMV_AID_LEN];
00273 size_t len;
00274 if ( self->dirty ) {
00275 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00276 return NULL;
00277 }
00278 emv_app_aid(self->app, ret, &len);
00279 return Py_BuildValue("s#", ret, len);
00280 }
00281
00282 static PyObject *cp_app_label(struct cp_app *self, PyObject *args)
00283 {
00284 if ( self->dirty ) {
00285 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00286 return NULL;
00287 }
00288 return Py_BuildValue("s", emv_app_label(self->app));
00289 }
00290
00291 static PyObject *cp_app_pname(struct cp_app *self, PyObject *args)
00292 {
00293 if ( self->dirty ) {
00294 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00295 return NULL;
00296 }
00297 return Py_BuildValue("s", emv_app_pname(self->app));
00298 }
00299
00300 static PyObject *cp_app_prio(struct cp_app *self, PyObject *args)
00301 {
00302 if ( self->dirty ) {
00303 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00304 return NULL;
00305 }
00306 return Py_BuildValue("i", emv_app_prio(self->app));
00307 }
00308
00309 static PyObject *cp_app_confirm(struct cp_app *self, PyObject *args)
00310 {
00311 if ( self->dirty ) {
00312 PyErr_SetString(PyExc_IOError, "emv_app dirty shit");
00313 return NULL;
00314 }
00315 return Py_BuildValue("i", emv_app_confirm(self->app));
00316 }
00317
00318 static PyMethodDef cp_app_methods[] = {
00319 {"rid",(PyCFunction)cp_app_rid, METH_NOARGS,
00320 "app.rid() - Registered application ID"},
00321 {"aid",(PyCFunction)cp_app_aid, METH_NOARGS,
00322 "app.aid() - Application ID"},
00323 {"label",(PyCFunction)cp_app_label, METH_NOARGS,
00324 "app.name() - Label"},
00325 {"pname",(PyCFunction)cp_app_pname, METH_NOARGS,
00326 "app.pname() - Preferred name"},
00327 {"prio",(PyCFunction)cp_app_prio, METH_NOARGS,
00328 "app.prio() - Application priority"},
00329 {"confirm",(PyCFunction)cp_app_confirm, METH_NOARGS,
00330 "app.confirm() - Application confirmation indicator"},
00331 {NULL, }
00332 };
00333
00334 static PyTypeObject app_pytype = {
00335 PyObject_HEAD_INIT(NULL)
00336 .tp_name = "emv.app",
00337 .tp_basicsize = sizeof(struct cp_app),
00338 .tp_flags = Py_TPFLAGS_DEFAULT,
00339 .tp_new = PyType_GenericNew,
00340 .tp_dealloc = (destructor)cp_app_dealloc,
00341 .tp_methods = cp_app_methods,
00342 .tp_doc = "EMV application",
00343 };
00344
00345 static int cp_emv_init(struct cp_emv *self, PyObject *args, PyObject *kwds)
00346 {
00347 struct cp_chipcard *cc;
00348
00349 if ( !PyArg_ParseTuple(args, "O", &cc) )
00350 return -1;
00351
00352 self->emv = emv_init(cc->slot);
00353 if ( NULL == self->emv ) {
00354 PyErr_SetString(PyExc_IOError, "emv_init() failed");
00355 return -1;
00356 }
00357
00358 self->applist = NULL;
00359 self->current = NULL;
00360
00361 return 0;
00362 }
00363
00364 static void dirty_applist(struct cp_emv *self)
00365 {
00366 if ( self->applist ) {
00367 Py_ssize_t nmemb, i;
00368
00369 nmemb = PyList_Size(self->applist);
00370 for(i = 0; nmemb > 0 && i < nmemb; i++) {
00371 struct cp_app *app;
00372 PyObject *o;
00373
00374 o = PyList_GetItem(self->applist, i);
00375 if ( o->ob_type != &app_pytype )
00376 continue;
00377
00378 app = (struct cp_app *)o;
00379 app->dirty = 1;
00380 }
00381
00382 Py_DECREF(self->applist);
00383 }
00384 }
00385
00386 static void cp_emv_dealloc(struct cp_emv *self)
00387 {
00388 dirty_applist(self);
00389 emv_fini(self->emv);
00390 self->ob_type->tp_free((PyObject*)self);
00391 }
00392
00393 static PyObject *app_list(struct cp_emv *self)
00394 {
00395 PyObject *applist = NULL;
00396 emv_app_t app;
00397
00398 applist = PyList_New(0);
00399 if ( NULL == applist )
00400 return NULL;
00401
00402 for(app = emv_appsel_pse_first(self->emv); app;
00403 app = emv_appsel_pse_next(self->emv, app) ) {
00404 struct cp_app *a;
00405
00406 a = (struct cp_app *)_PyObject_New(&app_pytype);
00407 if ( NULL == a )
00408 break;
00409
00410 Py_INCREF(self);
00411 a->owner = self;
00412 a->app = app;
00413 a->cur = 0;
00414 a->dirty = 0;
00415
00416 PyList_Append(applist, (PyObject *)a);
00417 }
00418
00419 return applist;
00420 }
00421
00422 static int set_current(struct cp_emv *self)
00423 {
00424 struct cp_app *a;
00425 emv_app_t app;
00426
00427 app = emv_current_app(self->emv);
00428 if ( NULL == app ) {
00429 set_err(self->emv);
00430 return 0;
00431 }
00432
00433 a = (struct cp_app *)_PyObject_New(&app_pytype);
00434 if ( NULL == a )
00435 return 0;
00436
00437 Py_INCREF(self);
00438 a->owner = self;
00439 a->app = app;
00440 a->cur = 1;
00441 a->dirty = 0;
00442 if ( self->current )
00443 self->current->dirty = 1;
00444 self->current = a;
00445 return 1;
00446 }
00447
00448 static PyObject *cp_appsel_pse(struct cp_emv *self, PyObject *args)
00449 {
00450 if ( !emv_appsel_pse(self->emv) ) {
00451 set_err(self->emv);
00452 return NULL;
00453 }
00454
00455 dirty_applist(self);
00456 self->applist = app_list(self);
00457 Py_INCREF(self->applist);
00458
00459 return self->applist;
00460 }
00461
00462 static PyObject *cp_select_pse(struct cp_emv *self, PyObject *args)
00463 {
00464 struct cp_app *app;
00465
00466 if ( !PyArg_ParseTuple(args, "O", &app) )
00467 return NULL;
00468
00469 if ( !emv_app_select_pse(self->emv, app->app) ) {
00470 set_err(self->emv);
00471 return NULL;
00472 }
00473
00474 if ( !set_current(self) )
00475 return NULL;
00476
00477 Py_INCREF(Py_None);
00478 return Py_None;
00479 }
00480
00481 static PyObject *cp_select_aid(struct cp_emv *self, PyObject *args)
00482 {
00483 const uint8_t *aid;
00484 size_t len;
00485
00486 if ( !PyArg_ParseTuple(args, "s#", &aid, &len) )
00487 return NULL;
00488
00489 if ( !emv_app_select_aid(self->emv, aid, len) ) {
00490 set_err(self->emv);
00491 return NULL;
00492 }
00493
00494 if ( !set_current(self) )
00495 return NULL;
00496
00497 Py_INCREF(Py_None);
00498 return Py_None;
00499 }
00500
00501 static PyObject *cp_select_aid_next(struct cp_emv *self, PyObject *args)
00502 {
00503 struct cp_app *app;
00504 const uint8_t *aid;
00505 size_t len;
00506
00507 if ( !PyArg_ParseTuple(args, "Os#", &app, &aid, &len) )
00508 return NULL;
00509
00510 if ( !emv_app_select_aid_next(self->emv, aid, len) ) {
00511 set_err(self->emv);
00512 return NULL;
00513 }
00514
00515 if ( !set_current(self) )
00516 return NULL;
00517
00518 Py_INCREF(Py_None);
00519 return Py_None;
00520 }
00521
00522 static PyObject *cp_current_app(struct cp_emv *self, PyObject *args)
00523 {
00524 return (PyObject *)self->current;
00525 }
00526
00527 static PyObject *cp_init(struct cp_emv *self, PyObject *args)
00528 {
00529 PyObject *tup;
00530 emv_aip_t aip;
00531
00532 if ( !emv_app_init(self->emv) ) {
00533 set_err(self->emv);
00534 return NULL;
00535 }
00536
00537 if ( !emv_app_aip(self->emv, aip) ) {
00538 set_err(self->emv);
00539 return NULL;
00540 }
00541
00542 tup = PyTuple_New(2);
00543 if ( NULL == tup )
00544 return NULL;
00545
00546 if ( PyTuple_SetItem(tup, 0, PyInt_FromLong(aip[0])) ||
00547 PyTuple_SetItem(tup, 1, PyInt_FromLong(aip[1])) ) {
00548 Py_DECREF(tup);
00549 return NULL;
00550 }
00551
00552 return tup;
00553 }
00554
00555 static PyObject *data_list(struct cp_emv *owner, emv_data_t *elem,
00556 unsigned int nmemb)
00557 {
00558 PyObject *list;
00559 unsigned int i;
00560
00561 list = PyList_New(nmemb);
00562 for(i = 0; i < nmemb; i++) {
00563 struct cp_data *val;
00564
00565 val = (struct cp_data *)_PyObject_New(&data_pytype);
00566 val->data = elem[i];
00567 val->owner = owner;
00568 Py_INCREF(owner);
00569
00570 PyList_SetItem(list, i, (PyObject *)val);
00571 }
00572
00573 return list;
00574 }
00575
00576 static PyObject *cp_read_app_data(struct cp_emv *self, PyObject *args)
00577 {
00578 emv_data_t *rec;
00579 unsigned int num_rec;
00580
00581 if ( !emv_read_app_data(self->emv) ) {
00582 set_err(self->emv);
00583 return NULL;
00584 }
00585
00586 rec = emv_retrieve_records(self->emv, &num_rec);
00587 return data_list(self, rec, num_rec);
00588 }
00589
00590 struct key_cb {
00591 PyObject *mod, *exp;
00592 };
00593
00594 static const uint8_t *get_mod(void *priv, unsigned int idx, size_t *len)
00595 {
00596 struct key_cb *cb = priv;
00597 PyObject *key, *args;
00598 Py_ssize_t key_len;
00599
00600 args = PyTuple_New(1);
00601 PyTuple_SetItem(args, 0, PyInt_FromLong(idx));
00602
00603 key = PyObject_CallObject(cb->mod, args);
00604 key_len = PyString_Size(key);
00605 if ( key_len <= 0 )
00606
00607 return NULL;
00608
00609 *len = (size_t)key_len;
00610 return (uint8_t *)PyString_AsString(key);
00611 }
00612
00613 static const uint8_t *get_exp(void *priv, unsigned int idx, size_t *len)
00614 {
00615 struct key_cb *cb = priv;
00616 PyObject *key, *args;
00617 Py_ssize_t key_len;
00618
00619 args = PyTuple_New(1);
00620 PyTuple_SetItem(args, 0, PyInt_FromLong(idx));
00621
00622 key = PyObject_CallObject(cb->exp, args);
00623 key_len = PyString_Size(key);
00624 if ( key_len <= 0 )
00625
00626 return NULL;
00627
00628 *len = (size_t)key_len;
00629 return (uint8_t *)PyString_AsString(key);
00630 }
00631
00632 static PyObject *cp_sda(struct cp_emv *self, PyObject *args)
00633 {
00634 struct key_cb cb;
00635
00636 if ( !PyArg_ParseTuple(args, "OO", &cb.mod, &cb.exp) )
00637 return NULL;
00638
00639 if ( !emv_authenticate_static_data(self->emv, get_mod, get_exp, &cb) ) {
00640 set_err(self->emv);
00641 return NULL;
00642 }
00643
00644 Py_INCREF(Py_None);
00645 return Py_None;
00646 }
00647
00648 static PyObject *cp_dda(struct cp_emv *self, PyObject *args)
00649 {
00650 struct key_cb cb;
00651
00652 if ( !PyArg_ParseTuple(args, "OO", &cb.mod, &cb.exp) )
00653 return NULL;
00654
00655 if ( !emv_authenticate_dynamic(self->emv, get_mod, get_exp, &cb) ) {
00656 set_err(self->emv);
00657 return NULL;
00658 }
00659
00660 Py_INCREF(Py_None);
00661 return Py_None;
00662 }
00663
00664 static PyObject *cp_cvm_pin(struct cp_emv *self, PyObject *args)
00665 {
00666 char *pin;
00667
00668 if ( !PyArg_ParseTuple(args, "s", &pin) )
00669 return NULL;
00670
00671 if ( !emv_cvm_pin(self->emv, pin) ) {
00672 set_err(self->emv);
00673 return NULL;
00674 }
00675
00676 Py_INCREF(Py_True);
00677 return Py_True;
00678 }
00679
00680 static PyObject *cp_pin_try_counter(struct cp_emv *self, PyObject *args)
00681 {
00682 return PyInt_FromLong(emv_pin_try_counter(self->emv));
00683 }
00684
00685 static PyObject *cp_atc(struct cp_emv *self, PyObject *args)
00686 {
00687 return PyInt_FromLong(emv_trm_atc(self->emv));
00688 }
00689
00690 static PyObject *cp_oatc(struct cp_emv *self, PyObject *args)
00691 {
00692 return PyInt_FromLong(emv_trm_last_online_atc(self->emv));
00693 }
00694
00695 static PyObject *ac2tuple(const uint8_t *ptr, size_t len)
00696 {
00697 PyObject *tup;
00698 int iad = (ptr[1] + 2 < len);
00699
00700 if ( len < 4 || ptr[0] != 0x80 || ptr[1] + 2 > len ) {
00701 PyErr_SetString(PyExc_ValueError, "Cryptogram format error");
00702 return NULL;
00703 }
00704
00705 tup = PyTuple_New(iad ? 4 : 3);
00706 if ( NULL == tup )
00707 return NULL;
00708
00709 PyTuple_SetItem(tup, 0, PyInt_FromLong(ptr[2]));
00710 PyTuple_SetItem(tup, 1, PyInt_FromLong(ptr[3]));
00711 PyTuple_SetItem(tup, 2, PyString_FromStringAndSize((char *)ptr + 4,
00712 ptr[1] - 2));
00713 if ( iad )
00714 PyTuple_SetItem(tup, 3,
00715 PyString_FromStringAndSize((char *)ptr + ptr[1] + 2,
00716 len - ptr[1] + 2));
00717
00718 return tup;
00719 }
00720
00721 static PyObject *cp_gen_ac(struct cp_emv *self, PyObject *args)
00722 {
00723 const uint8_t *tx, *rx;
00724 size_t txlen, rxlen;
00725 PyObject *tup;
00726 int ref;
00727
00728
00729 if ( !PyArg_ParseTuple(args, "is#", &ref, &tx, &txlen) )
00730 return NULL;
00731
00732 hex_dump(tx, txlen, 16);
00733
00734 rx = emv_generate_ac(self->emv, ref, tx, txlen, &rxlen);
00735 if ( NULL == rx ) {
00736 set_err(self->emv);
00737 return NULL;
00738 }
00739
00740 tup = ac2tuple(rx, rxlen);
00741 return tup;
00742 }
00743
00744 static PyMethodDef cp_emv_methods[] = {
00745 {"appsel_pse",(PyCFunction)cp_appsel_pse, METH_VARARGS,
00746 "emv.appsel_pse(app) - Read payment system directory"},
00747 {"select_pse",(PyCFunction)cp_select_pse, METH_VARARGS,
00748 "emv.select_pse(emv.app) - Select application from PSE entry"},
00749 {"select_aid",(PyCFunction)cp_select_aid, METH_VARARGS,
00750 "emv.select_aid(aid) - Select application from AID"},
00751 {"select_aid_next",(PyCFunction)cp_select_aid_next, METH_VARARGS,
00752 "emv.select_aid_next(aid) - Select next application from AID"},
00753 {"current_app",(PyCFunction)cp_current_app, METH_VARARGS,
00754 "emv.current_app(aid) - Returns currently selected app"},
00755 {"init",(PyCFunction)cp_init, METH_NOARGS,
00756 "emv.init() - Initiate application processing"},
00757 {"read_app_data",(PyCFunction)cp_read_app_data, METH_NOARGS,
00758 "emv.read_app_data() - Read application data"},
00759 {"authenticate_static_data",(PyCFunction)cp_sda, METH_VARARGS,
00760 "authenticate_static_data(mod_cb, exp_cb) - "
00761 "Static data authentication"},
00762 {"authenticate_dynamic",(PyCFunction)cp_dda, METH_VARARGS,
00763 "authenticate_static_data(mod_cb, exp_cb) - "
00764 "Dynamic data authentication"},
00765 {"cvm_pin",(PyCFunction)cp_cvm_pin, METH_VARARGS,
00766 "emv.cvm_pin(string) - Plaintext PIN cardholder verification"},
00767 {"pin_try_counter",(PyCFunction)cp_pin_try_counter, METH_NOARGS,
00768 "emv.pin_try_counter() - Remaining PIN tries allowed"},
00769 {"atc",(PyCFunction)cp_atc, METH_NOARGS,
00770 "emv.atc() - Application transaction counter"},
00771 {"last_online_atc",(PyCFunction)cp_oatc, METH_NOARGS,
00772 "emv.oatc() - ATC at last online transaction"},
00773 {"generate_ac",(PyCFunction)cp_gen_ac, METH_VARARGS,
00774 "emv.gen_ac() - Generate application cryptogram"},
00775 {NULL, }
00776 };
00777
00778 static PyTypeObject emv_pytype = {
00779 PyObject_HEAD_INIT(NULL)
00780 .tp_name = "emv.card",
00781 .tp_basicsize = sizeof(struct cp_emv),
00782 .tp_flags = Py_TPFLAGS_DEFAULT,
00783 .tp_new = PyType_GenericNew,
00784 .tp_init = (initproc)cp_emv_init,
00785 .tp_dealloc = (destructor)cp_emv_dealloc,
00786 .tp_methods = cp_emv_methods,
00787 .tp_doc = "EMV chip",
00788 };
00789
00790 struct dol_cb {
00791 PyObject *list;
00792 PyObject *dict;
00793 };
00794
00795 static int dol_cbfn(uint16_t tag, uint8_t *ptr, size_t len, void *priv)
00796 {
00797 struct dol_cb *p = priv;
00798 PyObject *list;
00799 PyObject *dict;
00800 PyObject *key, *value;
00801 Py_ssize_t plen;
00802
00803 list = p->list;
00804 dict = p->dict;
00805
00806 key = PyInt_FromLong(tag);
00807 if ( NULL == key )
00808 return 0;
00809
00810 PyList_Append(list, key);
00811
00812 if ( NULL == dict )
00813 return 1;
00814
00815 value = PyDict_GetItem(dict, key);
00816 if ( NULL == value ) {
00817 memset(ptr, 0, len);
00818 return 1;
00819 }
00820
00821 if ( &PyString_Type != value->ob_type ) {
00822 PyErr_SetString(PyExc_TypeError, "expected dictionary");
00823 return 0;
00824 }
00825
00826 plen = PyString_Size(value);
00827 if ( plen > len ) {
00828 PyErr_SetString(PyExc_ValueError, "DOL element too damn big");
00829 return 0;
00830 }
00831
00832 memcpy(ptr, PyString_AsString(value), plen);
00833 memset(ptr + plen, 0, len - plen);
00834 return 1;
00835 }
00836
00837 static PyObject *do_dol(struct cp_emv *self, PyObject *args, int create)
00838 {
00839 PyObject *list, *dict;
00840 struct dol_cb cb;
00841 uint8_t *dol;
00842 size_t len, rlen;
00843
00844 if ( create ) {
00845 if ( !PyArg_ParseTuple(args, "s#O", &dol, &len, &dict) )
00846 return NULL;
00847 if ( &PyDict_Type != dict->ob_type ) {
00848 PyErr_SetString(PyExc_TypeError, "expected dictionary");
00849 return NULL;
00850 }
00851 }else{
00852 if ( !PyArg_ParseTuple(args, "s#", &dol, &len) )
00853 return NULL;
00854 dict = NULL;
00855 }
00856
00857 list = PyList_New(0);
00858 if ( NULL == list )
00859 return NULL;
00860
00861 cb.list = list;
00862 cb.dict = dict;
00863
00864 dol = emv_construct_dol(dol_cbfn, dol, len, &rlen, &cb);
00865 if ( create ) {
00866 return PyString_FromStringAndSize((char *)dol, rlen);
00867 }else{
00868 free(dol);
00869 return list;
00870 }
00871 }
00872
00873 static PyObject *cp_dol_read(struct cp_emv *self, PyObject *args)
00874 {
00875 return do_dol(self, args, 0);
00876 }
00877
00878 static PyObject *cp_dol_create(struct cp_emv *self, PyObject *args)
00879 {
00880 return do_dol(self, args, 1);
00881 }
00882
00883 static PyMethodDef methods[] = {
00884 {"dol_read",(PyCFunction)cp_dol_read, METH_VARARGS,
00885 "dol_read(str) - returns list of (tag, len) tuples"},
00886 {"dol_create",(PyCFunction)cp_dol_create, METH_VARARGS,
00887 "dol_create(str) - returns the constructed binary data item"},
00888 {NULL, }
00889 };
00890
00891 #define _INT_CONST(m, c) PyModule_AddIntConstant(m, #c, EMV_ ## c)
00892 PyMODINIT_FUNC initemv(void)
00893 {
00894 PyObject *m;
00895
00896 if ( PyType_Ready(&emv_pytype) < 0 )
00897 return;
00898 if ( PyType_Ready(&app_pytype) < 0 )
00899 return;
00900 if ( PyType_Ready(&data_pytype) < 0 )
00901 return;
00902
00903 m = Py_InitModule3("emv", methods, "EMV chipcard API");
00904 if ( NULL == m )
00905 return;
00906
00907 _INT_CONST(m, DATA_BINARY);
00908 _INT_CONST(m, DATA_TEXT);
00909 _INT_CONST(m, DATA_INT);
00910 _INT_CONST(m, DATA_BCD);
00911 _INT_CONST(m, DATA_DATE);
00912
00913 _INT_CONST(m, ERR_SYSTEM);
00914 _INT_CONST(m, ERR_CCID);
00915 _INT_CONST(m, ERR_ICC);
00916 _INT_CONST(m, ERR_EMV);
00917
00918 _INT_CONST(m, ERR_SUCCESS);
00919 _INT_CONST(m, ERR_DATA_ELEMENT_NOT_FOUND);
00920 _INT_CONST(m, ERR_BAD_PIN_FORMAT);
00921 _INT_CONST(m, ERR_FUNC_NOT_SUPPORTED);
00922 _INT_CONST(m, ERR_KEY_NOT_FOUND);
00923 _INT_CONST(m, ERR_KEY_SIZE_MISMATCH);
00924 _INT_CONST(m, ERR_RSA_RECOVERY);
00925 _INT_CONST(m, ERR_CERTIFICATE);
00926 _INT_CONST(m, ERR_SSA_SIGNATURE);
00927 _INT_CONST(m, ERR_BAD_PIN);
00928
00929 _INT_CONST(m, TAG_MAGSTRIP_TRACK2);
00930 _INT_CONST(m, TAG_PAN);
00931 _INT_CONST(m, TAG_RECORD);
00932 _INT_CONST(m, TAG_CDOL1);
00933 _INT_CONST(m, TAG_CDOL2);
00934 _INT_CONST(m, TAG_CVM_LIST);
00935 _INT_CONST(m, TAG_CA_PK_INDEX);
00936 _INT_CONST(m, TAG_ISS_PK_CERT);
00937 _INT_CONST(m, TAG_ISS_PK_R);
00938 _INT_CONST(m, TAG_SSA_DATA);
00939 _INT_CONST(m, TAG_CARDHOLDER_NAME);
00940 _INT_CONST(m, TAG_DATE_EXP);
00941 _INT_CONST(m, TAG_DATE_EFF);
00942 _INT_CONST(m, TAG_ISSUER_COUNTRY);
00943 _INT_CONST(m, TAG_SERVICE_CODE);
00944 _INT_CONST(m, TAG_PAN_SEQ);
00945 _INT_CONST(m, TAG_USAGE_CONTROL);
00946 _INT_CONST(m, TAG_APP_VER);
00947 _INT_CONST(m, TAG_IAC_DEFAULT);
00948 _INT_CONST(m, TAG_IAC_DENY);
00949 _INT_CONST(m, TAG_IAC_ONLINE);
00950 _INT_CONST(m, TAG_MAGSTRIP_TRACK1);
00951 _INT_CONST(m, TAG_ISS_PK_EXP);
00952 _INT_CONST(m, TAG_SDA_TAG_LIST);
00953 _INT_CONST(m, TAG_UNPREDICTABLE_NUMBER);
00954
00955 _INT_CONST(m, AC_AAC);
00956 _INT_CONST(m, AC_TC);
00957 _INT_CONST(m, AC_ARQC);
00958 _INT_CONST(m, AC_CDA);
00959
00960 _INT_CONST(m, AIP_CDA);
00961 _INT_CONST(m, AIP_ISS);
00962 _INT_CONST(m, AIP_TRM);
00963 _INT_CONST(m, AIP_CVM);
00964 _INT_CONST(m, AIP_DDA);
00965 _INT_CONST(m, AIP_SDA);
00966
00967 _INT_CONST(m, AUC1_DOMESTIC_CASH);
00968 _INT_CONST(m, AUC1_INT_CASH);
00969 _INT_CONST(m, AUC1_DOMESTIC_GOODS);
00970 _INT_CONST(m, AUC1_INT_GOODS);
00971 _INT_CONST(m, AUC1_DOMESTIC_SERVICES);
00972 _INT_CONST(m, AUC1_INT_SERVICES);
00973 _INT_CONST(m, AUC1_ATM);
00974 _INT_CONST(m, AUC1_NON_ATM_TERMINALS);
00975 _INT_CONST(m, AUC2_DOMESTIC_CASHBACK);
00976 _INT_CONST(m, AUC2_INT_CASHBACK);
00977
00978 Py_INCREF(&emv_pytype);
00979 PyModule_AddObject(m, "card", (PyObject *)&emv_pytype);
00980 Py_INCREF(&app_pytype);
00981 PyModule_AddObject(m, "app", (PyObject *)&app_pytype);
00982 Py_INCREF(&data_pytype);
00983 PyModule_AddObject(m, "data", (PyObject *)&data_pytype);
00984 }