0% found this document useful (0 votes)
127 views

Work in C++

This document contains C++ code for communicating with smart cards. It includes functions for: 1) Mutual authentication between an administrator card and user card by exchanging data and performing internal and external authentication checks. 2) Reading data from the smart card memory by getting tag values, data lengths, and data values in chunks to handle larger data sizes. 3) Additional lower-level functions for operations like restoring memory security environments, getting card numbers, PIN verification, and accessing file identifiers.

Uploaded by

epuser
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
127 views

Work in C++

This document contains C++ code for communicating with smart cards. It includes functions for: 1) Mutual authentication between an administrator card and user card by exchanging data and performing internal and external authentication checks. 2) Reading data from the smart card memory by getting tag values, data lengths, and data values in chunks to handle larger data sizes. 3) Additional lower-level functions for operations like restoring memory security environments, getting card numbers, PIN verification, and accessing file identifiers.

Uploaded by

epuser
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Work in C++ (Embedded Systems)

This is the main code that I had prepared in the C++ language before implementing it into Java, since implementing these concepts was far simpler in the C++ language due to the core of Smart Card applications was in the C/C++ language. As a brief overview of the code will show, all the following functions are required to communicate with the Smart Card, after which data can be read from the card, and also written into the card. The memory locations in the Smart Card Memory Chip are addressed either with their respective Hexa Decimal addresses or as BYTE values. Mutual Authentication is the process in which the card is authenticating the user, allowing the user to perform read/write operations. Internal Authentication and External Authentication are other operations that are required as per the security measures I had designed for this application.

----------------------------------------------------------CODE---------------------------------------- ---------------------#include "StdAfx.h" #include ".\Verification_Card_IO.h" Verification_Card_IO::Verification_Card_IO(void){ pt = new APDU(); } Verification_Card_IO::~Verification_Card_IO(void){ free(pt); } void Verification_Card_IO::setAPDU(BYTE CLA, BYTE INS, BYTE P1, BYTE P2, BYTE Lc, BYTE *Lc_buffer, BYTE Le){ pt->setCLA(CLA); pt->setINS(INS); pt->setP1(P1); pt->setP2(P2); pt->setLc(Lc, Lc_buffer); pt->setLe(Le); return; } int Verification_Card_IO::Mutual_Authenticate(SCARDHANDLE hcard_user, SCARDHANDLE hcard_admin, int user_SE, int user_key, int admin_SE, int admin_key){ int result; BYTE usercard_num[16], challenge_data[16], out_data[16]; //Get User card number. result = GetCard_Numbar(hcard_user, usercard_num); if (result != 0) return result; //Restore MSE for Authority card. result = Restore_MSE(hcard_admin, admin_SE); if (result != 0) return result;

//Restore MSE for User card. result = Restore_MSE(hcard_user, user_SE); if (result != 0) return result; //Set MSE for Authority card. BYTE data[18]; data[0] = 0x94; data[1] = 0x10; for (int i =0; i <16; i++) data[i+2] = usercard_num[i]; result = Set_MSE(hcard_admin, 18, data); if (result != 0) return result; //Get challenge from User card. result = Get_Challenge(hcard_user, challenge_data); if (result != 0) return result; //Internal Authenticate to Authority card. result = Internal_Auth(hcard_admin, admin_key, challenge_data, out_data); if (result != 0) return result; //External Authenticate to User. result = External_Auth(hcard_user, user_key, out_data); if (result != 0) return result; return 0; } int Verification_Card_IO::GetCard_Numbar(SCARDHANDLE hcard, BYTE *card_num){ BYTE *response; setAPDU(0, 0xCA, 0x02, 0x46, 0, NULL, 16); if (pt->sendAPDU(hcard) !=0 ){ return -1; } response = pt->getResponse(); for (int i =0; i <16; i++) card_num[i] = response[i]; return 0; } int Verification_Card_IO::Restore_MSE(SCARDHANDLE hcard, BYTE SE){ setAPDU(0, 0x22, 0xF3, SE, 0, NULL, 0); if (pt->sendAPDU(hcard) !=0 ){ return -1; } return 0; } int Verification_Card_IO::Set_MSE(SCARDHANDLE hcard, BYTE in_data_len, BYTE *in_data){ setAPDU(0, 0x22, 0xC1, 0xA4, in_data_len, in_data, 0); if (pt->sendAPDU(hcard) !=0 ){

return -1; } return 0; } int Verification_Card_IO::Get_Challenge(SCARDHANDLE hcard, BYTE *challenge_data){ BYTE *response; setAPDU(0, 0x84, 0x00, 0x00, 0, NULL, 16); if (pt->sendAPDU(hcard) !=0 ){ return -1; } response = pt->getResponse(); for (int i =0; i <16; i++) challenge_data[i] = response[i]; return 0; } int Verification_Card_IO::Internal_Auth(SCARDHANDLE hcard, int key, BYTE *in_data, BYTE *out_data){ BYTE *response; setAPDU(0, 0x88, 0x00, key, 16, in_data, 16); if (pt->sendAPDU(hcard) !=0 ){ return -1; } response = pt->getResponse(); for (int i =0; i <16; i++) out_data[i] = response[i]; return 0; } int Verification_Card_IO::External_Auth(SCARDHANDLE hcard, int key, BYTE *in_data){ setAPDU(0, 0x82, 0x00, key, 16, in_data, 0); if (pt->sendAPDU(hcard) !=0 ){ return -1; } return 0; }

int Verification_Card_IO::Verify(SCARDHANDLE hcard_user, BYTE pin_len, BYTE *pin){ int result; setAPDU(0, 0x20, 0, 1, pin_len, pin, 0); result = pt->sendAPDU(hcard_user); return result ; } int Verification_Card_IO::Open_File(SCARDHANDLE hcard_user, BYTE *file_id){ int result; this->counter = 0; setAPDU(0, 0xA4, 0, 0, 2, file_id, 0); result = pt->sendAPDU(hcard_user); return result ; } int Verification_Card_IO::GetTag(SCARDHANDLE hcard, int *count, BYTE *tag){ int counter = *count, result;

char tag_len = 's', tag_type = 'p'; BYTE P1, P2; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return -1; response = pt->getResponse(); tag[0] = response[0]; tag[1] = 0; if ((response[0] & 0x20) == 0x20){ tag_type = 'c'; } if ((response[0] & 0x1F) == 0x1F){ counter++; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return -1; response = pt->getResponse(); tag[1] = response[0]; tag_len = 'd'; } counter ++; *count = counter; if ((tag_type == 'c') && (tag_len =='s')) return ONE_BYTE_CONSTRUCTED_TAG; else if ((tag_type == 'p') && (tag_len =='s')) return ONE_BYTE_PRIMITIVE_TAG; else if ((tag_type == 'c') && (tag_len =='d')) return TWO_BYTE_CONSTRUCTED_TAG; else return TWO_BYTE_PRIMITIVE_TAG; }

int Verification_Card_IO::GetNextTag(SCARDHANDLE hcard, int *count, BYTE *tag){ int counter = *count, result; BYTE tag1 = 0, tag2 = 0, P1, P2; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return -1; response = pt->getResponse(); tag1 = response[0]; if (response[0] == 0x82) counter += 3; else if (response[0] == 0x81) counter += 2; else counter ++; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1);

result = pt->sendAPDU(hcard); if (result != 0) return -1; response = pt->getResponse(); tag[0] = response[0]; tag[1] = 0; char tag_len = 's', tag_type = 'p'; if ((response[0] & 0x20) == 0x20){ tag_type = 'c'; } if ((response[0] & 0x1F) == 0x1F){ counter++; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return -1; response = pt->getResponse(); tag[1] = response[0]; tag_len = 'd'; } counter ++; *count = counter; if ((tag_type == 'c') && (tag_len =='s')) return ONE_BYTE_CONSTRUCTED_TAG; else if ((tag_type == 'p') && (tag_len =='s')) return ONE_BYTE_PRIMITIVE_TAG; else if ((tag_type == 'c') && (tag_len =='d')) return TWO_BYTE_CONSTRUCTED_TAG; else return TWO_BYTE_PRIMITIVE_TAG; }

int Verification_Card_IO::GetValue(SCARDHANDLE hcard, int *count, int *value_len, BYTE *value){ int len = 0, counter = *count, result; BYTE P1, P2; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return result; response = pt->getResponse(); if (response[0] == 0x82){ counter ++; P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 2); result = pt->sendAPDU(hcard); if (result != 0) return result; response = pt->getResponse(); len = ((int)response[0]) * 256; len += ((int)response[1]); counter += 2; } else if (response[0] == 0x81){ counter ++;

P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, 1); result = pt->sendAPDU(hcard); if (result != 0) return result; response = pt->getResponse(); len = (int)response[0]; counter ++; } else { len = (int)response[0]; counter++; } *value_len = len; int i, j = 0; if (len > CHUNK_SIZE){ int offset = 0, curr_size, count = counter; while (offset < len) { P1 = ((count >> 8) & 0x7F); P2 = (count & 0x00FF); curr_size = (CHUNK_SIZE <= (len - offset)) ? CHUNK_SIZE: len - offset; setAPDU(0x00, 0xB0, P1, P2, 0, NULL, curr_size); result = pt->sendAPDU(hcard); if (result != 0) return result; response = pt->getResponse(); for(i =0; i <curr_size; i++){ if (response[i] != '\0' && response[i] != '\n') value[j] = response[i]; else{ value[j] = 0xd; value[++j] = 0xa; *value_len = *value_len + 1; } count++; j++; } offset += CHUNK_SIZE; } } else { P1 = ((counter >> 8) & 0x7F); P2 = (counter & 0x00FF); setAPDU(0x00, 0xB0, P1, P2, 0, NULL, len); result = pt->sendAPDU(hcard); if (result != 0) return result; response = pt->getResponse(); for(i =0; i <len; i++){ if (response[i] != '\0' && response[i] != '\n') value[j] = response[i]; else{ value[j] = 0xd;

value[++j] = 0xa; *value_len = *value_len + 1; } j++; } } counter += len; *count = counter; return 0; } int Verification_Card_IO::Read_Data(SCARDHANDLE hcard, BYTE tag[], char value[]){ int result, tag_type, value_len; tag_type = GetTag(hcard, &counter, tag); if (tag_type == -1) return -1; while ((tag_type == ONE_BYTE_CONSTRUCTED_TAG || tag_type == TWO_BYTE_CONSTRUCTED_TAG)){ tag_type = GetNextTag(hcard, &counter, tag); if (tag_type == -1) return -1; } if (tag[0] == 0) return -1; result = GetValue(hcard, &counter, &value_len, (BYTE *)value); if (result != 0) return -1; value[value_len] = '\0'; return 0; }

You might also like