def test_06_wrong_password(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) with pkcs11.simulate_failure(pkcs11.mock.openSession, 1): with self.assertRaises(PyKCS11Error): hsm.setup_module({ "password": "******" }) self.assertFalse(hsm.is_ready) hsm.setup_module({ "password": "******" }) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock)
def test_03_retry(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({"password": "******"}) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) # session is opened once self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)]) # simulate that encryption succeeds after five tries password = "******" * 16 with pkcs11.simulate_failure(pkcs11.session_mock.encrypt, 5): encrypted = hsm.encrypt_password(password) # the session has been opened initially, and five times after that self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 6) # simulate that decryption succeeds after five tries with pkcs11.simulate_failure(pkcs11.session_mock.decrypt, 5): self.assertEqual(hsm.decrypt_password(encrypted), password) # the session has been opened initially, five times during encryption, and five times now self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 11) # simulate that random generation succeeds after five tries with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 5): self.assertEqual(hsm.random(4), b"\x00\x01\x02\x03") self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 16)
def test_02_basic(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) self.assertFalse(hsm.is_ready) self.assertEqual(pkcs11.mock.openSession.call_count, 0) hsm.setup_module({"password": "******"}) self.assertTrue(hsm.is_ready) self.assertEqual(pkcs11.mock.openSession.call_count, 1) self.assertIs(hsm.session, pkcs11.session_mock) # mock just returns \x00\x01... for random values self.assertEqual(hsm.random(4), b"\x00\x01\x02\x03") pkcs11.session_mock.generateRandom.assert_called_once_with(4) password = "******" * 16 crypted = hsm.encrypt_password(password) # to generate the IV pkcs11.session_mock.generateRandom.assert_called_with(16) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) self.assertEqual(pkcs11.session_mock.encrypt.call_count, 1) self.assertEqual(pkcs11.session_mock.encrypt.call_count, 1) # during the whole usage, we have only used one session self.assertEqual(pkcs11.mock.openSession.call_count, 1)
def test_01_instantiate(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", "password": "******" }) self.assertIsNotNone(hsm) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) self.assertEqual(pkcs11.mock.openSession.call_count, 1)
def test_03_retry(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({ "password": "******" }) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) # session is opened once self.assertEqual(pkcs11.mock.openSession.mock_calls, [ call(slot=1) ]) # simulate that encryption succeeds after five tries password = "******" * 16 with pkcs11.simulate_failure(pkcs11.session_mock.encrypt, 5): encrypted = hsm.encrypt_password(password) # the session has been opened initially, and five times after that self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 6) # simulate that decryption succeeds after five tries with pkcs11.simulate_failure(pkcs11.session_mock.decrypt, 5): self.assertEqual(hsm.decrypt_password(encrypted), password) # the session has been opened initially, five times during encryption, and five times now self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 11) # simulate that random generation succeeds after five tries with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 5): self.assertEqual(hsm.random(4), b"\x00\x01\x02\x03") self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 16)
def test_02_basic(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) self.assertFalse(hsm.is_ready) self.assertEqual(pkcs11.mock.openSession.call_count, 0) hsm.setup_module({ "password": "******" }) self.assertTrue(hsm.is_ready) self.assertEqual(pkcs11.mock.openSession.call_count, 1) self.assertIs(hsm.session, pkcs11.session_mock) # mock just returns \x00\x01... for random values self.assertEqual(hsm.random(4), b"\x00\x01\x02\x03") pkcs11.session_mock.generateRandom.assert_called_once_with(4) password = "******" * 16 crypted = hsm.encrypt_password(password) # to generate the IV pkcs11.session_mock.generateRandom.assert_called_with(16) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) self.assertEqual(pkcs11.session_mock.encrypt.call_count, 1) self.assertEqual(pkcs11.session_mock.encrypt.call_count, 1) # during the whole usage, we have only used one session self.assertEqual(pkcs11.mock.openSession.call_count, 1)
def test_05_hsm_recovery(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({"password": "******"}) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)]) # encryption+decryption succeeds once password = "******" * 16 crypted = hsm.encrypt_password(password) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) # simulate that the HSM disappears after that, so we cannot # even open a session with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 1), \ pkcs11.simulate_failure(pkcs11.mock.openSession, 1): with self.assertRaises(PyKCS11Error): hsm.encrypt_password(password) self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 2) # the Security Module is in a defunct state now # but we can recover from it! # simulate one failure, because this will make the security module # acquire a new session with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 1): crypted = hsm.encrypt_password(password) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 3)
def test_04_fail_encrypt(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({ "password": "******" }) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) # session is opened once self.assertEqual(pkcs11.mock.openSession.mock_calls, [ call(slot=1) ]) # simulate that encryption still fails after five tries password = "******" * 16 with pkcs11.simulate_failure(pkcs11.session_mock.encrypt, 6): with self.assertRaises(HSMException): hsm.encrypt_password(password) # the session has been opened initially, and six times after that self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 7)
def test_06_wrong_password(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) with pkcs11.simulate_failure(pkcs11.mock.openSession, 1): with self.assertRaises(PyKCS11Error): hsm.setup_module({"password": "******"}) self.assertFalse(hsm.is_ready) hsm.setup_module({"password": "******"}) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock)
def test_05_hsm_recovery(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({ "password": "******" }) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) self.assertEqual(pkcs11.mock.openSession.mock_calls, [ call(slot=1) ]) # encryption+decryption succeeds once password = "******" * 16 crypted = hsm.encrypt_password(password) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) # simulate that the HSM disappears after that, so we cannot # even open a session with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 1), \ pkcs11.simulate_failure(pkcs11.mock.openSession, 1): with self.assertRaises(PyKCS11Error): hsm.encrypt_password(password) self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 2) # the Security Module is in a defunct state now # but we can recover from it! # simulate one failure, because this will make the security module # acquire a new session with pkcs11.simulate_failure(pkcs11.session_mock.generateRandom, 1): crypted = hsm.encrypt_password(password) text = hsm.decrypt_password(crypted) self.assertEqual(text, password) self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 3)
def test_04_fail_encrypt(self): with PKCS11Mock() as pkcs11: hsm = AESHardwareSecurityModule({ "module": "testmodule", }) hsm.setup_module({"password": "******"}) self.assertTrue(hsm.is_ready) self.assertIs(hsm.session, pkcs11.session_mock) # session is opened once self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)]) # simulate that encryption still fails after five tries password = "******" * 16 with pkcs11.simulate_failure(pkcs11.session_mock.encrypt, 6): with self.assertRaises(HSMException): hsm.encrypt_password(password) # the session has been opened initially, and six times after that self.assertEqual(pkcs11.mock.openSession.mock_calls, [call(slot=1)] * 7)