def test_26_is_previous_otp(self): # check if the OTP was used prebiously serial = "previous" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.set_otpkey(self.otpkey) token.set_otplen(6) token.save() """ Truncated Count Hexadecimal Decimal HOTP 0 4c93cf18 1284755224 755224 1 41397eea 1094287082 287082 2 82fef30 137359152 359152 3 66ef7655 1726969429 969429 4 61c5938a 1640338314 338314 5 33c083d4 868254676 254676 6 7256c032 1918287922 287922 7 4e5b397 82162583 162583 8 2823443f 673399871 399871 9 2679dc69 645520489 520489 10 403154 """ r = token.check_otp("969429") self.assertEqual(r, 3) r = token.is_previous_otp("755224") self.assertEqual(r, True) r = token.is_previous_otp("254676") self.assertEqual(r, False) r = token.check_otp("254676") self.assertEqual(r, 5)
def test_04_failure(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({ "otpkey": hexlify(b"X" * 248).decode("utf-8"), "pin": self.otppin }) r = token.authenticate("{}123456".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"Y" * 224) # wrong PIN, the token secret has not been updated r = token.authenticate("WRONG123456".format(self.otppin)) self.assertEqual(r[0], False) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"Y" * 224) # another failure, but the token secret has been updated again! r = token.authenticate("{}234567".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"Z" * 224) token.delete_token()
def test_04_failure(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X"*248), "pin": self.otppin}) r = token.authenticate("{}123456".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Y"*224) # wrong PIN, the token secret has not been updated r = token.authenticate("WRONG123456".format(self.otppin)) self.assertEqual(r[0], False) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Y"*224) # another failure, but the token secret has been updated again! r = token.authenticate("{}234567".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Z"*224) token.delete_token()
def test_07_failures(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X"*248), "pin": self.otppin}) @mock_verification(create_mock_failure(123)) def _step1(): return token.authenticate("{}123456".format(self.otppin)) r = _step1() self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Y"*224) @mock_verification(create_mock_failure(202)) def _step2(): return token.authenticate("{}123456".format(self.otppin)) r = _step2() self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Z"*224) token.delete_token()
def test_07_failures(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X" * 248), "pin": self.otppin}) @mock_verification(create_mock_failure(123)) def _step1(): return token.authenticate("{}123456".format(self.otppin)) r = _step1() self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, "X" * 24 + "Y" * 224) @mock_verification(create_mock_failure(202)) def _step2(): return token.authenticate("{}123456".format(self.otppin)) r = _step2() self.assertEqual(r[0], True) self.assertEqual(r[1], -1) # failure, but the token secret has been updated nonetheless key = token.token.get_otpkey().getKey() self.assertEqual(key, "X" * 24 + "Z" * 224) token.delete_token()
def test_39_generate_sym_key(self): db_token = Token("symkey", tokentype="no_matter", userid=1000) db_token.save() token_obj = TokenClass(db_token) key = token_obj.generate_symmetric_key("1234567890", "abc") self.assertEqual(key, "1234567abc") self.assertRaises(Exception, token_obj.generate_symmetric_key, "1234", "1234") self.assertRaises(Exception, token_obj.generate_symmetric_key, "1234", "12345") # Now run the init/update process # 1. step token_obj.update({"2stepinit": "1", "genkey": "1" }) self.assertEqual(db_token.rollout_state, "clientwait") self.assertEqual(db_token.active, False) serial = db_token.serial details = token_obj.init_details server_component = details.get("otpkey") # 2. step client_component = "AAAAAA" token_obj.update({"serial": serial, "otpkey": client_component }) self.assertEqual(db_token.rollout_state, "") self.assertEqual(db_token.active, True) token_obj.delete_token()
def test_01_enroll_yubikey_and_auth(self): db_token = Token(self.serial1, tokentype="yubikey") db_token.save() token = YubikeyTokenClass(db_token) token.set_otpkey(self.otpkey) token.set_otplen(48) token.set_pin(self.pin) token.save() self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "yubikey", token.token) self.assertTrue(token.type == "yubikey", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "UBAM", class_prefix) self.assertTrue(token.get_class_type() == "yubikey", token) # Test a bunch of otp values old_r = 0 for otp in self.valid_otps: r = token.check_otp(otp) # check if the newly returned counter is bigger than the old one self.assertTrue(r > old_r, (r, old_r)) old_r = r # test otp_exist r = token.check_otp_exist(self.further_otps[0]) self.assertTrue(r > old_r, (r, old_r))
def test_38_last_auth(self): db_token = Token("lastauth001", tokentype="spass", userid=1000) db_token.save() token_obj = TokenClass(db_token) tdelta = datetime.timedelta(days=1) token_obj.add_tokeninfo(ACTION.LASTAUTH, datetime.datetime.now(tzlocal()) - tdelta) r = token_obj.check_last_auth_newer("10h") self.assertFalse(r) r = token_obj.check_last_auth_newer("2d") self.assertTrue(r) # Old time format # lastauth_alt = datetime.datetime.utcnow().isoformat() token_obj.add_tokeninfo(ACTION.LASTAUTH, datetime.datetime.utcnow() - tdelta) r = token_obj.check_last_auth_newer("10h") self.assertFalse(r) r = token_obj.check_last_auth_newer("2d") self.assertTrue(r) # Test a fault last_auth entry does not computer to True token_obj.add_tokeninfo(ACTION.LASTAUTH, "faulty format") r = token_obj.check_last_auth_newer("10h") self.assertFalse(r) token_obj.delete_token()
def test_39_generate_sym_key(self): db_token = Token("symkey", tokentype="no_matter", userid=1000) db_token.save() token_obj = TokenClass(db_token) key = token_obj.generate_symmetric_key("1234567890", "abc") self.assertEqual(key, "1234567abc") self.assertRaises(Exception, token_obj.generate_symmetric_key, "1234", "1234") self.assertRaises(Exception, token_obj.generate_symmetric_key, "1234", "12345") # Now run the init/update process # 1. step token_obj.update({"2stepinit": "1", "genkey": "1"}) self.assertEqual(db_token.rollout_state, "clientwait") self.assertEqual(db_token.active, False) serial = db_token.serial details = token_obj.init_details # 2. step client_component = "AAAAAA" token_obj.update({"serial": serial, "otpkey": client_component}) self.assertEqual(db_token.rollout_state, "") self.assertEqual(db_token.active, True) # Given a client component of K bytes, the base algorithm # simply replaces the last K bytes of the server component # with the client component. server_component = details.get("otpkey")[:-len(client_component)] expected_otpkey = server_component + client_component self.assertEqual(db_token.get_otpkey().getKey(), expected_otpkey) token_obj.delete_token()
def test_26_is_previous_otp(self): # check if the OTP was used previously serial = "previous" db_token = Token(serial, tokentype="totp") db_token.save() token = TotpTokenClass(db_token) token.set_otpkey(self.otpkey) token.set_hashlib("sha1") token.set_otplen(6) # Authenticate with the current OTP value counter = token._time2counter(time.time(), timeStepping=30) otp_now = token._calc_otp(counter) r = token.check_otp(otp_now, window=180) self.assertEqual(r, counter) # Now we try several is_previous_otp and the timeShift must stay the same! ts0 = float(token.get_tokeninfo("timeShift")) self.assertTrue(-181 < ts0 < 181) # Too old r = token.is_previous_otp(token._calc_otp(counter - 3)) self.assertEqual(r, False) ts = float(token.get_tokeninfo("timeShift")) self.assertEqual(ts, ts0) # The same OTP value r = token.is_previous_otp(otp_now) self.assertEqual(r, True) ts = float(token.get_tokeninfo("timeShift")) self.assertEqual(ts, ts0) # Future value r = token.is_previous_otp(token._calc_otp(counter + 8)) self.assertEqual(r, False) ts = float(token.get_tokeninfo("timeShift")) self.assertEqual(ts, ts0)
def test_05_success(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X"*248), "pin": self.otppin}) # wrong PIN, the token secret has not been updated r = token.authenticate("WRONG123456".format(self.otppin)) self.assertEqual(r[0], False) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "X"*224) # correct PIN + OTP r = token.authenticate("{}123456".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], 0) # TODO: that is success? key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Y"*224) # another success r = token.authenticate("{}234567".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], 0) # TODO: that is success? key = token.token.get_otpkey().getKey() self.assertEqual(key, "X"*24 + "Z"*224) token.delete_token()
def test_02a_fail_request_with_attestation(self): cwd = os.getcwd() # setup ca connector r = save_caconnector({ "cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR }) db_token = Token(self.serial2, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # A cert request will fail, since the attestation certificate does not match self.assertRaises(privacyIDEAError, token.update, { "ca": "localCA", "attestation": BOGUS_ATTESTATION, "request": REQUEST }) remove_token(self.serial2)
def test_05_success(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({ "otpkey": hexlify(b"X" * 248).decode("utf-8"), "pin": self.otppin }) # wrong PIN, the token secret has not been updated r = token.authenticate("WRONG123456".format(self.otppin)) self.assertEqual(r[0], False) self.assertEqual(r[1], -1) key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"X" * 224) # correct PIN + OTP r = token.authenticate("{}123456".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], 0) # TODO: that is success? key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"Y" * 224) # another success r = token.authenticate("{}234567".format(self.otppin)) self.assertEqual(r[0], True) self.assertEqual(r[1], 0) # TODO: that is success? key = token.token.get_otpkey().getKey() self.assertEqual(key, b"X" * 24 + b"Z" * 224) token.delete_token()
def test_03_no_vasco_library(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X"*248), "pin": self.otppin}) self.assertRaises(RuntimeError, token.authenticate, "{}123456".format(self.otppin)) token.delete_token()
def test_16_add_and_delete_tokeninfo_password(self): t1 = Token("serialTI2") t1.set_info({"key1": "value1", "key1.type": "password"}) t2 = Token.query.filter_by(serial="serialTI2").first() t2info = t2.get_info() self.assertTrue(t2info.get("key1.type") == "password", t2info)
def test_03_no_vasco_library(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X" * 248), "pin": self.otppin}) self.assertRaises(RuntimeError, token.authenticate, "{}123456".format(self.otppin)) token.delete_token()
def test_31_user_is_not_allowed_for_some_api_calls(self): self.authenticate_selfserive_user() serial = "serial0001" tok = Token(serial) tok.save() # Can not set things with self.app.test_request_context( '/token/set', method="POST", data={ "serial": serial, "pin": "test" }, headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not set token realm with self.app.test_request_context( '/token/realm/{0!s}'.format(serial), method="POST", data={"realms": "realm1"}, headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not call get_serial token with self.app.test_request_context( '/token/getserial/12345', method="GET", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not copy pin with self.app.test_request_context( '/token/copypin', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not copy user with self.app.test_request_context( '/token/copyuser', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not load tokens with self.app.test_request_context( '/token/load/test.xml', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res)
def test_11_challenge_response_hotp(self): # set a chalresp policy for HOTP with self.app.test_request_context('/policy/pol_chal_resp', data={'action': "challenge_response=hotp", 'scope': "authentication", 'realm': '', 'active': True}, method='POST', headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") self.assertTrue(result["status"] is True, result) self.assertTrue('"setPolicy pol_chal_resp": 1' in res.data, res.data) serial = "CHALRESP1" pin = "chalresp1" # create a token and assign to the user db_token = Token(serial, tokentype="hotp") db_token.update_otpkey(self.otpkey) db_token.save() token = HotpTokenClass(db_token) token.set_user(User("cornelius", self.realm1)) token.set_pin(pin) # Set the failcounter token.set_failcount(5) # create the challenge by authenticating with the OTP PIN with self.app.test_request_context('/validate/check', method='POST', data={"user": "******", "pass": pin}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") detail = json.loads(res.data).get("detail") self.assertFalse(result.get("value")) self.assertEqual(detail.get("message"), "please enter otp: ") transaction_id = detail.get("transaction_id") self.assertEqual(token.get_failcount(), 5) # send the OTP value with self.app.test_request_context('/validate/check', method='POST', data={"user": "******", "transaction_id": transaction_id, "pass": "******"}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") detail = json.loads(res.data).get("detail") self.assertTrue(result.get("value")) self.assertEqual(token.get_failcount(), 0) # delete the token remove_token(serial=serial)
def test_04_create_token_on_server(self): self.setUp_user_realms() cwd = os.getcwd() # setup ca connector r = save_caconnector({"cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR}) db_token = Token(self.serial3, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # missing user self.assertRaises(ParameterError, token.update, {"ca": "localCA","genkey": 1}) token.update({"ca": "localCA", "genkey": 1, "user": "******"}) self.assertEqual(token.token.serial, self.serial3) self.assertEqual(token.token.tokentype, "certificate") self.assertEqual(token.type, "certificate") detail = token.get_init_detail() certificate = detail.get("certificate") # At each testrun, the certificate might get another serial number! x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") # Test, if the certificate is also completely stored in the tokeninfo # and if we can retrieve it from the tokeninfo token = get_tokens(serial=self.serial3)[0] certificate = token.get_tokeninfo("certificate") x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") privatekey = token.get_tokeninfo("privatekey") self.assertTrue(privatekey.startswith("-----BEGIN PRIVATE KEY-----")) # check for pkcs12 self.assertTrue(detail.get("pkcs12")) # revoke the token r = token.revoke() self.assertEqual(r, int_to_hex(x509obj.get_serial_number()))
def test_08_invalid_otpkey(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) self.assertRaises(ParameterError, token.update, {"otpkey": hexlify("X" * 250)}) # wrong length self.assertRaises(TypeError, token.update, {"otpkey": "X" * 496}) # not a hex-string token.delete_token()
def test_05_get_set_realm(self): t1 = Token(serial="serial1123") t1.save() realms = t1.get_realms() self.assertTrue(len(realms) == 0) t1.set_realms(["realm1"]) t1.save() realms = t1.get_realms() self.assertTrue(len(realms) == 1)
def setUp(self): """ For each test we need to initialize the self.at and the self.at_user members. """ self.setUp_user_realms() Token(self.my_serial, tokentype="hotp", userid="1004", resolver="resolver1", realm="realm1").save() Token(self.foreign_serial, tokentype="hotp").save()
def test_31_user_is_not_allowed_for_some_api_calls(self): self.authenticate_selfserive_user() serial = "serial0001" tok = Token(serial) tok.save() # Can not set things with self.app.test_request_context('/token/set', method="POST", data={"serial": serial, "pin": "test"}, headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not set token realm with self.app.test_request_context('/token/realm/%s' % serial, method="POST", data={"realms": "realm1"}, headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not call get_serial token with self.app.test_request_context('/token/getserial/12345', method="GET", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not copy pin with self.app.test_request_context('/token/copypin', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not copy user with self.app.test_request_context('/token/copyuser', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res) # Can not load tokens with self.app.test_request_context('/token/load/test.xml', method="POST", headers={'Authorization': self.at_user}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 401, res)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="totp") db_token.save() token = TotpTokenClass(db_token) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "totp", token.token.tokentype) self.assertTrue(token.type == "totp", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "TOTP", class_prefix) self.assertTrue(token.get_class_type() == "totp", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "hotp", token.token) self.assertTrue(token.type == "hotp", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "OATH", class_prefix) self.assertTrue(token.get_class_type() == "hotp", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="daplug") db_token.save() token = DaplugTokenClass(db_token) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "daplug", token.token.tokentype) self.assertTrue(token.type == "daplug", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "DPLG", class_prefix) self.assertTrue(token.get_class_type() == "daplug", token)
def test_02_create_token_from_request(self): cwd = os.getcwd() # setup ca connector r = save_caconnector({ "cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR }) db_token = Token(self.serial2, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # just upload a ready certificate token.update({"ca": "localCA", "request": REQUEST}) self.assertTrue(token.token.serial == self.serial2, token) self.assertTrue(token.token.tokentype == "certificate", token.token.tokentype) self.assertTrue(token.type == "certificate", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "CRT", class_prefix) self.assertTrue(token.get_class_type() == "certificate", token) detail = token.get_init_detail() certificate = detail.get("certificate") # At each testrun, the certificate might get another serial number! x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual( "{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual( "{0!r}".format(x509obj.get_subject()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=requester.localdomain'>") # Test, if the certificate is also completely stored in the tokeninfo # and if we can retrieve it from the tokeninfo token = get_tokens(serial=self.serial2)[0] certificate = token.get_tokeninfo("certificate") x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual( "{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual( "{0!r}".format(x509obj.get_subject()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=requester.localdomain'>") remove_token(self.serial2)
def test_30_2step_otpkeyformat(self): serial = "2step3" db_token = Token(serial, tokentype="hotp") db_token.save() token = HotpTokenClass(db_token) token.update({ "2stepinit": "1", "2step_clientsize": "12", "hashlib": "sha512", }) self.assertEqual(token.token.rollout_state, "clientwait") self.assertEqual(token.get_tokeninfo("2step_clientsize"), "12") # fetch the server component for later tests server_component = binascii.unhexlify( token.token.get_otpkey().getKey()) # generate a 12-byte client component client_component = b'abcdefghijkl' checksum = hashlib.sha1(client_component).digest()[:4] # wrong checksum with warnings.catch_warnings(): warnings.simplefilter('ignore', category=DeprecationWarning) self.assertRaisesRegexp( ParameterError, "Incorrect checksum", token.update, { "otpkey": b32encode_and_unicode(b"\x37" + checksum[1:] + client_component).strip("="), "otpkeyformat": "base32check", }) # construct a secret token.update({ "otpkey": b32encode_and_unicode(checksum + client_component).strip("="), "otpkeyformat": "base32check", # the following values are ignored "2step_serversize": "23", "2step_difficulty": "666666", "2step_clientsize": "13" }) # check the generated secret secret = binascii.unhexlify(token.token.get_otpkey().getKey()) # check the correct lengths self.assertEqual(len(server_component), 64) # because of SHA-512 self.assertEqual(len(client_component), 12) self.assertEqual(len(secret), 64) # because of SHA-512 # check the secret has been generated according to the specification expected_secret = pbkdf2_hmac('sha1', binascii.hexlify(server_component), client_component, 10000, len(secret)) self.assertEqual(secret, expected_secret) self.assertTrue(token.token.active)
def test_01_create_token(self): db_token = Token(self.serial3, tokentype="radius") db_token.save() token = RadiusTokenClass(db_token) # Missing radius.user parameter self.assertRaises(ParameterError, token.update, self.params3) db_token = Token(self.serial2, tokentype="radius") db_token.save() token = RadiusTokenClass(db_token) token.update(self.params2) token.set_pin(self.otppin) db_token = Token(self.serial1, tokentype="radius") db_token.save() token = RadiusTokenClass(db_token) token.update(self.params1) token.set_pin(self.otppin) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "radius", token.token.tokentype) self.assertTrue(token.type == "radius", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PIRA", class_prefix) self.assertTrue(token.get_class_type() == "radius", token)
def test_01_create_token(self): db_token = Token(self.serial3, tokentype="remote") db_token.save() token = RemoteTokenClass(db_token) token.update(self.params3) token.set_pin(self.otppin) db_token = Token(self.serial2, tokentype="remote") db_token.save() token = RemoteTokenClass(db_token) token.update(self.params2) token.set_pin(self.otppin) db_token = Token(self.serial1, tokentype="remote") db_token.save() token = RemoteTokenClass(db_token) token.update(self.params1) token.set_pin(self.otppin) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "remote", token.token.tokentype) self.assertTrue(token.type == "remote", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PIRE", class_prefix) self.assertTrue(token.get_class_type() == "remote", token)
def test_08_invalid_otpkey(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) self.assertRaises(ParameterError, token.update, {"otpkey": hexlify("X"*250)}) # wrong length self.assertRaises(TypeError, token.update, {"otpkey": "X"*496}) # not a hex-string token.delete_token()
def test_04_create_token_on_server(self): self.setUp_user_realms() cwd = os.getcwd() # setup ca connector r = save_caconnector({"cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR}) db_token = Token(self.serial3, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # missing user self.assertRaises(ParameterError, token.update, {"ca": "localCA","genkey": 1}) token.update({"ca": "localCA", "genkey": 1, "user": "******"}) self.assertEqual(token.token.serial, self.serial3) self.assertEqual(token.token.tokentype, "certificate") self.assertEqual(token.type, "certificate") detail = token.get_init_detail() certificate = detail.get("certificate") # At each testrun, the certificate might get another serial number! x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") # Test, if the certificate is also completely stored in the tokeninfo # and if we can retrieve it from the tokeninfo token = get_tokens(serial=self.serial3)[0] certificate = token.get_tokeninfo("certificate") x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") privatekey = token.get_tokeninfo("privatekey") self.assertTrue(privatekey.startswith("-----BEGIN PRIVATE KEY-----")) # check for pkcs12 self.assertTrue(detail.get("pkcs12"))
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="spass") db_token.save() token = SpassTokenClass(db_token) token.update({}) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "spass", token.token.tokentype) self.assertTrue(token.type == "spass", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PISP", class_prefix) self.assertTrue(token.get_class_type() == "spass", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="pw") db_token.save() token = PasswordTokenClass(db_token) token.update({"otpkey": self.password}) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "pw", token.token.tokentype) self.assertTrue(token.type == "pw", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PW", class_prefix) self.assertTrue(token.get_class_type() == "pw", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="paper") db_token.save() token = PaperTokenClass(db_token) token.update({}) self.assertEqual(token.token.serial, self.serial1) self.assertEqual(token.token.tokentype, "paper") self.assertEqual(token.type, "paper") class_prefix = token.get_class_prefix() self.assertEqual(class_prefix, "PPR") self.assertEqual(token.get_class_type(), "paper")
def test_00_create_realms(self): self.setUp_user_realms() # create a token and assign it to the user db_token = Token(self.serials[0], tokentype="hotp") db_token.update_otpkey(self.otpkey) db_token.save() token = HotpTokenClass(db_token) self.assertTrue(token.token.serial == self.serials[0], token) token.set_user(User("cornelius", self.realm1)) token.set_pin("pin") self.assertTrue(token.token.user_id == "1000", token.token.user_id)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="sms") db_token.save() token = SmsTokenClass(db_token) token.update({"phone": self.phone1}) token.save() self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "sms", token.token) self.assertTrue(token.type == "sms", token.type) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PISM", class_prefix) self.assertTrue(token.get_class_type() == "sms", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({"otpkey": hexlify("X" * 248), "pin": self.otppin}) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "vasco", token.token.tokentype) self.assertTrue(token.type == "vasco", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "VASC", class_prefix) self.assertTrue(token.get_class_type() == "vasco", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="registration") db_token.save() token = RegistrationTokenClass(db_token) token.update({}) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "registration", token.token.tokentype) self.assertTrue(token.type == "registration", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "REG", class_prefix) self.assertTrue(token.get_class_type() == "registration", token)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="email") db_token.save() token = EmailTokenClass(db_token) token.update({"email": self.email}) token.save() self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "email", token.token) self.assertTrue(token.type == "email", token.type) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PIEM", class_prefix) self.assertTrue(token.get_class_type() == "email", token)
def test_09_failcount(self): db_token = Token(self.serial2, tokentype="vasco") db_token.save() token = VascoTokenClass(db_token) token.update({ "otpkey": hexlify(b"A" * 248).decode("utf-8"), "pin": self.otppin }) @mock_verification(create_mock_failure(1)) def _step1(): # correct PIN, wrong OTP return check_serial_pass(self.serial2, "{}123456".format(self.otppin)) self.assertTrue(token.check_failcount()) # fail 10 times for _ in range(10 + 1): r = _step1() self.assertEqual(r[0], False) self.assertEqual(r[1].get('message'), 'wrong otp value') key = token.token.get_otpkey().getKey() self.assertEqual(key, b"A" * 24 + b"L" * 224) # fail counter has been exceeded self.assertFalse(token.check_failcount()) @mock_verification(mock_success) def _step2(): # correct PIN, wrong OTP return check_serial_pass(self.serial2, "{}123456".format(self.otppin)) # subsequent authentication attempt fails due to fail counter r = _step2() self.assertEqual(r[0], False) self.assertEqual(r[1].get('message'), 'matching 1 tokens, Failcounter exceeded') # this actually does update the OTP key key = token.token.get_otpkey().getKey() self.assertEqual(key, b"A" * 24 + b"M" * 224) # reset the failcounter token.reset() # now, authentication works again r = _step2() self.assertEqual(r[0], True) self.assertEqual(r[1].get('message'), 'matching 1 tokens') key = token.token.get_otpkey().getKey() self.assertEqual(key, b"A" * 24 + b"N" * 224) token.delete_token()
def test_03_enroll_genkey(self): db_token = Token(self.serial2, tokentype="motp") db_token.save() token = MotpTokenClass(db_token) token.update({"genkey": "1", "motppin": self.motppin, "pin": self.otppin}) db_token = Token.query.filter(Token.serial == self.serial2).first() token = MotpTokenClass(db_token) # check that the userpin is set self.assertTrue(token.token.user_pin, token.token.user_pin) # check that the otp value is set self.assertTrue(token.token.key_enc, token.token.key_enc)
def test_01_create_token(self): db_token = Token(self.serial1, tokentype="motp") db_token.save() token = MotpTokenClass(db_token) token.update({"otpkey": "909a4d4ba980b2c6", "motppin": self.motppin, "pin": self.otppin}) self.assertTrue(token.token.serial == self.serial1, token) self.assertTrue(token.token.tokentype == "motp", token.token.tokentype) self.assertTrue(token.type == "motp", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "PIMO", class_prefix) self.assertTrue(token.get_class_type() == "motp", token)
def test_02_get_tokens(self): # get All tokens tokenobject_list = get_tokens() # Check if these are valid tokentypes self.assertTrue(len(tokenobject_list) > 0, tokenobject_list) for token_object in tokenobject_list: self.assertTrue(token_object.type in get_token_types(), token_object.type) # get assigned tokens tokenobject_list = get_tokens(assigned=True) self.assertTrue(len(tokenobject_list) == 0, tokenobject_list) # get unassigned tokens tokenobject_list = get_tokens(assigned=False) self.assertTrue(len(tokenobject_list) > 0, tokenobject_list) # pass the wrong parameter # This will ignore the filter! tokenobject_list = get_tokens(assigned="True") self.assertTrue(len(tokenobject_list) > 0, tokenobject_list) # get tokens of type HOTP tokenobject_list = get_tokens(tokentype="hotp") self.assertTrue(len(tokenobject_list) == 0, tokenobject_list) # get tokens of type TOTP tokenobject_list = get_tokens(tokentype="totp") self.assertTrue(len(tokenobject_list) > 0, tokenobject_list) # Search for tokens in realm db_token = Token("hotptoken", tokentype="hotp", userid=1000, resolver=self.resolvername1, realm=self.realm1) db_token.update_otpkey(self.otpkey) db_token.save() tokenobject_list = get_tokens(realm=self.realm1) self.assertTrue(len(tokenobject_list) == 1, tokenobject_list) self.assertTrue(tokenobject_list[0].type == "hotp", tokenobject_list[0].type) # get tokens for a given serial number tokenobject_list = get_tokens(serial="hotptoken") self.assertTrue(len(tokenobject_list) == 1, tokenobject_list) # ...but not in an unassigned state! tokenobject_list = get_tokens(serial="hotptoken", assigned=False) self.assertTrue(len(tokenobject_list) == 0, tokenobject_list) # get the tokens for the given user tokenobject_list = get_tokens(user=User(login="******", realm=self.realm1)) self.assertTrue(len(tokenobject_list) == 1, tokenobject_list)
def test_15_add_and_delete_tokeninfo(self): t1 = Token("serialTI") t1.save() t1.set_info({"key1": "value1", "key2": "value2", "key3": "value3"}) t2 = Token.query.filter_by(serial="serialTI").first() t2info = t2.get_info() self.assertTrue(t2info.get("key2") == "value2", t2info) t2.del_info("key2") t2info = t2.get_info() self.assertTrue(t2info.get("key2") is None, t2info)
def test_02_create_token_from_request(self): cwd = os.getcwd() # setup ca connector r = save_caconnector({"cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR}) db_token = Token(self.serial2, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # just upload a ready certificate token.update({"ca": "localCA", "request": REQUEST}) self.assertTrue(token.token.serial == self.serial2, token) self.assertTrue(token.token.tokentype == "certificate", token.token.tokentype) self.assertTrue(token.type == "certificate", token) class_prefix = token.get_class_prefix() self.assertTrue(class_prefix == "CRT", class_prefix) self.assertTrue(token.get_class_type() == "certificate", token) detail = token.get_init_detail() certificate = detail.get("certificate") # At each testrun, the certificate might get another serial number! x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=requester.localdomain'>") # Test, if the certificate is also completely stored in the tokeninfo # and if we can retrieve it from the tokeninfo token = get_tokens(serial=self.serial2)[0] certificate = token.get_tokeninfo("certificate") x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=requester.localdomain'>")