Even though there may be different Keys to protect CAPDUs and RAPDUs there is

only one Security Environment. Therefore, I merged the CAPDU_SE and RAPDU_SE
into current_SE. Works with the ePass Emulation, still need to test it with
the cryptoflex card.


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@446 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2011-07-29 14:15:10 +00:00
parent 47461a40ca
commit d9f16f5a69

View File

@@ -427,10 +427,8 @@ class PassportSAM(SAM):
#SAM.__init__(self, path, key,None)
SAM.__init__(self, None, None, mf)
self.SM_handler = ePass_SM(mf, None, None, None)
self.SM_handler.CAPDU_SE.cct.algorithm = "CC"
self.SM_handler.RAPDU_SE.cct.algorithm = "CC"
self.SM_handler.CAPDU_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.RAPDU_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.current_SE.cct.algorithm = "CC"
self.SM_handler.current_SE.ct.algorithm = "DES3-CBC"
def __computeKeys(self):
"""Computes the keys depending on the machine readable
@@ -487,15 +485,11 @@ class PassportSAM(SAM):
self.KSmac = self.derive_key(KSseed, 2)
#self.ssc = rnd_icc[-4:] + rnd_ifd[-4:]
#Set the current SE
self.SM_handler.CAPDU_SE.ct.key = self.KSenc
self.SM_handler.CAPDU_SE.cct.key = self.KSmac
self.SM_handler.RAPDU_SE.ct.key = self.KSenc
self.SM_handler.RAPDU_SE.cct.key = self.KSmac
self.SM_handler.current_SE.ct.key = self.KSenc
self.SM_handler.current_SE.cct.key = self.KSmac
self.SM_handler.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
self.SM_handler.CAPDU_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.RAPDU_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.CAPDU_SE.cct.algorithm = "CC"
self.SM_handler.RAPDU_SE.cct.algorithm = "CC"
self.SM_handler.current_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.current_SE.cct.algorithm = "CC"
return SW["NORMAL"], Eicc + Micc
def _mac(self, key, data, ssc = None, dopad=True):
@@ -557,6 +551,10 @@ class Security_Environment(object):
self.dst = CRT(TEMPLATE_DST)
self.ct = CRT(TEMPLATE_CT)
self.capdu_sm = False
self.rapdu_sm = False
self.internal_auth = False
self.externel_auth = False
def mse(self,config):
structure = TLVutils.unpack(config)
@@ -578,21 +576,15 @@ class Security_Environment(object):
class Secure_Messaging(object):
def __init__(self,MF,CAPDU_SE=None,RAPDU_SE=None):
def __init__(self,MF,SE=None):
import virtualsmartcard.CryptoUtils
self.mf = MF
if not CAPDU_SE:
self.CAPDU_SE = Security_Environment()
if not SE:
self.current_SE = Security_Environment()
else:
self.CAPDU_SE = CAPDU_SE
if not RAPDU_SE:
self.RAPDU_SE = Security_Environment()
else:
self.RAPDU_SE = RAPDU_SE
self.current_SE = Security_Environment()
self.current_SE = SE
def set_MF(self,mf):
self.mf = mf
@@ -620,13 +612,13 @@ class Secure_Messaging(object):
se = p1 >> 4
if(cmd == 0x01):
if se & 0x01: #Secure messaging in command data field
self.current_SE = self.CAPDU_SE
self.current_SE.capdu_sm = True
if se & 0x02: #Secure messaging in response data field
self.current_SE = self.RAPDU_SE
self.current_SE.rapdu_sm = True
if se & 0x04: #Computation, decipherment, internal authentication and key agreement
pass
self.current_SE.internal_auth = True
if se & 0x08: #Verification, encipherment, external authentication and key agreement
pass
self.current_SE.external_auth = True
self.__set_SE(p2,data)
elif(cmd== 0x02):
self.__store_SE(p2)
@@ -664,7 +656,7 @@ class Secure_Messaging(object):
Stores the current Security environment in the secure access module. The
SEID is used as a reference to identify the SE.
"""
SEstr = dumps(self.CAPDU_SE)
SEstr = dumps(self.current_SE)
try:
self.SAM.addkey(SEID, SEstr) #TODO: Need SAM reference
except ValueError:
@@ -679,9 +671,9 @@ class Secure_Messaging(object):
SEstr = self.SAM.get_key(SEID)
SE = loads(SEstr)
if isinstance(SE, SecurityEnvironment):
self.CAPDU_SE = SE
self.current_SE = SE
else:
raise ValueError
raise SwError(SW["ERR_REFNOTUSABLE"])
def __erase_SE(self,SEID):
"""
@@ -690,23 +682,6 @@ class Secure_Messaging(object):
self.SAM.removeKey(SEID)
def parse_SM_CAPDU(self,CAPDU,header_authentication):
"""
Frontend for the __parse_SM command. We set the right Security Environment and restore the
old one, when the command is finished
"""
current_SE = self.current_SE
self.current_SE = self.CAPDU_SE
try:
capdu = self.__parse_SM(CAPDU,header_authentication)
except SwError, e: #Restore Security Environment
self.current_SE = current_SE
raise e
self.current_SE = current_SE
return capdu
def __parse_SM(self,CAPDU,header_authentication):
"""
This methods parses a data field including Secure Messaging objects.
SM_header indicates wether or not the header of the message shall be authenticated
@@ -790,7 +765,7 @@ class Secure_Messaging(object):
sw, plain = self.decipher(tag,0x80,value[1:])
if sw != 0x9000:
raise ValueError
plain = virtualsmartcard.CryptoUtils.strip_padding(self.CAPDU_SE.ct.algorithm,plain,padding_indicator)
plain = virtualsmartcard.CryptoUtils.strip_padding(self.current_SE.ct.algorithm,plain,padding_indicator)
return_data.append(plain)
#SM data objects for authentication
@@ -838,23 +813,6 @@ class Secure_Messaging(object):
return c
def protect_response(self,sw,result):
"""
Frontend for the __protect command. We set the right Security Environment and restore the
old one, when the command is finished
"""
current_SE = self.current_SE
self.current_SE = self.RAPDU_SE
try:
sw, data = self.__protect(sw,result)
except SwError, e: #Restore Security Environment
self.current_SE = current_SE
raise e
self.current_SE = current_SE
return sw, data
def __protect(self,sw,result):
"""
This method protects a response APDU using secure messanging mechanisms
It returns the protected data and the SW bytes
@@ -878,15 +836,15 @@ class Secure_Messaging(object):
return_data += encrypted_tlv
if sw == SW["NORMAL"]:
if self.CAPDU_SE.cct.algorithm == None:
if self.current_SE.cct.algorithm == None:
raise SwError(SW["CONDITIONSNOTSATISFIED"])
elif self.CAPDU_SE.cct.algorithm == "CCT":
elif self.current_SE.cct.algorithm == "CCT":
tag = SM_Class["CHECKSUM"]
to_auth = virtualsmartcard.CryptoUtils.append_padding("DES-ECB", return_data)
sw, auth = self.compute_cryptographic_checksum(0x8E, 0x80, to_auth)
length = len(auth)
return_data += TLVutils.pack([(tag,length,auth)])
elif self.CAPDU_SE.cct.algorithm == "SIGNATURE":
elif self.current_SE.cct.algorithm == "SIGNATURE":
tag = SM_Class["DIGITAL_SIGNATURE"]
hash = self.hash(0x90, 0x80, return_data)
sw, auth = self.compute_digital_signature(0x9E, 0x9A, hash)
@@ -938,7 +896,7 @@ class Secure_Messaging(object):
"""
if p1 != 0x8E or p2 != 0x80:
raise SwError(SW["ERR_INCORRECTP1P2"])
if self.CAPDU_SE.cct.algorithm == None or self.current_SE.cct.key == None:
if self.current_SE.cct.key == None:
raise SwError(SE["ERR_CONDITIONNOTSATISFIED"])
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algorithm,
@@ -1096,15 +1054,15 @@ class Secure_Messaging(object):
from Crypto.Util.randpool import RandomPool
rnd = RandomPool()
cipher = self.CAPDU_SE.ct.algorithm #FIXME: Current SE?
cipher = self.current_SE.ct.algorithm
c_class = locals().get(cipher, None)
if c_class is None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
if p1 & 0x01 == 0x00: #Generate key
PublicKey = c_class.generate(self.CAPDU_SE.dst.keylength,rnd.get_bytes)
self.CAPDU_SE.dst.key = PublicKey
PublicKey = c_class.generate(self.current_SE.dst.keylength,rnd.get_bytes)
self.current_SE.dst.key = PublicKey
else:
pass #Read key
@@ -1161,7 +1119,7 @@ class CryptoflexSM(Secure_Messaging):
rnd = RandomPool()
PublicKey = RSA.generate(keylength,rnd.get_bytes)
self.CAPDU_SE.dst.key = PublicKey
self.current_SE.dst.key = PublicKey
e_in = struct.unpack("<i",data)
if e_in[0] != 65537:
@@ -1193,9 +1151,9 @@ class CryptoflexSM(Secure_Messaging):
class ePass_SM(Secure_Messaging):
def __init__(self,MF,CAPDU_SE,RAPDU_SE,ssc=None):
def __init__(self,MF,SE,ssc=None):
self.ssc = ssc
Secure_Messaging.__init__(self, MF, CAPDU_SE, RAPDU_SE)
Secure_Messaging.__init__(self, MF, SE)
def compute_cryptographic_checksum(self,p1,p2,data):
"""
@@ -1207,12 +1165,12 @@ class ePass_SM(Secure_Messaging):
if p1 != 0x8E or p2 != 0x80:
raise SwError(SW["ERR_INCORRECTP1P2"])
#checksum = virtualsmartcard.CryptoUtils.calculate_MAC(self.CAPDU_SE.cct.key,data,self.CAPDU_SE.cct.iv)
#checksum = virtualsmartcard.CryptoUtils.calculate_MAC(self.current_SE.cct.key,data,self.current_SE_SE.cct.iv)
self.ssc += 1
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.CAPDU_SE.cct.algorithm,
self.CAPDU_SE.cct.key,
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algorithm,
self.current_SE.cct.key,
data,
self.CAPDU_SE.cct.iv,
self.current_SE.cct.iv,
self.ssc)
return SW["NORMAL"], checksum