- Removed MF reference from Security Environment (only needed for cryptoflex card)

- General code cleanup


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@503 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2011-08-23 12:11:52 +00:00
parent 841069364c
commit 596b43a038
4 changed files with 36 additions and 39 deletions

View File

@@ -16,13 +16,13 @@
# You should have received a copy of the GNU General Public License along with # You should have received a copy of the GNU General Public License along with
# virtualsmartcard. If not, see <http://www.gnu.org/licenses/>. # virtualsmartcard. If not, see <http://www.gnu.org/licenses/>.
# #
import TLVutils from virtualsmartcard.TLVutils import pack, unpack, bertlv_pack
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, ALGO_MAPPING, SM_Class from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, ALGO_MAPPING, \
SM_Class
from virtualsmartcard.utils import inttostring, stringtoint, C_APDU from virtualsmartcard.utils import inttostring, stringtoint, C_APDU
from virtualsmartcard.SWutils import SwError, SW from virtualsmartcard.SWutils import SwError, SW
import virtualsmartcard.CryptoUtils as vsCrypto import virtualsmartcard.CryptoUtils as vsCrypto
import struct, logging
from time import time from time import time
from random import seed, randint from random import seed, randint
@@ -65,7 +65,7 @@ class ControlReferenceTemplate:
@param config : a TLV string containing the configuration for the CRT. @param config : a TLV string containing the configuration for the CRT.
""" """
structure = TLVutils.unpack(config) structure = unpack(config)
for tlv in structure: for tlv in structure:
tag, length, value = tlv tag, length, value = tlv
if tag == 0x80: if tag == 0x80:
@@ -135,12 +135,13 @@ class ControlReferenceTemplate:
replace it. Otherwise append tag, length and value to the config string. replace it. Otherwise append tag, length and value to the config string.
""" """
position = 0 position = 0
while self.__config_string[position:position+1] != tag and position < len(self.__config_string): while position < len(self.__config_string) and \
length = stringtoint(self.__config_string[position+1:position+2]) self.__config_string[position] != tag:
length = stringtoint(self.__config_string[position+1])
position += length + 3 position += length + 3
if position < len(self.__config_string): #Replace Tag if position < len(self.__config_string): #Replace Tag
length = stringtoint(self.__config_string[position+1:position+2]) length = stringtoint(self.__config_string[position+1])
self.__config_string = self.__config_string[:position] +\ self.__config_string = self.__config_string[:position] +\
chr(tag) + inttostring(len(data)) + data +\ chr(tag) + inttostring(len(data)) + data +\
self.__config_string[position+2+length:] self.__config_string[position+2+length:]
@@ -160,7 +161,6 @@ class ControlReferenceTemplate:
class Security_Environment(object): class Security_Environment(object):
def __init__(self, MF, SAM): def __init__(self, MF, SAM):
self.mf = MF
self.sam = SAM self.sam = SAM
self.SEID = None self.SEID = None
@@ -177,10 +177,7 @@ class Security_Environment(object):
self.capdu_sm = False self.capdu_sm = False
self.rapdu_sm = False self.rapdu_sm = False
self.internal_auth = False self.internal_auth = False
self.externel_auth = False self.external_auth = False
def set_MF(self, mf):
self.mf = mf
def manage_security_environment(self, p1, p2, data): def manage_security_environment(self, p1, p2, data):
""" """
@@ -212,10 +209,10 @@ class Security_Environment(object):
#Secure messaging in response data field #Secure messaging in response data field
if se & 0x02: if se & 0x02:
self.rapdu_sm = True self.rapdu_sm = True
#Computation, decipherment, internal authentication and key agreement #Computation, decryption, internal authentication and key agreement
if se & 0x04: if se & 0x04:
self.internal_auth = True self.internal_auth = True
#Verification, encipherment, external authentication and key agreement #Verification, encryption, external authentication and key agreement
if se & 0x08: if se & 0x08:
self.external_auth = True self.external_auth = True
return self.__set_SE(p2, data) return self.__set_SE(p2, data)
@@ -251,17 +248,17 @@ class Security_Environment(object):
elif p2 == 0xB8: elif p2 == 0xB8:
return self.ct.parse_SE_config(data) return self.ct.parse_SE_config(data)
def parse_SM_CAPDU(self, CAPDU, header_authentication): def parse_SM_CAPDU(self, CAPDU, authenticate_header):
""" """
This methods parses a data field including Secure Messaging objects. This methods parses a data field including Secure Messaging objects.
SM_header indicates whether or not the header of the message shall be SM_header indicates whether or not the header of the message shall be
authenticated. It returns an unprotected command APDU authenticated. It returns an unprotected command APDU
@param CAPDU: The protected CAPDU to be parsed @param CAPDU: The protected CAPDU to be parsed
@param header_authentication: Wether or not the header should be @param authenticate_header: Wether or not the header should be
included in authentication mechanisms included in authentication mechanisms
@return: Unprotected command APDU @return: Unprotected command APDU
""" """
structure = TLVutils.unpack(CAPDU.data) structure = unpack(CAPDU.data)
return_data = ["",] return_data = ["",]
expected = self.sm_objects expected = self.sm_objects
@@ -271,7 +268,7 @@ class Security_Environment(object):
p2 = None p2 = None
le = None le = None
if header_authentication: if authenticate_header:
to_authenticate = inttostring(CAPDU.cla) + inttostring(CAPDU.ins)+\ to_authenticate = inttostring(CAPDU.cla) + inttostring(CAPDU.ins)+\
inttostring(CAPDU.p1) + inttostring(CAPDU.p2) inttostring(CAPDU.p1) + inttostring(CAPDU.p2)
to_authenticate = vsCrypto.append_padding("DES-CBC", to_authenticate) to_authenticate = vsCrypto.append_padding("DES-CBC", to_authenticate)
@@ -292,7 +289,7 @@ class Security_Environment(object):
#FIXME: Need to pack value into a dummy CAPDU #FIXME: Need to pack value into a dummy CAPDU
elif tag in (SM_Class["PLAIN_VALUE_TLV_INCULDING_SM"], elif tag in (SM_Class["PLAIN_VALUE_TLV_INCULDING_SM"],
SM_Class["PLAIN_VALUE_TLV_INCULDING_SM_ODD"]): SM_Class["PLAIN_VALUE_TLV_INCULDING_SM_ODD"]):
return_data.append(self.parse_SM_CAPDU(value, header_authentication)) return_data.append(self.parse_SM_CAPDU(value, authenticate_header))
#Encapsulated plaintext BER-TLV objects #Encapsulated plaintext BER-TLV objects
elif tag in (SM_Class["PLAIN_VALUE_TLV_NO_SM"], elif tag in (SM_Class["PLAIN_VALUE_TLV_NO_SM"],
SM_Class["PLAIN_VALUE_TLV_NO_SM_ODD"]): SM_Class["PLAIN_VALUE_TLV_NO_SM_ODD"]):
@@ -311,14 +308,14 @@ class Security_Environment(object):
#SM data objects for confidentiality #SM data objects for confidentiality
if tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM"], if tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM"],
SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM_ODD"]): SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM_ODD"]):
#The Cryptogram includes SM objects. #The cryptogram includes SM objects.
#We decrypt them and parse the objects. #We decrypt them and parse the objects.
plain = self.decipher(tag, 0x80, value) plain = self.decipher(tag, 0x80, value)
#TODO: Need Le = length #TODO: Need Le = length
return_data.append(self.parse_SM_CAPDU(plain, header_authentication)) return_data.append(self.parse_SM_CAPDU(plain, authenticate_header))
elif tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM"], elif tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM"],
SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM_ODD"]): SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM_ODD"]):
#The Cryptogram includes BER-TLV enconded plaintext. #The cryptogram includes BER-TLV encoded plaintext.
#We decrypt them and return the objects. #We decrypt them and return the objects.
plain = self.decipher(tag, 0x80, value) plain = self.decipher(tag, 0x80, value)
return_data.append(plain) return_data.append(plain)
@@ -412,13 +409,13 @@ class Security_Environment(object):
# sw = inttostring(sw) # sw = inttostring(sw)
# length = len(sw) # length = len(sw)
# tag = SM_Class["PLAIN_PROCESSING_STATUS"] # tag = SM_Class["PLAIN_PROCESSING_STATUS"]
# tlv_sw = TLVutils.pack([(tag,length,sw)]) # tlv_sw = pack([(tag,length,sw)])
# return_data += tlv_sw # return_data += tlv_sw
if result != "": # Encrypt the data included in the RAPDU if result != "": # Encrypt the data included in the RAPDU
sw, encrypted = self.encipher(0x82, 0x80, result) sw, encrypted = self.encipher(0x82, 0x80, result)
encrypted = "\x01" + encrypted encrypted = "\x01" + encrypted
encrypted_tlv = TLVutils.pack([( encrypted_tlv = pack([(
SM_Class["CRYPTOGRAM_PADDING_INDICATOR_ODD"], SM_Class["CRYPTOGRAM_PADDING_INDICATOR_ODD"],
len(encrypted), len(encrypted),
encrypted)]) encrypted)])
@@ -429,16 +426,16 @@ class Security_Environment(object):
raise SwError(SW["CONDITIONSNOTSATISFIED"]) raise SwError(SW["CONDITIONSNOTSATISFIED"])
elif self.cct.algorithm == "CCT": elif self.cct.algorithm == "CCT":
tag = SM_Class["CHECKSUM"] tag = SM_Class["CHECKSUM"]
to_auth = vsCrypto.append_padding("DES-ECB", return_data) padded = vsCrypto.append_padding("DES-ECB", return_data)
sw, auth = self.compute_cryptographic_checksum(0x8E, 0x80, to_auth) sw, auth = self.compute_cryptographic_checksum(0x8E, 0x80, padded)
length = len(auth) length = len(auth)
return_data += TLVutils.pack([(tag, length, auth)]) return_data += pack([(tag, length, auth)])
elif self.cct.algorithm == "SIGNATURE": elif self.cct.algorithm == "SIGNATURE":
tag = SM_Class["DIGITAL_SIGNATURE"] tag = SM_Class["DIGITAL_SIGNATURE"]
hash = self.hash(0x90, 0x80, return_data) hash = self.hash(0x90, 0x80, return_data)
sw, auth = self.compute_digital_signature(0x9E, 0x9A, hash) sw, auth = self.compute_digital_signature(0x9E, 0x9A, hash)
length = len(auth) length = len(auth)
return_data += TLVutils.pack([(tag, length, auth)]) return_data += pack([(tag, length, auth)])
return SW["NORMAL"], return_data return SW["NORMAL"], return_data
@@ -513,7 +510,7 @@ class Security_Environment(object):
to_sign = data to_sign = data
elif p2 == 0xAC: #Data objects, sign values elif p2 == 0xAC: #Data objects, sign values
to_sign = "" to_sign = ""
structure = TLVutils.unpack(data) structure = unpack(data)
for tag, length, value in structure: for tag, length, value in structure:
to_sign += value to_sign += value
elif p2 == 0xBC: #Data objects to be signed elif p2 == 0xBC: #Data objects to be signed
@@ -555,7 +552,7 @@ class Security_Environment(object):
if algo == None or key == None: if algo == None or key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
structure = TLVutils.unpack(data) structure = unpack(data)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x80: if tag == 0x80:
plain = value plain = value
@@ -583,7 +580,7 @@ class Security_Environment(object):
if key == None: if key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
structure = TLVutils.unpack(data) structure = unpack(data)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x9E: if tag == 0x9E:
signature = value signature = value
@@ -669,8 +666,8 @@ class Security_Environment(object):
n = str(PublicKey.__getstate__()['n']) n = str(PublicKey.__getstate__()['n'])
e = str(PublicKey.__getstate__()['e']) e = str(PublicKey.__getstate__()['e'])
pk = ((0x81, len(n), n), (0x82, len(e), e)) pk = ((0x81, len(n), n), (0x82, len(e), e))
result = TLVutils.bertlv_pack(pk) result = bertlv_pack(pk)
#result = TLVutils.bertlv_pack((0x7F49, len(pk), pk)) #result = bertlv_pack((0x7F49, len(pk), pk))
#Private key #Private key
d = PublicKey.__getstate__()['d'] d = PublicKey.__getstate__()['d']
elif cipher == "DSA": elif cipher == "DSA":

View File

@@ -81,7 +81,7 @@ class SAM(object):
#Security Environments may be saved to/retrieved from this dictionary #Security Environments may be saved to/retrieved from this dictionary
self.saved_SEs = {} self.saved_SEs = {}
self.current_SE = Security_Environment(self.mf, self) self.current_SE = Security_Environment(self)
def set_MF(self, mf): def set_MF(self, mf):
""" """
@@ -89,7 +89,6 @@ class SAM(object):
needs a reference to the filesystem in order to store/retrieve keys. needs a reference to the filesystem in order to store/retrieve keys.
""" """
self.mf = mf self.mf = mf
self.current_SE.set_MF(mf)
def FSencrypt(self, data): def FSencrypt(self, data):
""" """

View File

@@ -30,7 +30,8 @@ import struct, logging
class CryptoflexSE(Security_Environment): class CryptoflexSE(Security_Environment):
def __init__(self, mf): def __init__(self, mf):
Security_Environment.__init__(self, mf) Security_Environment.__init__(self)
self.mf = mf
def generate_public_key_pair(self, p1, p2, data): def generate_public_key_pair(self, p1, p2, data):
""" """

View File

@@ -27,9 +27,9 @@ from os import urandom
class ePass_SE(Security_Environment): class ePass_SE(Security_Environment):
def __init__(self, MF, SE, ssc=None): def __init__(self, SE, ssc=None):
self.ssc = ssc self.ssc = ssc
Security_Environment.__init__(self, MF, SE) Security_Environment.__init__(self, SE)
def compute_cryptographic_checksum(self, p1, p2, data): def compute_cryptographic_checksum(self, p1, p2, data):
""" """
@@ -65,7 +65,7 @@ class PassportSAM(SAM):
self.KSmac = None self.KSmac = None
self.__computeKeys() self.__computeKeys()
SAM.__init__(self, None, None, mf) SAM.__init__(self, None, None, mf)
self.current_SE = ePass_SE(mf, None, None) self.current_SE = ePass_SE(None, None)
self.current_SE.cct.algorithm = "CC" self.current_SE.cct.algorithm = "CC"
self.current_SE.ct.algorithm = "DES3-CBC" self.current_SE.ct.algorithm = "DES3-CBC"