Merge pull request #19 from d0/master
Convert most of the remaining tests to unit tests
This commit is contained in:
@@ -513,10 +513,6 @@ def crypt(word, salt=None, iterations=None):
|
||||
rawhash = PBKDF2(word, salt, iterations).read(24)
|
||||
# return salt + "$" + b64encode(rawhash, "./") DO: Original return line
|
||||
return salt + "$" + rawhash
|
||||
# Add crypt as a static method of the PBKDF2 class
|
||||
# This makes it easier to do "from PBKDF2 import PBKDF2" and still use
|
||||
# crypt.
|
||||
PBKDF2.crypt = staticmethod(crypt)
|
||||
|
||||
def _makesalt():
|
||||
"""Return a 48-bit pseudorandom salt for crypt().
|
||||
@@ -525,82 +521,3 @@ def _makesalt():
|
||||
"""
|
||||
binarysalt = "".join([pack("@H", randint(0, 0xffff)) for i in range(3)])
|
||||
return b64encode(binarysalt, "./")
|
||||
|
||||
def test_pbkdf2():
|
||||
"""Module self-test"""
|
||||
|
||||
#
|
||||
# Test vectors from RFC 3962
|
||||
#
|
||||
|
||||
# Test 1
|
||||
result = PBKDF2("password", "ATHENA.MIT.EDUraeburn", 1).read(16)
|
||||
expected = a2b_hex("cdedb5281bb2f801565a1122b2563515")
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# Test 2
|
||||
result = PBKDF2("password", "ATHENA.MIT.EDUraeburn", 1200).hexread(32)
|
||||
expected = ("5c08eb61fdf71e4e4ec3cf6ba1f5512b"
|
||||
"a7e52ddbc5e5142f708a31e2e62b1e13")
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# Test 3
|
||||
result = PBKDF2("X"*64, "pass phrase equals block size", 1200).hexread(32)
|
||||
expected = ("139c30c0966bc32ba55fdbf212530ac9"
|
||||
"c5ec59f1a452f5cc9ad940fea0598ed1")
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# Test 4
|
||||
result = PBKDF2("X"*65, "pass phrase exceeds block size", 1200).hexread(32)
|
||||
expected = ("9ccad6d468770cd51b10e6a68721be61"
|
||||
"1a8b4d282601db3b36be9246915ec82a")
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
#
|
||||
# Other test vectors
|
||||
#
|
||||
|
||||
# Chunked read
|
||||
f = PBKDF2("kickstart", "workbench", 256)
|
||||
result = f.read(17)
|
||||
result += f.read(17)
|
||||
result += f.read(1)
|
||||
result += f.read(2)
|
||||
result += f.read(3)
|
||||
expected = PBKDF2("kickstart", "workbench", 256).read(40)
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
#
|
||||
# crypt() test vectors
|
||||
#
|
||||
|
||||
# crypt 1
|
||||
result = crypt("cloadm", "exec")
|
||||
expected = '$p5k2$$exec$r1EWMCMk7Rlv3L/RNcFXviDefYa0hlql'
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# crypt 2
|
||||
result = crypt("gnu", '$p5k2$c$u9HvcT4d$.....')
|
||||
expected = '$p5k2$c$u9HvcT4d$Sd1gwSVCLZYAuqZ25piRnbBEoAesaa/g'
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# crypt 3
|
||||
result = crypt("dcl", "tUsch7fU", iterations=13)
|
||||
expected = "$p5k2$d$tUsch7fU$nqDkaxMDOFBeJsTSfABsyn.PYUXilHwL"
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
|
||||
# crypt 4 (unicode)
|
||||
result = crypt(u'\u0399\u03c9\u03b1\u03bd\u03bd\u03b7\u03c2',
|
||||
'$p5k2$$KosHgqNo$9mjN8gqjt02hDoP0c2J0ABtLIwtot8cQ')
|
||||
expected = '$p5k2$$KosHgqNo$9mjN8gqjt02hDoP0c2J0ABtLIwtot8cQ'
|
||||
if result != expected:
|
||||
raise RuntimeError("self-test failed")
|
||||
print "PBKDF2 self test successfull"
|
||||
|
||||
@@ -709,7 +709,7 @@ class Security_Environment(object):
|
||||
else:
|
||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||
|
||||
result = bertlv_pack((0x7F49, len(pk), pk))
|
||||
result = bertlv_pack([[0x7F49, len(pk), pk]])
|
||||
#TODO: Internally store key pair
|
||||
|
||||
if p1 & 0x02 == 0x02:
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2014 Dominik Oepen
|
||||
#
|
||||
# This file is part of virtualsmartcard.
|
||||
#
|
||||
# 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
|
||||
# Software Foundation, either version 3 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# virtualsmartcard is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# virtualsmartcard. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import unittest
|
||||
from virtualsmartcard.CryptoUtils import *
|
||||
|
||||
@@ -20,4 +39,3 @@ class TestCryptoUtils(unittest.TestCase):
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
#test_pbkdf2()
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2014 Dominik Oepen
|
||||
#
|
||||
# This file is part of virtualsmartcard.
|
||||
#
|
||||
# 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
|
||||
# Software Foundation, either version 3 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# virtualsmartcard is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# virtualsmartcard. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import unittest
|
||||
from virtualsmartcard.SmartcardSAM import *
|
||||
|
||||
@@ -7,6 +26,9 @@ class TestSmartcardSAM(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.password = "DUMMYKEYDUMMYKEY"
|
||||
self.myCard = SAM("1234", "1234567890")
|
||||
self.secEnv = Security_Environment(None, self.myCard) #TODO: Set CRTs
|
||||
self.secEnv.ht.algorithm = "SHA"
|
||||
self.secEnv.ct.algorithm = "AES-CBC"
|
||||
|
||||
def test_incorrect_pin(self):
|
||||
with self.assertRaises(SwError):
|
||||
@@ -39,22 +61,32 @@ class TestSmartcardSAM(unittest.TestCase):
|
||||
print ("After external authenticate: " + result_data)
|
||||
self.assertEquals(sw, SW["NORMAL"])
|
||||
|
||||
def test_security_environment(self):
|
||||
print "Testvektor = %s" % self.password
|
||||
hash = self.secEnv.hash(0x90, 0x80, self.password)
|
||||
#The API should be changed so that the hash function returns SW_NORMAL
|
||||
#print "SW after hashing = %s" % sw
|
||||
print "Hash = %s" % hash
|
||||
self.secEnv.ct.key = hash[:16]
|
||||
crypted = self.secEnv.encipher(0x00, 0x00, self.password)
|
||||
#The API should be changed so that the encipher function returns SW_NORMAL
|
||||
#print "SW after encryption = %s" % sw
|
||||
plain = self.secEnv.decipher(0x00, 0x00, crypted)
|
||||
#The API should be changed so that the decipher function returns SW_NORMAL
|
||||
#print "SW after decryption = %s" % sw
|
||||
print "Testvektor after en- and deciphering: %s" % plain
|
||||
#self.assertEqual(plain, self.password)
|
||||
#secEnv.decipher doesn't strip padding. Should it?
|
||||
self.secEnv.ct.algorithm = "RSA" #should this really be secEnv.ct? probably rather secEnv.dst
|
||||
self.secEnv.dst.keylength = 1024
|
||||
sw, pk = self.secEnv.generate_public_key_pair(0x00, 0x00, "")
|
||||
#print "SW after keygen = %s" % swerror
|
||||
#print "Public Key = %s" % pk
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# Copyright (C) 2014 Dominik Oepen
|
||||
#
|
||||
# This file is part of virtualsmartcard.
|
||||
#
|
||||
# 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
|
||||
# Software Foundation, either version 3 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# virtualsmartcard is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# virtualsmartcard. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
import unittest
|
||||
from virtualsmartcard.utils import C_APDU, R_APDU, hexdump
|
||||
|
||||
class TestUtils(unittest.TestCase):
|
||||
|
||||
def test_CAPDU(self):
|
||||
a = C_APDU(1, 2, 3, 4) # case 1
|
||||
b = C_APDU(1, 2, 3, 4, 5) # case 2
|
||||
c = C_APDU((1, 2, 3), cla = 0x23, data = "hallo") # case 3
|
||||
d = C_APDU(1, 2, 3, 4, 2, 4, 6, 0) # case 4
|
||||
|
||||
print()
|
||||
print(a)
|
||||
print(b)
|
||||
print(c)
|
||||
print(d)
|
||||
print()
|
||||
print(repr(a))
|
||||
print(repr(b))
|
||||
print(repr(c))
|
||||
print(repr(d))
|
||||
|
||||
print()
|
||||
for i in a, b, c, d:
|
||||
print(hexdump(i.render()))
|
||||
|
||||
print()
|
||||
g = C_APDU(0x00, 0xb0, 0x9c, 0x00, 0x00, 0x00, 0x00) #case 2 extended length
|
||||
|
||||
print()
|
||||
print(g)
|
||||
print(repr(g))
|
||||
print(hexdump(g.render()))
|
||||
|
||||
h = C_APDU('\x0c\x2a\x00\xbe\x00\x01\x5f\x87\x82\x01\x51\x01\xf0\xa2\x21\xa1\x36\x27\xb1\x30\x31\x3e\xd0\x97\x09\xb5\xde\x73\x5e\x29\x90\xce\xf1\x3d\x8a\xfd\xe7\x92\xe5\xa4\x70\xb9\x5d\x31\xe2\x34\xe7\xe2\x06\x13\x17\x7a\x3e\xca\x06\x39\x24\x2e\x75\x8c\x29\x6d\xd8\xa3\x1b\x1a\x68\x58\xd0\x1a\x98\xd4\xd8\x19\x50\xe9\x1b\x3c\xd1\xfd\x10\x53\x5b\xf2\x3b\xff\x4a\xf6\x05\xd0\x72\xad\xae\xaa\x93\x1a\x0a\x90\xc8\xa1\xb1\xf1\x0a\xba\x5b\xd2\x23\x38\xf8\x9a\x38\x9e\xa2\x04\x8b\xcb\x8b\x8b\xc0\x80\xd9\x2a\x04\x47\x26\x83\xda\xfe\x57\x68\x6b\x00\xb9\xa2\xea\x96\xf2\x07\x7f\xc5\x9c\xee\xbe\xf3\x81\xbf\x24\x19\x1e\x49\x1e\x9a\x85\x8f\x34\xcb\x1a\x23\xae\x6d\x7f\xa4\xb6\x7b\x60\x5d\x56\x79\x1c\xec\x18\xcc\x09\xdb\xb2\xbb\xf4\x31\xee\x08\x54\x26\xd5\xde\x99\xfa\x43\xa2\x49\x8e\x60\xc0\xaa\x4f\xfd\xf7\xe5\xc8\x89\x43\x5e\x11\xa2\x28\xc4\x92\x11\xda\xba\xe4\x91\xec\x04\xc9\x2c\xbd\x91\x6a\x5e\x7e\xb9\x85\xa2\xfa\x07\xc9\x47\x24\xa4\x3b\x63\xef\x75\x65\xef\xaf\xac\x22\x75\x99\x8b\x19\xde\x95\x76\xc9\xc8\xbc\x30\x23\x48\x07\x28\x19\x1e\x49\x9e\xcb\x99\xc3\x48\xdd\x1d\x0f\x44\x62\x64\x2a\x19\x7b\xeb\xee\xdf\xa1\xa6\xae\x87\x6d\x93\x36\x2d\x35\x8f\xd9\x61\x73\xef\x2d\x39\xb5\xc5\xe2\x75\x4b\x63\x0b\x41\x94\x8c\xbb\x55\xf6\x98\x5f\x9c\x07\xca\xe3\x15\xe4\xe6\x93\xd0\xa3\x9b\x22\xfa\x62\x18\xc5\x63\xfa\x2d\x57\xbb\x29\x2d\x57\x10\xd3\x0c\x05\x80\x15\x27\x4b\xc0\x84\x23\x62\x22\x6b\xae\x39\xa2\x8f\x55\xac\x8e\x08\x34\x46\xcc\x83\xf9\x9d\x2a\x75\x00\x00')
|
||||
print()
|
||||
print(h)
|
||||
print(repr(h))
|
||||
|
||||
def test_RAPDU(self):
|
||||
e = R_APDU(0x90, 0)
|
||||
f = R_APDU("foo\x67\x00")
|
||||
|
||||
print()
|
||||
print(e)
|
||||
print(f)
|
||||
print()
|
||||
print(repr(e))
|
||||
print(repr(f))
|
||||
|
||||
print()
|
||||
for i in e, f:
|
||||
print(hexdump(i.render()))
|
||||
|
||||
@@ -382,50 +382,3 @@ class R_APDU(APDU):
|
||||
"Return this APDU as a binary string"
|
||||
return self.data + self.sw
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = C_APDU(1, 2, 3, 4) # case 1
|
||||
b = C_APDU(1, 2, 3, 4, 5) # case 2
|
||||
c = C_APDU((1, 2, 3), cla = 0x23, data = "hallo") # case 3
|
||||
d = C_APDU(1, 2, 3, 4, 2, 4, 6, 0) # case 4
|
||||
|
||||
print()
|
||||
print(a)
|
||||
print(b)
|
||||
print(c)
|
||||
print(d)
|
||||
print()
|
||||
print(repr(a))
|
||||
print(repr(b))
|
||||
print(repr(c))
|
||||
print(repr(d))
|
||||
|
||||
print()
|
||||
for i in a, b, c, d:
|
||||
print(hexdump(i.render()))
|
||||
|
||||
print()
|
||||
e = R_APDU(0x90, 0)
|
||||
f = R_APDU("foo\x67\x00")
|
||||
|
||||
print()
|
||||
print(e)
|
||||
print(f)
|
||||
print()
|
||||
print(repr(e))
|
||||
print(repr(f))
|
||||
|
||||
print()
|
||||
for i in e, f:
|
||||
print(hexdump(i.render()))
|
||||
|
||||
g = C_APDU(0x00, 0xb0, 0x9c, 0x00, 0x00, 0x00, 0x00) #case 2 extended length
|
||||
|
||||
print()
|
||||
print(g)
|
||||
print(repr(g))
|
||||
print(hexdump(g.render()))
|
||||
|
||||
h = C_APDU('\x0c\x2a\x00\xbe\x00\x01\x5f\x87\x82\x01\x51\x01\xf0\xa2\x21\xa1\x36\x27\xb1\x30\x31\x3e\xd0\x97\x09\xb5\xde\x73\x5e\x29\x90\xce\xf1\x3d\x8a\xfd\xe7\x92\xe5\xa4\x70\xb9\x5d\x31\xe2\x34\xe7\xe2\x06\x13\x17\x7a\x3e\xca\x06\x39\x24\x2e\x75\x8c\x29\x6d\xd8\xa3\x1b\x1a\x68\x58\xd0\x1a\x98\xd4\xd8\x19\x50\xe9\x1b\x3c\xd1\xfd\x10\x53\x5b\xf2\x3b\xff\x4a\xf6\x05\xd0\x72\xad\xae\xaa\x93\x1a\x0a\x90\xc8\xa1\xb1\xf1\x0a\xba\x5b\xd2\x23\x38\xf8\x9a\x38\x9e\xa2\x04\x8b\xcb\x8b\x8b\xc0\x80\xd9\x2a\x04\x47\x26\x83\xda\xfe\x57\x68\x6b\x00\xb9\xa2\xea\x96\xf2\x07\x7f\xc5\x9c\xee\xbe\xf3\x81\xbf\x24\x19\x1e\x49\x1e\x9a\x85\x8f\x34\xcb\x1a\x23\xae\x6d\x7f\xa4\xb6\x7b\x60\x5d\x56\x79\x1c\xec\x18\xcc\x09\xdb\xb2\xbb\xf4\x31\xee\x08\x54\x26\xd5\xde\x99\xfa\x43\xa2\x49\x8e\x60\xc0\xaa\x4f\xfd\xf7\xe5\xc8\x89\x43\x5e\x11\xa2\x28\xc4\x92\x11\xda\xba\xe4\x91\xec\x04\xc9\x2c\xbd\x91\x6a\x5e\x7e\xb9\x85\xa2\xfa\x07\xc9\x47\x24\xa4\x3b\x63\xef\x75\x65\xef\xaf\xac\x22\x75\x99\x8b\x19\xde\x95\x76\xc9\xc8\xbc\x30\x23\x48\x07\x28\x19\x1e\x49\x9e\xcb\x99\xc3\x48\xdd\x1d\x0f\x44\x62\x64\x2a\x19\x7b\xeb\xee\xdf\xa1\xa6\xae\x87\x6d\x93\x36\x2d\x35\x8f\xd9\x61\x73\xef\x2d\x39\xb5\xc5\xe2\x75\x4b\x63\x0b\x41\x94\x8c\xbb\x55\xf6\x98\x5f\x9c\x07\xca\xe3\x15\xe4\xe6\x93\xd0\xa3\x9b\x22\xfa\x62\x18\xc5\x63\xfa\x2d\x57\xbb\x29\x2d\x57\x10\xd3\x0c\x05\x80\x15\x27\x4b\xc0\x84\x23\x62\x22\x6b\xae\x39\xa2\x8f\x55\xac\x8e\x08\x34\x46\xcc\x83\xf9\x9d\x2a\x75\x00\x00')
|
||||
print()
|
||||
print(h)
|
||||
print(repr(h))
|
||||
|
||||
Reference in New Issue
Block a user