aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Redon <kevredon@mail.tsaitgaist.info>2011-05-16 15:25:18 +0200
committerKevin Redon <kevredon@mail.tsaitgaist.info>2011-05-16 15:25:18 +0200
commitd6978777d4a0696fd5a8f77795c8aa373b8aca68 (patch)
treef93a4877d97fe8d128323d1a6b362828a7f522e7
parentff8688bf8578d526f7ffc7a5d548d5c7bcde6cf5 (diff)
copy client works
-rw-r--r--src/copy_client.rb172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/copy_client.rb b/src/copy_client.rb
index b58a8bb..71e8e9d 100644
--- a/src/copy_client.rb
+++ b/src/copy_client.rb
@@ -27,6 +27,8 @@ class Copy
# to show the exact file being processed
VERBOSE = false
+ # show file discovery progress
+ PROGRESS = true
# create a Copy class
# io : I/O to the SAP server
@@ -46,8 +48,178 @@ class Copy
@sim = XML::Node.new("sim")
# get the ATR
@sim["atr"] = @client.atr.to_hex
+
+ # verify CHV1
+ while chv_enabled? do
+
+ print "enter PIN : "
+ STDOUT.flush
+ pin = gets.chomp
+ # pin is between 4 and 8 digits
+ unless pin.length>=4 and pin.length<=8 and pin.gsub(/\d/,"").length==0 then
+ puts "PIN has 4 to 8 digits"
+ redo
+ end
+
+ # encode pin in T.50 on 8 bytes
+ chv = [0xFF]*8
+ pin.length.times do |i|
+ chv[i]=0x30+pin[i,1].to_i
+ end
+
+ # select DF_GSM
+ cd [MF,DF_GSM]
+ # verify CHV1
+ begin
+ transmit(CHV1+chv)
+ @sim["CHV1"]=pin
+ break
+ rescue
+ puts "PIN wrong"
+ end
+ end
+
+ # get MF
+ puts "reading SIM files"
+ mf = explore([MF])
+ @sim << mf
+ puts "" if PROGRESS and !VERBOSE
+ puts "found #{@nb_directories} directories and #{@nb_files} files"
+
+ # get some tuples (run A38 algo)
+ puts "getting some A38 tuples"
+ a38_node = XML::Node.new("a38")
+ # the rands
+ rands = []
+ 16.times do |i|
+ rands << [(i<<4)+i]*16
+ end
+ # the results
+ rands.each do |r|
+ response = a38(r)
+ tuple_node = XML::Node.new("tuple")
+ tuple_node["rand"]=r.to_hex
+ tuple_node["sres"]=response[0,4].to_hex
+ tuple_node["kc"]=response[4..-1].to_hex
+ a38_node << tuple_node
+ end
+ @sim << a38_node
+
+ # write xml in file
+ puts "saving SIM files in #{file}"
+ xml = XML::Document.new
+ xml.root = @sim
+ xml.save(file)
end
+ # return the file
+ # - id : file ID
+ # return {:id,:type,:name,:structure,:header,:body}, or nil if file does not exist
+ def file(id)
+
+ # the data to return
+ to_return = {}
+
+ # select file
+ begin
+ response = select(id)
+ rescue Exception => e
+ if e.to_s.include? "file ID not found/pattern not found" then
+ return nil
+ else
+ raise e
+ end
+ end
+ to_return[:header] = response
+ # file id
+ to_return[:id] = [response[4],response[5]]
+ to_return[:name]=FILE_ID[(to_return[:id][0]<<8)+to_return[:id][1]]
+ # file type
+ type = case response[6]
+ when 0
+ "RFU"
+ when 1
+ "MF"
+ when 2
+ "DF"
+ when 4
+ "EF"
+ else
+ "unknown"
+ end
+ to_return[:type] = type
+
+ # read EF
+ if response[6]==0x04 then
+
+ # structure
+ structure = case response[13]
+ when 0
+ "transparent"
+ when 1
+ "linear fixed"
+ when 3
+ "cyclic"
+ else
+ "unknown"
+ end
+ to_return[:structure] = structure
+
+ # do I have the right to read ?
+ nibble = (response[8]>>4)&0x0f
+ read_right = (nibble==0 or nibble==1)
+
+ if read_right then
+ size = (response[2]<<8)+response[3]
+ # read ef (depending on the type of file)
+ if response[13]==0x00 then # transparent file (TS 51.011 9.3)
+ response = transmit(READ_BINARY+[0x00,0x00]+[size&0xFF])[0]
+ to_return[:body] = response
+ if size>0xFF then
+ response = transmit(READ_BINARY+[0x01, 0x00]+[(size>>8)&0xFF])[0]
+ to_return[:body] += response
+ end
+ else # linear fixed or cyclic
+ record_size = response[14]
+ to_return[:body] = []
+ # read all records
+ (1..size/record_size).each do |i|
+ response = transmit(READ_RECORD+[i,0x04,record_size])[0]
+ to_return[:body] << response
+ end
+ end
+ end
+
+ end
+
+ return to_return
+ end
+
+ # returns a node from the file data
+ def file2node(data)
+
+ node = XML::Node.new("file")
+ node["id"]=data[:id].to_hex
+ node["name"]=data[:name] if data[:name]
+ node["type"]=data[:type]
+ node << XML::Node.new("header",data[:header].to_hex)
+ if data[:type]=="EF" then
+ node["structure"]=data[:structure]
+ if data[:body] then# if I can read the body
+ if data[:structure]=="transparent" then
+ node << XML::Node.new("body",data[:body].to_hex)
+ else # linear fixed or cyclic
+ body_node = XML::Node.new("body")
+ data[:body].each do |record|
+ body_node << XML::Node.new("record",record.to_hex)
+ end
+ node << body_node
+ end
+ end
+ end
+ return node
+ end
+
# get all the files in the current directory
# does a recursive call
# files are saved in the xml file