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:
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user