From d6978777d4a0696fd5a8f77795c8aa373b8aca68 Mon Sep 17 00:00:00 2001 From: Kevin Redon Date: Mon, 16 May 2011 15:25:18 +0200 Subject: [PATCH] copy client works --- src/copy_client.rb | 172 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) 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