Bug hunting and beautifying with pylint

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@449 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2011-07-29 15:33:39 +00:00
parent dc040c7ab9
commit 0aae975fef

View File

@@ -16,13 +16,14 @@
# 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 virtualsmartcard.SmartcardFilesystem, TLVutils
import random, re, struct#, Crypto import random, struct, hashlib
import hashlib
from virtualsmartcard.SWutils import SwError, SW, SW_MESSAGES
from pickle import dumps, loads from pickle import dumps, loads
from virtualsmartcard.utils import inttostring, stringtoint, hexdump, C_APDU, R_APDU
#from Crypto.Cipher import DES3 import SmartcardFilesystem, TLVutils
import virtualsmartcard.CryptoUtils
from virtualsmartcard.SWutils import SwError, SW
from virtualsmartcard.utils import inttostring, stringtoint, hexdump, C_APDU
from virtualsmartcard.ConstantDefinitions import * from virtualsmartcard.ConstantDefinitions import *
from virtualsmartcard.SEutils import ControlReferenceTemplate as CRT from virtualsmartcard.SEutils import ControlReferenceTemplate as CRT
@@ -60,7 +61,7 @@ class CardContainer:
def __init__(self, PIN=None, cardNumber=None, cardSecret=None): def __init__(self, PIN=None, cardNumber=None, cardSecret=None):
from os import urandom from os import urandom
import virtualsmartcard.CryptoUtils from virtualsmartcard.CryptoUtils import get_cipher_keylen, cipher
self.cardNumber = cardNumber self.cardNumber = cardNumber
self.PIN = PIN self.PIN = PIN
@@ -71,7 +72,7 @@ class CardContainer:
self.salt = None self.salt = None
self.asym_key = None self.asym_key = None
keylen = virtualsmartcard.CryptoUtils.get_cipher_keylen(get_referenced_cipher(self.cipher)) keylen = get_cipher_keylen(get_referenced_cipher(self.cipher))
if cardSecret is None: #Generate a random card secret if cardSecret is None: #Generate a random card secret
self.cardSecret = urandom(keylen) self.cardSecret = urandom(keylen)
else: else:
@@ -92,11 +93,11 @@ class CardContainer:
def getCardSecret(self): def getCardSecret(self):
return self.cardSecret return self.cardSecret
def addKey(self,path,key): def addKey(self, path, key):
""" """
Encrypt key and store it in the SAM Encrypt key and store it in the SAM
""" """
crypted_key = virtualsmartcard.CryptoUtils.cipher(True,self.cipher,self.master_password,key) crypted_key = cipher(True, self.cipher, self.master_password, key)
if self.FSkeys.has_key(path): if self.FSkeys.has_key(path):
print "Overwriting key for path %s" % path print "Overwriting key for path %s" % path
self.FSkeys[path] = crypted_key self.FSkeys[path] = crypted_key
@@ -116,7 +117,7 @@ class CardContainer:
@return: key if the key is in the container, otherwise None @return: key if the key is in the container, otherwise None
""" """
if(self.FSkeys.has_key(path)): if(self.FSkeys.has_key(path)):
plain_key = virtualsmartcard.CryptoUtils.cipher(False,self.cipher, self.master_password,self.FSkeys[path]) #TODO: Error checking: plain_key = cipher(False, self.cipher, self.master_password, self.FSkeys[path]) #TODO: Error checking:
return plain_key return plain_key
else: else:
return None return None
@@ -216,7 +217,7 @@ class SAM(object):
else: else:
raise SwError(SW["ERR_AUTHBLOCKED"]) raise SwError(SW["ERR_AUTHBLOCKED"])
def change_reference_data(self,p1,p2,data): def change_reference_data(self, p1, p2, data):
""" """
Change the specified referenced data (e.g. CHV) of the card Change the specified referenced data (e.g. CHV) of the card
""" """
@@ -226,7 +227,7 @@ class SAM(object):
print "New PIN = %s" % self.CardContainer.getPIN() print "New PIN = %s" % self.CardContainer.getPIN()
return SW["NORMAL"], "" return SW["NORMAL"], ""
def internal_authenticate(self,p1,p2,data): def internal_authenticate(self, p1, p2, data):
""" """
Authenticate card to terminal. Encrypt the challenge of the terminal Authenticate card to terminal. Encrypt the challenge of the terminal
to prove key posession to prove key posession
@@ -247,7 +248,7 @@ class SAM(object):
return SW["NORMAL"], crypted_challenge return SW["NORMAL"], crypted_challenge
def external_authenticate(self,p1,p2,data): def external_authenticate(self, p1, p2, data):
""" """
Authenticate the terminal to the card. Check wether Terminal correctly Authenticate the terminal to the card. Check wether Terminal correctly
encrypted the given challenge or not encrypted the given challenge or not
@@ -310,7 +311,7 @@ class SAM(object):
result = card_challenge + terminal_challenge result = card_challenge + terminal_challenge
return SW["NORMAL"], virtualsmartcard.CryptoUtils.cipher(True,cipher,key,result) return SW["NORMAL"], virtualsmartcard.CryptoUtils.cipher(True,cipher,key,result)
def get_challenge(self,p1,p2,data): def get_challenge(self, p1, p2, data):
""" """
Generate a random number of maximum 8 Byte and return it. Generate a random number of maximum 8 Byte and return it.
""" """
@@ -333,7 +334,7 @@ class SAM(object):
def get_card_number(self): def get_card_number(self):
return SW["NORMAL"], inttostring(self.cardNumber) return SW["NORMAL"], inttostring(self.cardNumber)
def _get_referenced_key(self,p1,p2): def _get_referenced_key(self, p1, p2):
""" """
This method returns the key specified by the p2 parameter. The key may be This method returns the key specified by the p2 parameter. The key may be
stored on the cards filesystem or in memory. stored on the cards filesystem or in memory.
@@ -368,7 +369,7 @@ class SAM(object):
key = None key = None
if key == None: #Try to read the key from the Key Container if key == None: #Try to read the key from the Key Container
key = self.CardContainer.getKey(reference_data) key = self.CardContainer.getKey(p2)
if key != None: if key != None:
return key return key
@@ -396,7 +397,7 @@ class SAM(object):
return sw, result return sw, result
#The following commands define the interface to the Secure Messaging functions #The following commands define the interface to the Secure Messaging functions
def generate_public_key_pair(self,p1,p2,data): def generate_public_key_pair(self, p1, p2, data):
return self.SM_handler.generate_public_key_pair(p1, p2, data) return self.SM_handler.generate_public_key_pair(p1, p2, data)
def parse_SM_CAPDU(self,CAPDU,header_authentication): def parse_SM_CAPDU(self,CAPDU,header_authentication):
@@ -405,10 +406,10 @@ class SAM(object):
def protect_result(self,sw,unprotected_result): def protect_result(self,sw,unprotected_result):
return self.SM_handler.protect_response(sw, unprotected_result) return self.SM_handler.protect_response(sw, unprotected_result)
def perform_security_operation(self,p1,p2,data): def perform_security_operation(self, p1, p2, data):
return self.SM_handler.perform_security_operation(p1, p2, data) return self.SM_handler.perform_security_operation(p1, p2, data)
def manage_security_environment(self,p1,p2,data): def manage_security_environment(self, p1, p2, data):
return self.SM_handler.manage_security_environment(p1, p2, data) return self.SM_handler.manage_security_environment(p1, p2, data)
class PassportSAM(SAM): class PassportSAM(SAM):
@@ -477,7 +478,7 @@ class PassportSAM(SAM):
Kicc = inttostring(random.randint(0, int(max,16))) Kicc = inttostring(random.randint(0, int(max,16)))
#Generate Answer #Generate Answer
data = plain[8:16] + plain[:8] + Kicc data = plain[8:16] + plain[:8] + Kicc
Eicc = virtualsmartcard.CryptoUtils.cipher(True,"DES3-CBC",self.KEnc,data) Eicc = virtualsmartcard.CryptoUtils.cipher(True, "DES3-CBC", self.KEnc,data)
Micc = self._mac(self.KMac,Eicc) Micc = self._mac(self.KMac,Eicc)
#Derive the final keys #Derive the final keys
KSseed = virtualsmartcard.CryptoUtils.operation_on_string(Kicc, Kifd, lambda a,b: a^b) KSseed = virtualsmartcard.CryptoUtils.operation_on_string(Kicc, Kifd, lambda a,b: a^b)
@@ -508,12 +509,12 @@ class CryptoflexSAM(SAM):
SAM.__init__(self, None, None, mf) SAM.__init__(self, None, None, mf)
self.SM_handler = CryptoflexSM(mf) self.SM_handler = CryptoflexSM(mf)
def generate_public_key_pair(self,p1,p2,data): def generate_public_key_pair(self, p1, p2, data):
asym_key = self.SM_handler.generate_public_key_pair(p1, p2, data) asym_key = self.SM_handler.generate_public_key_pair(p1, p2, data)
self.set_asym_algorithm(asym_key, 0x07) self.set_asym_algorithm(asym_key, 0x07)
return SW["NORMAL"], "" return SW["NORMAL"], ""
def perform_security_operation(self,p1,p2,data): def perform_security_operation(self, p1, p2, data):
""" """
In the cryptoflex card, this is the verify key command. A key is send 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. to the card in plain text and compared to a key stored in the card.
@@ -529,7 +530,7 @@ class CryptoflexSAM(SAM):
#else: #else:
# return SW["WARN_NOINFO63"], "" # return SW["WARN_NOINFO63"], ""
def internal_authenticate(self,p1,p2,data): 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) sw, data = SAM.internal_authenticate(self, p1, p2, data)
if data != "": if data != "":
@@ -560,17 +561,15 @@ class Security_Environment(object):
structure = TLVutils.unpack(config) structure = TLVutils.unpack(config)
for tag, length, value in structure: for tag, length, value in structure:
if tag == TEMPLATE_AT: if tag == TEMPLATE_AT:
self.at.parse_config(config) self.at.parse_SE_config(config)
elif tag == TEMPLATE_CRT:
self.crt.parse_config(config)
elif tag == TEMPLATE_CCT: elif tag == TEMPLATE_CCT:
self.cct.parse_config(config) self.cct.parse_SE_config(config)
elif tag == TEMPLATE_KAT: elif tag == TEMPLATE_KAT:
self.kat.parse_config(config) self.kat.parse_SE_config(config)
elif tag == TEMPLATE_CT: elif tag == TEMPLATE_CT:
self.ct.parse_config(config) self.ct.parse_SE_config(config)
elif tag == TEMPLATE_DST: elif tag == TEMPLATE_DST:
self.dst.parse_config(config) self.dst.parse_SE_config(config)
else: else:
raise ValueError raise ValueError
@@ -588,7 +587,7 @@ class Secure_Messaging(object):
def set_MF(self,mf): def set_MF(self,mf):
self.mf = mf self.mf = mf
def manage_security_environment(self,p1,p2,data): def manage_security_environment(self, p1, p2, data):
""" """
This method is used to store, restore or erase Security Environments This method is used to store, restore or erase Security Environments
or to manipualte the various parameters of the current SE. or to manipualte the various parameters of the current SE.
@@ -670,7 +669,7 @@ class Secure_Messaging(object):
""" """
SEstr = self.SAM.get_key(SEID) SEstr = self.SAM.get_key(SEID)
SE = loads(SEstr) SE = loads(SEstr)
if isinstance(SE, SecurityEnvironment): if isinstance(SE, Security_Environment):
self.current_SE = SE self.current_SE = SE
else: else:
raise SwError(SW["ERR_REFNOTUSABLE"]) raise SwError(SW["ERR_REFNOTUSABLE"])
@@ -737,11 +736,11 @@ class Secure_Messaging(object):
#SM data objects for confidentiality #SM data objects for confidentiality
if tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM"],SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM_ODD"]): if tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM"],SM_Class["CRYPTOGRAM_PLAIN_TLV_INCLUDING_SM_ODD"]):
#The Cryptogram includes SM objects. We decrypt them and parse the objects. #The Cryptogram includes SM objects. We decrypt them and parse the objects.
plain = decipher(tag,0x80,value) #TODO: Need Le = length plain = decipher(tag, 0x80, value) #TODO: Need Le = length
return_data.append(self.parse_SM_CAPDU(plain, header_authentication)) return_data.append(self.parse_SM_CAPDU(plain, header_authentication))
elif tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM"],SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM_ODD"]): elif tag in (SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM"],SM_Class["CRYPTOGRAM_PLAIN_TLV_NO_SM_ODD"]):
#The Cryptogram includes BER-TLV enconded plaintext. We decrypt them and return the objects. #The Cryptogram includes BER-TLV enconded plaintext. We decrypt them and return the objects.
plain = decipher(tag,0x80,value) plain = decipher(tag, 0x80, value)
return_data.append(plain) return_data.append(plain)
elif tag in (SM_Class["CRYPTOGRAM_PADDING_INDICATOR"],SM_Class["CRYPTOGRAM_PADDING_INDICATOR_ODD"]): elif tag in (SM_Class["CRYPTOGRAM_PADDING_INDICATOR"],SM_Class["CRYPTOGRAM_PADDING_INDICATOR_ODD"]):
#The first byte of the specified data field indicates the padding to use: #The first byte of the specified data field indicates the padding to use:
@@ -773,19 +772,16 @@ class Secure_Messaging(object):
auth = virtualsmartcard.CryptoUtils.append_padding("DES-CBC", to_authenticate) auth = virtualsmartcard.CryptoUtils.append_padding("DES-CBC", to_authenticate)
sw, checksum = self.compute_cryptographic_checksum(0x8E, 0x80, auth) sw, checksum = self.compute_cryptographic_checksum(0x8E, 0x80, auth)
if checksum != value: if checksum != value:
print "Failed to verify checksum!"
raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"]) raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"])
elif tag == SM_Class["DIGITAL_SIGNATURE"]: elif tag == SM_Class["DIGITAL_SIGNATURE"]:
auth = to_authenticate #FIXME: Need padding? auth = to_authenticate #FIXME: Need padding?
sw, signature = self.compute_digital_signature(0x9E, 0x9A, auth) sw, signature = self.compute_digital_signature(0x9E, 0x9A, auth)
if signature != value: if signature != value:
print "Failed to verify signature!" raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"])
raise SwEroor(SW["ERR_SECMESSOBJECTSINCORRECT"])
elif tag in (SM_Class["HASH_CODE"],SM_Class["HASH_CODE_ODD"]): elif tag in (SM_Class["HASH_CODE"],SM_Class["HASH_CODE_ODD"]):
sw, hash = self.hash(p1, p2, to_authenticate) sw, hash = self.hash(p1, p2, to_authenticate)
if hash != value: if hash != value:
print "Failed to verify hash!" raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"])
raise SwEroor(SW["ERR_SECMESSOBJECTSINCORRECT"])
#Check if we just parsed a expected SM Object: #Check if we just parsed a expected SM Object:
pos = 0 pos = 0
@@ -854,7 +850,7 @@ class Secure_Messaging(object):
return SW["NORMAL"], return_data return SW["NORMAL"], return_data
#The following commands implement ISO 7816-8 {{{ #The following commands implement ISO 7816-8 {{{
def perform_security_operation(self,p1,p2,data): def perform_security_operation(self, p1, p2, data):
""" """
In the end this command is nothing but a big switch for all the other commands In the end this command is nothing but a big switch for all the other commands
in ISO 7816-8. It will invoke the appropiate command and return its result in ISO 7816-8. It will invoke the appropiate command and return its result
@@ -888,7 +884,7 @@ class Secure_Messaging(object):
return sw, response_data return sw, response_data
def compute_cryptographic_checksum(self,p1,p2,data): def compute_cryptographic_checksum(self, p1, p2, data):
""" """
Compute a cryptographic checksum (e.g. MAC) for the given data. Compute a cryptographic checksum (e.g. MAC) for the given data.
Algorithm and key are specified in the current (CAPDU) SE Algorithm and key are specified in the current (CAPDU) SE
@@ -897,7 +893,7 @@ class Secure_Messaging(object):
if p1 != 0x8E or p2 != 0x80: if p1 != 0x8E or p2 != 0x80:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
if self.current_SE.cct.key == None: if self.current_SE.cct.key == None:
raise SwError(SE["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algorithm, checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algorithm,
self.current_SE.cct.key, self.current_SE.cct.key,
@@ -905,7 +901,7 @@ class Secure_Messaging(object):
self.current_SE.cct.iv) self.current_SE.cct.iv)
return SW["NORMAL"], checksum return SW["NORMAL"], checksum
def compute_digital_signature(self,p1,p2,data): def compute_digital_signature(self, p1, p2, data):
""" """
Compute a digital signature for the given data. Compute a digital signature for the given data.
Algorithm and key are specified in the current SE Algorithm and key are specified in the current SE
@@ -917,7 +913,7 @@ class Secure_Messaging(object):
if p1 != 0x9E or not p2 in (0x9A,0xAC,0xBC): if p1 != 0x9E or not p2 in (0x9A,0xAC,0xBC):
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
if self.current_SE.dst.key == None: if self.current_SE.dst.key == None:
raise SwError(SE["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
if p2 == 0x9A: #Data to be signed if p2 == 0x9A: #Data to be signed
to_sign = data to_sign = data
@@ -932,7 +928,7 @@ class Secure_Messaging(object):
signature = self.current_SE.dst.key.sign(data,"") signature = self.current_SE.dst.key.sign(data,"")
return SW["NORMAL"], signature return SW["NORMAL"], signature
def hash(self,p1,p2,data): def hash(self, p1, p2, data):
""" """
Hash the given data using the algorithm specified by the Hash the given data using the algorithm specified by the
current Security environment. current Security environment.
@@ -950,7 +946,7 @@ class Secure_Messaging(object):
return SW["NORMAL"], hash return SW["NORMAL"], hash
def verify_cryptographic_checksum(self,p1,p2,data): def verify_cryptographic_checksum(self, p1, p2, data):
""" """
Verify the cryptographic checksum contained in the data field. Data field must contain Verify the cryptographic checksum contained in the data field. Data field must contain
a cryptographic checksum (tag 0x8E) and a plain value (tag 0x80) a cryptographic checksum (tag 0x8E) and a plain value (tag 0x80)
@@ -964,7 +960,7 @@ class Secure_Messaging(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(config) structure = TLVutils.unpack(data)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x80: if tag == 0x80:
plain = value plain = value
@@ -979,7 +975,7 @@ class Secure_Messaging(object):
else: else:
raise SwError["ERR_SECMESSOBJECTSINCORRECT"] raise SwError["ERR_SECMESSOBJECTSINCORRECT"]
def verify_digital_signature(self,p1,p2,data): def verify_digital_signature(self, p1, p2, data):
""" """
Verify the digital signature contained in the data field. Data must contain Verify the digital signature contained in the data field. Data must contain
a data to sign (tag 0x9A, 0xAC or 0xBC) and a digital signature (0x9E) a data to sign (tag 0x9A, 0xAC or 0xBC) and a digital signature (0x9E)
@@ -991,7 +987,7 @@ class Secure_Messaging(object):
if key == None: if key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
structure = TLVutils.unpack(config) structure = TLVutils.unpack(data)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x9E: if tag == 0x9E:
signature = value signature = value
@@ -1011,13 +1007,13 @@ class Secure_Messaging(object):
else: else:
raise SwError(["ERR_SECMESSOBJECTSINCORRECT"]) raise SwError(["ERR_SECMESSOBJECTSINCORRECT"])
def verify_certificate(self,p1,p2,data): def verify_certificate(self, p1, p2, data):
if p1 != 0x00 or p2 not in (0x92,0xAE,0xBE): if p1 != 0x00 or p2 not in (0x92, 0xAE, 0xBE):
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
else: else:
raise NotImplementedError raise NotImplementedError
def encipher(self,p1,p2,data): def encipher(self, p1, p2, data):
""" """
Encipher data using key, algorithm, IV and Padding specified Encipher data using key, algorithm, IV and Padding specified
by the current Security environment. by the current Security environment.
@@ -1032,7 +1028,7 @@ class Secure_Messaging(object):
crypted = virtualsmartcard.CryptoUtils.cipher(True, algo, key, padded, self.current_SE.ct.iv) crypted = virtualsmartcard.CryptoUtils.cipher(True, algo, key, padded, self.current_SE.ct.iv)
return SW["NORMAL"], crypted return SW["NORMAL"], crypted
def decipher(self,p1,p2,data): def decipher(self, p1, p2, data):
""" """
Decipher data using key, algorithm, IV and Padding specified Decipher data using key, algorithm, IV and Padding specified
by the current Security environment. by the current Security environment.
@@ -1043,10 +1039,10 @@ class Secure_Messaging(object):
if key == None or algo == None: if key == None or algo == None:
return SW["ERR_CONDITIONNOTSATISFIED"], "" return SW["ERR_CONDITIONNOTSATISFIED"], ""
else: else:
plain = virtualsmartcard.CryptoUtils.cipher(False,algo,key,data,self.current_SE.ct.iv) plain = virtualsmartcard.CryptoUtils.cipher(False, algo, key, data, self.current_SE.ct.iv)
return SW["NORMAL"], plain return SW["NORMAL"], plain
def generate_public_key_pair(self,p1,p2,data): def generate_public_key_pair(self, p1, p2, data):
""" """
Generate a new public-private key pair. Generate a new public-private key pair.
""" """
@@ -1061,7 +1057,7 @@ class Secure_Messaging(object):
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
if p1 & 0x01 == 0x00: #Generate key if p1 & 0x01 == 0x00: #Generate key
PublicKey = c_class.generate(self.current_SE.dst.keylength,rnd.get_bytes) PublicKey = c_class.generate(self.current_SE.dst.keylength, rnd.get_bytes)
self.current_SE.dst.key = PublicKey self.current_SE.dst.key = PublicKey
else: else:
pass #Read key pass #Read key
@@ -1071,9 +1067,9 @@ class Secure_Messaging(object):
#Public key #Public key
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 = TLVutils.bertlv_pack(pk)
#result = TLVutils.bertlv_pack((0x7F49,len(pk),pk)) #result = TLVutils.bertlv_pack((0x7F49, len(pk), pk))
#Private key #Private key
d = PublicKey.__getstate__()['d'] d = PublicKey.__getstate__()['d']
elif cipher == "DSA": elif cipher == "DSA":
@@ -1094,10 +1090,10 @@ class Secure_Messaging(object):
#}}} #}}}
class CryptoflexSM(Secure_Messaging): class CryptoflexSM(Secure_Messaging):
def __init__(self,mf): def __init__(self, mf):
Secure_Messaging.__init__(self,mf) #Does Cryptoflex need its own SE? Secure_Messaging.__init__(self, mf) #Does Cryptoflex need its own SE?
def generate_public_key_pair(self,p1,p2,data): def generate_public_key_pair(self, p1, p2, data):
""" """
In the Cryptoflex card this command only supports RSA keys. In the Cryptoflex card this command only supports RSA keys.
@@ -1118,10 +1114,10 @@ class CryptoflexSM(Secure_Messaging):
keylength = keylength_dict[p2] keylength = keylength_dict[p2]
rnd = RandomPool() rnd = RandomPool()
PublicKey = RSA.generate(keylength,rnd.get_bytes) PublicKey = RSA.generate(keylength, rnd.get_bytes)
self.current_SE.dst.key = PublicKey self.current_SE.dst.key = PublicKey
e_in = struct.unpack("<i",data) e_in = struct.unpack("<i", data)
if e_in[0] != 65537: if e_in[0] != 65537:
print "Warning: Exponents different from 65537 are ignored! The Exponent given is %i" % e_in[0] print "Warning: Exponents different from 65537 are ignored! The Exponent given is %i" % e_in[0]
@@ -1130,7 +1126,7 @@ class CryptoflexSM(Secure_Messaging):
n_str = inttostring(n) n_str = inttostring(n)
n_str = n_str[::-1] n_str = n_str[::-1]
e = PublicKey.__getstate__()['e'] e = PublicKey.__getstate__()['e']
e_str = inttostring(e,4) e_str = inttostring(e, 4)
e_str = e_str[::-1] e_str = e_str[::-1]
padd = 187 * '\x30' #We don't have chinese remainder theorem components, so we need to inject padding padd = 187 * '\x30' #We don't have chinese remainder theorem components, so we need to inject padding
pk_n = TLVutils.bertlv_pack(((0x81,len(n_str),n_str),(0x01,len(padd),padd),(0x82,len(e_str),e_str))) pk_n = TLVutils.bertlv_pack(((0x81,len(n_str),n_str),(0x01,len(padd),padd),(0x82,len(e_str),e_str)))
@@ -1151,11 +1147,11 @@ class CryptoflexSM(Secure_Messaging):
class ePass_SM(Secure_Messaging): class ePass_SM(Secure_Messaging):
def __init__(self,MF,SE,ssc=None): def __init__(self, MF, SE, ssc=None):
self.ssc = ssc self.ssc = ssc
Secure_Messaging.__init__(self, MF, SE) Secure_Messaging.__init__(self, MF, SE)
def compute_cryptographic_checksum(self,p1,p2,data): def compute_cryptographic_checksum(self, p1, p2, data):
""" """
Compute a cryptographic checksum (e.g. MAC) for the given data. Compute a cryptographic checksum (e.g. MAC) for the given data.
Algorithm and key are specified in the current (CAPDU) SE. The ePass Algorithm and key are specified in the current (CAPDU) SE. The ePass