def test_filewriterequest(): basedir = os.path.dirname(os.path.abspath(__file__)) filenames = [os.path.abspath(__file__), os.path.abspath("%s/../Accounting/test_account.py" % basedir)] testkey = PrivateKey() r = FileWriteRequest(source=filenames, testing_key=testkey) data = r.to_data() r2 = Request.from_data(data) assert(r == r2) assert(r.uid() == r2.uid()) for i, filename in enumerate(filenames): md5sum = hashlib.md5(open(filename, "rb").read()).hexdigest() assert(md5sum == r.checksums()[i]) r.authorisation().verify(r.resource_key(), testing_key=testkey.public_key()) r2.authorisation().verify(r2.resource_key(), testing_key=testkey.public_key()) testkey2 = PrivateKey() r2 = FileWriteRequest(source=filenames, testing_key=testkey2) assert(r != r2) assert(r.uid() != r2.uid()) for i, filename in enumerate(filenames): md5sum = hashlib.md5(open(filename, "rb").read()).hexdigest() assert(md5sum == r2.checksums()[i]) r2.authorisation().verify(r2.resource_key(), testing_key=testkey2) with pytest.raises(PermissionError): r.authorisation().verify(r.resource_key(), testing_key=testkey2) with pytest.raises(PermissionError): r.authorisation().verify(r2.resource_key(), testing_key=testkey) with pytest.raises(PermissionError): r2.authorisation().verify(r.resource_key(), testing_key=testkey2) with pytest.raises(PermissionError): r2.authorisation().verify(r2.resource_key(), testing_key=testkey)
def test_keys(): privkey = PrivateKey() pubkey = privkey.public_key() message = "Hello World" sig = privkey.sign(message.encode("utf-8")) pubkey.verify(sig, message.encode("utf-8")) c = pubkey.encrypt(message.encode("utf-8")) m = privkey.decrypt(c).decode("utf-8") assert (m == message) privkey2 = PrivateKey() sig2 = privkey2.sign(message.encode("utf-8")) with pytest.raises(SignatureVerificationError): pubkey.verify(sig2, message.encode("utf-8")) bytes = privkey.bytes("testPass32") PrivateKey.read_bytes(bytes, "testPass32") privkey.write("test.pem", "testPass32") PrivateKey.read("test.pem", "testPass32") bytes = pubkey.bytes() pubkey2 = PublicKey.read_bytes(bytes) assert (bytes == pubkey2.bytes()) long_message = str([random.getrandbits(8) for _ in range(4096)]).encode("utf-8") c = pubkey.encrypt(long_message) m = privkey.decrypt(c) assert (m == long_message) os.unlink("test.pem") data = pubkey.to_data() pubkey2 = PublicKey.from_data(data) assert (pubkey.bytes() == pubkey2.bytes()) data = privkey.to_data("testPass33") privkey2 = PrivateKey.from_data(data, "testPass33") assert (privkey == privkey2)
def test_authorisation(): key = PrivateKey() resource = uuid.uuid4() auth = Authorisation(resource=resource, testing_key=key) auth.verify(resource=resource, testing_key=key.public_key()) wrong_key = PrivateKey() with pytest.raises(PermissionError): auth.verify(resource=resource, testing_key=wrong_key.public_key()) wrong_resource = uuid.uuid4() with pytest.raises(PermissionError): auth.verify(resource=wrong_resource, testing_key=key.public_key()) data = auth.to_data() new_auth = Authorisation.from_data(data) new_auth.verify(resource=resource, testing_key=key.public_key()) with pytest.raises(PermissionError): new_auth.verify(resource=resource, testing_key=wrong_key.public_key()) with pytest.raises(PermissionError): new_auth.verify(resource=wrong_resource, testing_key=key.public_key())
def test_json_keys(): privkey = PrivateKey() pubkey = privkey.public_key() args = { "message": "Hello, this is a message", "status": 0, "long": [random.random() for _ in range(1000)] } packed = pack_arguments(args) crypted = pubkey.encrypt(packed) uncrypted = privkey.decrypt(crypted) unpacked = unpack_arguments(uncrypted) assert (args == unpacked)
def run(args): """This function will allow a user to register an account with a username and password""" status = 0 message = None provisioning_uri = None username = args["username"] password = args["password"] # generate a sanitised version of the username user_account = UserAccount(username) # generate the encryption keys and otp secret privkey = PrivateKey() pubkey = privkey.public_key() otp = OTP() provisioning_uri = otp.provisioning_uri(username) # save the encrypted private key (encrypted using the user's password) # and encrypted OTP secret (encrypted using the public key) user_account.set_keys(privkey.bytes(password), pubkey.bytes(), otp.encrypt(pubkey)) # remove the key and password from memory privkey = None password = None # now log into the central identity account to either register # the user, or to update to a new password bucket = login_to_service_account() account_key = "accounts/%s" % user_account.sanitised_name() try: existing_data = ObjectStore.get_object_from_json(bucket, account_key) except: existing_data = None message = "Created a new account for '%s'" % username status = 0 if existing_data is None: # save the new account details ObjectStore.set_object_from_json(bucket, account_key, user_account.to_data()) # need to update the "whois" database with the uuid of this user ObjectStore.set_string_object(bucket, "whois/%s" % user_account.uuid(), user_account.username()) else: # The account already exists. See if this is a password change # request old_password = None try: old_password = args["old_password"] except: raise ExistingAccountError( "An account by this name already exists!") if old_password != password: # this is a change of password request - validate that # the existing password unlocks the existing key user_account = UserAccount.from_data(existing_data) testkey = PrivateKey.read_bytes(user_account.private_key(), old_password) # decrypt the old secret old_secret = testkey.decrypt(user_account.otp_secret()) # now encrypt the secret with the new key new_key = PublicKey.read_bytes(pubkey) new_secret = new_key.encrypt(old_secret) user_account.set_keys(privkey, pubkey, new_secret) # save the new account details ObjectStore.set_object_from_json(bucket, account_key, user_account.to_data()) message = "Updated the password for '%s'" % username else: message = "No need to change account '%s'" % username return_value = create_return_value(status, message) if provisioning_uri: return_value["provisioning_uri"] = provisioning_uri return return_value