Commit 473c3414 authored by Arturo Hernandez's avatar Arturo Hernandez

misc refactor

parent 4f8d9c26
......@@ -86,7 +86,8 @@ def card_start():
LOGGER.info('UUIDHex: {}'.format(toHexString(uid, 1)))
return card, atr, uid
def populate_match(data, atr):
def find_atr(data, atr):
""" requires data{ATR_match:[], ATR_possible:[]}"""
found = parseATR.match_atr_differentiated(atr, "src/parseATR/smartcard_list.txt")
if found:
if atr in found:
......@@ -97,6 +98,7 @@ def populate_match(data, atr):
for d in found[a]:
data["ATR_possible"].append(str(d))
class MainHandler(tornado.web.RequestHandler):
def get(self):
LOGGER.debug(self.request)
......@@ -119,9 +121,8 @@ class ReadCardHandler(tornado.web.RequestHandler):
print("reading card...")
block = int(self.get_argument("block",default=-1,strip=True))
key_a = self.get_argument("key_a",default=config.DEFAULT_KEY_A,strip=True)
key_a = list(bytes.fromhex(key_a))
key_b = self.get_argument("key_b",default=config.DEFAULT_KEY_B,strip=True)
key_b = list(bytes.fromhex(key_b))
use_keyb = config.str2bool(self.get_argument("use_keyb", default="False"))
try:
card, atr, uid = card_start()
......@@ -141,22 +142,7 @@ class ReadCardHandler(tornado.web.RequestHandler):
if block >=0:
LOGGER.info("reading block %i", block)
card.send_key(key_a, 0)
card.send_key(key_b, 1)
#try auth_
auth = False
try:
LOGGER.warn("Trying keyA")
card.auth_block(block, TYPE_KEYA, 0)
auth = True
except SWException as e:
try:
LOGGER.warn("Trying keyB")
card.auth_block(block, TYPE_KEYB, 1)
auth = True
except SWException as e:
LOGGER.error("Can't auth with keys. %s", e)
if auth:
if card.auth_with_keys(block,key_a, key_b, use_keyb):
block_data = card.read_block(block)
data["data"]={
"block" : block,
......@@ -172,7 +158,7 @@ class ReadCardHandler(tornado.web.RequestHandler):
if value is not None:
data["data"]["isValue"] = True
data["data"]["value"] = value[0] #TODO: adr?
populate_match(data, atr)
find_atr(data, atr)
self.write(data)
......@@ -192,11 +178,10 @@ class WriteCardHandler(tornado.web.RequestHandler):
def post(self):
print("writing card...")
block = int(self.get_argument("block",strip=True))
data = list(bytes.fromhex(self.get_argument("data", strip=True)))
key_a = self.get_argument("key_a", default=config.DEFAULT_KEY_A, strip=True)
key_a = list(bytes.fromhex(key_a))
key_b = self.get_argument("key_b", default=config.DEFAULT_KEY_B, strip=True)
key_b = list(bytes.fromhex(key_b))
first_keyb = config.str2bool(self.get_argument("first_keyb", default="False"))
use_keyb = config.str2bool(self.get_argument("use_keyb", default="False"))
try:
card, atr, uid = card_start()
except OMNIKEYException as e:
......@@ -214,50 +199,11 @@ class WriteCardHandler(tornado.web.RequestHandler):
}
LOGGER.info("Writing block %i", block)
card.send_key(key_a, 0)
card.send_key(key_b, 1)
#try auth_
auth = False
try:
if first_keyb:
LOGGER.warn("Trying keyB")
card.auth_block(block, TYPE_KEYB, 1)
auth = True
else:
LOGGER.warn("Trying keyA")
card.auth_block(block, TYPE_KEYA, 0)
auth = True
except SWException as e:
try:
if first_keyb:
LOGGER.warn("Trying keyA")
card.auth_block(block, TYPE_KEYA, 0)
auth = True
else:
LOGGER.warn("Trying keyB")
card.auth_block(block, TYPE_KEYB, 1)
auth = True
except SWException as e:
LOGGER.error("Can't auth with keys. %s", e)
self.write({"error": "No se pudo autenticar"})
return
if auth:
block_data = card.read_block(block)
data["data"]={
"block" : block,
"array" : block_data,
"hex": toHexString(block_data,1),
"string" : toHexString(block_data),
"isValue": False,
"value": 0,
"isTrailer": (block & 0x03) == 0x03 if block < 128 else (block & 0x0F) == 0x0F,
}
#check if value
value = card.parse_value(block_data)
if value is not None:
data["data"]["isValue"] = True
data["data"]["value"] = value[0] #TODO: adr?
populate_match(data, atr)
if not card.auth_with_keys(block,key_a, key_b, use_keyb):
self.write({"error": "No se pudo autenticar"})
return
card.write_block(block,data)
find_atr(data, atr)
self.write(data)
class InitCardHandler(tornado.web.RequestHandler):
......@@ -301,7 +247,7 @@ class InitCardHandler(tornado.web.RequestHandler):
'message': 'OK',
'init': str(init)
}
populate_match(data, atr)
find_atr(data, atr)
self.write(data)
class IndexHandler(tornado.web.RequestHandler):
......
......@@ -44,9 +44,6 @@ DATA_BLOCK = DATA_SECTOR * 4
DATA_BLOCK_CNT = DATA_SECTOR * 4 + 1
DATA_BLOCK_HID = DATA_SECTOR * 4 + 2
DATA_TRAILER = DATA_SECTOR * 4 + 3
class AccessBlockException(SmartcardException):
""" raised when trying TODO: migrate to OMNIKEYException """
pass
class OMNIKEYException(Exception):
pass
......@@ -146,6 +143,7 @@ class OMNIKEYCard(object):
self.APDU_set_field(1) #turn off?
self.APDU_exit_transparent_session()
return inited
@staticmethod
def parse_value(block):
value = None
......@@ -161,6 +159,7 @@ class OMNIKEYCard(object):
else:
LOGGER.debug("not a value block...")
return value
def APDU_get_version(self):
data, sw1, sw2 = self.connection.transmit([0xFF, 0x68, 0x0E, 0x08, 0x02, 0x01, 0x00]) # propietary reader command "get version"
LOGGER.debug('VERSION {} sw: {}'.format(toHexString(data), toHexString([sw1, sw2])))
......@@ -238,6 +237,31 @@ class OMNIKEYCard(object):
self.sw1 = sw1; self.sw2 = sw2
errorchain[0](data, sw1, sw2)
def auth_with_keys(self, block, key_a="FFFFFFFFFFFF", key_b="FFFFFFFFFFFF", use_keyb=False):
key_a = list(bytes.fromhex(key_a)) #TODO: check if already list
key_b = list(bytes.fromhex(key_b))
self.send_key(key_a, 0)
self.send_key(key_b, 1) #optional, should send only one?
try:
if not use_keyb:
LOGGER.warn("Trying keyA")
self.auth_block(block, TYPE_KEYA, 0)
else:
LOGGER.warn("Trying keyB")
self.auth_block(block, TYPE_KEYB, 1)
except SWException as e:
try:
if use_keyb:
LOGGER.warn("Trying keyA")
card.auth_block(block, TYPE_KEYA, 0)
else:
LOGGER.warn("Trying keyB")
card.auth_block(block, TYPE_KEYB, 1)
except SWException as e:
LOGGER.error("Can't auth with keys. %s", e)
return False
return True
def read_block(self, block):
data, sw1, sw2 = self.connection.transmit([0xFF, 0xB0, 0x00 , block, 0x00]) # read block
LOGGER.debug ("RB#{}, data:{}, sw {}". format(block, toHexString(data), toHexString([sw1, sw2])))
......@@ -248,8 +272,10 @@ class OMNIKEYCard(object):
def write_block(self, block, data):
if (block % 4) == 3:
LOGGER.debug ("Intentando escribir bloque de llaves #{}". format(block))
raise AccessBlockException("bloqueado acceso a llaves")
raise OMNIKEYException("bloqueado acceso a llaves")
#TODO: check data size must be always 16
if len(data) != 16:
raise OMNIKEYException("tamaño de datos incorrecto")
response, sw1, sw2 = self.connection.transmit([0xFF, 0xD6, 0x00 , block, len(data)] + data) # read block
LOGGER.debug ("WB#{}, data:{}, sw {}". format(block, toHexString(data), toHexString([sw1, sw2])))
self.sw1 = sw1; self.sw2 = sw2
......@@ -258,7 +284,7 @@ class OMNIKEYCard(object):
def write_value(self, block, value, addr=0):
if (block % 4) == 3:
LOGGER.debug ("Intentando escribir bloque de llaves #{}". format(block))
raise AccessBlockException("bloqueado acceso a llaves")
raise OMNIKEYException("bloqueado acceso a llaves")
#TODO: check value as int32 and addr as byte
#build value block
data = [ byte2int(x) for x in pack("<IIIBBBB",
......@@ -266,17 +292,21 @@ class OMNIKEYCard(object):
addr, 0xFF ^ addr, addr, 0xFF ^ addr)]
self.write_block(block, data)
@staticmethod
def isTrailer(block):
return (block & 0x03) == 0x03 if block < 128 else (block & 0x0F) == 0x0F
def read_value(self, block):
data = self.read_block(block)
parsed = unpack("<IIIBBBB", bytearray(data))
LOGGER.debug ("RV values: {}". format(parsed))
#TODO: verify data integrity?
return parsed[0]
#verify data integrity?
return self.parse_value(data)
def increment_value(self, block, value_inc):
if (block % 4) == 3:
if self.isTrailer(block):
LOGGER.debug ("Intentando escribir bloque de llaves #{}". format(block))
raise AccessBlockException("bloqueado acceso a llaves")
raise OMNIKEYException("bloqueado acceso a llaves")
#TODO: check value is int32
data = [ byte2int(x) for x in pack("I", value_inc)]
response, sw1, sw2 = self.connection.transmit([0xFF, 0xD4, 0x00 , block, 4] + data) # read block
......@@ -285,9 +315,9 @@ class OMNIKEYCard(object):
errorchain[0](response, sw1, sw2)
def decrement_value(self, block, value_dec):
if (block % 4) == 3:
if self.isTrailer(block):
LOGGER.debug ("Intentando escribir bloque de llaves #{}". format(block))
raise AccessBlockException("bloqueado acceso a llaves")
raise OMNIKEYException("bloqueado acceso a llaves")
#TODO: check value is int32
data = [ byte2int(x) for x in pack("I", value_dec)]
response, sw1, sw2 = self.connection.transmit([0xFF, 0xD8, 0x00 , block, 4] + data) # read block
......@@ -296,9 +326,9 @@ class OMNIKEYCard(object):
errorchain[0](response, sw1, sw2)
def write_trailer(self, block, key_a=DEFAULT_KEY, access_bits=[0xFF, 0x07, 0x80, 0x69], key_b=DEFAULT_KEY):
if (block % 4) != 3:
LOGGER.debug ("Intentando escribir bloque de llaves #{}". format(block))
raise AccessBlockException("bloqueado acceso normal")
if not self.isTrailer(block):
LOGGER.debug ("Intentando escribir bloque normal #{}". format(block))
raise OMNIKEYException("bloqueado acceso normal")
response, sw1, sw2 = self.connection.transmit([0xFF, 0xD6, 0x00 , block, 16] + key_a + access_bits + key_b) # read block
LOGGER.debug ("WT#{}, data:{}, sw {}". format(block, toHexString(response), toHexString([sw1, sw2])))
self.sw1 = sw1; self.sw2 = sw2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment