diff --git a/appveyor.yml b/appveyor.yml index 31e3b38..c76c01a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ platform: - x86 - x64 -os: Visual Studio 2015 +os: Visual Studio 2019 install: - 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) #- 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 - pip install virtualenv - pip install -U setuptools - - easy_install PyCrypto + - pip install pycryptodome - pip install pbkdf2 - pip install Pillow - pip install pyreadline @@ -35,8 +41,8 @@ install: - pip install pyinstaller - set PATH=C:\cygwin\bin;%PATH% - # set Visual Studio 2015 build environment - - set VSVER=14 + # set Visual Studio 2019 build environment + - set VSVER=19 - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py index fd89f6c..36deb2d 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SEutils.py @@ -239,11 +239,11 @@ class Security_Environment(object): if se & 0x08: self.external_auth = True return self._set_SE(p2, data) - elif(cmd == 0x02): + elif cmd == 0x02: return self.sam.store_SE(p2) - elif(cmd == 0x03): + elif cmd == 0x03: return self.sam.restore_SE(p2) - elif(cmd == 0x04): + elif cmd == 0x04: return self.sam.erase_SE(p2) else: raise SwError(SW["ERR_INCORRECTP1P2"]) @@ -684,8 +684,6 @@ class Security_Environment(object): """ from Crypto.PublicKey import RSA, DSA - from Crypto.Util.randpool import RandomPool - rnd = RandomPool() cipher = self.ct.algorithm @@ -694,7 +692,7 @@ class Security_Environment(object): raise SwError(SW["ERR_CONDITIONNOTSATISFIED"]) 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 else: pass # Read key @@ -702,23 +700,23 @@ class Security_Environment(object): # Encode keys if cipher == "RSA": # Public key - n = inttostring(PublicKey.__getstate__()['n']) - e = inttostring(PublicKey.__getstate__()['e']) + n = inttostring(PublicKey.n) + e = inttostring(PublicKey.e) pk = ((0x81, len(n), n), (0x82, len(e), e)) result = bertlv_pack(pk) # Private key - d = PublicKey.__getstate__()['d'] + d = PublicKey.d elif cipher == "DSA": # DSAParams - p = inttostring(PublicKey.__getstate__()['p']) - q = inttostring(PublicKey.__getstate__()['q']) - g = inttostring(PublicKey.__getstate__()['g']) + p = inttostring(PublicKey.p) + q = inttostring(PublicKey.q) + g = inttostring(PublicKey.g) # Public key - y = inttostring(PublicKey.__getstate__()['y']) + y = inttostring(PublicKey.y) pk = ((0x81, len(p), p), (0x82, len(q), q), (0x83, len(g), g), (0x84, len(y), y)) # Private key - x = inttostring(PublicKey.__getstate__()['x']) + x = inttostring(PublicKey.x) # Add more algorithms here # elif cipher = "ECDSA": else: diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py index 51baad6..3723e7d 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py @@ -229,7 +229,7 @@ class SAM(object): blocklen = vsCrypto.get_cipher_blocklen(cipher) reference = vsCrypto.append_padding(blocklen, self.last_challenge) reference = vsCrypto.encrypt(cipher, key, reference) - if(reference == data): + if reference == data: # Invalidate last challenge self.last_challenge is None return SW["NORMAL"], "" @@ -249,20 +249,20 @@ class SAM(object): key = self._get_referenced_key(p1, p2) card_number = self.get_card_number() - if (key is None): + if key is None: raise SwError(SW["ERR_INCORRECTP1P2"]) if p1 == 0x00: # No information given cipher = get_referenced_cipher(self.cipher) else: cipher = get_referenced_cipher(p1) - if (cipher is None): + if cipher is None: raise SwError(SW["ERR_INCORRECTP1P2"]) plain = vsCrypto.decrypt(cipher, key, mutual_challenge) last_challenge_len = len(self.last_challenge) - terminal_challenge = plain[:last_challenge_len-1] - card_challenge = plain[last_challenge_len:-len(card_number)-1] + terminal_challenge = plain[:last_challenge_len - 1] + card_challenge = plain[last_challenge_len:-len(card_number) - 1] serial_number = plain[-len(card_number):] if terminal_challenge != self.last_challenge: @@ -277,7 +277,7 @@ class SAM(object): """ 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"]) length = 8 # Length of the challenge in Byte @@ -315,7 +315,7 @@ class SAM(object): algo = get_referenced_cipher(p1) 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 # We treat global and specific reference data alike else: diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/TLVutils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/TLVutils.py index eb7be9d..725f9ab 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/TLVutils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/TLVutils.py @@ -19,35 +19,36 @@ from virtualsmartcard.utils import stringtoint, inttostring -TAG = {} -TAG["FILECONTROLPARAMETERS"] = 0x62 -TAG["FILEMANAGEMENTDATA"] = 0x64 -TAG["FILECONTROLINFORMATION"] = 0x6F -TAG["BYTES_EXCLUDINGSTRUCTURE"] = 0x80 -TAG["BYTES_INCLUDINGSTRUCTURE"] = 0x81 -TAG["FILEDISCRIPTORBYTE"] = 0x82 -TAG["FILEIDENTIFIER"] = 0x83 -TAG["DFNAME"] = 0x84 -TAG["PROPRIETARY_NOTBERTLV"] = 0x85 -TAG["PROPRIETARY_SECURITY"] = 0x86 -TAG["FIDEF_CONTAININGFCI"] = 0x87 -TAG["SHORTFID"] = 0x88 -TAG["LIFECYCLESTATUS"] = 0x8A -TAG["SA_EXPANDEDFORMAT"] = 0x8B -TAG["SA_COMPACTFORMAT"] = 0x8C -TAG["FIDEF_CONTAININGSET"] = 0x8D -TAG["CHANNELSECURITY"] = 0x8E -TAG["SA_DATAOBJECTS"] = 0xA0 -TAG["PROPRIETARY_SECURITYTEMP"] = 0xA1 -TAG["PROPRIETARY_BERTLV"] = 0xA5 -TAG["SA_EXPANDEDFORMAT_TEMP"] = 0xAB -TAG["CRYPTIDENTIFIER_TEMP"] = 0xAC -TAG["DISCRETIONARY_DATA"] = 0x53 -TAG["DISCRETIONARY_TEMPLATE"] = 0x73 -TAG["OFFSET_DATA"] = 0x54 -TAG["TAG_LIST"] = 0x5C -TAG["HEADER_LIST"] = 0x5D -TAG["EXTENDED_HEADER_LIST"] = 0x4D +TAG = { + "FILECONTROLPARAMETERS": 0x62, + "FILEMANAGEMENTDATA": 0x64, + "FILECONTROLINFORMATION": 0x6F, + "BYTES_EXCLUDINGSTRUCTURE": 0x80, + "BYTES_INCLUDINGSTRUCTURE": 0x81, + "FILEDISCRIPTORBYTE": 0x82, + "FILEIDENTIFIER": 0x83, + "DFNAME": 0x84, + "PROPRIETARY_NOTBERTLV": 0x85, + "PROPRIETARY_SECURITY": 0x86, + "FIDEF_CONTAININGFCI": 0x87, + "SHORTFID": 0x88, + "LIFECYCLESTATUS": 0x8A, + "SA_EXPANDEDFORMAT": 0x8B, + "SA_COMPACTFORMAT": 0x8C, + "FIDEF_CONTAININGSET": 0x8D, + "CHANNELSECURITY": 0x8E, + "SA_DATAOBJECTS": 0xA0, + "PROPRIETARY_SECURITYTEMP": 0xA1, + "PROPRIETARY_BERTLV": 0xA5, + "SA_EXPANDEDFORMAT_TEMP": 0xAB, + "CRYPTIDENTIFIER_TEMP": 0xAC, + "DISCRETIONARY_DATA": 0x53, + "DISCRETIONARY_TEMPLATE": 0x73, + "OFFSET_DATA": 0x54, + "TAG_LIST": 0x5C, + "HEADER_LIST": 0x5D, + "EXTENDED_HEADER_LIST": 0x4D +} 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): - result = b"" + result = [] for data in tlv_data: tag, length, value = data[:3] @@ -143,9 +144,9 @@ def pack(tlv_data, recalculate_length=False): assert len(l) < 0x7f l = inttostring(0x80 | len(l)) + l - result = result + t - result = result + l - result = result + value + result.append(t) + result.append(l) + result.append(value) return b"".join(result) @@ -180,7 +181,7 @@ def unpack(data, with_marks=None, offset=0, include_filler=False): for type, mark_start, mark_stop in with_marks: if (mark_start, mark_stop) == (start, stop): marks.append(type) - marks = (marks, ) + marks = (marks,) else: marks = () @@ -239,11 +240,11 @@ def simpletlv_unpack(data): length = rest[1] if length == 0xff: length = (rest[2] << 8) + rest[3] - newvalue = rest[4:4+length] - rest = rest[4+length:] + newvalue = rest[4:4 + length] + rest = rest[4 + length:] else: - newvalue = rest[2:2+length] - rest = rest[2+length:] + newvalue = rest[2:2 + length] + rest = rest[2 + length:] result.append((tag, length, newvalue)) return result diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py index ccd330e..c4d0f95 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py @@ -503,7 +503,10 @@ class VirtualICC(object): def __sendToVPICC(self, msg): """ Send a message to the vpcd """ - self.sock.sendall(struct.pack('!H', len(msg)) + msg) + if isinstance(msg, str): + self.sock.sendall(struct.pack('!H', len(msg)) + msg.encode()) + else: + self.sock.sendall(struct.pack('!H', len(msg)) + msg) def __recvFromVPICC(self): """ Receive a message from the vpcd """ diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py index 9181622..992ed8a 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py @@ -40,14 +40,14 @@ class TestSmartcardSAM(unittest.TestCase): self.myCard.verify(0x00, 0x00, "3456".encode('ascii')) except SwError as e: pass - self.assertEquals(self.myCard.counter, ctr1 - 1) + self.assertEqual(self.myCard.counter, ctr1 - 1) def test_internal_authenticate(self): sw, challenge = self.myCard.get_challenge(0x00, 0x00, b"") blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") padded = vsCrypto.append_padding(blocklen, challenge) 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): 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.external_authenticate(0x00, 0x00, result_data) - self.assertEquals(sw, SW["NORMAL"]) + self.assertEqual(sw, SW["NORMAL"]) def test_security_environment(self): hash = self.secEnv.hash(0x90, 0x80, self.password) @@ -74,7 +74,7 @@ class TestSmartcardSAM(unittest.TestCase): self.secEnv.ct.algorithm = "RSA" self.secEnv.dst.keylength = 1024 sw, pk = self.secEnv.generate_public_key_pair(0x00, 0x00, b"") - self.assertEquals(sw, SW["NORMAL"]) + self.assertEqual(sw, SW["NORMAL"]) if __name__ == "__main__":