From 25d751c91d04b586f7487d83bdb5669834b4f680 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 23 Jul 2014 22:00:51 +0200 Subject: [PATCH 1/4] Convert existing unit tests to the python unittest framework --- .../src/vpicc/virtualsmartcard/CryptoUtils.py | 35 +++++----- .../vpicc/virtualsmartcard/SmartcardSAM.py | 65 +++++++++++-------- 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py index 029d6cc..f0ccfe7 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License along with # virtualsmartcard. If not, see . # -import sys, binascii, random, logging +import sys, binascii, random, logging, unittest from Crypto.Cipher import DES3, DES, AES, ARC4#@UnusedImport from struct import pack from binascii import b2a_hex, a2b_hex @@ -605,20 +605,23 @@ def test_pbkdf2(): raise RuntimeError("self-test failed") print "PBKDF2 self test successfull" -if __name__ == "__main__": - too_short = binascii.a2b_hex("".join("89 45 19 BF".split())) - padded = append_padding(8, too_short) - print "Padded data: " + hexdump(padded) - unpadded = strip_padding(8, padded) - print "Without padding: " + hexdump(unpadded) - - teststring = "DEADBEEFistatsyksdvhwohfwoehcowc8hw8rogfq8whv75tsgohsav8wress" - foo = append_padding(16, teststring) - assert(strip_padding(16, foo) == teststring) +class TestCryptoUtils(unittest.TestCase): - testpass = "SomeRandomPassphrase" - protectedString = protect_string(teststring, testpass) - unprotectedString = read_protected_string(protectedString, testpass) - assert(teststring == unprotectedString) - + def setUp(self): + self.teststring = "DEADBEEFistatsyksdvhwohfwoehcowc8hw8rogfq8whv75tsgohsav8wress" + self.testpass = "SomeRandomPassphrase" + + def test_padding(self): + padded = append_padding(16, self.teststring) + unpadded = strip_padding(16, padded) + self.assertEqual(unpadded, self.teststring) + + def test_protect_string(self): + protectedString = protect_string(self.teststring, self.testpass) + unprotectedString = read_protected_string(protectedString, self.testpass) + self.assertEqual(self.teststring, unprotectedString) + + +if __name__ == "__main__": + unittest.main() #test_pbkdf2() diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py index 59048b2..88837de 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py @@ -17,7 +17,7 @@ # virtualsmartcard. If not, see . # -import logging +import logging, unittest from pickle import dumps, loads from os import urandom @@ -357,32 +357,45 @@ class SAM(object): return self.current_SE.manage_security_environment(p1, p2, data) #Unit Tests +class TestSmartcardSAM(unittest.TestCase): + + def setUp(self): + self.password = "DUMMYKEYDUMMYKEY" + self.myCard = SAM("1234", "1234567890") + + def test_incorrect_pin(self): + with self.assertRaises(SwError): + self.myCard.verify(0x00, 0x00, "5678") + + def test_counter_decrement(self): + ctr1 = self.myCard.counter + try: + self.myCard.verify(0x00, 0x00, "3456") + except SwError as e: + pass + self.assertEquals(self.myCard.counter, ctr1 - 1) + + def test_internal_authenticate(self): + sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") + print("Before encryption: " + challenge) + blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") + padded = vsCrypto.append_padding(blocklen, challenge) + sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) + print("Internal Authenticate status code: %x" % sw) + self.assertEquals(sw, SW["NORMAL"]) + + def test_external_authenticate(self): + sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") + print("Before encryption: " + challenge) + blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") + padded = vsCrypto.append_padding(blocklen, challenge) + sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) + sw, result_data = self.myCard.external_authenticate(0x00, 0x00, result_data) + print ("After external authenticate: " + result_data) + self.assertEquals(sw, SW["NORMAL"]) + if __name__ == "__main__": - - password = "DUMMYKEYDUMMYKEY" - - MyCard = SAM("1234", "1234567890") - try: - print(MyCard.verify(0x00, 0x00, "5678")) - except SwError as e: - print(e.message) - - print("Counter = " + str(MyCard.counter)) - print(MyCard.verify(0x00, 0x00, "1234")) - print("Counter = " + str(MyCard.counter)) - sw, challenge = MyCard.get_challenge(0x00, 0x00, "") - print("Before encryption: " + challenge) - blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") - padded = vsCrypto.append_padding(blocklen, challenge) - sw, result_data = MyCard.internal_authenticate(0x00, 0x00, padded) - print("Internal Authenticate status code: %x" % sw) - - try: - sw, res = MyCard.external_authenticate(0x00, 0x00, result_data) - except SwError as e: - print(e.message) - sw = e.sw - print("Decryption Status code: %x" % sw) + unittest.main() #SE = Security_Environment(None) #testvektor = "foobar" From 2053648dd0ce56e29cfe4b70cdd38cee08d7cf47 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 23 Jul 2014 22:02:56 +0200 Subject: [PATCH 2/4] Bump the year in the header --- virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py | 2 +- virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py index f0ccfe7..e7ee3e7 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py @@ -1,5 +1,5 @@ # -# Copyright (C) 2011 Dominik Oepen +# Copyright (C) 2014 Dominik Oepen # # This file is part of virtualsmartcard. # diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py index 88837de..d0e171f 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py @@ -1,5 +1,5 @@ # -# Copyright (C) 2011 Dominik Oepen +# Copyright (C) 2014 Dominik Oepen # # This file is part of virtualsmartcard. # From f4e013f3a0a1fa18996f767908cb739cb1f0d66c Mon Sep 17 00:00:00 2001 From: Dominik Date: Thu, 24 Jul 2014 20:46:59 +0200 Subject: [PATCH 3/4] Moved unit tests to a subpackage --- .../src/vpicc/virtualsmartcard/CryptoUtils.py | 23 +------ .../vpicc/virtualsmartcard/SmartcardSAM.py | 60 +------------------ .../tests/CryptoUtils_test.py | 23 +++++++ .../tests/SmartcardSAM_test.py | 60 +++++++++++++++++++ .../vpicc/virtualsmartcard/tests/__init__.py | 0 5 files changed, 85 insertions(+), 81 deletions(-) create mode 100644 virtualsmartcard/src/vpicc/virtualsmartcard/tests/CryptoUtils_test.py create mode 100644 virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py create mode 100644 virtualsmartcard/src/vpicc/virtualsmartcard/tests/__init__.py diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py index e7ee3e7..5b3138e 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CryptoUtils.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License along with # virtualsmartcard. If not, see . # -import sys, binascii, random, logging, unittest +import sys, binascii, random, logging from Crypto.Cipher import DES3, DES, AES, ARC4#@UnusedImport from struct import pack from binascii import b2a_hex, a2b_hex @@ -604,24 +604,3 @@ def test_pbkdf2(): if result != expected: raise RuntimeError("self-test failed") print "PBKDF2 self test successfull" - -class TestCryptoUtils(unittest.TestCase): - - def setUp(self): - self.teststring = "DEADBEEFistatsyksdvhwohfwoehcowc8hw8rogfq8whv75tsgohsav8wress" - self.testpass = "SomeRandomPassphrase" - - def test_padding(self): - padded = append_padding(16, self.teststring) - unpadded = strip_padding(16, padded) - self.assertEqual(unpadded, self.teststring) - - def test_protect_string(self): - protectedString = protect_string(self.teststring, self.testpass) - unprotectedString = read_protected_string(protectedString, self.testpass) - self.assertEqual(self.teststring, unprotectedString) - - -if __name__ == "__main__": - unittest.main() - #test_pbkdf2() diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py index d0e171f..4670951 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/SmartcardSAM.py @@ -17,7 +17,7 @@ # virtualsmartcard. If not, see . # -import logging, unittest +import logging from pickle import dumps, loads from os import urandom @@ -355,62 +355,4 @@ class SAM(object): def manage_security_environment(self, p1, p2, data): return self.current_SE.manage_security_environment(p1, p2, data) - -#Unit Tests -class TestSmartcardSAM(unittest.TestCase): - def setUp(self): - self.password = "DUMMYKEYDUMMYKEY" - self.myCard = SAM("1234", "1234567890") - - def test_incorrect_pin(self): - with self.assertRaises(SwError): - self.myCard.verify(0x00, 0x00, "5678") - - def test_counter_decrement(self): - ctr1 = self.myCard.counter - try: - self.myCard.verify(0x00, 0x00, "3456") - except SwError as e: - pass - self.assertEquals(self.myCard.counter, ctr1 - 1) - - def test_internal_authenticate(self): - sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") - print("Before encryption: " + challenge) - blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") - padded = vsCrypto.append_padding(blocklen, challenge) - sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) - print("Internal Authenticate status code: %x" % sw) - self.assertEquals(sw, SW["NORMAL"]) - - def test_external_authenticate(self): - sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") - print("Before encryption: " + challenge) - blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") - padded = vsCrypto.append_padding(blocklen, challenge) - sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) - sw, result_data = self.myCard.external_authenticate(0x00, 0x00, result_data) - print ("After external authenticate: " + result_data) - self.assertEquals(sw, SW["NORMAL"]) - -if __name__ == "__main__": - unittest.main() - - #SE = Security_Environment(None) - #testvektor = "foobar" - #print "Testvektor = %s" % testvektor - #sw, hash = SE.hash(0x90,0x80,testvektor) - #print "SW after hashing = %s" % sw - #print "Hash = %s" % hash - #sw, crypted = SE.encipher(0x00, 0x00, testvektor) - #print "SW after encryption = %s" % sw - #sw, plain = SE.decipher(0x00, 0x00, crypted) - #print "SW after encryption = %s" % sw - #print "Testvektor after en- and deciphering: %s" % plain - #sw, pk = SE.generate_public_key_pair(0x02, 0x00, "") - #print "SW after keygen = %s" % sw - #print "Public Key = %s" % pk - #CF = CryptoflexSE(None) - #print CF.generate_public_key_pair(0x00, 0x80, "\x01\x00\x01\x00") - #print MyCard._get_referenced_key(0x01) diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/tests/CryptoUtils_test.py b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/CryptoUtils_test.py new file mode 100644 index 0000000..05acf1b --- /dev/null +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/CryptoUtils_test.py @@ -0,0 +1,23 @@ +import unittest +from virtualsmartcard.CryptoUtils import * + +class TestCryptoUtils(unittest.TestCase): + + def setUp(self): + self.teststring = "DEADBEEFistatsyksdvhwohfwoehcowc8hw8rogfq8whv75tsgohsav8wress" + self.testpass = "SomeRandomPassphrase" + + def test_padding(self): + padded = append_padding(16, self.teststring) + unpadded = strip_padding(16, padded) + self.assertEqual(unpadded, self.teststring) + + def test_protect_string(self): + protectedString = protect_string(self.teststring, self.testpass) + unprotectedString = read_protected_string(protectedString, self.testpass) + self.assertEqual(self.teststring, unprotectedString) + + +if __name__ == "__main__": + unittest.main() + #test_pbkdf2() diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py new file mode 100644 index 0000000..0f30241 --- /dev/null +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/SmartcardSAM_test.py @@ -0,0 +1,60 @@ +import unittest +from virtualsmartcard.SmartcardSAM import * + +#Unit Tests +class TestSmartcardSAM(unittest.TestCase): + + def setUp(self): + self.password = "DUMMYKEYDUMMYKEY" + self.myCard = SAM("1234", "1234567890") + + def test_incorrect_pin(self): + with self.assertRaises(SwError): + self.myCard.verify(0x00, 0x00, "5678") + + def test_counter_decrement(self): + ctr1 = self.myCard.counter + try: + self.myCard.verify(0x00, 0x00, "3456") + except SwError as e: + pass + self.assertEquals(self.myCard.counter, ctr1 - 1) + + def test_internal_authenticate(self): + sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") + print("Before encryption: " + challenge) + blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") + padded = vsCrypto.append_padding(blocklen, challenge) + sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) + print("Internal Authenticate status code: %x" % sw) + self.assertEquals(sw, SW["NORMAL"]) + + def test_external_authenticate(self): + sw, challenge = self.myCard.get_challenge(0x00, 0x00, "") + print("Before encryption: " + challenge) + blocklen = vsCrypto.get_cipher_blocklen("DES3-ECB") + padded = vsCrypto.append_padding(blocklen, challenge) + sw, result_data = self.myCard.internal_authenticate(0x00, 0x00, padded) + sw, result_data = self.myCard.external_authenticate(0x00, 0x00, result_data) + print ("After external authenticate: " + result_data) + self.assertEquals(sw, SW["NORMAL"]) + +if __name__ == "__main__": + unittest.main() + #SE = Security_Environment(None) + #testvektor = "foobar" + #print "Testvektor = %s" % testvektor + #sw, hash = SE.hash(0x90,0x80,testvektor) + #print "SW after hashing = %s" % sw + #print "Hash = %s" % hash + #sw, crypted = SE.encipher(0x00, 0x00, testvektor) + #print "SW after encryption = %s" % sw + #sw, plain = SE.decipher(0x00, 0x00, crypted) + #print "SW after encryption = %s" % sw + #print "Testvektor after en- and deciphering: %s" % plain + #sw, pk = SE.generate_public_key_pair(0x02, 0x00, "") + #print "SW after keygen = %s" % sw + #print "Public Key = %s" % pk + #CF = CryptoflexSE(None) + #print CF.generate_public_key_pair(0x00, 0x80, "\x01\x00\x01\x00") + #print MyCard._get_referenced_key(0x01) diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/tests/__init__.py b/virtualsmartcard/src/vpicc/virtualsmartcard/tests/__init__.py new file mode 100644 index 0000000..e69de29 From 9e606bb0d55db2977cf4f69a36e1e0b221dd95ff Mon Sep 17 00:00:00 2001 From: Dominik Date: Thu, 24 Jul 2014 20:53:32 +0200 Subject: [PATCH 4/4] Run vpicc unit tests from Travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b122c90..fb79b88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,8 @@ env: -PREFIX=/tmp/install script: #Build virtualsmartcard - - cd virtualsmartcard && autoreconf -vsi && ./configure && make && cd .. + - cd virtualsmartcard && autoreconf -vsi && ./configure && make + - cd src/vpicc/ && export PYTHONPATH=$PYTHONPATH:`pwd` && python -m unittest discover -s virtualsmartcard.tests -p *_test.py -v && cd $TRAVIS_BUILD_DIR # Build pcsc-relay, which requires libnfc - cd /tmp && git clone https://code.google.com/p/libnfc && cd libnfc && autoreconf -i && ./configure --prefix=$PREFIX && make install && cd $TRAVIS_BUILD_DIR - cd pcsc-relay && autoreconf -vsi && ./configure && make && cd ..