Skip to content

Instantly share code, notes, and snippets.

@mad
Created April 4, 2011 16:36
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mad/901931 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
require 'rexml/document'
require '../lab1/static_auth.rb'
# Used for inteprete tags from card and decrypt cert and static auth
class CardReader
attr_accessor :dynamic_tags, :card_dynamic_info, :dynamic_auth
def initialize(static_tags, dynamic_tags, ca_keys)
@static_tags = static_tags
@dynamic_tags = dynamic_tags
# Load all keys
ca = CA.new(ca_keys)
# Find us key
rid = @static_tags['4f - Application identifier (AID)'].unpack('a10')[0]
caKeyIndex = @static_tags['8f - Certification Authority Public Key Index']
@ca_key = ca.getKey(rid, caKeyIndex)
# Do main work
decrypt_static_cert()
decrypt_static_auth()
decrypt_dynamic_cert()
decrypt_dynamic_auth()
end
def decrypt_dynamic_cert()
mod = @card_static_info['mod_em']
if @static_tags['92 - Issuer Public Key Remainder'] != nil
mod = mod + @static_tags['92 - Issuer Public Key Remainder']
end
# card_info = cert^e mod n
card_info_raw = @dynamic_tags['9F46 - Integrated Circuit Card (ICC) Public Key Certificate'].hex.
mod_pow(@static_tags['9f32 - Issuer Public Key Exponent'].hex, mod.hex)
mod_len_with_padding = (@dynamic_tags['9F46 - Integrated Circuit Card (ICC) Public Key Certificate'].size/2 - 42)
@card_dynamic_info =
Hash.create(['prefix', # 1 byte
'format', # 1 byte
'card_number', # 10 byte
'expire_date', # 2 byte
'serial', # 3 byte
'alg_hash', # 1 byte
'alg_sign', # 1 byte
'mod_len', # 1 byte
'exp_len', # 1 byte
'mod_em', # L(CA) - 42
'cert_hash', # 20 byte
'suffix' # 1 byte
], card_info_raw.to_s(16).unpack("a2a2a20a4a6a2a2a2a2a" + (mod_len_with_padding * 2).to_s + "a40a2"))
check_bounds(@card_dynamic_info)
# Remove padding if exists
# XXX: hm, we may notify about that?
padding_len = mod_len_with_padding - @card_dynamic_info['mod_len'].hex
if padding_len > 0
@card_dynamic_info['mod_em'] = @card_dynamic_info['mod_em'].chomp("bb" * padding_len)
end
end
def decrypt_dynamic_auth()
mod = @card_dynamic_info['mod_em']
if @dynamic_tags['9F48 - Integrated Circuit Card (ICC) Public Key Remainder'] != nil
mod = mod + @dynamic_tags['9F48 - Integrated Circuit Card (ICC) Public Key Remainder']
end
dynamic_auth_raw = @dynamic_tags['9F4B - Signed Dynamic Application Data'].hex.
mod_pow(@dynamic_tags['9F47 - Integrated Circuit Card (ICC) Public Key Exponent'].hex, mod.hex)
# XXX: 9 is len of dynamic data. Static? Where we find it?
padding_len = (@dynamic_tags['9F4B - Signed Dynamic Application Data'].size/2 - 25 - 9)
@dynamic_auth =
Hash.create(['prefix', # 1 byte
'format', # 1 byte
'alg_hash', # 1 byte
'len_data', # 1 byte
'dyn_data', # 9 byte
'padding', # L(ICC) - L(DD) - 25
'card_hash', # 20 byte
'suffix' # 1 byte
], dynamic_auth_raw.to_s(16).unpack("a2a2a2a2a18a" + (padding_len * 2).to_s + "a40a2"))
check_bounds(@dynamic_auth)
end
def check_bounds(data)
unless data['prefix'] == "6a" and data['suffix'] == "bc"
raise "Bad card info, prefix = #{data['prefix']} and suffix = #{data['suffix']}"
end
end
private :check_bounds
end
# It is my task
$card_dynamic_var2 = {
'9F37 - Unpredictable number' => 'BABABABA',
'9F46 - Integrated Circuit Card (ICC) Public Key Certificate' => '06A4B80EBD734270ADAE007C0DE8B173' +
'D3411FB297084B1415578201DB71A738' +
'8EE5109463DE286398DBFAB5797B04DF' +
'DD355D0152BD6ABF7AB7B65AC4D375F3' +
'4F3B8B945158E0CE581A5A90F494589B' +
'1A07B7559C24E39006EC501B68AC1CEA' +
'F05E22636E3E840A6E8F77ECAADC9E3F' +
'79D47C0E8B5B65731C27E030B59DBE46',
'9F47 - Integrated Circuit Card (ICC) Public Key Exponent' => '03',
'9F48 - Integrated Circuit Card (ICC) Public Key Remainder' => nil,
'9F49 - Dynamic Data Authentication Data Object List (DDOL)' => '9F3704',
'9F4B - Signed Dynamic Application Data' => '33085A1397B566C317690A1A68DA5073' +
'8677DB80D5F32A20F64D38669DF41F3E' +
'F54C7E2CAB8B32230FFE146C8B330ADB' +
'56015533076C4A23A3FBB2B3F8CDCFD1'
}
# XXX: We use static tags from 1 lab.
if __FILE__ == $PROGRAM_NAME
cr = CardReader.new($card_static_var2, $card_dynamic_var2, '../ca_keys.xml')
print_hash("Dynamic tag", $card_dynamic_var2)
print_hash("Ca key", cr.ca_key)
print_hash("Dynamic info", cr.card_dynamic_info)
print_hash("Dynamic auth", cr.dynamic_auth)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment