uslp project – smart card readers · uslp – smart card readers gene & zhong 4 /*using the...

16
Authors: Alvaro J. Gene and John M. Zhong Website: www.teraexe.com © Copyright 2015. Alvaro J. Gene and John M. Zhong. All rights reserved USLP Project – Smart Card Readers Version 1.1

Upload: others

Post on 02-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

Authors: Alvaro J. Gene and John M. Zhong

Website: www.teraexe.com

© Copyright 2015. Alvaro J. Gene and John M. Zhong. All rights reserved

USLP Project – Smart Card Readers

Version 1.1

Page 2: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

1

USLP PROJECT – SMART CARD READERS

JAVA VERSION

Page 3: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

2

C# VERSION

Page 4: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

3

FILES: AG_USLP_JAVA_SCREADER.CLASS & AG_USLP_JAVA_SCREADER.JAR

/*Importing the AccessController class to use the doPrivileged method, which will

provide some privileges to a block of code:*/

import java.security.AccessController;

/*Using two classes to run codes if there is an exception related to privileges:*/

import java.security.PrivilegedActionException;

import java.security.PrivilegedExceptionAction;

//Importing the smartcardio class to work with smart cards:

import javax.smartcardio.Card;

import javax.smartcardio.CardChannel;

import javax.smartcardio.CardTerminal;

import javax.smartcardio.CommandAPDU;

import javax.smartcardio.ResponseAPDU;

import javax.smartcardio.TerminalFactory;

import javax.smartcardio.ATR;

//Importing the util class and its List method to get a list of smart cards:

import java.util.List;

//Importing the JApplet class to build a Java applet

import javax.swing.JApplet;

//Importing the awt class to add some labels and text-fields:

import java.awt.Label;

import java.awt.TextField;

public class AG_USLP_Java_SCReader extends JApplet {

@SuppressWarnings({ "unchecked", "rawtypes" })

/* Using the init method, which is going to execute a block of code when a Java

* applet is loaded; in this case, we will use the init method to execute some

* codes that will display a smart card serial number and other details.*/

public void init() {

/*Because we do not want our Java applet to use a layout manager, we will use

the setLayout method and a null value inside of it.*/

setLayout(null);

/* Using the doPrivileged method of the AccessController class to run some codes

* with privileges. As you can see, a coder has to use this method with another

* method that is called the run method.*/

try {

AccessController.doPrivileged(new PrivilegedExceptionAction() {

public Boolean run() {

try {

/*The TerminalFactory Class: Using the TerminalFactory class to build

the AG_TF object, which is going to get the name and model of a smart card

reader. While a coder is using the TerminalFactory class, he/she can use

the getDefault method to return or get the name and model of a smart card

terminal, also known as a smart card reader.*/

TerminalFactory AG_TF = TerminalFactory.getDefault();

Page 5: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

4

/*Using the terminals method (and the list method) of the TerminalFactory

class to store a list of smart card readers inside of the AG_T variable.*/

List<CardTerminal> AG_T = AG_TF.terminals().list();

/*After using the list method to display a list of readers, we will use the

get method to store the first terminal, also called the smart card reader.

As you can see, we are typing zero (0) inside of the get method because the

get method is zero-based; hence, typing zero is a way to get the first

smart card reader.*/

CardTerminal AG_T2 = AG_T.get(0);

//Using the Card class and the connect method to connect to a smart card:

Card AGCard = AG_T2.connect("*");

/*Using the CardChannel class to establish a logical channel connection

to a smart card. After performing that operation, a coder will be able to

send/receive APDU commands to a smart card. While a coder is using the

CardChannel class, he/she can use one of those two methods to build an object

that will exchange APDU commands: getBasicChannel and openLogicalChannel.

Example of use:

CardChannel Object_Channel = CardChannel_Object.getBasicChannel();*/

CardChannel channel = AGCard.getBasicChannel();

//Storing a group of APDU commands inside of a variable, which is called Array_APDU:

byte[] Array_APDU = { (byte)0xFF, (byte)0xCA, (byte)0x00, (byte)0x00, (byte)0x00};

/*The CommandAPDU Class: A coder can use the CommandAPDU class to send

APDU commands to a smart card. Syntax: CommandAPDU (Array);

First Parameter (Array): In this field, a coder has to type a byte array that will

have those kinds of APDU commands that a coder wants to send to a smart card.*/

CommandAPDU AG_C_APDU = new CommandAPDU(Array_APDU);

/*The Transmit Method: A coder can use the transmit method of the CardChannel

class when he/she wants to transmit APDU commands to a smart card. While a coder

is using this method, he/she can also use the ResponseAPDU class to store the

APDU response on a variable. As you can see, this is the syntax:

ResponseAPDU Object_Response = CardChannel_Object.Transmit(CommandAPDU_Object);*/

ResponseAPDU AG_APDUResponse = channel.transmit(AG_C_APDU);

//Using the getBytes method to store the number of bytes on a variable:

byte[] AG_Bytes = AG_APDUResponse.getBytes();

/*Using the StringBuilder class to build the AG_StringBuilder variable,

which will store the serial number of a smart card:*/

StringBuilder AG_StringBuilder = new StringBuilder();

//Using the for-loop statement to store the APDU response on a variable:

for(int i=0; i<AG_Bytes.length; i++) {

byte AG_Byte = AG_Bytes[i];

/*If the length of the i variable is less than the length of

Page 6: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

5

the AG_Bytes variable (the AG_Bytes variable minus 3 characters), then,

the application will store its value on the AG_StringBuilder variable.*/

if( i <= AG_Bytes.length -3) {

//Using the append method to update the value of an object:

AG_StringBuilder.append(String.format("%02X ", AG_Byte));

}

}

//Using the ATR class and its getATR method to get the Answer to Reset (ATR):

ATR AG_ATR = AGCard.getATR();

//Using the getBytes method of the ATR class to get the number of bytes of an ATR:

byte[] ATR_Bytes = AG_ATR.getBytes();

/*Using the StringBuilder class to build the AG_ATR_SB variable, which is a

variable that is going to store the answer to reset (ATR).*/

StringBuilder AG_ATR_SB = new StringBuilder();

//Using the for-loop statement to store the APDU response on a variable:

for(int ATR_i=0; ATR_i<ATR_Bytes.length; ATR_i++) {

//Storing the bytes on the ATR_AG_Byte variable:

byte ATR_AG_Byte = ATR_Bytes[ATR_i];

//Using the append method to update the value of an object:

AG_ATR_SB.append(String.format("%02X ", ATR_AG_Byte));

}

//Using the awt class and its Label method to build a Label object (AG_L1):

Label AG_L1;

AG_L1 = new Label();

//Using the setText method to add some characters to our label:

AG_L1.setText("1) Smart Card Reader:");

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_L1.setBounds(10,12,150,15);

//Using the add method to add a label to our Java applet:

add(AG_L1);

//Using the awt class and its TextField method to build the AG_TF1 object:

TextField AG_TF1;

AG_TF1 = new TextField();

/*The AG_T variable has the name and method of a smart card reader, and we

will use the setText method to add the AG_T values to our Text-Field:*/

AG_TF1.setText(AG_T.toString());

/*Because we do not want a user to modify or edit our Text-Field manually,

we will use the false value on the setEditable method.*/

AG_TF1.setEditable(false);

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

Page 7: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

6

AG_TF1.setBounds(10,37,395,20);

//Using the add method to add a TextField to our Java applet:

add(AG_TF1);

//Using the awt class and its Label method to build a Label object (AG_L2):

Label AG_L2;

AG_L2 = new Label();

//Using the setText method to add some characters to our label:

AG_L2.setText("2) Reader and Active Protocol:");

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_L2.setBounds(10,65,240,15);

//Using the add method to add a label to our Java applet:

add(AG_L2);

//Using the awt class and its TextField method to build the AG_TF2 object:

TextField AG_TF2;

AG_TF2 = new TextField();

/*The AGCard variable has the active protocol of a smart card reader, and we

will use the setText method to add the AGCard values to our Text-Field:*/

AG_TF2.setText(AGCard.toString());

/*Because we do not want a user to modify or edit our Text-Field manually,

we will use the false value on the setEditable method.*/

AG_TF2.setEditable(false);

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_TF2.setBounds(10,87,395,20);

//Using the add method to add a TextField to our Java applet:

add(AG_TF2);

//Using the awt class and its Label method to build a Label object (AG_L3):

Label AG_L3;

AG_L3 = new Label();

//Using the setText method to add some characters to our label:

AG_L3.setText("3) APDU Response:");

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_L3.setBounds(10,115,150,15);

//Using the add method to add a label to our Java applet:

add(AG_L3);

//Using the awt class and its TextField method to build the AG_TF3 object:

TextField AG_TF3;

AG_TF3 = new TextField();

/*The AG_APDUResponse variable has the APDU response, and we will use

the setText method to add the AG_APDUResponse values to our Text-Field:*/

AG_TF3.setText(AG_APDUResponse.toString());

/*Because we do not want a user to modify or edit our Text-Field manually,

we will use the false value on the setEditable method.*/

AG_TF3.setEditable(false);

/*Using the setBounds method to set a location.

Page 8: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

7

Syntax: setBounds(x, y, width, height)*/

AG_TF3.setBounds(10,137,395,20);

//Using the add method to add a TextField to our Java applet:

add(AG_TF3);

//Using the awt class and its Label method to build a Label object (AG_L4):

Label AG_L4;

AG_L4 = new Label();

//Using the setText method to add some characters to our label:

AG_L4.setText("4) Smart Card Serial Number:");

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_L4.setBounds(10,165,250,15);

//Using the add method to add a label to our Java applet:

add(AG_L4);

//Using the awt class and its TextField method to build the AG_TF4 object:

TextField AG_TF4;

AG_TF4 = new TextField();

/*The AG_StringBuilder variable has the serial number of a smart card, and

we are going to use the setText method to add the AG_StringBuilder values

to our Text-Field:*/

AG_TF4.setText(AG_StringBuilder.toString());

/*Because we do not want a user to modify or edit our Text-Field manually,

we will use the false value on the setEditable method.*/

AG_TF4.setEditable(false);

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_TF4.setBounds(10,187,395,20);

//Using the add method to add a TextField to our Java applet:

add(AG_TF4);

//Using the awt class and its Label method to build a Label object (AG_L5):

Label AG_L5;

AG_L5 = new Label();

//Using the setText method to add some characters to our label:

AG_L5.setText("5) Answer to Reset (ATR):");

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_L5.setBounds(10,215,150,15);

//Using the add method to add a label to our Java applet:

add(AG_L5);

//Using the awt class and its TextField method to build the AG_TF5 object:

TextField AG_TF5;

AG_TF5 = new TextField();

/*The AG_ATR_SB variable has the answer to reset (ATR) of a smart card,

and we are going to use the setText method to add the AG_ATR_SB values

to our Text-Field:*/

AG_TF5.setText(AG_ATR_SB.toString());

/*Because we do not want a user to modify or edit our Text-Field manually,

Page 9: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

8

we will use the false value on the setEditable method.*/

AG_TF5.setEditable(false);

/*Using the setBounds method to set a location.

Syntax: setBounds(x, y, width, height)*/

AG_TF5.setBounds(10,237,395,20);

//Using the add method to add a label to our Java applet:

add(AG_TF5);

//Closing the "Try" of the smart card:

}

/*Using the catch method to display a text message if there is an error related

to the smart card. For example, if a reader is not connected to a computer, the

application will display a text message like this:

Error: javax.smartcardio.CardException: list() failed*/

catch(Exception e) {

System.out.println("Error: " + e.toString());

}

/*While a coder is using the doPrivileged method and a Boolean run method to

deal with objects, he/she has to use the next line of code.

The Valueof method of the Boolean class will return the Boolean value

represented by the string.*/

return Boolean.valueOf(true);

//Closing the run method:

}

//Closing the PrivilegedExceptionAction method:

}

//Closing the doPrivileged method:

);

//Closing the "Try" of the doPrivileged method:

}

/*If there is an error related to the doPrivileged method, the application will

display some characters through some methods like PrivilegedActionException and

printStackTrace.*/

catch (PrivilegedActionException e) {

e.printStackTrace();

}

//Closing the init method:

}

//Closing the Java applet:

}

Page 10: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

9

FILE: AG_USLP_SCREADER.HTML

<html>

<style>

applet {

border: 7px solid #a1a1a1;

border-radius: 12px;

background: #dddddd;

width: 430px;

height: 285px;

margin: 23px;

}

div {

position: absolute;

left: 50%;

top: 50%;

margin-left: -250px;

margin-top: -250px;

}

h1 {

color: #585858;

letter-spacing: 4px;

font: 26px Lucide Console;

}

h1:after {

background-color: #686868;

content: "";

height: 1px;

position: absolute;

Page 11: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

10

top: 30px;

width: 122px;

right: -120;

}

h1:before {

background-color: #686868;

content: "";

height: 1px;

position: absolute;

width: 122px;

top: 30px;

left: -120;

}

</style>

<div>

<body background="background.jpg">

<center>

<h1>SMART CARD READER</h1>

<applet code="AG_USLP_Java_SCReader.class"

archive="AG_USLP_Java_SCReader.jar"

width="414" height="270">

</applet>

</center>

</body>

</div>

</html>

Page 12: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

11

FILE: AG_USLP_SCREADER.EXE

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using PCSC; //Importing the PCSC API to work with smart cards.

using PCSC.Iso7816; //Importing the PCSC API to work with smart cards.

namespace AG_USLP_SCReader {

class Program {

static void Main() {

Console.Clear(); //Using the Clear method to clear a terminal screen.

Console.Write("\n");

Console.Write("======================================================================\n");

Console.Write("=========================== USLP-SCReader ============================\n");

Console.Write("======================================================================\n\n\n\n");

Console.Write("______________________________________________________________________\n\n");

Console.Write("Authors: Alvaro J. Gene and John M. Zhong\n\n");

Console.Write("Year: August 25, 2015\n\n");

Console.Write("Description: An application to display information about smart cards.\n");

Console.Write("______________________________________________________________________\n\n\n\n");

/**************************************************************************************

******************************The SCardContext Constructor*****************************

**************************************************************************************/

/*Declaring the AG_hContext variable, which is going to use some

methods or functions of the SCardContext constructor*/

var AG_hContext = new SCardContext();

/*Using the Establish method to establish the Resource Manager

Context, which is going to perform operations or tasks on a smart card.*/

AG_hContext.Establish(SCardScope.System);

/*Using the GetReaders method of the SCardContext constructor to get one or more smart

card readers. If the application is not able to identify a smart card reader, it will

display this text message: Cannot find a smart card reader.*/

string[] AG_SR = AG_hContext.GetReaders();

/**************************************************************************************

******************************The SCardMonitor Constructor*****************************

**************************************************************************************/

/*Using the SCardMonitor constructor to monitor a smart card and display information

about its status. In addition, a coder can use this constructor to execute a block of

code if a smart card is able to change its status. On the one hand, an active status

is when a smart card reader is able to read a smart card; on the other hand, an

inactive status is when a smart card reader is not able to read a smart card.*/

var AG_SCardMonitor = new SCardMonitor(new SCardContext(), SCardScope.System);

/* 1. The CardInserved: Using the CardInserted event of the SCardMonitor constructor

to execute a block of code if a card is inserted; in other words, the CardInserted

Page 13: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

12

event will perform an operation if a reader is able to read a smart card.

Syntax: CardInsertedEvent CardInserted*/

AG_SCardMonitor.CardInserted += (sender, args) => AG_Func_CInserted(args);

/* 2. CardRemoved: Using the CardRemoved event of the SCardMonitor constructor to

execute some codes if a card is removed. Syntax: CardRemovedEvent CardRemoved*/

AG_SCardMonitor.CardRemoved += (sender, args) => AG_Func_CRemoved(args);

//Using the Start method of the SCardMonitor constructor to start monitoring smart cards:

AG_SCardMonitor.Start(AG_SR);

/*Thanks to the ReadKey method, the application will run until a user types a keyword.

Then, the application will execute the other two lines, which are using those methods:

Cancel (it will stop monitoring) and Dispose (it will dispose monitor resources).*/

Console.ReadKey();

//Using the Calcel method to stop monitoring smart cards:

AG_SCardMonitor.Cancel();

/*Using the Dispose method to dispose monitor resources, as you can see, a coder has

to use this method with a variable that was built through the SCardContext constructor:*/

AG_SCardMonitor.Dispose();

}

/*Building the AG_Func_CInserted function to execute some codes if a card is inserted.

The CardStatusEventArgs:

Syntax: CardStatusEventArgs (string ReaderName, SCRState state, byte[] atr);

Second Parameter: SCRState (Smart Card Reader State) = unknown.*/

private static void AG_Func_CInserted(CardStatusEventArgs unknown) {

Console.Clear(); //Using the Clear method to clear a terminal screen.

Console.Write("\n");

Console.Write("======================================================================\n");

Console.Write("=========================== USLP-SCReader ============================\n");

Console.Write("======================================================================\n\n\n\n");

Console.Write("______________________________________________________________________\n\n");

Console.Write("Authors: Alvaro J. Gene and John M. Zhong\n\n");

Console.Write("Year: August 25, 2015\n\n");

Console.Write("Description: An application to display information about smart cards.\n");

Console.Write("______________________________________________________________________\n\n\n\n");

Console.WriteLine("Smart Card Reader: {0}\n", unknown.ReaderName);

Console.WriteLine("Card Status: A smart card is connected to the reader.\n");

/*Declaring the AG_Receive_Buffer variable to receive and store data from a smart card.

After sending some APDU commands, the AG_Receive_Buffer will store its response.*/

byte[] AG_Receive_Buffer = new byte[256];

/**************************************************************************************

******************************The SCardContext Constructor*****************************

**************************************************************************************/

/*Declaring the AG_hContext variable, which is going to use some

methods or functions of the SCardContext constructor*/

var AG_hContext = new SCardContext();

/*Using the Establish method to establish the Resource Manager

Context, which is going to perform operations or tasks on a smart card.*/

AG_hContext.Establish(SCardScope.System);

Page 14: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

13

/*Using the GetReaders method of the SCardContext constructor to get one or more smart

card readers. If the application is not able to identify a smart card reader, it will

display this text message: Cannot find a smart card reader.*/

string[] AG_SR = AG_hContext.GetReaders();

/**************************************************************************************

******************************The SCardReader Constructor******************************

**************************************************************************************/

/*Using the SCardReader class to build the AG_SCReader Object; in the future,

the AG_SCReader object will connect to a smart card and get its active protocol.*/

SCardReader AG_SCReader = new SCardReader(AG_hContext);

/*Using the Connect method of the SCardReader class to establish a connection

to a smart card.

1. First Parameter: A coder has to type a reader name (a string of a reader name).

2. Second Parameter: A coder has to specify a connection mode, which can be

SCardShareMode.Shared or SCardShareMode.Exclusive.

2.1 SCardShareMode.Shared: A C# developer can use this parameter when he/she wants

to share the smart card reader with other individuals.

3. Third Parameter: In this field, a coder has to type the active protocol that a method

or variable (AG_SCReader) is going to store and return; in this case, it will store

and return one of those protocols: SCardProtocol.T0 or SCardProtocol.T1.*/

AG_SCReader.Connect(AG_SR[0],

SCardShareMode.Shared,

SCardProtocol.T0 | SCardProtocol.T1);

/*Using the ActiveProtocol property of the SCardReader class to execute a

block of code if the AG_SCReader variable was able to store an active protocol

(T0 or T1) through the Connect method.*/

switch (AG_SCReader.ActiveProtocol) {

case SCardProtocol.T0:

//Displaying a text message related to an active protocol:

Console.WriteLine("Active Protocol: T0\n");

break;

case SCardProtocol.T1:

//Displaying information about an active protocol:

Console.WriteLine("Active Protocol: T1\n");

break;

default:

/*The application will display a text message if it is not able to identify

an active protocol.*/

throw new PCSCException(SCardError.ProtocolMismatch,

"Active protocol unnegotiated or unknown" + AG_SCReader.ActiveProtocol.ToString());

}

/**************************************************************************************

******************************The CommandApdu Constructor******************************

**************************************************************************************/

/*Using the CommandApdu Constructor to send APDU commands to a smart card.

Syntax: CommandApdu (IsoCase, PCSC.SCardProtocol) {Properties}

1. First Parameter (IsoCase): A coder has to use the IsoCase keyword to send an APDU

Page 15: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

14

message to a smart card. This keyword is like a rule.

2. Second Parameter (PCSC.SCardProtocol): Shortly, in this field, a coder has to specify

an active protocol.

3. Properties: As you can see, those are some of the properties that a coder can use

while he/she is using the CommandApdu constructor: CLA, Instruction, P1, P2, and Le.*/

var AG_APDU_Const = new CommandApdu(IsoCase.Case2Short, AG_SCReader.ActiveProtocol) {

CLA = 0xFF,

Instruction = InstructionCode.GetData,

P1 = 0x00,

P2 = 0x00,

Le = 0

};

/*Using the ToArray method of the CommandApdu constructor to convert the

APDU structure to an array that we can use with the Transmit method:*/

var AG_APDU_Commands = AG_APDU_Const.ToArray();

//Declaring a variable that will store the active protocol of a smart card (T0 or T1).

var AG_pioSendPci = SCardPCI.GetPci(AG_SCReader.ActiveProtocol);

/*Using the Transmit function to send APDU commands to a smart card.*/

AG_SCReader.Transmit(

AG_pioSendPci, //Variable with data about the active protocol.

AG_APDU_Commands, //Sending APDU Commands.

ref AG_Receive_Buffer); //Storing data from a smart card.

/**************************************************************************************

******************************The ResponseApdu Constructor*****************************

**************************************************************************************/

/*After sending some APDU commands through the CommnadApdu constructor, we will use the

ResponseApdu constructor to get that kind of data that is coming from a smart card.

Syntax: ResponseApdu(response, IsoCase, Active_Protocol);*/

var AG_R_Apdu = new ResponseApdu(

AG_Receive_Buffer, //Data from Transmit function.

IsoCase.Case2Short, //Same IsoCase of CommandApdu.

AG_SCReader.ActiveProtocol); //Protocol (T0 or T1),

//********Using the ResponseApdu constructor to display data from a smart card:********

//Using the SW1 property of the ResponseApdu class to display the status word one:

Console.Write("Status Word One (SW1): {0:X2}\n", AG_R_Apdu.SW1);

//Using the SW2 property of the ResponseApdu class to display the status word two:

Console.Write("\nStatus Word Two (SW2): {0:X2}\n", AG_R_Apdu.SW2);

/*Using the GetData property of the ResponseApdu class to get the smart card response,

which is holding the serial number of a smart card:*/

var AG_GetData = AG_R_Apdu.GetData();

/*Using the ToString method of the BitConverter class to convert an array into

an hexadecimal value:*/

var AG_BitConverter = BitConverter.ToString(AG_GetData);

Page 16: USLP Project – Smart Card Readers · USLP – Smart Card Readers Gene & Zhong 4 /*Using the terminals method (and the list method) of the TerminalFactory class to store a list of

USLP – Smart Card Readers Gene & Zhong

15

//Displaying the Smart Card Serial Number:

Console.Write("\nSmart Card Serial Number: {0}\n\n", AG_BitConverter);

/**************************************************************************************

**********************************The GetAttrib Method*********************************

**************************************************************************************/

//Declaring the AG_ATR variable to receive the ATR (ATR string attribute):

byte[] AG_ATR;

/*Using the GetAttrib method of the SCardReader constructor to get the answer to reset,

also called ATR.

Syntax: GetAttrib(SCardAttribute.attributeId, out byte[] attribute).

Code: AG_SCReader.GetAttrib(SCardAttribute.AtrString, out AG_ATR);

A. First Parameter: In this field, we are going to type SCardAttribute enum because we

want to get an attribute of the smart card reader; then, after a period, we are going

to use the AtrString member (Answer to reset (ATR) string) because we want to get the

ATR of a smart card reader.

B. Second Parameter (attribute = AG_ATR): After building a variable of byte data-type

(byte[] AG_ATR;), a coder has to use that variable on the second parameter of

the GetAttrib method to receive the data (ATR) that is coming from a smart card reader.

Notice that we want to store the ATR value on a variable to display that value on a

terminal.*/

AG_SCReader.GetAttrib(SCardAttribute.AtrString, out AG_ATR);

/*Using the ToString method of the BitConverter class to convert an array into

an hexadecimal value*/

var AG_BitConv_ATR = BitConverter.ToString(AG_ATR);

//Displaying the Answer to Reset of a smart card:

Console.WriteLine("Answer to Reset (ATR): {0}\n", AG_BitConv_ATR);

}

//Building the AG_Func_CRemoved function to execute some codes if a card is removed:

private static void AG_Func_CRemoved(CardStatusEventArgs unknown) {

Console.Clear(); //Using the Clear method to clear a terminal screen.

Console.Write("\n");

Console.Write("======================================================================\n");

Console.Write("=========================== USLP-SCReader ============================\n");

Console.Write("======================================================================\n\n\n\n");

Console.Write("______________________________________________________________________\n\n");

Console.Write("Authors: Alvaro J. Gene and John M. Zhong\n\n");

Console.Write("Year: August 25, 2015\n\n");

Console.Write("Description: An application to display information about smart cards.\n");

Console.Write("______________________________________________________________________\n\n\n\n");

Console.WriteLine("Smart Card Reader: {0}\n", unknown.ReaderName);

Console.WriteLine("Card Status: Waiting for a smart card...\n");

}

}

}