added support for TA and CA (currently untested)

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@676 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2011-12-19 20:50:00 +00:00
parent a7b5f9c042
commit 58ac87489b
3 changed files with 60 additions and 21 deletions

View File

@@ -149,7 +149,6 @@ class CardGenerator(object):
self.mf = MF()
self.mf.append(TransparentStructureEF(parent=self.mf, fid=0x011c, shortfid=0x1c, data=card_access))
self.sam = nPA_SAM(pin="pin", can="can", mrz="mrz", puk="puk", mf=self.mf)
self.sam.card_access = card_access
def __generate_cryptoflex(self):
"""Generate the Filesystem and SAM of a cryptoflex card"""

View File

@@ -499,6 +499,7 @@ class NPAOS(Iso7816OS):
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_EXTENDED_LE):
Iso7816OS.__init__(self, mf, sam, ins2handler, maxle)
self.ins2handler[0x86] = self.SAM.general_authenticate
self.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90\x00\x75'
def formatResult(self, seekable, le, data, sw, sm):
if seekable:
@@ -564,7 +565,6 @@ class VirtualICC(object):
self.os = Iso7816OS(MF, SAM)
elif card_type == "nPA":
self.os = NPAOS(MF, SAM)
self.os.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90\x00\x75'
elif card_type == "cryptoflex":
self.os = CryptoflexOS(MF, SAM)
elif card_type == "relay":

View File

@@ -41,13 +41,12 @@ class nPA_AT_CRT(ControlReferenceTemplate):
chat = CHAT(bertlv_pack([[tag, length, value]]))
print(chat)
elif tag == 0x67:
auxiliary_data = value
self.auxiliary_data = value
elif tag == 0x80 or tag == 0x84 or tag == 0x83:
# handled by ControlReferenceTemplate.parse_SE_config
pass
elif tag == 0x91:
eph_key = value
# TODO handle security environment
self.eph_pub_key = value
else:
raise SwError(SW["ERR_REFNOTUSABLE"])
@@ -81,7 +80,7 @@ class nPA_SE(Security_Environment):
if self.eac_step != 4:
SwError(SW["ERR_AUTHBLOCKED"])
elif self.at.algorithm == "CA":
if self.eac_step != 7:
if self.eac_step != 5:
SwError(SW["ERR_AUTHBLOCKED"])
return sw, resp
@@ -90,14 +89,16 @@ class nPA_SE(Security_Environment):
if (p1, p2) != (0x00, 0x00):
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
if (self.eac_step == 0):
if self.eac_step == 0 and self.at.algorithm == "PACE":
return self.__eac_pace_step1(data)
elif (self.eac_step == 1):
elif self.eac_step == 1 and self.at.algorithm == "PACE":
return self.__eac_pace_step2(data)
elif (self.eac_step == 2):
elif self.eac_step == 2 and self.at.algorithm == "PACE":
return self.__eac_pace_step3(data)
elif (self.eac_step == 3):
elif self.eac_step == 3 and self.at.algorithm == "PACE":
return self.__eac_pace_step4(data)
elif self.eac_step == 5 and self.at.algorithm == "CA":
return self.__eac_ca(data)
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
@@ -126,8 +127,7 @@ class nPA_SE(Security_Environment):
def __eac_pace_step1(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
if self.at.algorithm != "PACE" or tlv_data != []:
print 'value %r' % tlv_data
if tlv_data != []:
raise SwError(SW["WARN_NOINFO63"])
self.__eac_abort()
@@ -169,8 +169,6 @@ class nPA_SE(Security_Environment):
def __eac_pace_step2(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
if self.at.algorithm != "PACE":
raise SwError(SW["WARN_NOINFO63"])
pubkey = pace.buf2string(pace.PACE_STEP3A_generate_mapping_data(self.eac_ctx))
@@ -186,8 +184,6 @@ class nPA_SE(Security_Environment):
def __eac_pace_step3(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
if self.at.algorithm != "PACE":
raise SwError(SW["WARN_NOINFO63"])
my_epp_pubkey = pace.buf2string(pace.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx))
@@ -204,9 +200,6 @@ class nPA_SE(Security_Environment):
def __eac_pace_step4(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
if self.at.algorithm != "PACE":
raise SwError(SW["WARN_NOINFO63"])
pace.PACE_STEP3C_derive_keys(self.eac_ctx)
my_token = pace.buf2string(pace.PACE_STEP3D_compute_authentication_token(self.eac_ctx, self.pace_opp_pub_key))
token = ""
@@ -237,12 +230,59 @@ class nPA_SE(Security_Environment):
return 0x9000, nPA_SE.__pack_general_authenticate([[0x86, len(my_token), my_token]])
def __eac_ca(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
pubkey = ""
for tag, length, value in tlv_data:
if tag == 0x80:
pubkey = value
else:
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
pace.CA_STEP4_compute_shared_secret(self.eac_ctx,
pace.get_buf(pubkey))
nonce, token = pace.CA_STEP5_derive_keys(self.eac_ctx,
pace.get_buf(pubkey))
# TODO activate SM
return 0x9000, nPA_SE.__pack_general_authenticate([[0x81,
len(nonce), nonce], [0x82, len(token), token]])
def verify_certificate(se, p1, p2, data):
if (p1, p2) != (0x00, 0xbe):
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
cert = CHAT(bertlv_pack([[0x7f, len(data), data]]))
pace.TA_STEP2_import_certificate(self.eac_ctx, pace.get_buf(cert))
cert = bertlv_pack([[0x7f, len(data), data]])
if 1 != pace.TA_STEP2_import_certificate(self.eac_ctx, pace.get_buf(cert)):
raise SwError(SW["ERR_NOINFO69"])
def external_authenticate(self, p1, p2, data):
"""
Authenticate the terminal to the card. Check whether Terminal correctly
encrypted the given challenge or not
"""
if self.at.algorithm == "TA":
if self.last_challenge is None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
pace.EAC_CTX_init_ta(self.eac_ctx, "", 0, self.dst.keyref,
len(self.dst.keyref), "", 0)
if 1 != pace.TA_STEP6_verify(self.eac_ctx,
pace.get_buf(self.at.eph_pub_key), id_picc,
pace.get_buf(self.last_challenge),
pace.get_buf(self.auxiliary_data), pace.get_buf(data)):
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
self.eac_step += 1
return 0x9000, ""
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
class nPA_SAM(SAM):