Refactored the python files in the cards directory according to PEP8
This commit is contained in:
@@ -32,16 +32,18 @@ class HandlerTestOS(SmartcardOS):
|
||||
lastCommandOffcut = ''
|
||||
|
||||
def getATR(self):
|
||||
return '\x3B\xD6\x18\x00\x80\xB1\x80\x6D\x1F\x03\x80\x51\x00\x61\x10\x30\x9E'
|
||||
return '\x3B\xD6\x18\x00\x80\xB1\x80\x6D\x1F\x03\x80\x51\x00\x61' + \
|
||||
'\x10\x30\x9E'
|
||||
|
||||
def __output_from_le(self, msg):
|
||||
le = (ord(msg[2])<<8)+ord(msg[3])
|
||||
return ''.join([chr(num&0xff) for num in xrange(le)])
|
||||
le = (ord(msg[2]) << 8) + ord(msg[3])
|
||||
return ''.join([chr(num & 0xff) for num in xrange(le)])
|
||||
|
||||
def execute(self, msg):
|
||||
ok = '\x90\x00'
|
||||
error = '\x6d\x00'
|
||||
if msg == '\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\x50' or msg == '\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF':
|
||||
if (msg == '\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\x50' or
|
||||
msg == '\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF'):
|
||||
logging.info('Select applet')
|
||||
return ok
|
||||
elif msg.startswith('\x80\x38\x00'):
|
||||
@@ -65,7 +67,7 @@ class HandlerTestOS(SmartcardOS):
|
||||
self.lastCommandOffcut = self.__output_from_le(msg)
|
||||
if len(self.lastCommandOffcut) > 0xFF:
|
||||
return '\x61\x00'
|
||||
return '' + chr(len(self.lastCommandOffcut)&0xFF)
|
||||
return '' + chr(len(self.lastCommandOffcut) & 0xFF)
|
||||
elif len(msg) == 6+ord(msg[4]):
|
||||
logging.info('Case 4, APDU')
|
||||
return self.__output_from_le(msg) + ok
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
# virtualsmartcard. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import atexit
|
||||
import logging
|
||||
import smartcard
|
||||
import sys
|
||||
from virtualsmartcard.VirtualSmartcard import SmartcardOS
|
||||
import smartcard, logging, sys, atexit
|
||||
|
||||
|
||||
class RelayOS(SmartcardOS):
|
||||
@@ -30,7 +33,8 @@ class RelayOS(SmartcardOS):
|
||||
"""
|
||||
def __init__(self, readernum):
|
||||
"""
|
||||
Initialize the connection to the (physical) smart card via a given reader
|
||||
Initialize the connection to the (physical) smart card via a given
|
||||
reader
|
||||
"""
|
||||
|
||||
# See which readers are available
|
||||
|
||||
@@ -27,7 +27,8 @@ from virtualsmartcard.SmartcardFilesystem import MF, TransparentStructureEF, \
|
||||
RecordStructureEF, DF, EF
|
||||
from virtualsmartcard.ConstantDefinitions import FDB, MAX_SHORT_LE
|
||||
|
||||
import struct, logging
|
||||
import struct
|
||||
import logging
|
||||
|
||||
|
||||
class CryptoflexOS(Iso7816OS):
|
||||
@@ -43,14 +44,17 @@ class CryptoflexOS(Iso7816OS):
|
||||
c = C_APDU(msg)
|
||||
except ValueError as e:
|
||||
logging.debug("Failed to parse APDU %s", msg)
|
||||
return self.formatResult(False, 0, 0, "", SW["ERR_INCORRECTPARAMETERS"])
|
||||
return self.formatResult(False, 0, 0, "",
|
||||
SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
try:
|
||||
sw, result = self.ins2handler.get(c.ins, notImplemented)(c.p1, c.p2, c.data)
|
||||
#print type(result)
|
||||
sw, result = self.ins2handler.get(c.ins, notImplemented)(c.p1,
|
||||
c.p2,
|
||||
c.data)
|
||||
# print type(result)
|
||||
except SwError as e:
|
||||
logging.info(e.message)
|
||||
#traceback.print_exception(*sys.exc_info())
|
||||
# traceback.print_exception(*sys.exc_info())
|
||||
sw = e.sw
|
||||
result = ""
|
||||
|
||||
@@ -62,20 +66,22 @@ class CryptoflexOS(Iso7816OS):
|
||||
# cryptoflex does not inpterpret le==0 as maxle
|
||||
self.lastCommandSW = sw
|
||||
self.lastCommandOffcut = data
|
||||
r = R_APDU(inttostring(SW["ERR_WRONGLENGTH"] +\
|
||||
min(0xff, len(data)))).render()
|
||||
r = R_APDU(inttostring(SW["ERR_WRONGLENGTH"] +
|
||||
min(0xff, len(data)))).render()
|
||||
else:
|
||||
if ins == 0xa4 and len(data):
|
||||
# get response should be followed by select file
|
||||
self.lastCommandSW = sw
|
||||
self.lastCommandOffcut = data
|
||||
r = R_APDU(inttostring(SW["NORMAL_REST"] +\
|
||||
min(0xff, len(data)))).render()
|
||||
r = R_APDU(inttostring(SW["NORMAL_REST"] +
|
||||
min(0xff, len(data)))).render()
|
||||
else:
|
||||
r = Iso7816OS.formatResult(self, Iso7816OS.seekable(ins), le, data, sw, False)
|
||||
r = Iso7816OS.formatResult(self, Iso7816OS.seekable(ins), le,
|
||||
data, sw, False)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
class CryptoflexSE(Security_Environment):
|
||||
def __init__(self, MF, SAM):
|
||||
Security_Environment.__init__(self, MF, SAM)
|
||||
@@ -95,11 +101,11 @@ class CryptoflexSE(Security_Environment):
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Util.randpool import RandomPool
|
||||
|
||||
keynumber = p1 #TODO: Check if key exists
|
||||
keynumber = p1 # TODO: Check if key exists
|
||||
|
||||
keylength_dict = {0x40: 256, 0x60: 512, 0x80: 1024}
|
||||
|
||||
if not keylength_dict.has_key(p2):
|
||||
if p2 not in keylength_dict:
|
||||
raise SwError(SW["ERR_INCORRECTP1P2"])
|
||||
else:
|
||||
keylength = keylength_dict[p2]
|
||||
@@ -110,31 +116,31 @@ class CryptoflexSE(Security_Environment):
|
||||
|
||||
e_in = struct.unpack("<i", data)
|
||||
if e_in[0] != 65537:
|
||||
logging.warning("Warning: Exponents different from 65537 are ignored!" +\
|
||||
"The Exponent given is %i" % e_in[0])
|
||||
logging.warning("Warning: Exponents different from 65537 are " +
|
||||
"ignored! The Exponent given is %i" % e_in[0])
|
||||
|
||||
#Encode Public key
|
||||
# Encode Public key
|
||||
n = PublicKey.__getstate__()['n']
|
||||
n_str = inttostring(n)
|
||||
n_str = n_str[::-1]
|
||||
e = PublicKey.__getstate__()['e']
|
||||
e_str = inttostring(e, 4)
|
||||
e_str = e_str[::-1]
|
||||
pad = 187 * '\x30' #We don't have CRT components, so we need to pad
|
||||
pad = 187 * '\x30' # We don't have CRT components, so we need to pad
|
||||
pk_n = TLVutils.bertlv_pack(((0x81, len(n_str), n_str),
|
||||
(0x01, len(pad), pad),
|
||||
(0x82, len(e_str), e_str)))
|
||||
#Private key
|
||||
# Private key
|
||||
d = PublicKey.__getstate__()['d']
|
||||
|
||||
#Write result to FID 10 12 EF-PUB-KEY
|
||||
# Write result to FID 10 12 EF-PUB-KEY
|
||||
df = self.mf.currentDF()
|
||||
ef_pub_key = df.select("fid", 0x1012)
|
||||
ef_pub_key.writebinary([0], [pk_n])
|
||||
data = ef_pub_key.getenc('data')
|
||||
|
||||
#Write private key to FID 00 12 EF-PRI-KEY (not necessary?)
|
||||
#How to encode the private key?
|
||||
# Write private key to FID 00 12 EF-PRI-KEY (not necessary?)
|
||||
# How to encode the private key?
|
||||
ef_priv_key = df.select("fid", 0x0012)
|
||||
ef_priv_key.writebinary([0], [inttostring(d)])
|
||||
data = ef_priv_key.getenc('data')
|
||||
@@ -148,11 +154,11 @@ class CryptoflexSAM(SAM):
|
||||
|
||||
def generate_public_key_pair(self, p1, p2, data):
|
||||
asym_key = self.current_SE.generate_public_key_pair(p1, p2, data)
|
||||
#TODO: Use SE instead (and remove SAM.set_asym_algorithm)
|
||||
# TODO: Use SE instead (and remove SAM.set_asym_algorithm)
|
||||
self.set_asym_algorithm(asym_key, 0x07)
|
||||
return SW["NORMAL"], ""
|
||||
|
||||
def perform_security_operation(self, p1, p2, data):
|
||||
def pezorform_security_operation(self, p1, p2, data):
|
||||
"""
|
||||
In the cryptoflex card, this is the verify key command. A key is send
|
||||
to the card in plain text and compared to a key stored in the card.
|
||||
@@ -163,21 +169,22 @@ class CryptoflexSAM(SAM):
|
||||
"""
|
||||
|
||||
return SW["NORMAL"], ""
|
||||
#FIXME
|
||||
#key = self._get_referenced_key(p1,p2)
|
||||
#if key == data:
|
||||
# return SW["NORMAL"], ""
|
||||
#else:
|
||||
# return SW["WARN_NOINFO63"], ""
|
||||
# FIXME
|
||||
# key = self._get_referenced_key(p1,p2)
|
||||
# if key == data:
|
||||
# return SW["NORMAL"], ""
|
||||
# else:
|
||||
# return SW["WARN_NOINFO63"], ""
|
||||
|
||||
def internal_authenticate(self, p1, p2, data):
|
||||
data = data[::-1] #Reverse Byte order
|
||||
data = data[::-1] # Reverse Byte order
|
||||
sw, data = SAM.internal_authenticate(self, p1, p2, data)
|
||||
if data != "":
|
||||
data = data[::-1]
|
||||
return sw, data
|
||||
|
||||
class CryptoflexMF(MF): # {{{
|
||||
|
||||
class CryptoflexMF(MF): # {{{
|
||||
|
||||
@staticmethod
|
||||
def create(p1, p2, data):
|
||||
@@ -195,15 +202,17 @@ class CryptoflexMF(MF): # {{{
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_TRANSPARENT"]
|
||||
new_file = TransparentStructureEF(**args)
|
||||
elif data[6] == "\x02":
|
||||
if len(data)>16:
|
||||
if len(data) > 16:
|
||||
args["maxrecordsize"] = stringtoint(data[16])
|
||||
elif p2:
|
||||
# if given a number of records
|
||||
args["maxrecordsize"] = (stringtoint(data[2:4])/p2)
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_FIXED_NOFURTHERINFO"]
|
||||
args["maxrecordsize"] = (stringtoint(data[2:4]) / p2)
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_FIXED_"
|
||||
"NOFURTHERINFO"]
|
||||
new_file = RecordStructureEF(**args)
|
||||
elif data[6] == "\x03":
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_VARIABLE_NOFURTHERINFO"]
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_LINEAR_VARIABLE_"
|
||||
"NOFURTHERINFO"]
|
||||
new_file = RecordStructureEF(**args)
|
||||
elif data[6] == "\x04":
|
||||
args["filedescriptor"] = FDB["EFSTRUCTURE_CYCLIC_NOFURTHERINFO"]
|
||||
@@ -216,7 +225,6 @@ class CryptoflexMF(MF): # {{{
|
||||
logging.error("unknown type: 0x%x" % ord(data[6]))
|
||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
|
||||
return [new_file]
|
||||
|
||||
def recordHandlingDecode(self, p1, p2):
|
||||
@@ -225,7 +233,6 @@ class CryptoflexMF(MF): # {{{
|
||||
|
||||
return MF.recordHandlingDecode(self, p1, p2)
|
||||
|
||||
|
||||
def dataUnitsDecodePlain(self, p1, p2, data):
|
||||
ef = self.currentEF()
|
||||
# FIXME: Cyberflex Access TM Software Development Kit Release 3C
|
||||
@@ -243,19 +250,23 @@ class CryptoflexMF(MF): # {{{
|
||||
integers and 'data' as binary string. Returns the status bytes as two
|
||||
byte long integer and the response data as binary string.
|
||||
"""
|
||||
P2_FCI = 0
|
||||
P2_FCP = 1 << 2
|
||||
P2_FMD = 2 << 2
|
||||
P2_FCI = 0
|
||||
P2_FCP = 1 << 2
|
||||
P2_FMD = 2 << 2
|
||||
P2_NONE = 3 << 2
|
||||
file = self._selectFile(p1, p2, data)
|
||||
|
||||
if isinstance(file, EF):
|
||||
size = inttostring(min(0xffff, len(file.getenc('data'))), 2) # File size (body only)
|
||||
extra = chr(0) # RFU
|
||||
if isinstance(file, RecordStructureEF) and file.hasFixedRecordSize() and not file.isCyclic():
|
||||
extra += chr(0) + chr(min(file.records, 0xff)) # Length of records
|
||||
# File size (body only)
|
||||
size = inttostring(min(0xffff, len(file.getenc('data'))), 2)
|
||||
extra = chr(0) # RFU
|
||||
if (isinstance(file, RecordStructureEF) and
|
||||
file.hasFixedRecordSize() and not file.isCyclic()):
|
||||
# Length of records
|
||||
extra += chr(0) + chr(min(file.records, 0xff))
|
||||
elif isinstance(file, DF):
|
||||
size = inttostring(0xffff, 2) # Number of unused EEPROM bytes available in the DF
|
||||
# Number of unused EEPROM bytes available in the DF
|
||||
size = inttostring(0xffff, 2)
|
||||
efcount = 0
|
||||
dfcount = 0
|
||||
chv1 = None
|
||||
@@ -274,26 +285,26 @@ class CryptoflexMF(MF): # {{{
|
||||
if isinstance(f, DF):
|
||||
dfcount += 1
|
||||
if chv1:
|
||||
extra = chr(1) # TODO LSB correct?
|
||||
extra = chr(1) # TODO LSB correct?
|
||||
else:
|
||||
extra = chr(0) # TODO LSB correct?
|
||||
extra = chr(0) # TODO LSB correct?
|
||||
extra += chr(efcount)
|
||||
extra += chr(dfcount)
|
||||
extra += chr(0) # TODO Number of PINs and unblock CHV PINs
|
||||
extra += chr(0) # RFU
|
||||
extra += chr(0) # TODO Number of PINs and unblock CHV PINs
|
||||
extra += chr(0) # RFU
|
||||
if chv1:
|
||||
extra += chr(0) # TODO Number of remaining CHV1 attempts
|
||||
extra += chr(0) # TODO Number of remaining unblock CHV1 attempts
|
||||
extra += chr(0) # TODO remaining CHV1 attempts
|
||||
extra += chr(0) # TODO remaining unblock CHV1 attempts
|
||||
if chv2:
|
||||
extra += chr(0) # TODO CHV2 key status
|
||||
extra += chr(0) # TODO CHV2 unblocking key status
|
||||
extra += chr(0) # TODO CHV2 key status
|
||||
extra += chr(0) # TODO CHV2 unblocking key status
|
||||
|
||||
data = inttostring(0, 2) # RFU
|
||||
data = inttostring(0, 2) # RFU
|
||||
data += size
|
||||
data += inttostring(file.fid, 2)
|
||||
data += inttostring(file.filedescriptor) # File type
|
||||
data += inttostring(0, 4) # ACs TODO
|
||||
data += chr(file.lifecycle & 1) # File status
|
||||
data += inttostring(file.filedescriptor) # File type
|
||||
data += inttostring(0, 4) # ACs TODO
|
||||
data += chr(file.lifecycle & 1) # File status
|
||||
data += chr(len(extra))
|
||||
data += extra
|
||||
|
||||
|
||||
@@ -22,9 +22,11 @@ import virtualsmartcard.CryptoUtils as vsCrypto
|
||||
from virtualsmartcard.SWutils import SwError, SW
|
||||
from virtualsmartcard.utils import stringtoint
|
||||
|
||||
import hashlib, struct
|
||||
import hashlib
|
||||
import struct
|
||||
from os import urandom
|
||||
|
||||
|
||||
class ePass_SE(Security_Environment):
|
||||
"""This class implements the Security Environment of the ICAO Passports. It
|
||||
is required in order to use the send sequence counter for secure messaging.
|
||||
@@ -46,10 +48,11 @@ class ePass_SE(Security_Environment):
|
||||
|
||||
self.ssc += 1
|
||||
checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key,
|
||||
data, self.cct.iv, self.ssc)
|
||||
data, self.cct.iv, self.ssc)
|
||||
|
||||
return checksum
|
||||
|
||||
|
||||
class PassportSAM(SAM):
|
||||
"""
|
||||
SAM for ICAO ePassport. Implements Basic access control and key derivation
|
||||
@@ -58,7 +61,7 @@ class PassportSAM(SAM):
|
||||
def __init__(self, mf):
|
||||
import virtualsmartcard.SmartcardFilesystem as vsFS
|
||||
|
||||
SAM.__init__(self, None, None, mf, default_se = ePass_SE)
|
||||
SAM.__init__(self, None, None, mf, default_se=ePass_SE)
|
||||
|
||||
ef_dg1 = vsFS.walk(mf, "\x00\x04\x01\x01")
|
||||
dg1 = ef_dg1.readbinary(5)
|
||||
@@ -77,7 +80,7 @@ class PassportSAM(SAM):
|
||||
"""
|
||||
|
||||
MRZ_information = self.mrz2[0:10] + self.mrz2[13:20] + self.mrz2[21:28]
|
||||
H = hashlib.sha1(MRZ_information).digest() #pylint: disable=E1101
|
||||
H = hashlib.sha1(MRZ_information).digest() # pylint: disable=E1101
|
||||
self.KSeed = H[:16]
|
||||
self.KEnc = self.derive_key(self.KSeed, 1)
|
||||
self.KMac = self.derive_key(self.KSeed, 2)
|
||||
@@ -91,7 +94,7 @@ class PassportSAM(SAM):
|
||||
Returns: Ka + Kb
|
||||
Note: Does not adjust parity. Nobody uses that anyway ..."""
|
||||
D = seed + struct.pack(">i", c)
|
||||
H = hashlib.sha1(D).digest() #pylint: disable=E1101
|
||||
H = hashlib.sha1(D).digest() # pylint: disable=E1101
|
||||
Ka = H[0:8]
|
||||
Kb = H[8:16]
|
||||
return Ka + Kb
|
||||
@@ -101,29 +104,31 @@ class PassportSAM(SAM):
|
||||
the ICAO MRTD standard"""
|
||||
rnd_icc = self.last_challenge
|
||||
|
||||
#Receive Mutual Authenticate APDU from terminal
|
||||
#Decrypt data and check MAC
|
||||
# Receive Mutual Authenticate APDU from terminal
|
||||
# Decrypt data and check MAC
|
||||
Eifd = resp_data[:-8]
|
||||
padded_Eifd = vsCrypto.append_padding(self.current_SE.cct.blocklength, Eifd)
|
||||
padded_Eifd = vsCrypto.append_padding(self.current_SE.cct.blocklength,
|
||||
Eifd)
|
||||
Mifd = vsCrypto.crypto_checksum("CC", self.KMac, padded_Eifd)
|
||||
#Check the MAC
|
||||
# Check the MAC
|
||||
if not Mifd == resp_data[-8:]:
|
||||
raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"])
|
||||
#Decrypt the data
|
||||
# Decrypt the data
|
||||
plain = vsCrypto.decrypt("DES3-CBC", self.KEnc, resp_data[:-8])
|
||||
if plain[8:16] != rnd_icc:
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
#Extract keying material from IFD, generate ICC keying material
|
||||
# Extract keying material from IFD, generate ICC keying material
|
||||
Kifd = plain[16:]
|
||||
rnd_ifd = plain[:8]
|
||||
Kicc = urandom(16)
|
||||
#Generate Answer
|
||||
# Generate Answer
|
||||
data = plain[8:16] + plain[:8] + Kicc
|
||||
Eicc = vsCrypto.encrypt("DES3-CBC", self.KEnc, data)
|
||||
padded_Eicc = vsCrypto.append_padding(self.current_SE.cct.blocklength, Eicc)
|
||||
padded_Eicc = vsCrypto.append_padding(self.current_SE.cct.blocklength,
|
||||
Eicc)
|
||||
Micc = vsCrypto.crypto_checksum("CC", self.KMac, padded_Eicc)
|
||||
#Derive the final keys and set the current SE
|
||||
KSseed = vsCrypto.operation_on_string(Kicc, Kifd, lambda a, b: a^b)
|
||||
# Derive the final keys and set the current SE
|
||||
KSseed = vsCrypto.operation_on_string(Kicc, Kifd, lambda a, b: a ^ b)
|
||||
self.current_SE.ct.key = self.derive_key(KSseed, 1)
|
||||
self.current_SE.cct.key = self.derive_key(KSseed, 2)
|
||||
self.current_SE.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
|
||||
|
||||
@@ -18,30 +18,42 @@
|
||||
|
||||
from virtualsmartcard.SmartcardSAM import SAM
|
||||
from virtualsmartcard.VirtualSmartcard import Iso7816OS
|
||||
from virtualsmartcard.SEutils import ControlReferenceTemplate, Security_Environment
|
||||
from virtualsmartcard.SEutils import ControlReferenceTemplate, \
|
||||
Security_Environment
|
||||
from virtualsmartcard.SWutils import SwError, SW
|
||||
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, SM_Class, ALGO_MAPPING, MAX_EXTENDED_LE, MAX_SHORT_LE
|
||||
from virtualsmartcard.TLVutils import unpack, bertlv_pack, decodeDiscretionaryDataObjects, tlv_find_tag
|
||||
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, SM_Class, \
|
||||
ALGO_MAPPING, MAX_EXTENDED_LE, MAX_SHORT_LE
|
||||
from virtualsmartcard.TLVutils import unpack, bertlv_pack, \
|
||||
decodeDiscretionaryDataObjects, tlv_find_tag
|
||||
from virtualsmartcard.SmartcardFilesystem import make_property
|
||||
from virtualsmartcard.utils import inttostring, R_APDU
|
||||
import virtualsmartcard.CryptoUtils as vsCrypto
|
||||
from chat import CHAT, CVC, PACE_SEC, EAC_CTX
|
||||
import binascii
|
||||
import eac
|
||||
import logging, binascii
|
||||
import logging
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
|
||||
class NPAOS(Iso7816OS):
|
||||
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_EXTENDED_LE, ef_cardsecurity=None, ef_cardaccess=None, ca_key=None, cvca=None, disable_checks=False, esign_key=None, esign_ca_cert=None, esign_cert=None):
|
||||
def __init__(self, mf, sam, ins2handler=None, maxle=MAX_EXTENDED_LE,
|
||||
ef_cardsecurity=None, ef_cardaccess=None, ca_key=None,
|
||||
cvca=None, disable_checks=False, esign_key=None,
|
||||
esign_ca_cert=None, esign_cert=None):
|
||||
Iso7816OS.__init__(self, mf, sam, ins2handler, maxle)
|
||||
self.ins2handler[0x86] = self.SAM.general_authenticate
|
||||
self.ins2handler[0x2c] = self.SAM.reset_retry_counter
|
||||
|
||||
# different ATR (Answer To Reset) values depending on used Chip version
|
||||
# It's just a playground, because in past one of all those eID clients did not recognize the card correctly with newest ATR values
|
||||
self.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90\x00\x75'
|
||||
#self.atr = '\x3B\x8A\x80\x01\x80\x31\xB8\x73\x84\x01\xE0\x82\x90\x00\x06'
|
||||
#self.atr = '\x3B\x88\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x09'
|
||||
#self.atr = '\x3B\x87\x80\x01\x80\x31\xB8\x73\x84\x01\xE0\x19'
|
||||
# It's just a playground, because in past one of all those eID clients
|
||||
# did not recognize the card correctly with newest ATR values
|
||||
self.atr = '\x3B\x8A\x80\x01\x80\x31\xF8\x73\xF7\x41\xE0\x82\x90' + \
|
||||
'\x00\x75'
|
||||
# self.atr = '\x3B\x8A\x80\x01\x80\x31\xB8\x73\x84\x01\xE0\x82\x90' + \
|
||||
# '\x00\x06'
|
||||
# self.atr = '\x3B\x88\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x09'
|
||||
# self.atr = '\x3B\x87\x80\x01\x80\x31\xB8\x73\x84\x01\xE0\x19'
|
||||
|
||||
self.SAM.current_SE.disable_checks = disable_checks
|
||||
if ef_cardsecurity:
|
||||
@@ -54,7 +66,8 @@ class NPAOS(Iso7816OS):
|
||||
self.SAM.current_SE.cvca = cvca
|
||||
if ca_key:
|
||||
self.SAM.current_SE.ca_key = ca_key
|
||||
esign = self.mf.select('dfname', '\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E')
|
||||
esign = self.mf.select('dfname',
|
||||
'\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E')
|
||||
if esign_ca_cert:
|
||||
ef = esign.select('fid', 0xC000)
|
||||
ef.data = esign_ca_cert
|
||||
@@ -62,7 +75,6 @@ class NPAOS(Iso7816OS):
|
||||
ef = esign.select('fid', 0xC001)
|
||||
ef.data = esign_cert
|
||||
|
||||
|
||||
def formatResult(self, seekable, le, data, sw, sm):
|
||||
if seekable:
|
||||
# when le = 0 then we want to have 0x9000. here we only have the
|
||||
@@ -72,7 +84,7 @@ class NPAOS(Iso7816OS):
|
||||
if le > len(data) and le != MAX_EXTENDED_LE and le != MAX_SHORT_LE:
|
||||
sw = SW["WARN_EOFBEFORENEREAD"]
|
||||
|
||||
if le != None:
|
||||
if le is not None:
|
||||
result = data[:le]
|
||||
else:
|
||||
result = data[:0]
|
||||
@@ -81,7 +93,6 @@ class NPAOS(Iso7816OS):
|
||||
sw, result = self.SAM.protect_result(sw, result)
|
||||
except SwError as e:
|
||||
logging.info(e.message)
|
||||
import traceback, sys
|
||||
traceback.print_exception(*sys.exc_info())
|
||||
sw = e.sw
|
||||
result = ""
|
||||
@@ -105,22 +116,22 @@ class nPA_AT_CRT(ControlReferenceTemplate):
|
||||
CommunityID = None
|
||||
|
||||
def keyref_is_mrz(self):
|
||||
if self.keyref_secret_key == '%c'% self.PACE_MRZ:
|
||||
if self.keyref_secret_key == '%c' % self.PACE_MRZ:
|
||||
return True
|
||||
return False
|
||||
|
||||
def keyref_is_can(self):
|
||||
if self.keyref_secret_key == '%c'% self.PACE_CAN:
|
||||
if self.keyref_secret_key == '%c' % self.PACE_CAN:
|
||||
return True
|
||||
return False
|
||||
|
||||
def keyref_is_pin(self):
|
||||
if self.keyref_secret_key == '%c'% self.PACE_PIN:
|
||||
if self.keyref_secret_key == '%c' % self.PACE_PIN:
|
||||
return True
|
||||
return False
|
||||
|
||||
def keyref_is_puk(self):
|
||||
if self.keyref_secret_key == '%c'% self.PACE_PUK:
|
||||
if self.keyref_secret_key == '%c' % self.PACE_PUK:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -145,13 +156,16 @@ class nPA_AT_CRT(ControlReferenceTemplate):
|
||||
mapped_algo = ALGO_MAPPING[oidvalue]
|
||||
if mapped_algo == "DateOfBirth":
|
||||
self.DateOfBirth = int(reference)
|
||||
logging.info("Found reference DateOfBirth: " + str(self.DateOfBirth))
|
||||
logging.info("Found reference DateOfBirth: " +
|
||||
str(self.DateOfBirth))
|
||||
elif mapped_algo == "DateOfExpiry":
|
||||
self.DateOfExpiry = int(reference)
|
||||
logging.info("Found reference DateOfExpiry: " + str(self.DateOfExpiry))
|
||||
logging.info("Found reference DateOfExpiry: " +
|
||||
str(self.DateOfExpiry))
|
||||
elif mapped_algo == "CommunityID":
|
||||
self.CommunityID = binascii.hexlify(reference)
|
||||
logging.info("Found reference CommunityID: " + str(self.CommunityID))
|
||||
logging.info("Found reference CommunityID: " +
|
||||
str(self.CommunityID))
|
||||
except:
|
||||
pass
|
||||
elif tag == 0x80 or tag == 0x84 or tag == 0x83 or tag == 0x91:
|
||||
@@ -170,7 +184,7 @@ class nPA_SE(Security_Environment):
|
||||
def __init__(self, MF, SAM):
|
||||
Security_Environment.__init__(self, MF, SAM)
|
||||
self.at = nPA_AT_CRT()
|
||||
#This breaks support for 3DES
|
||||
# This breaks support for 3DES
|
||||
self.cct.blocklength = 16
|
||||
self.cct.algorithm = "CC"
|
||||
self.eac_step = 0
|
||||
@@ -206,7 +220,7 @@ class nPA_SE(Security_Environment):
|
||||
if (p1, p2) != (0x00, 0x00):
|
||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
if self.eac_step == 0 and self.at.algorithm == "PACE":
|
||||
if self.eac_step == 0 and self.at.algorithm == "PACE":
|
||||
return self.__eac_pace_step1(data)
|
||||
elif self.eac_step == 1 and self.at.algorithm == "PACE":
|
||||
return self.__eac_pace_step2(data)
|
||||
@@ -217,8 +231,12 @@ class nPA_SE(Security_Environment):
|
||||
elif self.eac_step == 5 and self.at.algorithm == "CA":
|
||||
return self.__eac_ca(data)
|
||||
elif self.eac_step == 6:
|
||||
# TODO implement RI "\x7c\x22\x81\x20\" is some prefix and the rest is our RI
|
||||
return SW["NORMAL"], "\x7c\x22\x81\x20\x48\x1e\x58\xd1\x7c\x12\x9a\x0a\xb4\x63\x7d\x43\xc7\xf7\xeb\x2b\x06\x10\x6f\x26\x90\xe3\x00\xc4\xe7\x03\x54\xa0\x41\xf0\xd3\x90"
|
||||
# TODO implement RI
|
||||
# "\x7c\x22\x81\x20\" is some prefix and the rest is our RI
|
||||
return SW["NORMAL"], "\x7c\x22\x81\x20\x48\x1e\x58\xd1\x7c\x12" + \
|
||||
"\x9a\x0a\xb4\x63\x7d\x43\xc7\xf7\xeb\x2b" + \
|
||||
"\x06\x10\x6f\x26\x90\xe3\x00\xc4\xe7\x03" + \
|
||||
"\x54\xa0\x41\xf0\xd3\x90"
|
||||
|
||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
@@ -241,7 +259,7 @@ class nPA_SE(Security_Environment):
|
||||
|
||||
def __eac_pace_step1(self, data):
|
||||
tlv_data = nPA_SE.__unpack_general_authenticate(data)
|
||||
if tlv_data != []:
|
||||
if tlv_data != []:
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
|
||||
if self.at.keyref_is_mrz():
|
||||
@@ -277,27 +295,33 @@ class nPA_SE(Security_Environment):
|
||||
|
||||
ef_card_security = self.mf.select('fid', 0x011d)
|
||||
ef_card_security_data = ef_card_security.data
|
||||
eac.EAC_CTX_init_ef_cardsecurity(ef_card_security_data, self.eac_ctx)
|
||||
eac.EAC_CTX_init_ef_cardsecurity(ef_card_security_data,
|
||||
self.eac_ctx)
|
||||
|
||||
if self.ca_key:
|
||||
ca_pubkey = eac.CA_get_pubkey(self.eac_ctx, ef_card_security_data)
|
||||
ca_pubkey = eac.CA_get_pubkey(self.eac_ctx,
|
||||
ef_card_security_data)
|
||||
if 1 != eac.CA_set_key(self.eac_ctx, self.ca_key, ca_pubkey):
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
else:
|
||||
# we don't have a good CA key, so we simply generate an ephemeral one
|
||||
# we don't have a good CA key, so we simply generate an
|
||||
# ephemeral one
|
||||
comp_pubkey = eac.TA_STEP3_generate_ephemeral_key(self.eac_ctx)
|
||||
pubkey = eac.CA_STEP2_get_eph_pubkey(self.eac_ctx)
|
||||
if not comp_pubkey or not pubkey:
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
|
||||
# save public key in EF.CardSecurity (and invalidate the signature)
|
||||
# save public key in EF.CardSecurity (and invalidate the
|
||||
# signature)
|
||||
# FIXME this only works for the default EF.CardSecurity.
|
||||
# Better use an ASN.1 parser to do this manipulation
|
||||
ef_card_security = self.mf.select('fid', 0x011d)
|
||||
ef_card_security_data = ef_card_security.data
|
||||
ef_card_security_data = ef_card_security_data[:61+4+239+2+1] + pubkey + ef_card_security_data[61+4+239+2+1+len(pubkey):]
|
||||
ef_card_security_data = \
|
||||
ef_card_security_data[:61+4+239+2+1] + pubkey + \
|
||||
ef_card_security_data[61+4+239+2+1+len(pubkey):]
|
||||
ef_card_security.data = ef_card_security_data
|
||||
|
||||
nonce = eac.PACE_STEP1_enc_nonce(self.eac_ctx, self.sec)
|
||||
@@ -327,12 +351,14 @@ class nPA_SE(Security_Environment):
|
||||
|
||||
self.eac_step += 1
|
||||
|
||||
return 0x9000, nPA_SE.__pack_general_authenticate([[0x82, len(pubkey), pubkey]])
|
||||
return 0x9000, \
|
||||
nPA_SE.__pack_general_authenticate([[0x82, len(pubkey), pubkey]])
|
||||
|
||||
def __eac_pace_step3(self, data):
|
||||
tlv_data = nPA_SE.__unpack_general_authenticate(data)
|
||||
|
||||
self.my_pace_eph_pubkey = eac.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx)
|
||||
self.my_pace_eph_pubkey = \
|
||||
eac.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx)
|
||||
if not self.my_pace_eph_pubkey:
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
@@ -341,18 +367,23 @@ class nPA_SE(Security_Environment):
|
||||
for tag, length, value in tlv_data:
|
||||
if tag == 0x83:
|
||||
self.pace_opp_pub_key = value
|
||||
eac.PACE_STEP3B_compute_shared_secret(self.eac_ctx, self.pace_opp_pub_key)
|
||||
eac.PACE_STEP3B_compute_shared_secret(self.eac_ctx,
|
||||
self.pace_opp_pub_key)
|
||||
else:
|
||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
self.eac_step += 1
|
||||
|
||||
return 0x9000, nPA_SE.__pack_general_authenticate([[0x84, len(eph_pubkey), eph_pubkey]])
|
||||
return 0x9000, \
|
||||
nPA_SE.__pack_general_authenticate([[0x84, len(eph_pubkey),
|
||||
eph_pubkey]])
|
||||
|
||||
def __eac_pace_step4(self, data):
|
||||
tlv_data = nPA_SE.__unpack_general_authenticate(data)
|
||||
eac.PACE_STEP3C_derive_keys(self.eac_ctx)
|
||||
my_token = eac.PACE_STEP3D_compute_authentication_token(self.eac_ctx, self.pace_opp_pub_key)
|
||||
my_token = \
|
||||
eac.PACE_STEP3D_compute_authentication_token(self.eac_ctx,
|
||||
self.pace_opp_pub_key)
|
||||
token = ""
|
||||
for tag, length, value in tlv_data:
|
||||
if tag == 0x85:
|
||||
@@ -360,7 +391,8 @@ class nPA_SE(Security_Environment):
|
||||
else:
|
||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
||||
|
||||
if not my_token or 1 != eac.PACE_STEP3D_verify_authentication_token(self.eac_ctx, token):
|
||||
ver = eac.PACE_STEP3D_verify_authentication_token(self.eac_ctx, token)
|
||||
if not my_token or ver != 1:
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
|
||||
@@ -394,7 +426,6 @@ class nPA_SE(Security_Environment):
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["WARN_NOINFO63"])
|
||||
|
||||
|
||||
return 0x9000, nPA_SE.__pack_general_authenticate(result)
|
||||
|
||||
def __eac_ca(self, data):
|
||||
@@ -423,8 +454,9 @@ class nPA_SE(Security_Environment):
|
||||
# TODO activate SM
|
||||
self.new_encryption_ctx = eac.EAC_ID_CA
|
||||
|
||||
return 0x9000, nPA_SE.__pack_general_authenticate([[0x81,
|
||||
len(nonce), nonce], [0x82, len(token), token]])
|
||||
return 0x9000, \
|
||||
nPA_SE.__pack_general_authenticate([[0x81, len(nonce), nonce],
|
||||
[0x82, len(token), token]])
|
||||
|
||||
def verify_certificate(self, p1, p2, data):
|
||||
if (p1, p2) != (0x00, 0xbe):
|
||||
@@ -444,8 +476,9 @@ class nPA_SE(Security_Environment):
|
||||
Authenticate the terminal to the card. Check whether Terminal correctly
|
||||
encrypted the given challenge or not
|
||||
"""
|
||||
if self.dst.keyref_public_key: # TODO check if this is the correct CAR
|
||||
id_picc = eac.EAC_Comp(self.eac_ctx, eac.EAC_ID_PACE, self.my_pace_eph_pubkey)
|
||||
if self.dst.keyref_public_key: # TODO check if this is the correct CAR
|
||||
id_picc = eac.EAC_Comp(self.eac_ctx, eac.EAC_ID_PACE,
|
||||
self.my_pace_eph_pubkey)
|
||||
|
||||
# FIXME auxiliary_data might be from an older run of PACE
|
||||
if hasattr(self.at, "auxiliary_data"):
|
||||
@@ -454,7 +487,7 @@ class nPA_SE(Security_Environment):
|
||||
auxiliary_data = None
|
||||
|
||||
if 1 != eac.TA_STEP6_verify(self.eac_ctx, self.at.iv, id_picc,
|
||||
auxiliary_data, data):
|
||||
auxiliary_data, data):
|
||||
eac.print_ossl_err()
|
||||
print "Could not verify Terminal's signature"
|
||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||
@@ -517,7 +550,7 @@ class nPA_SE(Security_Environment):
|
||||
tlv_sw = bertlv_pack([(tag, length, sw_str)])
|
||||
return_data += tlv_sw
|
||||
|
||||
if self.cct.algorithm == None:
|
||||
if self.cct.algorithm is None:
|
||||
raise SwError(SW["CONDITIONSNOTSATISFIED"])
|
||||
elif self.cct.algorithm == "CC":
|
||||
tag = SM_Class["CHECKSUM"]
|
||||
@@ -535,13 +568,18 @@ class nPA_SE(Security_Environment):
|
||||
return sw, return_data
|
||||
|
||||
def compute_digital_signature(self, p1, p2, data):
|
||||
# TODO Signing with brainpoolP256r1 or any other key needs some more effort ;-)
|
||||
return '\x0D\xB2\x9B\xB9\x5E\x97\x7D\x42\x73\xCF\xA5\x45\xB7\xED\x5C\x39\x3F\xCE\xCD\x4A\xDE\xDC\x2B\x85\x23\x9F\x66\x52\x10\xC2\x67\xDC\xA6\x35\x94\x2D\x24\xED\xEB\xC8\x34\x6C\x4B\xD1\xA1\x15\xB4\x48\x3A\xA4\x4A\xCE\xFF\xED\x97\x0E\x07\xF3\x72\xF0\xFB\xA3\x62\x8C'
|
||||
# TODO Signing with brainpoolP256r1 or any other key needs some more
|
||||
# effort ;-)
|
||||
return '\x0D\xB2\x9B\xB9\x5E\x97\x7D\x42\x73\xCF\xA5\x45\xB7\xED' + \
|
||||
'\x5C\x39\x3F\xCE\xCD\x4A\xDE\xDC\x2B\x85\x23\x9F\x66\x52' + \
|
||||
'\x10\xC2\x67\xDC\xA6\x35\x94\x2D\x24\xED\xEB\xC8\x34\x6C' + \
|
||||
'\x4B\xD1\xA1\x15\xB4\x48\x3A\xA4\x4A\xCE\xFF\xED\x97\x0E' + \
|
||||
'\x07\xF3\x72\xF0\xFB\xA3\x62\x8C'
|
||||
|
||||
|
||||
class nPA_SAM(SAM):
|
||||
|
||||
def __init__(self, eid_pin, can, mrz, puk, qes_pin, mf, default_se = nPA_SE):
|
||||
def __init__(self, eid_pin, can, mrz, puk, qes_pin, mf, default_se=nPA_SE):
|
||||
SAM.__init__(self, qes_pin, None, mf)
|
||||
self.active = True
|
||||
self.current_SE = default_se(self.mf, self)
|
||||
@@ -559,14 +597,15 @@ class nPA_SAM(SAM):
|
||||
if self.current_SE.eac_step < 4:
|
||||
raise SwError(SW["ERR_SECSTATUS"])
|
||||
|
||||
# TODO check CAN and PIN for the correct character set
|
||||
# TODO: check CAN and PIN for the correct character set
|
||||
if p1 == 0x02:
|
||||
# change secret
|
||||
if p2 == self.current_SE.at.PACE_CAN:
|
||||
self.can = data
|
||||
print "Changed CAN to %r" % self.can
|
||||
elif p2 == self.current_SE.at.PACE_PIN:
|
||||
# TODO allow terminals to change the PIN with permission "CAN allowed"
|
||||
# TODO: allow terminals to change the PIN with permission
|
||||
# "CAN allowed"
|
||||
if not self.current_SE.at.keyref_is_pin():
|
||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||
self.eid_pin = data
|
||||
@@ -583,7 +622,8 @@ class nPA_SAM(SAM):
|
||||
self.active = True
|
||||
print "Resumed PIN"
|
||||
elif self.current_SE.at.keyref_is_pin():
|
||||
# PACE was successful with PIN, nothing to do resume/unblock
|
||||
# PACE was successful with PIN, nothing to do
|
||||
# resume/unblock
|
||||
pass
|
||||
elif self.current_SE.at.keyref_is_puk():
|
||||
# TODO unblock PIN for signature
|
||||
@@ -608,7 +648,8 @@ class nPA_SAM(SAM):
|
||||
if (p1 != 0x00 or p2 != 0x00):
|
||||
raise SwError(SW["ERR_INCORRECTP1P2"])
|
||||
|
||||
self.last_challenge = eac.TA_STEP4_get_nonce(self.current_SE.eac_ctx)
|
||||
self.last_challenge = \
|
||||
eac.TA_STEP4_get_nonce(self.current_SE.eac_ctx)
|
||||
if not self.last_challenge:
|
||||
eac.print_ossl_err()
|
||||
raise SwError(SW["ERR_NOINFO69"])
|
||||
@@ -624,11 +665,14 @@ class nPA_SAM(SAM):
|
||||
[(tag, _, value)] = structure = unpack(data)
|
||||
if tag == 6:
|
||||
mapped_algo = ALGO_MAPPING[value]
|
||||
eid = self.mf.select('dfname', '\xe8\x07\x04\x00\x7f\x00\x07\x03\x02')
|
||||
eid = self.mf.select('dfname', '\xe8\x07\x04\x00\x7f\x00'
|
||||
'\x07\x03\x02')
|
||||
if mapped_algo == "DateOfExpiry":
|
||||
[(_, _, [(_, _, mine)])] = unpack(eid.select('fid', 0x0103).data)
|
||||
logging.info("DateOfExpiry: " + str(mine)
|
||||
+ "; reference: " + str(self.current_SE.at.DateOfExpiry))
|
||||
[(_, _, [(_, _, mine)])] = \
|
||||
unpack(eid.select('fid', 0x0103).data)
|
||||
logging.info("DateOfExpiry: " + str(mine) +
|
||||
"; reference: " +
|
||||
str(self.current_SE.at.DateOfExpiry))
|
||||
if self.current_SE.at.DateOfExpiry < mine:
|
||||
print("Date of expiry verified")
|
||||
return SW["NORMAL"], ""
|
||||
@@ -636,16 +680,19 @@ class nPA_SAM(SAM):
|
||||
print("Date of expiry not verified (expired)")
|
||||
return SW["WARN_NOINFO63"], ""
|
||||
elif mapped_algo == "DateOfBirth":
|
||||
[(_, _, [(_, _, mine)])] = unpack(eid.select('fid', 0x0108).data)
|
||||
[(_, _, [(_, _, mine)])] = \
|
||||
unpack(eid.select('fid', 0x0108).data)
|
||||
# case1: YYYYMMDD -> good
|
||||
# case2: YYYYMM -> mapped to last day of given month, i.e. YYYYMM31 ;-)
|
||||
# case2: YYYYMM -> mapped to last day of given month,
|
||||
# i.e. YYYYMM31 ;-)
|
||||
# case3: YYYY -> mapped to YYYY-12-31
|
||||
if len(str(mine)) == 6:
|
||||
mine = int(str(mine) + "31")
|
||||
elif len(str(mine)) == 4:
|
||||
mine = int(str(mine) + "1231")
|
||||
logging.info("DateOfBirth: " + str(mine)
|
||||
+ "; reference: " + str(self.current_SE.at.DateOfExpiry))
|
||||
logging.info("DateOfBirth: " + str(mine) +
|
||||
"; reference: " +
|
||||
str(self.current_SE.at.DateOfExpiry))
|
||||
if self.current_SE.at.DateOfBirth < mine:
|
||||
print("Date of birth verified (old enough)")
|
||||
return SW["NORMAL"], ""
|
||||
@@ -653,15 +700,18 @@ class nPA_SAM(SAM):
|
||||
print("Date of birth not verified (too young)")
|
||||
return SW["WARN_NOINFO63"], ""
|
||||
elif mapped_algo == "CommunityID":
|
||||
[(_, _, [(_, _, mine)])] = unpack(eid.select('fid', 0x0112).data)
|
||||
[(_, _, [(_, _, mine)])] = \
|
||||
unpack(eid.select('fid', 0x0112).data)
|
||||
mine = binascii.hexlify(mine)
|
||||
logging.info("CommunityID: " + str(mine)
|
||||
+ "; reference: " + str(self.current_SE.at.CommunityID))
|
||||
logging.info("CommunityID: " + str(mine) +
|
||||
"; reference: " +
|
||||
str(self.current_SE.at.CommunityID))
|
||||
if mine.startswith(self.current_SE.at.CommunityID):
|
||||
print("Community ID verified (living there)")
|
||||
return SW["NORMAL"], ""
|
||||
else:
|
||||
print("Community ID not verified (not living there)")
|
||||
print("Community ID not verified (not living"
|
||||
"there)")
|
||||
return SW["WARN_NOINFO63"], ""
|
||||
else:
|
||||
return SwError(SW["ERR_DATANOTFOUND"])
|
||||
@@ -677,10 +727,12 @@ class nPA_SAM(SAM):
|
||||
protocol = "PACE"
|
||||
else:
|
||||
protocol = "CA"
|
||||
logging.info("switching to new encryption context established in %s:" % protocol)
|
||||
logging.info("switching to new encryption context established in "
|
||||
"%s:" % protocol)
|
||||
logging.info(eac.EAC_CTX_print_private(self.current_SE.eac_ctx, 4))
|
||||
|
||||
eac.EAC_CTX_set_encryption_ctx(self.current_SE.eac_ctx, self.current_SE.new_encryption_ctx)
|
||||
eac.EAC_CTX_set_encryption_ctx(self.current_SE.eac_ctx,
|
||||
self.current_SE.new_encryption_ctx)
|
||||
|
||||
delattr(self.current_SE, "new_encryption_ctx")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user