Merge pull request #175 from sorcerer86pt/python3_fixes

[vpicc] Python 3 updates and code fixing
This commit is contained in:
Frank Morgner
2020-09-18 00:15:36 +02:00
committed by GitHub
6 changed files with 77 additions and 69 deletions

View File

@@ -2,7 +2,7 @@ platform:
- x86 - x86
- x64 - x64
os: Visual Studio 2015 os: Visual Studio 2019
install: install:
- date /T & time /T - date /T & time /T
@@ -23,11 +23,17 @@ install:
# BUGFIX: wdf directory was renamed to 00wdf, rename it back (see github.com/appveyor/ci/issues/414) # BUGFIX: wdf directory was renamed to 00wdf, rename it back (see github.com/appveyor/ci/issues/414)
#- ps: ren 'C:\Program Files (x86)\Windows Kits\10\include\00wdf' 'wdf' #- ps: ren 'C:\Program Files (x86)\Windows Kits\10\include\00wdf' 'wdf'
- choco install swig
- $current_path = Get-Location | select -ExpandProperty Path
- $full_path = $current_path + "\swigwin-4.0.2.zip"
- $folder_path = $current_path + "\swig_win"
- (new-object net.webclient).DownloadFile("https://kumisystems.dl.sourceforge.net/project/swig/swigwin/swigwin-4.0.2/swigwin-4.0.2.zip", $full_path)
- Expand-Archive -LiteralPath $full_path -DestinationPath $folder_path
- $env:Path += ";"+$folder_path+"\swigwin-4.0.2"
- python -m pip install --upgrade pip - python -m pip install --upgrade pip
- pip install virtualenv - pip install virtualenv
- pip install -U setuptools - pip install -U setuptools
- easy_install PyCrypto - pip install pycryptodome
- pip install pbkdf2 - pip install pbkdf2
- pip install Pillow - pip install Pillow
- pip install pyreadline - pip install pyreadline
@@ -35,8 +41,8 @@ install:
- pip install pyinstaller - pip install pyinstaller
- set PATH=C:\cygwin\bin;%PATH% - set PATH=C:\cygwin\bin;%PATH%
# set Visual Studio 2015 build environment # set Visual Studio 2019 build environment
- set VSVER=14 - set VSVER=19
- ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
- echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
- call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%

View File

@@ -239,11 +239,11 @@ class Security_Environment(object):
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)
elif(cmd == 0x02): elif cmd == 0x02:
return self.sam.store_SE(p2) return self.sam.store_SE(p2)
elif(cmd == 0x03): elif cmd == 0x03:
return self.sam.restore_SE(p2) return self.sam.restore_SE(p2)
elif(cmd == 0x04): elif cmd == 0x04:
return self.sam.erase_SE(p2) return self.sam.erase_SE(p2)
else: else:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
@@ -684,8 +684,6 @@ class Security_Environment(object):
""" """
from Crypto.PublicKey import RSA, DSA from Crypto.PublicKey import RSA, DSA
from Crypto.Util.randpool import RandomPool
rnd = RandomPool()
cipher = self.ct.algorithm cipher = self.ct.algorithm
@@ -694,7 +692,7 @@ class Security_Environment(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.dst.keylength, rnd.get_bytes) PublicKey = c_class.generate(self.dst.keylength)
self.dst.key = PublicKey self.dst.key = PublicKey
else: else:
pass # Read key pass # Read key
@@ -702,23 +700,23 @@ class Security_Environment(object):
# Encode keys # Encode keys
if cipher == "RSA": if cipher == "RSA":
# Public key # Public key
n = inttostring(PublicKey.__getstate__()['n']) n = inttostring(PublicKey.n)
e = inttostring(PublicKey.__getstate__()['e']) e = inttostring(PublicKey.e)
pk = ((0x81, len(n), n), (0x82, len(e), e)) pk = ((0x81, len(n), n), (0x82, len(e), e))
result = bertlv_pack(pk) result = bertlv_pack(pk)
# Private key # Private key
d = PublicKey.__getstate__()['d'] d = PublicKey.d
elif cipher == "DSA": elif cipher == "DSA":
# DSAParams # DSAParams
p = inttostring(PublicKey.__getstate__()['p']) p = inttostring(PublicKey.p)
q = inttostring(PublicKey.__getstate__()['q']) q = inttostring(PublicKey.q)
g = inttostring(PublicKey.__getstate__()['g']) g = inttostring(PublicKey.g)
# Public key # Public key
y = inttostring(PublicKey.__getstate__()['y']) y = inttostring(PublicKey.y)
pk = ((0x81, len(p), p), (0x82, len(q), q), (0x83, len(g), g), pk = ((0x81, len(p), p), (0x82, len(q), q), (0x83, len(g), g),
(0x84, len(y), y)) (0x84, len(y), y))
# Private key # Private key
x = inttostring(PublicKey.__getstate__()['x']) x = inttostring(PublicKey.x)
# Add more algorithms here # Add more algorithms here
# elif cipher = "ECDSA": # elif cipher = "ECDSA":
else: else:

View File

@@ -229,7 +229,7 @@ class SAM(object):
blocklen = vsCrypto.get_cipher_blocklen(cipher) blocklen = vsCrypto.get_cipher_blocklen(cipher)
reference = vsCrypto.append_padding(blocklen, self.last_challenge) reference = vsCrypto.append_padding(blocklen, self.last_challenge)
reference = vsCrypto.encrypt(cipher, key, reference) reference = vsCrypto.encrypt(cipher, key, reference)
if(reference == data): if reference == data:
# Invalidate last challenge # Invalidate last challenge
self.last_challenge is None self.last_challenge is None
return SW["NORMAL"], "" return SW["NORMAL"], ""
@@ -249,14 +249,14 @@ class SAM(object):
key = self._get_referenced_key(p1, p2) key = self._get_referenced_key(p1, p2)
card_number = self.get_card_number() card_number = self.get_card_number()
if (key is None): if key is None:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
if p1 == 0x00: # No information given if p1 == 0x00: # No information given
cipher = get_referenced_cipher(self.cipher) cipher = get_referenced_cipher(self.cipher)
else: else:
cipher = get_referenced_cipher(p1) cipher = get_referenced_cipher(p1)
if (cipher is None): if cipher is None:
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
plain = vsCrypto.decrypt(cipher, key, mutual_challenge) plain = vsCrypto.decrypt(cipher, key, mutual_challenge)
@@ -277,7 +277,7 @@ class SAM(object):
""" """
Generate a random number of maximum 8 Byte and return it. Generate a random number of maximum 8 Byte and return it.
""" """
if (p1 != 0x00 or p2 != 0x00): # RFU if p1 != 0x00 or p2 != 0x00: # RFU
raise SwError(SW["ERR_INCORRECTP1P2"]) raise SwError(SW["ERR_INCORRECTP1P2"])
length = 8 # Length of the challenge in Byte length = 8 # Length of the challenge in Byte
@@ -315,7 +315,7 @@ class SAM(object):
algo = get_referenced_cipher(p1) algo = get_referenced_cipher(p1)
keylength = vsCrypto.get_cipher_keylen(algo) keylength = vsCrypto.get_cipher_keylen(algo)
if (p2 == 0x00): # No information given, use the global card key if p2 == 0x00: # No information given, use the global card key
key = self.cardSecret key = self.cardSecret
# We treat global and specific reference data alike # We treat global and specific reference data alike
else: else:

View File

@@ -19,35 +19,36 @@
from virtualsmartcard.utils import stringtoint, inttostring from virtualsmartcard.utils import stringtoint, inttostring
TAG = {} TAG = {
TAG["FILECONTROLPARAMETERS"] = 0x62 "FILECONTROLPARAMETERS": 0x62,
TAG["FILEMANAGEMENTDATA"] = 0x64 "FILEMANAGEMENTDATA": 0x64,
TAG["FILECONTROLINFORMATION"] = 0x6F "FILECONTROLINFORMATION": 0x6F,
TAG["BYTES_EXCLUDINGSTRUCTURE"] = 0x80 "BYTES_EXCLUDINGSTRUCTURE": 0x80,
TAG["BYTES_INCLUDINGSTRUCTURE"] = 0x81 "BYTES_INCLUDINGSTRUCTURE": 0x81,
TAG["FILEDISCRIPTORBYTE"] = 0x82 "FILEDISCRIPTORBYTE": 0x82,
TAG["FILEIDENTIFIER"] = 0x83 "FILEIDENTIFIER": 0x83,
TAG["DFNAME"] = 0x84 "DFNAME": 0x84,
TAG["PROPRIETARY_NOTBERTLV"] = 0x85 "PROPRIETARY_NOTBERTLV": 0x85,
TAG["PROPRIETARY_SECURITY"] = 0x86 "PROPRIETARY_SECURITY": 0x86,
TAG["FIDEF_CONTAININGFCI"] = 0x87 "FIDEF_CONTAININGFCI": 0x87,
TAG["SHORTFID"] = 0x88 "SHORTFID": 0x88,
TAG["LIFECYCLESTATUS"] = 0x8A "LIFECYCLESTATUS": 0x8A,
TAG["SA_EXPANDEDFORMAT"] = 0x8B "SA_EXPANDEDFORMAT": 0x8B,
TAG["SA_COMPACTFORMAT"] = 0x8C "SA_COMPACTFORMAT": 0x8C,
TAG["FIDEF_CONTAININGSET"] = 0x8D "FIDEF_CONTAININGSET": 0x8D,
TAG["CHANNELSECURITY"] = 0x8E "CHANNELSECURITY": 0x8E,
TAG["SA_DATAOBJECTS"] = 0xA0 "SA_DATAOBJECTS": 0xA0,
TAG["PROPRIETARY_SECURITYTEMP"] = 0xA1 "PROPRIETARY_SECURITYTEMP": 0xA1,
TAG["PROPRIETARY_BERTLV"] = 0xA5 "PROPRIETARY_BERTLV": 0xA5,
TAG["SA_EXPANDEDFORMAT_TEMP"] = 0xAB "SA_EXPANDEDFORMAT_TEMP": 0xAB,
TAG["CRYPTIDENTIFIER_TEMP"] = 0xAC "CRYPTIDENTIFIER_TEMP": 0xAC,
TAG["DISCRETIONARY_DATA"] = 0x53 "DISCRETIONARY_DATA": 0x53,
TAG["DISCRETIONARY_TEMPLATE"] = 0x73 "DISCRETIONARY_TEMPLATE": 0x73,
TAG["OFFSET_DATA"] = 0x54 "OFFSET_DATA": 0x54,
TAG["TAG_LIST"] = 0x5C "TAG_LIST": 0x5C,
TAG["HEADER_LIST"] = 0x5D "HEADER_LIST": 0x5D,
TAG["EXTENDED_HEADER_LIST"] = 0x4D "EXTENDED_HEADER_LIST": 0x4D
}
def tlv_unpack(data): def tlv_unpack(data):
@@ -114,7 +115,7 @@ def tlv_find_tag(tlv_data, tag, num_results=None):
def pack(tlv_data, recalculate_length=False): def pack(tlv_data, recalculate_length=False):
result = b"" result = []
for data in tlv_data: for data in tlv_data:
tag, length, value = data[:3] tag, length, value = data[:3]
@@ -143,9 +144,9 @@ def pack(tlv_data, recalculate_length=False):
assert len(l) < 0x7f assert len(l) < 0x7f
l = inttostring(0x80 | len(l)) + l l = inttostring(0x80 | len(l)) + l
result = result + t result.append(t)
result = result + l result.append(l)
result = result + value result.append(value)
return b"".join(result) return b"".join(result)

View File

@@ -503,6 +503,9 @@ class VirtualICC(object):
def __sendToVPICC(self, msg): def __sendToVPICC(self, msg):
""" Send a message to the vpcd """ """ Send a message to the vpcd """
if isinstance(msg, str):
self.sock.sendall(struct.pack('!H', len(msg)) + msg.encode())
else:
self.sock.sendall(struct.pack('!H', len(msg)) + msg) self.sock.sendall(struct.pack('!H', len(msg)) + msg)
def __recvFromVPICC(self): def __recvFromVPICC(self):

View File

@@ -40,14 +40,14 @@ class TestSmartcardSAM(unittest.TestCase):
self.myCard.verify(0x00, 0x00, "3456".encode('ascii')) self.myCard.verify(0x00, 0x00, "3456".encode('ascii'))
except SwError as e: except SwError as e:
pass pass
self.assertEquals(self.myCard.counter, ctr1 - 1) self.assertEqual(self.myCard.counter, ctr1 - 1)
def test_internal_authenticate(self): def test_internal_authenticate(self):
sw, challenge = self.myCard.get_challenge(0x00, 0x00, b"") sw, challenge = self.myCard.get_challenge(0x00, 0x00, b"")
blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB")
padded = vsCrypto.append_padding(blocklen, challenge) padded = vsCrypto.append_padding(blocklen, challenge)
sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded)
self.assertEquals(sw, SW["NORMAL"]) self.assertEqual(sw, SW["NORMAL"])
def test_external_authenticate(self): def test_external_authenticate(self):
sw, challenge = self.myCard.get_challenge(0x00, 0x00, b"") sw, challenge = self.myCard.get_challenge(0x00, 0x00, b"")
@@ -56,7 +56,7 @@ class TestSmartcardSAM(unittest.TestCase):
sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded)
sw, result_data = self.myCard.external_authenticate(0x00, 0x00, sw, result_data = self.myCard.external_authenticate(0x00, 0x00,
result_data) result_data)
self.assertEquals(sw, SW["NORMAL"]) self.assertEqual(sw, SW["NORMAL"])
def test_security_environment(self): def test_security_environment(self):
hash = self.secEnv.hash(0x90, 0x80, self.password) hash = self.secEnv.hash(0x90, 0x80, self.password)
@@ -74,7 +74,7 @@ class TestSmartcardSAM(unittest.TestCase):
self.secEnv.ct.algorithm = "RSA" self.secEnv.ct.algorithm = "RSA"
self.secEnv.dst.keylength = 1024 self.secEnv.dst.keylength = 1024
sw, pk = self.secEnv.generate_public_key_pair(0x00, 0x00, b"") sw, pk = self.secEnv.generate_public_key_pair(0x00, 0x00, b"")
self.assertEquals(sw, SW["NORMAL"]) self.assertEqual(sw, SW["NORMAL"])
if __name__ == "__main__": if __name__ == "__main__":