Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeKevin committed Jun 12, 2016
1 parent c4a94a1 commit 7c27f52
Show file tree
Hide file tree
Showing 82 changed files with 34,337 additions and 0 deletions.
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CC = gcc
LD = gcc
INCPATHS = -Iopenssl/include -Iwinscard/include
CFLAGS = -W -Wno-write-strings -Wno-unused-function -O4 -DNDEBUG $(INCPATHS)
LIBS = openssl/lib/ssleay32.a openssl/lib/libeay32.a winscard/lib/WinSCard.Lib

OBJS = iclassified.o
EXES = iclass.exe

all: $(OBJS) $(EXES)

%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<

%.exe : %.c $(OBJS)
$(LD) $(CFLAGS) $(LDFLAGS) -o $@ $< $(OBJS) $(LIBS)

clean:
rm -f $(OBJS) $(EXES)
252 changes: 252 additions & 0 deletions iclass.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/*
iClass Key Diversification (iClass Demo)
Copyright (C) 2011 Radboud University Nijmegen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <openssl/des.h>
#include <windows.h>
#include <winscard.h>
#include "iclassified.h"
#include "stdbyte.h"

#define PCSC_MAX_DEVICES 16
byte_t pbtRx[BUF_SIZE];
size_t szRxLen;

typedef struct struct_iclass_mem {
byte_t app_limit;
byte_t otp[2];
byte_t write_lock;
byte_t chip_conf;
byte_t mem_conf;
byte_t eas;
byte_t fuses;
} iclass_mem;

void print_bytes(const byte_t* bt, size_t len) {
size_t count;
for (count=0; count<len; count++) {
printf("%02x",bt[count]);
}
printf("\n");
}

void read_card(SCARDHANDLE hCard){
int i;
byte_t pbtApduRead[] = { 0x84,0xB0,0x00,0x00,0x00,0x08 };
for (i = 0; i <= 0x1F; ++i)
{
if (!SendApdu(hCard,pbtApduRead,sizeof(pbtApduRead),pbtRx,&szRxLen)) {
printf("Error: Could not read block %02x\n", i);
}
print_bytes(pbtRx,szRxLen);
pbtApduRead[3]++;
}
}

void read_data(SCARDHANDLE hCard, char* block_str){
int block = strtoul(block_str, NULL, 0);
byte_t read_block[] = { 0x84,0xB0,0x00,block,0x00,0x08 };

if (!SendApdu(hCard,read_block,sizeof(read_block),pbtRx,&szRxLen)) {
printf("Error: Could not read block %d\n", block);
return;
}

print_bytes(pbtRx,szRxLen);
return;
}

void write_data(SCARDHANDLE hCard, char* block_str, char* data){
int block = strtoul(block_str, NULL, 0);

byte_t val[8];
char* pos = data;
size_t count = 0;

// Convert hexstring to byte array
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) {
sscanf(pos, "%2hhx", &val[count]);
pos += 2;
}

byte_t pbtApduWrite[] = { 0x84,0xD6,0x00,block,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

count = 0;
for(count = 0; count < 8; count++){
pbtApduWrite[5+count] = val[count];
}

if (!SendApdu(hCard, pbtApduWrite, sizeof(pbtApduWrite), pbtRx, &szRxLen)) {
printf("Error: Write failed\n");
print_bytes(pbtRx,szRxLen);
return;
}

printf("SUCCESS\n");
return;
}

void print_help(){
printf("iclass\n");
printf("\n");
printf("Usage:\n");
printf(" iclass read <block>\n");
printf(" iclass write <block> <data>\n");
printf("\n");
printf("Examples:\n");
printf(" To read the entire card:\n");
printf(" iclass read\n");
printf("\n");
printf(" To read a specific block:\n");
printf(" iclass read 6\n");
printf("\n");
printf(" To write to a specific block:\n");
printf(" iclass write 6 4141414141414141\n");
return;
}

int main(int argc, char* argv[]) {

DWORD rc;
DWORD dwActiveProtocol;
SCARDCONTEXT hContext;
SCARDHANDLE hCard;

size_t szPos = 0;
char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES];
size_t szDeviceNamesLen = sizeof (acDeviceNames);
DWORD dwDeviceNamesLen;
bool bFoundReader = false;

bool read = false;
bool write = false;
char* block = NULL;
char* data = NULL;

// Enough data
if (argc < 2) {
print_help();
exit(1);
} else if( strcmp(argv[1], "read") != 0 && strcmp(argv[1], "write") != 0){
print_help();
exit(1);
}

// Which command
read = strcmp(argv[1], "read") == 0;
if (!read) {
write = strcmp(argv[1], "write") == 0;
}

// Which block if there is a block
if (argc > 2){
block = argv[2];

if (write && (argc == 4)){
data = argv[3];
if (strlen(data) != 16){
printf("FAIL: Data written to a block must be 8 bytes\n");
exit(1);
}
} else if (write && argc <= 4){
printf("FAIL: Missing data to write\n");
exit(1);
}
}

////////////////////////////////////////////////////////////////////
// Initialize Card Reader
////////////////////////////////////////////////////////////////////

rc = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hContext);
if(rc != SCARD_S_SUCCESS) {
printf("FAIL: Could not establish smartcard memory context\n");
return 1;
}

// Retrieve the string array of all available pcsc readers
dwDeviceNamesLen = (DWORD)szDeviceNamesLen;
if (SCardListReadersA(hContext, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS) {
printf("FAIL: Could not connect retrieve smartcard reader list\n");
return false;
}

while (acDeviceNames[szPos] != '\0')
{
rc = SCardConnectA(hContext,acDeviceNames+szPos,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
if(rc != SCARD_S_SUCCESS) {
printf("Failed\n");
} else {
byte_t pbtApduSecured[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
if (SendApdu(hCard,pbtApduSecured,sizeof(pbtApduSecured),pbtRx,&szRxLen)){
bFoundReader = true;
break;
}
printf("Failed\n");
SCardDisconnect(hCard,SCARD_LEAVE_CARD);
}
// Find next device name position
while (acDeviceNames[szPos++] != '\0');
}

if (!bFoundReader) {
printf("FAIL: Could not find OMNIKEY Reader\n");
return 1;
}

////////////////////////////////////////////////////////////////////
// INITIALIZE SECURE MODE
////////////////////////////////////////////////////////////////////

byte_t pbtApduSecured[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
if (!SendApdu(hCard, pbtApduSecured, sizeof(pbtApduSecured), pbtRx, &szRxLen)) {
printf("FAIL: Could not start the OMNIKEY secure mode\n");
return 1;
}

////////////////////////////////////////////////////////////////////
// AUTHENTICATE
////////////////////////////////////////////////////////////////////

byte_t pbtApduAuthKey[] = { 0x84,0x88,0x00,0x21,0x00 };
if (!SendApdu(hCard,pbtApduAuthKey,sizeof(pbtApduAuthKey),pbtRx,&szRxLen)) {
printf("Error: Authentication failed\n");
return 1;
}

////////////////////////////////////////////////////////////////////
// INITIALIZE SECURE MODE
////////////////////////////////////////////////////////////////////

byte_t pbtApduSecured2[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
if (!SendApdu(hCard, pbtApduSecured2, sizeof(pbtApduSecured2), pbtRx, &szRxLen)) {
printf("FAIL: Could not start the OMNIKEY secure mode\n");
return 1;
}


if (read && block){
read_data(hCard, block);
} else if (read && argc == 2){
read_card(hCard);
} else if (write){
write_data(hCard, block, data);
}

return 0;
}
91 changes: 91 additions & 0 deletions iclass.pyw
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
try:
import tkinter as tk # Python 3
from tkinter import messagebox as msgbox
except:
import Tkinter as tk # Python 2
import tkMessageBox as msgbox
import pygubu
import subprocess
from pprint import pprint

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

class Application(pygubu.TkApplication):
def _create_ui(self):
global builder
#1: Create a builder
self.builder = builder = pygubu.Builder()

#2: Load an ui file
builder.add_from_file('iclass.ui')

#3: Create the widget using a master as parent
self.mainwindow = builder.get_object('iclass', self.master)
self.set_title('HID iClass Cloner')

builder.connect_callbacks(self)

def on_block_select(self, event):
w = event.widget
block = int(w.curselection()[0])
data = w.get(block)
print block, data
self.load_data(block, data)

def load_data(self, block, data):
data_entry = self.builder.get_object("Data")
data_entry.delete(0, tk.END)
data_entry.insert(0, data)

block_entry = self.builder.get_object("Block Choice")
block_entry.delete(0, tk.END)
block_entry.insert(0, block)

def read_card(self):
print "READCARD"
self.block_list = block_list = self.builder.get_object("Block List")

self.block_list.bind('<<ListboxSelect>>', self.on_block_select)
self.block_list.delete(0, tk.END)

self.block_list.bind('<Control-a>', lambda x: self.block_list.select_set(0,tk.END))

try:
blocks = subprocess.check_output(['iclass.exe', 'read'], startupinfo=startupinfo).split()
for block in blocks:
block_list.insert(tk.END, block)
except Exception as e:
status = e.output
msgbox.showinfo('Result', status)


def write_block(self):
print "WRITEBLOCK"
block_list = self.builder.get_object("Block List")

block_entry = self.builder.get_object("Block Choice")
block = block_entry.get()
data_entry = self.builder.get_object("Data")
data = data_entry.get()
try:
status = subprocess.check_output(['iclass.exe', 'write' , block, data], startupinfo=startupinfo)
check = subprocess.check_output(['iclass.exe', 'read', block], startupinfo=startupinfo)
print repr(check), repr(data)
if check.strip() != data.strip():
msgbox.showinfo('Result', "FAIL: Data read does not match data written")
else:
msgbox.showinfo('Result', status)
except Exception as e:
status = e.output

block_list.delete(block)
block_list.insert(block, data)



if __name__ == '__main__':
root = tk.Tk()
root.resizable(0, 0)
app = Application(root)
app.run()
Loading

0 comments on commit 7c27f52

Please sign in to comment.