-Fixed two unhandled exceptions

-Removed some trailing whitespaces


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@164 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
oepen
2010-06-22 18:16:07 +00:00
parent 0b03fced4a
commit a1766913a3

View File

@@ -1,18 +1,18 @@
# #
# Copyright (C) 2009 Dominik Oepen # Copyright (C) 2009 Dominik Oepen
# #
# This file is part of virtualsmartcard. # This file is part of virtualsmartcard.
# #
# virtualsmartcard is free software: you can redistribute it and/or modify it # virtualsmartcard is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free # under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any # Software Foundation, either version 3 of the License, or (at your option) any
# later version. # later version.
# #
# virtualsmartcard is distributed in the hope that it will be useful, but # virtualsmartcard is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
# #
# 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/>.
# #
@@ -26,12 +26,12 @@ from Crypto.Cipher import DES3
from ConstantDefinitions import * from ConstantDefinitions import *
from SEutils import ControlReferenceTemplate as CRT from SEutils import ControlReferenceTemplate as CRT
def get_referenced_cipher(p1): def get_referenced_cipher(p1):
""" """
P1 defines the algorithm and mode to use. We dispatch it and return a P1 defines the algorithm and mode to use. We dispatch it and return a
string that is understood by CryptoUtils.py functions string that is understood by CryptoUtils.py functions
""" """
ciphertable = { ciphertable = {
0x00: "DES3-ECB", 0x00: "DES3-ECB",
0x01: "DES3-ECB", 0x01: "DES3-ECB",
@@ -41,18 +41,18 @@ def get_referenced_cipher(p1):
0x05: "AES-ECB", 0x05: "AES-ECB",
0x06: "AES-CBC", 0x06: "AES-CBC",
0x07: "RSA", 0x07: "RSA",
0x08: "DSA" 0x08: "DSA"
} }
if (ciphertable.has_key(p1)): if (ciphertable.has_key(p1)):
return ciphertable[p1] return ciphertable[p1]
else: else:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
class CardContainer: class CardContainer:
""" """
This class is used to store the data needed by the SAM This class is used to store the data needed by the SAM
It includes the PIN, the master key of the SAM and a It includes the PIN, the master key of the SAM and a
hashmap containing all the keys used by the file encryption hashmap containing all the keys used by the file encryption
system. The keys in the hashmap are indexed via the path system. The keys in the hashmap are indexed via the path
to the corresponding container. to the corresponding container.
@@ -985,7 +985,7 @@ class Secure_Messaging(object):
raise SwError(SW["ERR_SECMESSNOTSUPPORTED"]) raise SwError(SW["ERR_SECMESSNOTSUPPORTED"])
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
@@ -993,13 +993,13 @@ class Secure_Messaging(object):
""" """
plain = "" plain = ""
cct = "" cct = ""
algo = self.current_SE.cct.algo algo = self.current_SE.cct.algo
key = self.current_SE.cct.key key = self.current_SE.cct.key
iv = self.current_SE.cct.iv iv = self.current_SE.cct.iv
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(config)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x80: if tag == 0x80:
@@ -1014,19 +1014,19 @@ class Secure_Messaging(object):
return SW["NORMAL"], "" return SW["NORMAL"], ""
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)
""" """
key = self.current_SE.dst.key key = self.current_SE.dst.key
to_sign = "" to_sign = ""
signature = "" signature = ""
if key == None: if key == None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
structure = TLVutils.unpack(config) structure = TLVutils.unpack(config)
for tag, length, value in structure: for tag, length, value in structure:
if tag == 0x9E: if tag == 0x9E:
@@ -1037,24 +1037,22 @@ class Secure_Messaging(object):
pass pass
elif tag == 0xBC: elif tag == 0xBC:
pass pass
if to_sign == "" or signature == "": if to_sign == "" or signature == "":
raise SwError(SW["ERR_SECMESSOBJECTSMISSING"]) raise SwError(SW["ERR_SECMESSOBJECTSMISSING"])
try: my_signature = key.sign(value)
my_signature = key.sign(value)
except error, e: #FIXME: Foobar
pass
if my_signature == signature: if my_signature == signature:
return SW["NORMAL"], "" return SW["NORMAL"], ""
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"])
pass else:
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
@@ -1069,7 +1067,7 @@ class Secure_Messaging(object):
padded = CryptoUtils.append_padding(algo, data) padded = CryptoUtils.append_padding(algo, data)
crypted = CryptoUtils.cipher(True, algo, key, padded, self.current_SE.ct.iv) crypted = 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
@@ -1082,8 +1080,8 @@ class Secure_Messaging(object):
return SW["ERR_CONDITIONNOTSATISFIED"], "" return SW["ERR_CONDITIONNOTSATISFIED"], ""
else: else:
plain = CryptoUtils.cipher(False,algo,key,data,self.current_SE.ct.iv) plain = 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.
@@ -1091,19 +1089,19 @@ class Secure_Messaging(object):
from Crypto.PublicKey import RSA, DSA from Crypto.PublicKey import RSA, DSA
from Crypto.Util.randpool import RandomPool from Crypto.Util.randpool import RandomPool
rnd = RandomPool() rnd = RandomPool()
cipher = self.CAPDU_SE.ct.algo #FIXME: Current SE? cipher = self.CAPDU_SE.ct.algo #FIXME: Current SE?
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.CAPDU_SE.dst.keylength,rnd.get_bytes) PublicKey = c_class.generate(self.CAPDU_SE.dst.keylength,rnd.get_bytes)
self.CAPDU_SE.dst.key = PublicKey self.CAPDU_SE.dst.key = PublicKey
else: else:
pass #Read key pass #Read key
#Encode keys #Encode keys
if cipher == "RSA": if cipher == "RSA":
#Public key #Public key
@@ -1123,38 +1121,38 @@ class Secure_Messaging(object):
#Private key #Private key
x = str(PublicKey.__getstate__()['x']) x = str(PublicKey.__getstate__()['x'])
#Add more algorithms here #Add more algorithms here
if p1 & 0x02 == 0x02: if p1 & 0x02 == 0x02:
return SW["NORMAL"], result return SW["NORMAL"], result
else: else:
#FIXME: Where to put the keys? #FIXME: Where to put the keys?
return SW["NORMAL"], "" return SW["NORMAL"], ""
#}}} #}}}
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.
@param data: Contains the public exponent used for key generation @param data: Contains the public exponent used for key generation
@param p1: The keynumber. Can be used later to refer to the generated key @param p1: The keynumber. Can be used later to refer to the generated key
@param p2: Used to specifiy the keylength. The mapping is: 0x40 => 256 Bit, 0x60 => 512 Bit, 0x80 => 1024 @param p2: Used to specifiy the keylength. The mapping is: 0x40 => 256 Bit, 0x60 => 512 Bit, 0x80 => 1024
""" """
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from Crypto.Util.randpool import RandomPool 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} keylength_dict = {0x40: 256, 0x60: 512, 0x80: 1024}
if not keylength_dict.has_key(p2): if not keylength_dict.has_key(p2):
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
else: else:
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.CAPDU_SE.dst.key = PublicKey self.CAPDU_SE.dst.key = PublicKey
@@ -1162,7 +1160,7 @@ class CryptoflexSM(Secure_Messaging):
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]
#Encode Public key #Encode Public key
n = PublicKey.__getstate__()['n'] n = PublicKey.__getstate__()['n']
n_str = inttostring(n) n_str = inttostring(n)
@@ -1173,8 +1171,8 @@ class CryptoflexSM(Secure_Messaging):
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)))
#Private key #Private key
d = PublicKey.__getstate__()['d'] 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() df = self.mf.currentDF()
file = df.select("fid", 0x1012) file = df.select("fid", 0x1012)
@@ -1205,28 +1203,28 @@ class ePass_SM(Secure_Messaging):
#checksum = CryptoUtils.calculate_MAC(self.CAPDU_SE.cct.key,data,self.CAPDU_SE.cct.iv) #checksum = CryptoUtils.calculate_MAC(self.CAPDU_SE.cct.key,data,self.CAPDU_SE.cct.iv)
self.ssc += 1 self.ssc += 1
checksum = CryptoUtils.crypto_checksum(self.CAPDU_SE.cct.algo, checksum = CryptoUtils.crypto_checksum(self.CAPDU_SE.cct.algo,
self.CAPDU_SE.cct.key, self.CAPDU_SE.cct.key,
data, data,
self.CAPDU_SE.cct.iv, self.CAPDU_SE.cct.iv,
self.ssc) self.ssc)
return SW["NORMAL"], checksum return SW["NORMAL"], checksum
if __name__ == "__main__": if __name__ == "__main__":
""" """
Unit test: Unit test:
""" """
password = "DUMMYKEYDUMMYKEY" password = "DUMMYKEYDUMMYKEY"
#generate_SAM_config("1234567890", "1234", "keykeykeykeykeyk", path, password) #generate_SAM_config("1234567890", "1234", "keykeykeykeykeyk", path, password)
MyCard = SAM("1234", "1234567890") MyCard = SAM("1234", "1234567890")
try: try:
print MyCard.verify(0x00, 0x00, "5678") print MyCard.verify(0x00, 0x00, "5678")
except SwError, e: except SwError, e:
print e.message print e.message
print "Counter = " + str(MyCard.counter) print "Counter = " + str(MyCard.counter)
print MyCard.verify(0x00, 0x00, "1234") print MyCard.verify(0x00, 0x00, "1234")
print "Counter = " + str(MyCard.counter) print "Counter = " + str(MyCard.counter)
@@ -1235,7 +1233,7 @@ if __name__ == "__main__":
padded = CryptoUtils.append_padding("DES3-ECB", challenge) padded = CryptoUtils.append_padding("DES3-ECB", challenge)
sw, result = MyCard.internal_authenticate(0x00, 0x00, padded) sw, result = MyCard.internal_authenticate(0x00, 0x00, padded)
print "Internal Authenticate status code: %x" % sw print "Internal Authenticate status code: %x" % sw
try: try:
sw, res = MyCard.external_authenticate(0x00, 0x00, result) sw, res = MyCard.external_authenticate(0x00, 0x00, result)
except SwError, e: except SwError, e: