Changeset 1010 for trunk/src/ifd


Ignore:
Timestamp:
12/17/07 13:29:24 (4 years ago)
Author:
ludovic.rousseau
Message:

the entire file was duplicated

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ifd/ifd-rutoken.c

    r1009 r1010  
    391391        ifd_driver_register("rutoken", &rutoken_driver); 
    392392} 
    393 /* 
    394  * driver for Rutoken devices 
    395  * 
    396  * Copyright (C) 2007, Pavel Mironchik <rutoken@rutoken.ru> 
    397  * Copyright (C) 2007, Eugene Hermann <e_herman@tut.by> 
    398  */ 
    399  
    400 #include "internal.h" 
    401 #include "stdio.h" 
    402 #include "unistd.h" 
    403 #include "string.h" 
    404  
    405 #define MAX_BUF_T0_LEN  256 
    406 #define T0_HDR_LEN      5 
    407  
    408  
    409 #define USB_ICC_POWER_ON        0x62 
    410 #define USB_ICC_POWER_OFF       0x63 
    411 #define USB_ICC_XFR_BLOCK       0x65 
    412 #define USB_ICC_DATA_BLOCK      0x6F 
    413 #define USB_ICC_GET_STATUS      0xA0 
    414  
    415 #define ICC_STATUS_IDLE                 0x00 
    416 #define ICC_STATUS_READY_DATA   0x10 
    417 #define ICC_STATUS_READY_SW             0x20 
    418 #define ICC_STATUS_BUSY_COMMON  0x40 
    419 #define ICC_STATUS_MUTE                 0x80 
    420  
    421 #define OUR_ATR_LEN     19 
    422  
    423 static int rutoken_open(ifd_reader_t * reader, const char *device_name) 
    424 { 
    425         ifd_device_t *dev; 
    426         ifd_debug(1, "rutoken_open - %s\n", device_name); 
    427         ifd_debug(1, "%s:%d rutoken_open()", __FILE__, __LINE__); 
    428  
    429         reader->name = "ruToken driver.\n"; 
    430         reader->nslots = 1; 
    431         if (!(dev = ifd_device_open(device_name))) 
    432                 return -1; 
    433  
    434         if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) { 
    435                 ct_error("ruToken driver: device %s is not a USB device", device_name); 
    436                 ifd_device_close(dev); 
    437                 return -1; 
    438         } 
    439  
    440         reader->device = dev; 
    441         dev->timeout = 1000; 
    442  
    443         ifd_debug(1, "%s:%d Checkpoint", __FILE__, __LINE__); 
    444         return 0; 
    445 } 
    446  
    447 static int rutoken_activate(ifd_reader_t * reader) 
    448 { 
    449         ifd_debug(1, "%s:%d rutoken_activate()", __FILE__, __LINE__); 
    450         return 0; 
    451 } 
    452  
    453 static int rutoken_deactivate(ifd_reader_t * reader) 
    454 { 
    455         ifd_debug(1, "%s:%d rutoken_deactivate()", __FILE__, __LINE__); 
    456         return -1; 
    457 } 
    458  
    459 // Get Status 0 - OK 
    460 //              - ERROR 
    461 // 
    462 int rutoken_getstatus(ifd_reader_t * reader, char *status) 
    463 { 
    464         // TODO Chech for timeout 
    465         //ifd_debug(1, ""); 
    466         if(!ifd_usb_control(reader->device, 0xc1, USB_ICC_GET_STATUS, 0, 0, status, 1, 1000) < 0 ) 
    467                 return -1; 
    468         if((*status & 0xF0) == ICC_STATUS_BUSY_COMMON){ 
    469                 int i; 
    470                 for(i = 0; i < 100000; i++) { 
    471                         if(!ifd_usb_control(reader->device, 0xc1, USB_ICC_GET_STATUS, 0, 0, status, 1, 1000) < 0 ) 
    472                                 return -1; 
    473                         if((*status & 0xF0) != ICC_STATUS_BUSY_COMMON) 
    474                                 return 0; 
    475                         usleep(1000); 
    476                 } 
    477                 return -1; 
    478         } 
    479         return *status; 
    480 } 
    481  
    482 static int rutoken_card_reset(ifd_reader_t * reader, int slot, void *atr, 
    483                 size_t atr_len) 
    484 { 
    485         ifd_debug(1, "%s:%d rutoken_card_reset()", __FILE__, __LINE__); 
    486  
    487         int nLen = 0, i; 
    488         ifd_debug(1, "rutoken_card_reset, slot = %X\n", slot); 
    489         if(ifd_usb_control(reader->device, 0x41, USB_ICC_POWER_OFF, 0, 0, 0, 0, -1) < 0) 
    490         { 
    491                 ifd_debug(1, "error poweroff\n"); 
    492                 return -1; 
    493         } 
    494         char status; 
    495         if( rutoken_getstatus(reader, &status) < 0) 
    496         { 
    497                 ifd_debug(1, "error get status\n"); 
    498                 return -1; 
    499         } 
    500         if( status == ICC_STATUS_READY_DATA ) { 
    501                 char buf[OUR_ATR_LEN]; 
    502                 memset(buf, 0, OUR_ATR_LEN); 
    503  
    504                 nLen = ifd_usb_control(reader->device, 0xc1, USB_ICC_POWER_ON, 0, 0, buf, OUR_ATR_LEN, 1000); 
    505                 if( nLen < 0 ) 
    506                 { 
    507                         ifd_debug(1, "error poewron\n"); 
    508                         return -1; 
    509                 } 
    510  
    511                 ifd_debug(1, "returned len = %d", nLen); 
    512                 for(i = 0; i < OUR_ATR_LEN; i++) ifd_debug(1, "%c", buf[i]); 
    513                 memcpy(atr, buf, nLen); 
    514                 return nLen; 
    515         } 
    516  
    517         ifd_debug(1, "error bad status\n"); 
    518         return -1; 
    519 } 
    520  
    521 static int rutoken_restart(ifd_reader_t * reader) 
    522 { 
    523         char atr[256]; 
    524         return rutoken_card_reset(reader, 0, atr, 256); 
    525 } 
    526  
    527 /* 
    528  * Select a protocol. 
    529  */ 
    530 static int rutoken_set_protocol(ifd_reader_t * reader, int nslot, int proto) 
    531 { 
    532         ifd_debug(1, "set protocol: {%d}", proto); 
    533  
    534         ifd_slot_t *slot; 
    535         ifd_protocol_t *p; 
    536  
    537         ifd_debug(1, "proto=%d", proto); 
    538         if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_TRANSPARENT) { 
    539                 ct_error("%s: protocol %d not supported", reader->name, proto); 
    540                 return IFD_ERROR_NOT_SUPPORTED; 
    541         } 
    542         slot = &reader->slot[nslot]; 
    543         p = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT, reader, slot->dad); 
    544         if (p == NULL) { 
    545                 ct_error("%s: internal error", reader->name); 
    546                 return IFD_ERROR_GENERIC; 
    547         } 
    548         if (slot->proto) { 
    549                 ifd_protocol_free(slot->proto); 
    550                 slot->proto = NULL; 
    551         } 
    552         slot->proto = p; 
    553         ifd_debug(1, "success"); 
    554         return 0; 
    555 } 
    556  
    557 static int rutoken_card_status(ifd_reader_t * reader, int slot, 
    558                 int *status) 
    559 { 
    560         //ifd_debug(1, ""); 
    561         *status = IFD_CARD_PRESENT; 
    562         return 0; 
    563 } 
    564  
    565 static int rutoken_send(ifd_reader_t * reader, unsigned int dad, 
    566                 const unsigned char *buffer, size_t len) 
    567 { 
    568         int ret; 
    569         char status; 
    570         ifd_debug(3, "usb send %s len %d", ct_hexdump(buffer, len), len); 
    571         ret =  ifd_usb_control(reader->device, 0x41, USB_ICC_XFR_BLOCK, 0, 0, (void *)buffer, len, -1); 
    572  
    573         if (rutoken_getstatus(reader, &status) < 0) 
    574         { 
    575                 ret = -1; 
    576                 ifd_debug(1, "error get status"); 
    577         } 
    578         return ret; 
    579 } 
    580  
    581 static int rutoken_recv(ifd_reader_t * reader, unsigned int dad, 
    582                 unsigned char *buffer, size_t len, long timeout) 
    583 { 
    584         char status; 
    585         int ret = len; 
    586         // USB_ICC_DATA_BLOCK 
    587         if( (ret = ifd_usb_control(reader->device, 0xc1, USB_ICC_DATA_BLOCK, 0, 0, buffer, len, timeout)) >= 0) 
    588                 if (rutoken_getstatus(reader, &status) < 0) 
    589                 { 
    590                         ret = -1; 
    591                         ifd_debug(1, "error get status, %0x", status); 
    592                 } 
    593         ifd_debug(3, "usd recv %s len %d", ct_hexdump(buffer, ret), ret); 
    594         return ret; 
    595 } 
    596  
    597 static int rutoken_recv_sw(ifd_reader_t * reader, int dad, unsigned char *sw) 
    598 { 
    599         unsigned char status; 
    600         if(rutoken_getstatus(reader, &status) == ICC_STATUS_MUTE) 
    601         {  //If device not responsive 
    602                 ifd_debug(1, "status = ICC_STATUS_MUTE"); 
    603                 return(rutoken_restart(reader)); 
    604         } 
    605         if(status == ICC_STATUS_READY_SW) 
    606         { 
    607                 ifd_debug(1, "status = ICC_STATUS_READY_SW;"); 
    608                 if(rutoken_recv(reader, 0, sw, 2, 10000) < 0) 
    609                         return -5; 
    610                 ifd_debug(1, "Get SW %x %x", sw[0], sw[1]); 
    611                 return 2; 
    612         } 
    613         return -1; 
    614 } 
    615  
    616 // return how mach byte send 
    617 // sbuf - APDU bufer 
    618 // slen 
    619 static int rutoken_send_tpducomand(ifd_reader_t * reader, int dad, const void *sbuf, size_t slen, void *rbuf, size_t rlen, int iscase4) 
    620 { 
    621         ifd_debug(1, "send tpdu command %s, len: %d", ct_hexdump(sbuf, slen), slen); 
    622         int rrecv = 0; 
    623         unsigned char status; 
    624         unsigned char sw[2]; 
    625         ifd_iso_apdu_t iso; 
    626         if ( ifd_iso_apdu_parse(sbuf, slen, &iso) < 0) 
    627                 return -1; 
    628         unsigned char hdr[T0_HDR_LEN]={iso.cla, iso.ins, iso.p1, iso.p2, 0}; 
    629         switch(iso.cse){ 
    630                 case    IFD_APDU_CASE_1: 
    631                         // {cla, ins, p1, p2, 0}; 
    632                         ifd_debug(1, "case 1"); 
    633                         break; 
    634                 case    IFD_APDU_CASE_2S: 
    635                         // {cla, ins, p1, p2, le}; 
    636                         // Rutoken Bug!!! 
    637                         ifd_debug(1, "case 2"); 
    638                         if(iso.ins == 0xa4){ 
    639                                 hdr[4] = 0x20; 
    640                                 iso.le = 0x20; 
    641                         } 
    642                         else{ 
    643                                 hdr[4] = iso.le; 
    644                         } 
    645                         break; 
    646                 case    IFD_APDU_CASE_3S: 
    647                         // {cla, ins, p1, p2, lc}; 
    648                         ifd_debug(1, "case 3"); 
    649                         hdr[4] = iso.lc; 
    650                         break; 
    651                 default: 
    652                         break; 
    653         } 
    654         //send TPDU header 
    655         if (rutoken_send(reader, 0, hdr, T0_HDR_LEN) < 0) 
    656                 return -1; 
    657         // send TPDU data or get answere and sw 
    658         switch(iso.cse){ 
    659                 case    IFD_APDU_CASE_1: 
    660                         // get sw 
    661                         if (rutoken_recv_sw(reader, 0, sw) < 0) 
    662                                 return -2; 
    663                         break; 
    664                 case    IFD_APDU_CASE_2S: 
    665                         // get answere 
    666                         ifd_debug(1, "Get Data %d", iso.le); 
    667                         if(rutoken_getstatus(reader, &status) == ICC_STATUS_READY_DATA) 
    668                         { 
    669                                 rrecv = rutoken_recv(reader, 0, rbuf, iso.le, 10000); 
    670                                 if (rrecv < 0) 
    671                                         return -2; 
    672                                 ifd_debug(1, "Get TPDU Anser %s", ct_hexdump(rbuf, iso.le)); 
    673                         } 
    674                         if (rutoken_recv_sw(reader, 0, sw) < 0) 
    675                                 return -2; 
    676                         if ( sw[0] == 0x67) { 
    677                                 // Le definitely not accepted 
    678                                 break; 
    679                         } 
    680                         if ( (sw[0] == 0x6c) ) { 
    681                                 unsigned char sbuftmp[slen]; 
    682                                 memcpy(sbuftmp, sbuf, slen); 
    683                                 sbuftmp[4] = sw[1]; 
    684                                 return rutoken_send_tpducomand(reader, dad, sbuftmp, slen, rbuf,  rlen, 0); 
    685                         } 
    686  
    687                         break; 
    688                 case    IFD_APDU_CASE_3S: 
    689                         // send data 
    690                         ifd_debug(1, "Send Data %d", iso.lc); 
    691                         if(rutoken_getstatus(reader, &status) == ICC_STATUS_READY_DATA) 
    692                         { 
    693                                 ifd_debug(1, "Send TPDU Data %s", ct_hexdump(iso.data, iso.lc)); 
    694                                 if (rutoken_send(reader, 0, iso.data, iso.lc) < 0) return -4; 
    695                         } else return -3; 
    696                         // get sw 
    697                         if (rutoken_recv_sw(reader, 0, sw) < 0) 
    698                                 return -2; 
    699  
    700                         // NOT STANDART TPDU!!! BEGIN 
    701                         if ( sw[0]== 0x61){ 
    702                                 unsigned char lx = sw[1]; 
    703                                 hdr[0] = 0x00;  //  iso.cla; (ruTokens specific) 
    704                                 hdr[1] = 0xc0; // ins get response 
    705                                 hdr[2] = 0; // p1 
    706                                 hdr[3] = 0; // p2 
    707                                 hdr[4] = lx ; //lx (case 2) 
    708                                 if(iscase4) 
    709                                         return rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
    710                                 else { 
    711                                         int recvtmp = rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
    712                                         rrecv = 0; 
    713                                         memcpy(sw, rbuf+recvtmp-2, 2); 
    714                                         break; 
    715                                 } 
    716                         } 
    717  
    718                         if ( (sw[0] == 0x90) && (sw[1] == 0x00)) 
    719                         { 
    720                                 hdr[0] = 0x00; //iso.cla; 
    721                                 hdr[1] = 0xc0; // ins get response 
    722                                 hdr[2] = 0; // p1 
    723                                 hdr[3] = 0; // p2 
    724                                 hdr[4] = iso.le; // le (case 2) 
    725                                 if(iscase4) 
    726                                         return rutoken_send_tpducomand(reader, dad, hdr, T0_HDR_LEN, rbuf, rlen, 0); 
    727                         } 
    728                         // NOT STANDART TPDU!!! END 
    729  
    730                         break; 
    731                 default: 
    732                         break; 
    733         } 
    734         // Add SW to respond 
    735         memcpy(((char *)rbuf)+rrecv, sw, 2); 
    736         rrecv+=2; 
    737         ifd_debug(1, "Recv %d bytes", rrecv); 
    738         return rrecv; 
    739 } 
    740  
    741 static int rutoken_transparent( ifd_reader_t * reader, int dad, 
    742                 const void *sbuf, size_t slen, 
    743                 void *rbuf, size_t rlen) 
    744 { 
    745         int rrecv = 0; 
    746         ifd_iso_apdu_t iso; 
    747         ifd_debug(1, "buffer %s rlen = %d", ct_hexdump(sbuf, slen), rlen); 
    748         if ( ifd_iso_apdu_parse(sbuf, slen, &iso) < 0) 
    749                 return -1; 
    750         ifd_debug(1, "iso.le = %d", iso.le); 
    751         switch(iso.cse){ 
    752                 case    IFD_APDU_CASE_1: 
    753                 case    IFD_APDU_CASE_2S: 
    754                 case    IFD_APDU_CASE_3S: 
    755                         return rutoken_send_tpducomand(reader, dad, sbuf, slen, rbuf, rlen, 0); 
    756                         break; 
    757                 case    IFD_APDU_CASE_4S: 
    758                         // make send case 4 command 
    759                         rrecv = rutoken_send_tpducomand(reader, dad, sbuf, slen-1, rbuf, rlen, 1); 
    760                         return rrecv; 
    761                         break; 
    762                 default: 
    763                         break; 
    764         } 
    765         return -1; 
    766 } 
    767  
    768 static struct ifd_driver_ops rutoken_driver; 
    769  
    770 void ifd_rutoken_register(void) 
    771 { 
    772         ifd_debug(1, "ifd_rutoken_register()\n"); 
    773         rutoken_driver.open = rutoken_open; 
    774         rutoken_driver.activate = rutoken_activate; 
    775         rutoken_driver.deactivate = rutoken_deactivate; 
    776         rutoken_driver.card_reset = rutoken_card_reset; 
    777         rutoken_driver.card_status = rutoken_card_status; 
    778         rutoken_driver.set_protocol = rutoken_set_protocol; 
    779         rutoken_driver.transparent = rutoken_transparent; 
    780  
    781         ifd_driver_register("rutoken", &rutoken_driver); 
    782 } 
Note: See TracChangeset for help on using the changeset viewer.