Amadis

OLA - C Sample Code

/* * main.c * * Created on: Mar 17, 2020 * Author: amadis */ //--------------------------------------------------------- // Includes //--------------------------------------------------------- #include "ola.h" #include "gpi.h" // APDU file read #include <stdio.h> void logOLATester(char* data) { if(data) { printf("%s",data); } } static uint8_t MCW_DATA[] = // From TMS system { 0x9F,0x06,0x07,0xA0,0x00,0x00,0x00,0x04,0x10,0x10, // Application AID. Not used by L2 but standard EMV 0xCE,0x01,0x00, // Not used by L2 0xD0,0x01,0x06, // Not used by L2 0xCB,0x01,0x03,// Not used by L2 /**/ 0xDF,0x1B,0x01,0x01, /**/ 0xDF,0x4B,0x03,0x00,0x00,0x30, 0xDF,0x1C,0x01,0x00, // Not used by L2 (TAG_MAXIMUM_TARGET_PERCENTAGE_FOR_BIASED_RANDOM_SELECTION) /**/ 0xDF,0x2D,0x06,0x00,0x99,0x99,0x99,0x99,0x99, /**/ 0xDF,0x2E,0x06,0x00,0x00,0x00,0x00,0x00,0x01, /**/ 0xDF,0x30,0x14,0x95,0x05,0xC5,0x01,0xCA,0x04,0xD0,0x01,0xD2,0x01,0xCC,0x10,0x9F,0x34,0x03,0x9F,0x41,0x04,0x8A,0x02, /**/ 0xDF,0x31,0x06,0x00,0x00,0x00,0x01,0x00,0x00, 0xDF,0x1D,0x01,0x00, // Not used by L2 (TAG_TARGET_PERCENTAGE_FOR_RANDOM_SELECTION) 0x9F,0x1B,0x04,0x00,0x00,0x27,0x10, // Terminal Floor Limit 0xDF,0x21,0x04,0x00,0x00,0x00,0x00, // Not used by L2 (TAG_THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION) 0x9F,0x53,0x01,0x01, // Transaction Category Code. Not used by L2 but standard EMV /**/ 0xDF,0x22,0x06,0x00,0x00,0x00,0x01,0x00,0x00, /**/ 0xDF,0x23,0x06,0x00,0x00,0x00,0x03,0x00,0x00, /**/ 0xDF,0x25,0x02,0x00,0x05, 0x9F,0x4E,0x3B, 0x43,0x68,0x61,0x6D,0x70,0x20,0x64,0x65,0x20,0x4D,0x61,0x72,0x73,0x2C,0x20,0x35,0x20,0x41,0x76,0x65,0x6E,0x75,0x65,0x20,0x41,0x6E,0x61,0x74, 0x6F,0x6C,0x65,0x20,0x46,0x72,0x61,0x6E,0x63,0x65,0x2C,0x20,0x37,0x35,0x30,0x30,0x37,0x20,0x50,0x61,0x72,0x69,0x73,0x2C,0x20,0x46,0x72,0x61, 0x6E,0x63,0x65, // Merchant Name And Location. Not used by L2 but standard EMV 0x9F,0x15,0x02,0x53,0x99, // Merchant Category Code. Not used by L2 but standard EMV 0x9F,0x16,0x0F,0x52,0x43,0x54,0x53,0x54,0x30,0x30,0x30,0x30,0x30,0x34,0x36,0x31,0x33,0x37, // Merchant ID. Not used by L2 but standard EMV 0x9F,0x01,0x06,0x01,0x00,0x09,0x28,0x73,0x51, // Acquirer ID. Not used by L2 but standard EMV /**/ 0xDF,0x41,0x0A,0x4D,0x41,0x53,0x54,0x45,0x52,0x43,0x41,0x52,0x44, /**/ 0xDF,0x27,0x05,0x8E,0xC0,0x21,0xF0,0xF2, /**/ 0xDF,0x28,0x02,0xF8,0x40, 0xDF,0x81,0x18,0x01,0x00, // TAG_CVM_CAPABILITY_CVM_REQUIRED 0xDF,0x81,0x19,0x01,0x08, // TAG_CVM_CAPABILITY_NO_CVM_REQUIRED 0xDF,0x1A,0x03,0x9F,0x37,0x04, // why not DF 81 1A? Looks like default UDOL 0xDF,0x81,0x30,0x01,0x0A, // TAG_HOLDTIME_VALUE 0xDF,0x81,0x1B,0x01,0x20, // TAG_KERNEL_2_CONFIGURATION 0xDF,0x81,0x1E,0x01,0xF0, // TAG_MAGSTRIPE_CVM_CAPABILITY_CVM_REQUIRED 0xDF,0x81,0x2C,0x01,0x00, // TAG_MAGSTRIPE_CVM_CAPABILITY_NO_CVM_REQUIRED 0xDF,0x81,0x2D,0x03,0x00,0x00,0x30, // TAG_MESSAGE_HOLD_TIME /**/ 0xDF,0x2C,0x07,0xF0,0x00,0x00,0x00,0x00,0x0F,0xC0, 0xDF,0x81,0x31, 0x28,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x20,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x20,0x00,0x00,0x02,0x00, 0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, // Not used by L2 0xDF,0x81,0x24,0x06,0x00,0x00,0x00,0x00,0x30,0x00, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM 0xDF,0x81,0x25,0x06,0x00,0x00,0x00,0x01,0x00,0x00, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_DEVICE_CVM 0xDF,0x81,0x26,0x06,0x00,0x00,0x00,0x00,0x30,0x00, // TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT /**/ 0xDF,0x32,0x0A,0x4D,0x61,0x73,0x74,0x65,0x72,0x43,0x61,0x72,0x64, 0xDF,0x1E,0x05,0xFC,0x50,0x80,0x88,0x00, // TAG_TAC_DEFAULT 0xDF,0x1F,0x05,0x00,0x00,0x00,0x00,0x00, // TAG_TAC_DENIAL 0xDF,0x20,0x05,0xFC,0x50,0x80,0x88,0x00, // TAG_TAC_ONLINE 0x9F,0x1D,0x08,0x0C,0x3A,0x80,0x00,0x00,0x00,0x00,0x00, // Terminal Risk Management Data. Not used by L2 but standard EMV /**/ 0xDF,0x19,0x01,0x03, /**/ 0xDF,0x24,0x01,0x90, 0x9F,0x1C,0x08,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31, // Terminal Identification. Not used by L2 but standard EMV 0xC5,0x01,0x05 // Not used by L2 }; static uint8_t VIS_DATA[] = // From TMS system { 0x9F,0x06,0x07,0xA0,0x00,0x00,0x00,0x03,0x10,0x10, // Application AID. Not used by L2 but standard EMV 0xCE,0x01,0x00, // Not used by L2 0xD0,0x01,0x06, // Not used by L2 0xCB,0x01,0x01, // Not used by L2 /**/ 0xDF,0x1B,0x01,0x01, /**/ 0xDF,0x4B,0x03,0x00,0x00,0x30, 0xDF,0x1C,0x01,0x00, // Not used by L2 (TAG_MAXIMUM_TARGET_PERCENTAGE_FOR_BIASED_RANDOM_SELECTION) /**/ 0xDF,0x2D,0x06,0x00,0x99,0x99,0x99,0x99,0x99, /**/ 0xDF,0x2E,0x06,0x00,0x00,0x00,0x00,0x00,0x01, /**/ 0xDF,0x30,0x14,0x95,0x05,0xC5,0x01,0xCA,0x04,0xD0,0x01,0xD2,0x01,0xCC,0x10,0x9F,0x34,0x03,0x9F,0x41,0x04,0x8A,0x02, /**/ 0xDF,0x31,0x06,0x00,0x00,0x00,0x01,0x00,0x00, 0xDF,0x1D,0x01,0x00, // Not used by L2 (TAG_TARGET_PERCENTAGE_FOR_RANDOM_SELECTION) 0x9F,0x1B,0x04,0x00,0x00,0x27,0x10, // Terminal Floor Limit 0xDF,0x21,0x04,0x00,0x00,0x00,0x00, // Not used by L2 (TAG_THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION) 0x9F,0x53,0x01,0x01, // Transaction Category Code. Not used by L2 but standard EMV /**/ 0xDF,0x22,0x06,0x00,0x00,0x00,0x01,0x00,0x00, /**/ 0xDF,0x23,0x06,0x00,0x00,0x00,0x03,0x00,0x00, /**/ 0xDF,0x25,0x02,0x00,0x05, 0x9F,0x4E,0x3B,0x43,0x68,0x61,0x6D,0x70,0x20,0x64,0x65,0x20,0x4D,0x61,0x72,0x73,0x2C,0x20,0x35,0x20,0x41,0x76,0x65,0x6E,0x75,0x65,0x20,0x41,0x6E,0x61,0x74, 0x6F,0x6C,0x65,0x20,0x46,0x72,0x61,0x6E,0x63,0x65,0x2C,0x20,0x37,0x35,0x30,0x30,0x37,0x20,0x50,0x61,0x72,0x69,0x73,0x2C,0x20,0x46,0x72,0x61, 0x6E,0x63,0x65, // Merchant Name And Location. Not used by L2 but standard EMV 0x9F,0x15,0x02,0x53,0x99, // Merchant Category Code. Not used by L2 but standard EMV 0x9F,0x16,0x0F,0x52,0x43,0x54,0x53,0x54,0x30,0x30,0x30,0x30,0x30,0x34,0x36,0x31,0x33,0x37, // Merchant ID. Not used by L2 but standard EMV 0x9F,0x01,0x06,0x01,0x00,0x09,0x28,0x73,0x51, // Acquirer ID. Not used by L2 but standard EMV 0xDF,0x41,0x04,0x56,0x49,0x53,0x41, 0xDF,0x27,0x05,0x8E,0xC0,0x21,0xF0,0xF2, 0xDF,0x28,0x02,0xF8,0x40, 0xDF,0x1A,0x03,0x9F,0x37,0x04, 0xDF,0x44,0x01,0x00, 0xDF,0x2C,0x07,0xF0,0x00,0x00,0x00,0x00,0x0F,0xC0, 0xDF,0x32,0x04,0x56,0x49,0x53,0x41, 0xDF,0x1E,0x05,0xD8,0x40,0x00,0xA8,0x00, // TAC not used by VISA 0xDF,0x1F,0x05,0x00,0x10,0x00,0x00,0x00, // TAC not used by VISA 0xDF,0x20,0x05,0xD8,0x40,0x00,0xF8,0x00, // TAC not used by VISA 0xDF,0x19,0x01,0x01, 0xDF,0x24,0x01,0x90, 0x9F,0x1C,0x08,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31, // Terminal Identification. Not used by L2 but standard EMV 0xC5,0x01,0x05, // Not used by L2 0xDF,0x05,0x04,0x32,0x20,0x40,0x00, 0xDF,0x08,0x06,0x00,0x00,0x010,0x03,0x00,0x01, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM_PREPROCESSING 0xDF,0x09,0x06,0x00,0x00,0x00,0x00,0x10,0x00, // TAG_READER_CONTACTLESS_FLOOR_LIMIT_PREPROCESSING 0xDF,0x0B,0x06,0x00,0x00,0x00,0x00,0x20,0x01 // TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT_PREPROCESSING }; static uint8_t AGNOS_INI [] = // Specific to Agnos to illustrate proprietary initialization { 0xDF,0x01,0x08,'.','/','A','G','N','O','S','/', 0xDF,0x02,0x0E,'.','/','A','G','N','O','S','/','C','A','K','e','y','s', 0xDF,0x03,0x0B,'.','/','A','G','N','O','S','/','c','r','l', 0xDF,0x04,0x0B,'.','/','A','G','N','O','S','/','e','f','l', 0xDF,0x05,0x00, // pcsc not used 0xDF,0x06,0x00, // lang not used 0xDF,0x07,0x07,0x00,0x0F,0x04,0x0F,0x0A,0x00,0x01, 0xDF,0x08,0x01,0x03 }; //--------------------------------------------------------- // Definitions //--------------------------------------------------------- int main(int argc, char** argv) { uint8_t nb_candidates=0; uint8_t kernelId=0; int pse=0; tOlaPubKey key1={{0xA0,0x00,0x00,0x00,0x03},{0x05},0x08,{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},0x01,{0x00,0x00,0x03},{0x00,0x00,0x00}}; tOlaPubKey key2={{0xA0,0x00,0x00,0x00,0x04},{0xFE},0x08,{0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18},0x01,{0x00,0x00,0x03},{0x00,0x00,0x00}}; uint8_t cs[20]=""; unsigned char contact=0, contactless=1; ola_initialize_at_start_up(AGNOS_INI,sizeof(AGNOS_INI)); ola_set_trace_function(&logOLATester); ola_pubkey_flush(); ola_pubkey_add(&key1,cs); ola_pubkey_add(&key2,cs); if(contact) { ola_contact_flush_aid_supported(); ola_contact_answer_to_reset(NULL); ola_contact_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x04\x10\x10",7,0); ola_contact_add_aid_supported((const uint8_t *)"\xB0\x12\x34\x56\x78\x12\x34",7,0); ola_contact_build_candidate_list(&nb_candidates,&pse); ola_contact_final_select_candidate(1); ola_emv_set_tag(0x9F02,(uint8_t*)"\x00\x00\x00\x00\x01\x50",6); ola_emv_set_tag(0x9F03,(uint8_t*)"\x00\x00\x00\x00\x00\x50",6); ola_emv_set_tag(0x9C,(uint8_t*)"\x00",1); ola_emv_set_tag(0x9F1A,(uint8_t*)"\x00\x00",2); ola_emv_set_tag(0x9F33,(uint8_t*)"\x00\x00\x00",3); ola_emv_set_tag(0x9F35,(uint8_t*)"\x00",1); ola_emv_set_tag(0x9F40,(uint8_t*)"\x00\x00\x00\x00\x00",5); ola_contact_initiate_transaction(metUndef); ola_contact_complete_transaction((const uint8_t*)"\x30\x30",(const uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00",8); ola_contact_clean(); } if (contactless) { ola_emv_set_tag(0xDF10,(uint8_t*)"\x04",1); // Mag + CL + CT = 0x45 ola_contactless_flush_aid_supported(); ola_contactless_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x04\x10\x10",7,0, 2, MCW_DATA,sizeof(MCW_DATA)); ola_contactless_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x03\x10\x10",7,0, 3, VIS_DATA,sizeof(VIS_DATA)); ola_emv_set_tag(0x9F02,(uint8_t*)"\x00\x00\x00\x00\x01\x50",6); ola_emv_set_tag(0x9F03,(uint8_t*)"\x00\x00\x00\x00\x00\x50",6); ola_emv_set_tag(0x9C,(uint8_t*)"\x00",1); ola_emv_set_tag(0x9A,(uint8_t*)"\x20\x10\x28",3); ola_emv_set_tag(0x9F21,(uint8_t*)"\12\x00\x00",3); ola_contactless_preprocess(); ola_contactless_build_candidate_list(&nb_candidates); ola_contactless_final_select_candidate(1,&kernelId); ola_contactless_do_transaction(); ola_contactless_clean(); } return 0; }