added PIN management for nPA

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@675 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2011-12-19 02:36:35 +00:00
parent 045514ae20
commit a7b5f9c042
2 changed files with 70 additions and 14 deletions

View File

@@ -226,7 +226,7 @@ class Security_Environment(object):
#Verification, encryption, external authentication and key agreement
if se & 0x08:
self.external_auth = True
return self.__set_SE(p2, data)
return self._set_SE(p2, data)
elif(cmd== 0x02):
return self.sam.store_SE(p2)
elif(cmd == 0x03):
@@ -237,15 +237,12 @@ class Security_Environment(object):
raise SwError(SW["ERR_INCORRECTP1P2"])
def __set_SE(self, p2, data):
def _set_SE(self, p2, data):
"""
Manipulate the current Security Environment. P2 is the tag of a
control reference template, data contains control reference objects
"""
valid_p2 = (0xA4, 0xA6, 0xB4, 0xB6, 0xB8)
if not p2 in valid_p2:
raise SwError(SW["ERR_INCORRECTP1P2"])
if p2 == 0xA4:
return self.at.parse_SE_config(data)
elif p2 == 0xA6:
@@ -258,6 +255,8 @@ class Security_Environment(object):
return self.dst.parse_SE_config(data)
elif p2 == 0xB8:
return self.ct.parse_SE_config(data)
raise SwError(SW["ERR_INCORRECTP1P2"])
def parse_SM_CAPDU(self, CAPDU, authenticate_header):
"""

View File

@@ -30,6 +30,7 @@ class nPA_AT_CRT(ControlReferenceTemplate):
ControlReferenceTemplate.__init__(self, CRT_TEMPLATE["AT"])
def parse_SE_config(self, config):
r = 0x9000
try:
ControlReferenceTemplate.parse_SE_config(self, config)
except SwError as e:
@@ -37,12 +38,11 @@ class nPA_AT_CRT(ControlReferenceTemplate):
for tlv in structure:
tag, length, value = tlv
if tag == 0x7f4c:
from chat import CHAT
chat = CHAT(bertlv_pack([[tag, length, value]]))
print(chat)
elif tag == 0x67:
auxiliary_data = value
elif tag == 0x80 or tag == 0x83 or tag == 0x84:
elif tag == 0x80 or tag == 0x84 or tag == 0x83:
# handled by ControlReferenceTemplate.parse_SE_config
pass
elif tag == 0x91:
@@ -51,7 +51,16 @@ class nPA_AT_CRT(ControlReferenceTemplate):
else:
raise SwError(SW["ERR_REFNOTUSABLE"])
return 0x9000 , ""
structure = unpack(config)
for tlv in structure:
if [0x83, len('\x03'), '\x03'] == tlv:
if self.sam.counter <= 0:
r = 0x63c0
elif self.sam.counter == 1:
r = 0x63c1
elif self.sam.counter == 2:
r = 0x63c2
return r, ""
class nPA_SE(Security_Environment):
# TODO call __eac_abort whenever an error occurred
@@ -63,6 +72,20 @@ class nPA_SE(Security_Environment):
self.sec = None
self.eac_ctx = None
def _set_SE(self, p2, data):
sw, resp = Security_Environment._set_SE(self, p2, data)
if self.at.algorithm == "PACE":
self.eac_step = 0
elif self.at.algorithm == "TA":
if self.eac_step != 4:
SwError(SW["ERR_AUTHBLOCKED"])
elif self.at.algorithm == "CA":
if self.eac_step != 7:
SwError(SW["ERR_AUTHBLOCKED"])
return sw, resp
def general_authenticate(self, p1, p2, data):
if (p1, p2) != (0x00, 0x00):
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
@@ -80,7 +103,9 @@ class nPA_SE(Security_Environment):
def __eac_abort(self):
pace.EAC_CTX_clear_free(self.eac_ctx)
self.eac_ctx = None
pace.PACE_SEC_clear_free(self.sec)
self.sec = None
@staticmethod
def __unpack_general_authenticate(data):
@@ -113,9 +138,21 @@ class nPA_SE(Security_Environment):
elif self.at.keyref == '\x02':
self.sec = pace.PACE_SEC_new(self.sam.can, pace.PACE_CAN)
elif self.at.keyref == '\x03':
self.sec = pace.PACE_SEC_new(self.sam.pin, pace.PACE_PIN)
if self.sam.counter <= 0:
print "Must use PUK to unblock"
raise SwError(SW["WARN_NOINFO63"])
if self.sam.counter == 1 and not self.sam.active:
print "Must use CAN to activate"
return 0x63c1, ""
self.sec = pace.PACE_SEC_new(self.sam.PIN, pace.PACE_PIN)
self.sam.counter -= 1
if self.sam.counter <= 1:
self.sam.active = False
elif self.at.keyref == '\x04':
if self.sam.counter_puk <= 0:
raise SwError(SW["WARN_NOINFO63"])
self.sec = pace.PACE_SEC_new(self.sam.puk, pace.PACE_PUK)
self.sam.counter_puk -= 1
else:
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
@@ -172,13 +209,28 @@ class nPA_SE(Security_Environment):
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 = ""
for tag, length, value in tlv_data:
if tag == 0x85:
pace.PACE_STEP3D_verify_authentication_token(self.eac_ctx, pace.get_buf(value))
token = value
else:
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
if 1 != pace.PACE_STEP3D_verify_authentication_token(self.eac_ctx, pace.get_buf(token)):
raise SwError(SW["WARN_NOINFO63"])
if self.at.keyref == '\x02':
if (self.sam.counter == 1):
self.sam.active = True
print "PIN resumed"
elif self.at.keyref == '\x04':
self.sam.active = True
self.sam.counter = 3
print "PIN unblocked"
elif self.at.keyref == '\x03':
self.sam.active = True
self.sam.counter = 3
self.eac_step += 1
# TODO activate SM
@@ -186,19 +238,24 @@ class nPA_SE(Security_Environment):
return 0x9000, nPA_SE.__pack_general_authenticate([[0x86, len(my_token), my_token]])
def verify_certificate(se, p1, p2, data):
pass
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))
class nPA_SAM(SAM):
eac_step = make_property("eac_step", "next step to performed for EAC")
def __init__(self, pin, can, mrz, puk, mf, default_se = nPA_SE):
SAM.__init__(self, None, None, mf)
SAM.__init__(self, pin, None, mf)
self.active = True
self.current_SE = default_se(self.mf, self)
self.pin = pin
self.can = can
self.mrz = mrz
self.puk = puk
self.counter_puk = 10
def general_authenticate(self, p1, p2, data):
return self.current_SE.general_authenticate(p1, p2, data)