aboutsummaryrefslogtreecommitdiffstats
path: root/cards
diff options
context:
space:
mode:
authorhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2006-06-17 01:49:40 +0000
committerhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2006-06-17 01:49:40 +0000
commit73ece936e80e01861cd19ce47c92b1fb6a31dd09 (patch)
treee929a95b4b8bea82882e6bb5e87ebe841ca7cbd9 /cards
parentea0fc4540d83038eab9189b25a1d01636ff8d68f (diff)
mtcos permission decoding
git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@95 f711b948-2313-0410-aaa9-d29f33439f0b
Diffstat (limited to 'cards')
-rw-r--r--cards/mtcos_card.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/cards/mtcos_card.py b/cards/mtcos_card.py
index b5cc561..a63d4b9 100644
--- a/cards/mtcos_card.py
+++ b/cards/mtcos_card.py
@@ -82,9 +82,107 @@ class MTCOS_Card(ISO_7816_4_Card,building_blocks.Card_with_80_aa):
elif len(value) == 1:
return "\nDefault key reference for authentication commands in this environment: 0x%02x" % ord(value[0])
+ def decode_security_attributes(value):
+ results = []
+ if len(value) == 6:
+ results.append( " " + utils.hexdump(value, short=True) )
+ else:
+ results.append("")
+
+ for i in range(len(value)/6):
+ part = value[i*6:i*6+6]
+ partresponse = []
+ if len(value) != 6:
+ partresponse.append("Rule: %s\n" % utils.hexdump(part, short=True))
+
+ if ord(part[0])&0xFE == 0x60:
+ partresponse.append("Admin commands")
+ else:
+ partresponse.append("Command 0x%02X" % (ord(part[0])&0xFE) )
+ all = not (ord(part[0])&0x01)
+
+ secrets = []
+ b2 = ord(part[1])
+ for k in range(4):
+ if b2 & (0x10<<k):
+ secrets.append("global password ID %s / SFID %s" % (hex(k+1), hex(k+0x11)) )
+ for k in range(4):
+ if b2 & (0x01<<k):
+ secrets.append("local password ID %s / SFID %s" % (hex(k+1), hex(k+0x11)) )
+
+ b3 = ord(part[2])
+ for k in range(8):
+ if b3 & (0x01<<k):
+ secrets.append("global key SFID %s" % (k+1))
+
+ b4 = ord(part[3])
+ for k in range(8):
+ if b4 & (0x01<<k):
+ secrets.append("local key SFID %s" % (k+1))
+
+ if len(secrets) > 1:
+ partresponse.append(
+ " needs\n\t " + (all and "\n\tAND " or "\n\t OR ").join(secrets)
+ )
+ elif len(secrets) == 1:
+ partresponse.append(" needs " + secrets[0])
+ elif len(secrets) == 0:
+ partresponse.append(" is always allowed")
+
+ def decode_key(value):
+ partresponse.append( (value&0x80) and "local" or "global" )
+ partresponse.append(" key, ")
+ partresponse.append( (value&0x40) and "random" or "any" )
+ partresponse.append(" IV")
+ if not (value & 0x20):
+ partresponse.append(", key number: ")
+ if (value & 0x1F) != 0x1F:
+ partresponse.append("0x%02x" % (value & 0x1F) )
+ else:
+ partresponse.append("RFU")
+
+ b5 = ord(part[4])
+ b6 = ord(part[5])
+ if b5 == 0xff:
+ partresponse.append("\nSecure messaging: no checksum required")
+ else:
+ partresponse.append("\nCryptographic checksum with ")
+ decode_key(b5)
+
+ if b6 == 0xff:
+ partresponse.append("\nSecure messaging: no encryption required")
+ elif not (b6 & 0x20):
+ partresponse.append("\nEncryption with ")
+ decode_key(b6)
+ else:
+ partresponse.append("\nEncryption: RFU")
+
+ if len(value) != 6:
+ results.append("\n\t".join("".join(partresponse).splitlines()))
+ else:
+ results.append("".join(partresponse))
+
+ return "\n".join(results)
+
+ physical_access_byte_descriptions = (
+ (0xFF, 0x01, None, "Access by contacts according to ISO 7816-3"),
+ (0xFF, 0x02, None, "Access by contactless (radio frequency) according to ISO 14443"),
+ (0xFF, 0x03, None, "Dual interface"),
+ (0xFC, 0x00, "RFU", None),
+ )
+ def decode_physical_access(value):
+ return "\n"+"\n".join(
+ utils.parse_binary(
+ ord(value[0]), MTCOS_Card.physical_access_byte_descriptions, True
+ )
+ )
+
TLV_utils.identifier("context_A5")
TLV_OBJECTS = {
TLV_utils.context_FCP: {
+ 0x86: (decode_security_attributes, "Security attributes"),
+ 0x91: (decode_physical_access, "Following security attribute is valid for"),
+ 0xA1: (TLV_utils.recurse, "Security attribute template for physical access", TLV_utils.context_FCP),
0xA5: (TLV_utils.recurse, "Proprietary security attributes", context_A5),
},
context_A5: {