10
0
Fork 0

more apdu methods added

This commit is contained in:
Kevin Redon 2011-05-05 23:09:57 +02:00
parent 2fbfa5ce07
commit 238fa1025e
1 changed files with 163 additions and 0 deletions

View File

@ -17,6 +17,8 @@ along with SAP. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
=end
# this librarie is to centralise the APDU related work
$KCODE = 'UTF8'
require 'jcode'
# transform binary string into readable hex string
class String
@ -82,6 +84,10 @@ end
module APDU
#===============
#== constants ==
#===============
# APDU constants (TS 102.221 10.1.2)
# SIM Class code (TS 51.011 9.2)
CLASS = 0xA0
@ -103,8 +109,54 @@ module APDU
EF_ICCID = [0x2F,0xE2]
DF_GSM = [0x7F,0x20]
EF_IMSI = [0x6F,0x07] # TS 51.011 10.3.2
EF_KC = [0x6F,0x20] # TS 51.011 10.3.3
EF_PLMNSEL = [0x6F,0x30] # TS 51.011 10.3.4
EF_HPPLMN = [0x6F,0x31] # TS 51.011 10.3.5
EF_FPLMN = [0x6F,0x7B] # TS 51.011 10.3.16
EF_PLMNWACT = [0x6F,0x60] # TS 51.011 10.3.35
EF_OPLMNWACT = [0x6F,0x61] # TS 51.011 10.3.36
EF_PHASE = [0x6F,0xAE] # TS 51.011 10.3.19
EF_SST = [0x6F,0x38] # TS 51.011 10.3.7
EF_AD = [0x6F,0xAD] # TS 51.011 10.3.18
EF_LOCI = [0x6F,0x7E] # TS 51.011 10.3.17
EF_SPN = [0x6F,0x46] # TS 51.011 10.3.11
EF_ACC = [0x6F,0x78] # TS 51.011 10.3.15
DF_TELECOM = [0x7F,0x10]
EF_SMS = [0x6F,0x3C] # TS 51.011 10.5.3
EF_SMSS = [0x6F,0x43] # TS 51.011 10.5.7
EF_MSISDN = [0x6F,0x40] # TS 51.011 10.5.5
# File IF (from ETSI TS 151 011 V4.9.0, figure 8)
FILE_ID = {
0x3f00 => "MF",
0x7f20=>"DF_GSM",0x7f10=>"DF_TELECOM",0x7f22=>"DF_IS-41",0x7f23=>"DF_FR-CTS",0x2fe2=>"EF_ICCID",0x2f05=>"EF_ELP",
0x6f3a=>"EF_ADN",0x6f3b=>"EF_FDN",0x6f3c=>"EF_SMS",0x6f3d=>"EF_CCP",0x6f40=>"EF_MSISDN",
0x6f42=>"EF_SMSP",0x6f43=>"EF_SMSS",0x6f44=>"EF_LND",0x6f47=>"EF_SMSR",0x6f49=>"EF_SDN",
0x6f4a=>"EF_EXT1",0x6f4b=>"EF_EXT2",0x6f4c=>"EF_EXT3",0x6f4d=>"EF_BDN",0x6f4d=>"EF_EXT4",
0x5f50=>"DF_GRAPHICS",0x4f20=>"EF_IMG",0x6f4f=>"EF_ECCP",
0x5f30=>"DF_IRIDIUM",0x5f31=>"DF_GLOBST",0x5f32=>"DF_ICO",0x5f33=>"DF_ACeS",
0x5f40=>"DF_EIA/TIA-553",0x5f60=>"DF_CTS",0x5f70=>"DF_SoLSA",0x4f30=>"EF_SAI",0x4F31=>"EF_SLL",
0x5f3c=>"DF_MExE",0x4f40=>"EF_MExE-ST",0x4f41=>"EF_ORPK",0x4f42=>"EF_ARPK",0x4f43=>"EF_TPRPK",
0x6f05=>"EF_LP",0x6f07=>"EF_IMSI",0x6f20=>"EF_Kc",0x6f2c=>"ED_DCK",0x6f30=>"EF_PLMNsel",0x6f31=>"EF_HPPLMN",
0x6f32=>"EF_CNL",0x6f37=>"EF_ACMmax",0x6f38=>"EF_SST",0x6f39=>"EF_ACM",0x6f3e=>"GID1",0x6f3f=>"GID2",
0x6f41=>"EF_PUCT",0x6f45=>"EF_CBMI",0x6f46=>"EF_SPN",0x6f48=>"EF_CBMID",0x6f74=>"EF_BCCH",0x6f78=>"EF_ACC",
0x6f7b=>"EF_FPLMN",0x6f7e=>"EF_LOCI",0x6fad=>"EF_AD",0x6fae=>"EF-PHASE",0x6fb1=>"EF_VGCS",0x6fba=>"EF_VGCSS",
0x6fb3=>"EF_VBS",0x6fb4=>"EF_VBSS",0x6fb5=>"EF_eMLPP",0x6fb6=>"EF_AAeM",0x6fb7=>"EF_ECC",0x6f50=>"EF_CBMIR",
0x6f51=>"EF_NIA",0x6f52=>"EF_KcGPRS",0x6f53=>"EF_LOCIGPRS",0x6f54=>"EF_SUME",0x6f58=>"EF_CMI",0x6f60=>"EF_PLMNwEAcT",
0x6f61=>"EF_OPLMNwAcT",0x6f62=>"EF_HPLMNAcT",0x6f63=>"EF_CPBCCH",0x6f64=>"EF_INVSCAN",0x6fc5=>"EF_PNN",0x6fc6=>"EF_OPL",
0x6fc7=>"EF_MBDN",0x6fc8=>"EF_EXT6",0x6fc9=>"EF_MBI",0x6fca=>"EF_MWIS",0x6fcb=>"EF_CFIS",0x6fcc=>"EF_EXT7",
0x6fcd=>"EF_SPDI",0x6fce=>"EF_MMSN",0x6fcf=>"EF_EXT8",0x6fd0=>"EF_MMSIFP",0x6fd1=>"EF_MMSUP",0x6fd2=>"EF_MMSUCP"
}
# GSM alphabet (7 bits)
# 0x1b escape caharacter is now space
GSM_ALPHABET = "@£$¥èéùìòÇ\rØø\nÅåΔ_ΦΓΛΩΠΨΣΘΞ ÆæßÉ !\"#¤%&'()*=,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà"
# not defined is a space
EXTENDED_ALPHABET = " ^ {} \\ [~] | € "
#=============
#== methods ==
#=============
# send APDU byte array
# return : APDU response
@ -181,4 +233,115 @@ module APDU
return response
end
# get the status (current directory)
def status
begin
response, sw1, sw2 = transmit(STATUS+[0x00])
rescue
return nil
end
response, sw1, sw2 = transmit(GET_RESPONSE+[sw2])
return response
end
# RUN GSM ALGORITHM
def a38(rand)
# am I in DF_GSM ?
pwd = status()
cd [MF,DF_GSM] unless pwd and pwd[4,2]==DF_GSM
# run algo
response, sw1, sw2 = transmit(A38+rand)
response, sw1, sw2 = transmit(GET_RESPONSE+[sw2])
return response
end
# change directory
# - path : array of files (EF/DF) to browse
def cd(path)
# change each folder
path.each do |folder|
# select folder
response = select(folder)
# verify it's a folder (MF or DF)
raise "#{folder.to_hex_disp} is not a folder" unless response[6]==1 or response[6]==2
end
end
# read an elementary file
# - path : array of files (directory+ef) to browse
# returns the content (binary or record)
def read_ef(path)
# browse the path
cd path[0..-2]
# select file
response = select(path[-1])
size = (response[2]<<8)+response[3]
# verify it's really and EF (TS 51.011 9.3)
if response[6]==0x04 then
# read ef (depending on the type of file)
if response[13]==0x00 then # transparent file (TS 51.011 9.3)
response, sw1, sw2 = transmit(READ_BINARY+[0x00,0x00]+[size&0xFF])
to_return = response
if size>0xFF then
response, sw1, sw2 = transmit(READ_BINARY+[0x01, 0x00]+[(size>>8)&0xFF])
to_return += response
end
else # linear fixed or cyclic
record_size = response[14]
to_return = []
# read all records
(1..size/record_size).each do |i|
response = transmit(READ_RECORD+[i,0x04,record_size])[0]
to_return << response
end
end
else
raise "selection is not an EF"
# TODO : implement the MF/DF reading
end
return to_return
end
# is the CHV1/PIN required
def chv_enabled?
# goto DF_GSM and verify if CHV is required
cd [MF]
response = select(DF_GSM)
# check if enabled
chv_enabled = (response[13]>>7)&0x01==0
chv_tries = response[18]&0x0f
if chv_enabled and chv_tries==0 then
puts "no CHV1 try left. enter PUK1 on your phone"
exit 0
elsif chv_enabled
puts "#{chv_tries} CHV1 tries left"
end
return chv_enabled
end
# convert a 7-bit GSM alphabet text into UTF8
def alphabet(text)
converted = ""
escape = false
text.each do |c|
if escape then # extended table
converted += EXTENDED_ALPHABET.char_at(c)
escape = false
else # gsm 7 bit alphabet
if c==0x1b then
escape = true
else
converted += GSM_ALPHABET.char_at(c)
end
end
end
return converted
end
end