merged with changes of r320
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@326 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -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 virtualsmartcard.SmartcardFilesystem, virtualsmartcard.CryptoUtils, virtualsmartcard.TLVutils
|
import virtualsmartcard.SmartcardFilesystem, TLVutils
|
||||||
import random, re, struct, Crypto
|
import random, re, struct#, Crypto
|
||||||
import hashlib
|
import hashlib
|
||||||
from virtualsmartcard.SWutils import SwError, SW, SW_MESSAGES
|
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 virtualsmartcard.utils import inttostring, stringtoint, hexdump, C_APDU, R_APDU
|
||||||
from Crypto.Cipher import DES3
|
#from Crypto.Cipher import DES3
|
||||||
from virtualsmartcard.ConstantDefinitions import *
|
from virtualsmartcard.ConstantDefinitions import *
|
||||||
from virtualsmartcard.SEutils import ControlReferenceTemplate as CRT
|
from virtualsmartcard.SEutils import ControlReferenceTemplate as CRT
|
||||||
|
|
||||||
@@ -60,6 +60,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
|
||||||
|
|
||||||
self.cardNumber = cardNumber
|
self.cardNumber = cardNumber
|
||||||
self.PIN = PIN
|
self.PIN = PIN
|
||||||
@@ -123,6 +124,7 @@ class CardContainer:
|
|||||||
class SAM(object):
|
class SAM(object):
|
||||||
|
|
||||||
def __init__(self, PIN, cardNumber, mf=None):
|
def __init__(self, PIN, cardNumber, mf=None):
|
||||||
|
import virtualsmartcard.CryptoUtils
|
||||||
|
|
||||||
self.CardContainer = CardContainer(PIN, cardNumber)
|
self.CardContainer = CardContainer(PIN, cardNumber)
|
||||||
#self.CardContainer.loadConfiguration(path, password)
|
#self.CardContainer.loadConfiguration(path, password)
|
||||||
@@ -425,10 +427,10 @@ class PassportSAM(SAM):
|
|||||||
#SAM.__init__(self, path, key,None)
|
#SAM.__init__(self, path, key,None)
|
||||||
SAM.__init__(self, None, None, mf)
|
SAM.__init__(self, None, None, mf)
|
||||||
self.SM_handler = ePass_SM(mf, None, None, None)
|
self.SM_handler = ePass_SM(mf, None, None, None)
|
||||||
self.SM_handler.CAPDU_SE.cct.algo = "CC"
|
self.SM_handler.CAPDU_SE.cct.algorithm = "CC"
|
||||||
self.SM_handler.RAPDU_SE.cct.algo = "CC"
|
self.SM_handler.RAPDU_SE.cct.algorithm = "CC"
|
||||||
self.SM_handler.CAPDU_SE.ct.algo = "DES3-CBC"
|
self.SM_handler.CAPDU_SE.ct.algorithm = "DES3-CBC"
|
||||||
self.SM_handler.RAPDU_SE.ct.algo = "DES3-CBC"
|
self.SM_handler.RAPDU_SE.ct.algorithm = "DES3-CBC"
|
||||||
|
|
||||||
def __computeKeys(self):
|
def __computeKeys(self):
|
||||||
"""Computes the keys depending on the machine readable
|
"""Computes the keys depending on the machine readable
|
||||||
@@ -490,10 +492,10 @@ class PassportSAM(SAM):
|
|||||||
self.SM_handler.RAPDU_SE.ct.key = self.KSenc
|
self.SM_handler.RAPDU_SE.ct.key = self.KSenc
|
||||||
self.SM_handler.RAPDU_SE.cct.key = self.KSmac
|
self.SM_handler.RAPDU_SE.cct.key = self.KSmac
|
||||||
self.SM_handler.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
|
self.SM_handler.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
|
||||||
self.SM_handler.CAPDU_SE.ct.algo = "DES3-CBC"
|
self.SM_handler.CAPDU_SE.ct.algorithm = "DES3-CBC"
|
||||||
self.SM_handler.RAPDU_SE.ct.algo = "DES3-CBC"
|
self.SM_handler.RAPDU_SE.ct.algorithm = "DES3-CBC"
|
||||||
self.SM_handler.CAPDU_SE.cct.algo = "CC"
|
self.SM_handler.CAPDU_SE.cct.algorithm = "CC"
|
||||||
self.SM_handler.RAPDU_SE.cct.algo = "CC"
|
self.SM_handler.RAPDU_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):
|
||||||
@@ -575,7 +577,10 @@ class Security_Environment(object):
|
|||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
class Secure_Messaging(object):
|
class Secure_Messaging(object):
|
||||||
|
|
||||||
def __init__(self,MF,CAPDU_SE=None,RAPDU_SE=None):
|
def __init__(self,MF,CAPDU_SE=None,RAPDU_SE=None):
|
||||||
|
import virtualsmartcard.CryptoUtils
|
||||||
|
|
||||||
self.mf = MF
|
self.mf = MF
|
||||||
if not CAPDU_SE:
|
if not CAPDU_SE:
|
||||||
self.CAPDU_SE = Security_Environment()
|
self.CAPDU_SE = Security_Environment()
|
||||||
@@ -784,7 +789,7 @@ class Secure_Messaging(object):
|
|||||||
sw, plain = self.decipher(tag,0x80,value[1:])
|
sw, plain = self.decipher(tag,0x80,value[1:])
|
||||||
if sw != 0x9000:
|
if sw != 0x9000:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
plain = virtualsmartcard.CryptoUtils.strip_padding(self.CAPDU_SE.ct.algo,plain,padding_indicator)
|
plain = virtualsmartcard.CryptoUtils.strip_padding(self.CAPDU_SE.ct.algorithm,plain,padding_indicator)
|
||||||
return_data.append(plain)
|
return_data.append(plain)
|
||||||
|
|
||||||
#SM data objects for authentication
|
#SM data objects for authentication
|
||||||
@@ -872,15 +877,15 @@ class Secure_Messaging(object):
|
|||||||
return_data += encrypted_tlv
|
return_data += encrypted_tlv
|
||||||
|
|
||||||
if sw == SW["NORMAL"]:
|
if sw == SW["NORMAL"]:
|
||||||
if self.CAPDU_SE.cct.algo == None:
|
if self.CAPDU_SE.cct.algorithm == None:
|
||||||
raise SwError(SW["CONDITIONSNOTSATISFIED"])
|
raise SwError(SW["CONDITIONSNOTSATISFIED"])
|
||||||
elif self.CAPDU_SE.cct.algo == "CCT":
|
elif self.CAPDU_SE.cct.algorithm == "CCT":
|
||||||
tag = SM_Class["CHECKSUM"]
|
tag = SM_Class["CHECKSUM"]
|
||||||
to_auth = virtualsmartcard.CryptoUtils.append_padding("DES-ECB", return_data)
|
to_auth = virtualsmartcard.CryptoUtils.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.CAPDU_SE.cct.algo == "SIGNATURE":
|
elif self.CAPDU_SE.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)
|
||||||
@@ -932,10 +937,10 @@ 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.CAPDU_SE.cct.algo == None or self.current_SE.cct.key == None:
|
if self.CAPDU_SE.cct.algorithm == None or self.current_SE.cct.key == None:
|
||||||
raise SWError(SE["ERR_CONDITIONNOTSATISFIED"])
|
raise SWError(SE["ERR_CONDITIONNOTSATISFIED"])
|
||||||
|
|
||||||
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algo,
|
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.current_SE.cct.algorithm,
|
||||||
self.current_SE.cct.key,
|
self.current_SE.cct.key,
|
||||||
data,
|
data,
|
||||||
self.current_SE.cct.iv)
|
self.current_SE.cct.iv)
|
||||||
@@ -976,7 +981,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.algo
|
algo = self.current_SE.ht.algorithm
|
||||||
if algo == None:
|
if algo == None:
|
||||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||||
try:
|
try:
|
||||||
@@ -994,7 +999,7 @@ class Secure_Messaging(object):
|
|||||||
plain = ""
|
plain = ""
|
||||||
cct = ""
|
cct = ""
|
||||||
|
|
||||||
algo = self.current_SE.cct.algo
|
algo = self.current_SE.cct.algorithm
|
||||||
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:
|
||||||
@@ -1059,7 +1064,7 @@ 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.algo
|
algo = self.current_SE.ct.algorithm
|
||||||
key = self.current_SE.ct.key
|
key = self.current_SE.ct.key
|
||||||
if key == None or algo == None:
|
if key == None or algo == None:
|
||||||
return SW["ERR_CONDITIONNOTSATISFIED"], ""
|
return SW["ERR_CONDITIONNOTSATISFIED"], ""
|
||||||
@@ -1074,7 +1079,7 @@ 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.algo
|
algo = self.current_SE.ct.algorithm
|
||||||
key = self.current_SE.ct.key
|
key = self.current_SE.ct.key
|
||||||
if key == None or algo == None:
|
if key == None or algo == None:
|
||||||
return SW["ERR_CONDITIONNOTSATISFIED"], ""
|
return SW["ERR_CONDITIONNOTSATISFIED"], ""
|
||||||
@@ -1090,7 +1095,7 @@ class Secure_Messaging(object):
|
|||||||
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.algorithm #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:
|
||||||
@@ -1201,9 +1206,9 @@ class ePass_SM(Secure_Messaging):
|
|||||||
if p1 != 0x8E or p2 != 0x80:
|
if p1 != 0x8E or p2 != 0x80:
|
||||||
raise SwError(SW["ERR_INCORRECTP1P2"])
|
raise SwError(SW["ERR_INCORRECTP1P2"])
|
||||||
|
|
||||||
#checksum = CryptoUtils.calculate_MAC(self.CAPDU_SE.cct.key,data,self.CAPDU_SE.cct.iv)
|
#checksum = virtualsmartcard.CryptoUtils.calculate_MAC(self.CAPDU_SE.cct.key,data,self.CAPDU_SE.cct.iv)
|
||||||
self.ssc += 1
|
self.ssc += 1
|
||||||
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.CAPDU_SE.cct.algo,
|
checksum = virtualsmartcard.CryptoUtils.crypto_checksum(self.CAPDU_SE.cct.algorithm,
|
||||||
self.CAPDU_SE.cct.key,
|
self.CAPDU_SE.cct.key,
|
||||||
data,
|
data,
|
||||||
self.CAPDU_SE.cct.iv,
|
self.CAPDU_SE.cct.iv,
|
||||||
@@ -1216,6 +1221,8 @@ if __name__ == "__main__":
|
|||||||
Unit test:
|
Unit test:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import virtualsmartcard.CryptoUtils
|
||||||
|
|
||||||
password = "DUMMYKEYDUMMYKEY"
|
password = "DUMMYKEYDUMMYKEY"
|
||||||
#generate_SAM_config("1234567890", "1234", "keykeykeykeykeyk", path, password)
|
#generate_SAM_config("1234567890", "1234", "keykeykeykeykeyk", path, password)
|
||||||
|
|
||||||
@@ -1241,21 +1248,21 @@ 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)
|
#SM = Secure_Messaging(None)
|
||||||
testvektor = "foobar"
|
#testvektor = "foobar"
|
||||||
print "Testvektor = %s" % testvektor
|
#print "Testvektor = %s" % testvektor
|
||||||
sw, hash = SM.hash(0x90,0x80,testvektor)
|
#sw, hash = SM.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 = SM.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 = SM.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 = SM.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 = CryptoflexSM(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._read_FS_data(0x01, 16)
|
#print MyCard._read_FS_data(0x01, 16)
|
||||||
print MyCard._get_referenced_key(0x01)
|
#print MyCard._get_referenced_key(0x01)
|
||||||
|
|||||||
Reference in New Issue
Block a user