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)
Example #2
0
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)
Example #5
0
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