Refactoring: Merged Secure_Messaging and Security_Environment classes

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@489 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2011-08-17 10:31:18 +00:00
parent 4af89d967f
commit ffeb5ef066

View File

@@ -82,11 +82,13 @@ class SAM(object):
else: else:
self.cardSecret = cardSecret self.cardSecret = cardSecret
self.SM_handler = Secure_Messaging(self.mf, self) #Security Environments may be saved and retrieved from/to this dictionary
self.saved_SEs = {}
self.current_SE = Security_Environment(self.mf, self)
def set_MF(self, mf): def set_MF(self, mf):
self.mf = mf self.mf = mf
self.SM_handler.set_MF(mf) self.current_SE.set_MF(mf)
def FSencrypt(self, data): def FSencrypt(self, data):
""" """
@@ -104,6 +106,45 @@ class SAM(object):
""" """
return data return data
def store_SE(self, SEID):
"""
Stores the current Security environment in the secure access module. The
SEID is used as a reference to identify the SE.
"""
SEstr = dumps(self.current_SE)
self.saved_SEs[SEID] = SEstr
return SW["NORMAL"], ""
def restore_SE(self, SEID):
"""
Restores a Security Environment from the SAM and replaces the current SE
with it
"""
if (not self.saved_SEs.has_key(SEID)):
raise SwError(SW["ERR_REFNOTUSABLE"])
else:
SEstr = self.saved_SEs[SEID]
SE = loads(SEstr)
if isinstance(SE, Security_Environment):
self.current_SE = SE
else:
raise SwError(SW["ERR_REFNOTUSABLE"])
return SW["NORMAL"], ""
def erase_SE(self, SEID):
"""
Erases a Security Environment stored under SEID from the SAM
"""
if (not self.saved_SEs.has_key(SEID)):
raise SwError(SW["ERR_REFNOTUSABLE"])
else:
del self.saved_SEs[SEID]
return SW["NORMAL"], ""
def set_asym_algorithm(self, cipher, keytype): def set_asym_algorithm(self, cipher, keytype):
""" """
@param cipher: Public/private key object from used for encryption @param cipher: Public/private key object from used for encryption
@@ -123,7 +164,7 @@ class SAM(object):
""" """
logging.debug("Received PIN: %s" % PIN.strip()) logging.debug("Received PIN: %s" % PIN.strip())
PIN = PIN.replace("\0","") #Strip NULL charakters PIN = PIN.replace("\0","") #Strip NULL characters
if p1 != 0x00: if p1 != 0x00:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
@@ -143,7 +184,7 @@ class SAM(object):
Change the specified referenced data (e.g. CHV) of the card Change the specified referenced data (e.g. CHV) of the card
""" """
data = data.replace("\0","") #Strip NULL charakters data = data.replace("\0","") #Strip NULL characters
self.PIN = data self.PIN = data
return SW["NORMAL"], "" return SW["NORMAL"], ""
@@ -285,19 +326,19 @@ class SAM(object):
#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.current_SE.generate_public_key_pair(p1, p2, data)
def parse_SM_CAPDU(self, CAPDU, header_authentication): def parse_SM_CAPDU(self, CAPDU, header_authentication):
return self.SM_handler.parse_SM_CAPDU(CAPDU, header_authentication) return self.current_SE.parse_SM_CAPDU(CAPDU, header_authentication)
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.current_SE.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.current_SE.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.current_SE.manage_security_environment(p1, p2, data)
class PassportSAM(SAM): class PassportSAM(SAM):
def __init__(self, mf): def __init__(self, mf):
@@ -314,9 +355,9 @@ 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.SM_handler = ePass_SM(mf, None, None) self.current_SE = ePass_SE(mf, None, None)
self.SM_handler.current_SE.cct.algorithm = "CC" self.current_SE.cct.algorithm = "CC"
self.SM_handler.current_SE.ct.algorithm = "DES3-CBC" self.current_SE.ct.algorithm = "DES3-CBC"
def __computeKeys(self): def __computeKeys(self):
""" """
@@ -375,11 +416,11 @@ class PassportSAM(SAM):
self.KSmac = self.derive_key(KSseed, 2) self.KSmac = self.derive_key(KSseed, 2)
#self.ssc = rnd_icc[-4:] + rnd_ifd[-4:] #self.ssc = rnd_icc[-4:] + rnd_ifd[-4:]
#Set the current SE #Set the current SE
self.SM_handler.current_SE.ct.key = self.KSenc self.current_SE.ct.key = self.KSenc
self.SM_handler.current_SE.cct.key = self.KSmac self.current_SE.cct.key = self.KSmac
self.SM_handler.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:]) self.current_SE.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
self.SM_handler.current_SE.ct.algorithm = "DES3-CBC" self.current_SE.ct.algorithm = "DES3-CBC"
self.SM_handler.current_SE.cct.algorithm = "CC" self.current_SE.cct.algorithm = "CC"
return SW["NORMAL"], Eicc + Micc return SW["NORMAL"], Eicc + Micc
def _mac(self, key, data, ssc = None, dopad=True): def _mac(self, key, data, ssc = None, dopad=True):
@@ -396,10 +437,10 @@ class PassportSAM(SAM):
class CryptoflexSAM(SAM): class CryptoflexSAM(SAM):
def __init__(self, mf=None): def __init__(self, mf=None):
SAM.__init__(self, None, None, mf) SAM.__init__(self, None, None, mf)
self.SM_handler = CryptoflexSM(mf) self.current_SE = CryptoflexSE(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.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) self.set_asym_algorithm(asym_key, 0x07)
return SW["NORMAL"], "" return SW["NORMAL"], ""
@@ -429,7 +470,10 @@ class CryptoflexSAM(SAM):
class Security_Environment(object): class Security_Environment(object):
def __init__(self): def __init__(self, MF, SAM):
self.mf = MF
self.sam = SAM
self.SEID = None self.SEID = None
self.sm_objects = "" self.sm_objects = ""
@@ -446,20 +490,6 @@ class Security_Environment(object):
self.internal_auth = False self.internal_auth = False
self.externel_auth = False self.externel_auth = False
class Secure_Messaging(object):
def __init__(self, MF, SAM, SE=None):
self.mf = MF
self.sam = SAM
#Security Environments may be saved and retrieved from/to this dictionary
self.saved_SEs = {}
if not SE:
self.current_SE = Security_Environment()
else:
self.current_SE = SE
def set_MF(self, mf): def set_MF(self, mf):
self.mf = mf self.mf = mf
@@ -489,23 +519,23 @@ class Secure_Messaging(object):
if(cmd == 0x01): if(cmd == 0x01):
#Secure messaging in command data field #Secure messaging in command data field
if se & 0x01: if se & 0x01:
self.current_SE.capdu_sm = True self.capdu_sm = True
#Secure messaging in response data field #Secure messaging in response data field
if se & 0x02: if se & 0x02:
self.current_SE.rapdu_sm = True self.rapdu_sm = True
#Computation, decipherment, internal authentication and key agreement #Computation, decipherment, internal authentication and key agreement
if se & 0x04: if se & 0x04:
self.current_SE.internal_auth = True self.internal_auth = True
#Verification, encipherment, external authentication and key agreement #Verification, encipherment, external authentication and key agreement
if se & 0x08: if se & 0x08:
self.current_SE.external_auth = True self.external_auth = True
return self.__set_SE(p2, data) return self.__set_SE(p2, data)
elif(cmd== 0x02): elif(cmd== 0x02):
return self.__store_SE(p2) return self.sam.store_SE(p2)
elif(cmd == 0x03): elif(cmd == 0x03):
return self.__restore_SE(p2) return self.sam.restore_SE(p2)
elif(cmd == 0x04): elif(cmd == 0x04):
return self.__erase_SE(p2) return self.sam.erase_SE(p2)
else: else:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
@@ -520,56 +550,17 @@ class Secure_Messaging(object):
if not p2 in valid_p2: if not p2 in valid_p2:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
if p2 == 0xA4: if p2 == 0xA4:
return self.current_SE.at.parse_SE_config(data) return self.at.parse_SE_config(data)
elif p2 == 0xA6: elif p2 == 0xA6:
return self.current_SE.kat.parse_SE_config(data) return self.kat.parse_SE_config(data)
elif p2 == 0xAA: elif p2 == 0xAA:
return self.current_SE.ht.parse_SE_config(data) return self.ht.parse_SE_config(data)
elif p2 == 0xB4: elif p2 == 0xB4:
return self.current_SE.cct.parse_SE_config(data) return self.cct.parse_SE_config(data)
elif p2 == 0xB6: elif p2 == 0xB6:
return self.current_SE.dst.parse_SE_config(data) return self.dst.parse_SE_config(data)
elif p2 == 0xB8: elif p2 == 0xB8:
return self.current_SE.ct.parse_SE_config(data) return self.ct.parse_SE_config(data)
def __store_SE(self, SEID):
"""
Stores the current Security environment in the secure access module. The
SEID is used as a reference to identify the SE.
"""
SEstr = dumps(self.current_SE)
self.saved_SEs[SEID] = SEstr
return SW["NORMAL"], ""
def __restore_SE(self, SEID):
"""
Restores a Security Environment from the SAM and replaces the current SE
with it
"""
if (not self.saved_SEs.has_key(SEID)):
raise SwError(SW["ERR_REFNOTUSABLE"])
else:
SEstr = self.saved_SEs[SEID]
SE = loads(SEstr)
if isinstance(SE, Security_Environment):
self.current_SE = SE
else:
raise SwError(SW["ERR_REFNOTUSABLE"])
return SW["NORMAL"], ""
def __erase_SE(self, SEID):
"""
Erases a Security Environment stored under SEID from the SAM
"""
if (not self.saved_SEs.has_key(SEID)):
raise SwError(SW["ERR_REFNOTUSABLE"])
else:
del self.saved_SEs[SEID]
return SW["NORMAL"], ""
def parse_SM_CAPDU(self, CAPDU, header_authentication): def parse_SM_CAPDU(self, CAPDU, header_authentication):
""" """
@@ -583,7 +574,7 @@ class Secure_Messaging(object):
""" """
structure = TLVutils.unpack(CAPDU.data) structure = TLVutils.unpack(CAPDU.data)
return_data = ["",] return_data = ["",]
expected = self.current_SE.sm_objects expected = self.sm_objects
cla = None cla = None
ins = None ins = None
@@ -675,8 +666,7 @@ class Secure_Messaging(object):
""" """
padding_indicator = stringtoint(value[0]) padding_indicator = stringtoint(value[0])
sw, plain = self.decipher(tag, 0x80, value[1:]) sw, plain = self.decipher(tag, 0x80, value[1:])
plain = vsCrypto.strip_padding(self.current_SE.ct.algorithm, plain = vsCrypto.strip_padding(self.ct.algorithm, plain,
plain,
padding_indicator) padding_indicator)
return_data.append(plain) return_data.append(plain)
@@ -728,7 +718,7 @@ class Secure_Messaging(object):
This method protects a response APDU using secure messaging mechanisms This method protects a response APDU using secure messaging mechanisms
It returns the protected data and the SW bytes It returns the protected data and the SW bytes
""" """
expected = self.current_SE.sm_objects expected = self.sm_objects
for pos in range(len(expected)): for pos in range(len(expected)):
tag = expected[pos] tag = expected[pos]
@@ -750,15 +740,15 @@ class Secure_Messaging(object):
return_data += encrypted_tlv return_data += encrypted_tlv
if sw == SW["NORMAL"]: if sw == SW["NORMAL"]:
if self.current_SE.cct.algorithm == None: if self.cct.algorithm == None:
raise SwError(SW["CONDITIONSNOTSATISFIED"]) raise SwError(SW["CONDITIONSNOTSATISFIED"])
elif self.current_SE.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) to_auth = 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, to_auth)
length = len(auth) length = len(auth)
return_data += TLVutils.pack([(tag, length, auth)]) return_data += TLVutils.pack([(tag, length, auth)])
elif self.current_SE.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)
@@ -811,13 +801,11 @@ 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.cct.key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
checksum = vsCrypto.crypto_checksum(self.current_SE.cct.algorithm, checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key,
self.current_SE.cct.key, data, self.cct.iv)
data,
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):
@@ -832,7 +820,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.dst.key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
to_sign = "" to_sign = ""
@@ -846,7 +834,7 @@ class Secure_Messaging(object):
elif p2 == 0xBC: #Data objects to be signed elif p2 == 0xBC: #Data objects to be signed
pass pass
signature = self.current_SE.dst.key.sign(to_sign, "") signature = self.dst.key.sign(to_sign, "")
return SW["NORMAL"], signature return SW["NORMAL"], signature
def hash(self, p1, p2, data): def hash(self, p1, p2, data):
@@ -857,7 +845,7 @@ class Secure_Messaging(object):
""" """
if p1 != 0x90 or not p2 in (0x80, 0xA0): if p1 != 0x90 or not p2 in (0x80, 0xA0):
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
algo = self.current_SE.ht.algorithm algo = self.ht.algorithm
if algo == None: if algo == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
try: try:
@@ -876,9 +864,9 @@ class Secure_Messaging(object):
plain = "" plain = ""
cct = "" cct = ""
algo = self.current_SE.cct.algorithm algo = self.cct.algorithm
key = self.current_SE.cct.key key = self.cct.key
iv = self.current_SE.cct.iv iv = self.cct.iv
if algo == None or key == None: if algo == None or key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
@@ -903,7 +891,7 @@ class Secure_Messaging(object):
contain a data to sign (tag 0x9A, 0xAC or 0xBC) and a digital signature contain a data to sign (tag 0x9A, 0xAC or 0xBC) and a digital signature
(0x9E) (0x9E)
""" """
key = self.current_SE.dst.key key = self.dst.key
to_sign = "" to_sign = ""
signature = "" signature = ""
@@ -942,13 +930,13 @@ class Secure_Messaging(object):
by the current Security environment. by the current Security environment.
Return raw data (no TLV coding). Return raw data (no TLV coding).
""" """
algo = self.current_SE.ct.algorithm algo = self.ct.algorithm
key = self.current_SE.ct.key key = self.ct.key
if key == None or algo == None: if key == None or algo == None:
return SW["ERR_CONDITIONNOTSATISFIED"], "" return SW["ERR_CONDITIONNOTSATISFIED"], ""
else: else:
padded = vsCrypto.append_padding(algo, data) padded = vsCrypto.append_padding(algo, data)
crypted = vsCrypto.encrypt(algo, key, padded, self.current_SE.ct.iv) crypted = vsCrypto.encrypt(algo, key, padded, self.ct.iv)
return SW["NORMAL"], crypted return SW["NORMAL"], crypted
def decipher(self, p1, p2, data): def decipher(self, p1, p2, data):
@@ -957,12 +945,12 @@ class Secure_Messaging(object):
by the current Security environment. by the current Security environment.
Return raw data (no TLV coding). Padding is not removed!!! Return raw data (no TLV coding). Padding is not removed!!!
""" """
algo = self.current_SE.ct.algorithm algo = self.ct.algorithm
key = self.current_SE.ct.key key = self.ct.key
if key == None or algo == None: if key == None or algo == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
else: else:
plain = vsCrypto.decrypt(algo, key, data, self.current_SE.ct.iv) plain = vsCrypto.decrypt(algo, key, data, self.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):
@@ -973,16 +961,15 @@ class Secure_Messaging(object):
from Crypto.Util.randpool import RandomPool from Crypto.Util.randpool import RandomPool
rnd = RandomPool() rnd = RandomPool()
cipher = self.current_SE.ct.algorithm cipher = self.ct.algorithm
c_class = locals().get(cipher, None) c_class = locals().get(cipher, None)
if c_class is None: if c_class is None:
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, PublicKey = c_class.generate(self.dst.keylength, rnd.get_bytes)
rnd.get_bytes) self.dst.key = PublicKey
self.current_SE.dst.key = PublicKey
else: else:
pass #Read key pass #Read key
@@ -1016,9 +1003,9 @@ class Secure_Messaging(object):
return SW["NORMAL"], "" return SW["NORMAL"], ""
#}}} #}}}
class CryptoflexSM(Secure_Messaging): class CryptoflexSE(Security_Environment):
def __init__(self, mf): def __init__(self, mf):
Secure_Messaging.__init__(self, mf) #Does Cryptoflex need its own SE? Security_Environment.__init__(self, mf)
def generate_public_key_pair(self, p1, p2, data): def generate_public_key_pair(self, p1, p2, data):
""" """
@@ -1043,7 +1030,7 @@ class CryptoflexSM(Secure_Messaging):
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.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:
@@ -1077,11 +1064,11 @@ class CryptoflexSM(Secure_Messaging):
data = ef_priv_key.getenc('data') data = ef_priv_key.getenc('data')
return PublicKey return PublicKey
class ePass_SM(Secure_Messaging): class ePass_SE(Security_Environment):
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) Security_Environment.__init__(self, MF, SE)
def compute_cryptographic_checksum(self, p1, p2, data): def compute_cryptographic_checksum(self, p1, p2, data):
""" """
@@ -1093,11 +1080,8 @@ class ePass_SM(Secure_Messaging):
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
self.ssc += 1 self.ssc += 1
checksum = vsCrypto.crypto_checksum(self.current_SE.cct.algorithm, checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key,
self.current_SE.cct.key, data, self.cct.iv, self.ssc)
data,
self.current_SE.cct.iv,
self.ssc)
return SW["NORMAL"], checksum return SW["NORMAL"], checksum
@@ -1130,20 +1114,20 @@ if __name__ == "__main__":
sw = e.sw sw = e.sw
print "Decryption Status code: %x" % sw print "Decryption Status code: %x" % sw
#SM = Secure_Messaging(None) #SE = Security_Environment(None)
#testvektor = "foobar" #testvektor = "foobar"
#print "Testvektor = %s" % testvektor #print "Testvektor = %s" % testvektor
#sw, hash = SM.hash(0x90,0x80,testvektor) #sw, hash = SE.hash(0x90,0x80,testvektor)
#print "SW after hashing = %s" % sw #print "SW after hashing = %s" % sw
#print "Hash = %s" % hash #print "Hash = %s" % hash
#sw, crypted = SM.encipher(0x00, 0x00, testvektor) #sw, crypted = SE.encipher(0x00, 0x00, testvektor)
#print "SW after encryption = %s" % sw #print "SW after encryption = %s" % sw
#sw, plain = SM.decipher(0x00, 0x00, crypted) #sw, plain = SE.decipher(0x00, 0x00, crypted)
#print "SW after encryption = %s" % sw #print "SW after encryption = %s" % sw
#print "Testvektor after en- and deciphering: %s" % plain #print "Testvektor after en- and deciphering: %s" % plain
#sw, pk = SM.generate_public_key_pair(0x02, 0x00, "") #sw, pk = SE.generate_public_key_pair(0x02, 0x00, "")
#print "SW after keygen = %s" % sw #print "SW after keygen = %s" % sw
#print "Public Key = %s" % pk #print "Public Key = %s" % pk
#CF = CryptoflexSM(None) #CF = CryptoflexSE(None)
#print CF.generate_public_key_pair(0x00, 0x80, "\x01\x00\x01\x00") #print CF.generate_public_key_pair(0x00, 0x80, "\x01\x00\x01\x00")
#print MyCard._get_referenced_key(0x01) #print MyCard._get_referenced_key(0x01)