Exemple #1
0
def access_keys():
    access_key_data = request.get_json()
    identity = access_key_data['identity']
    csr_data = base64.decodebytes(access_key_data['csr'].encode())
    signature = base64.decodebytes(access_key_data['signature'].encode())

    key_string = database_functions.get_key(DATABASE_FILE, identity)

    # ...and we need to restore the key to the full PEM format that the RSA functions are expecting.
    restored_key = KeyEx_helpers.fixkey(key_string)

    # Now we can import that restored key string into a full RSA key object, get the SAH256 hash for the
    # message (the device ID), and create a verifier object to check the signature...
    pbkey = serialization.load_pem_public_key(restored_key.encode(),
                                              backend=default_backend())

    # Validate that the signature is valid for the csr_data signed by this device...
    try:
        pbkey.verify(
            signature, csr_data,
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

        # We're okay – so sign it...
        with open(CA_KEY, 'rb') as f:
            ca_key_data = f.read()
        ca_key = serialization.load_pem_private_key(ca_key_data, b'rabbit',
                                                    default_backend())

        csr = x509.load_pem_x509_csr(csr_data, default_backend())

        with open(CA_CRT, 'rb') as f:
            ca_crt_data = f.read()
        ca_crt = x509.load_pem_x509_certificate(ca_crt_data, default_backend())

        if isinstance(csr.signature_hash_algorithm, hashes.SHA256):
            cert = x509.CertificateBuilder().subject_name(csr.subject).issuer_name(ca_crt.issuer).public_key\
                (csr.public_key()).serial_number(x509.random_serial_number()).not_valid_before\
                (datetime.datetime.utcnow()).not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))\
                .sign(ca_key, hashes.SHA256(), default_backend())

            return_data = {
                'certificate':
                base64.encodebytes(
                    cert.public_bytes(serialization.Encoding.PEM)).decode(),
                'CA_certificate':
                base64.encodebytes(ca_crt_data).decode()
            }

            rv = KeyExReturn.OK(json.dumps(return_data))
            return rv()

    except (InvalidSignature, ValueError, TypeError) as e:
        rv = KeyExReturn.CSRVerificationError()
        return rv()
Exemple #2
0
def validate():
    validation_data = request.get_json()
    identity = validation_data['identity']
    # Because the signatures are composed of arbitrary byte-streams we need to base64 encode them before trying to put
    # them into a JSON object - and so we must reverse that process here...
    signature = base64.decodebytes(validation_data['signature'].encode())

    # Next we need to get the key string associated with the public key for the device that's claiming to have the
    # specified identity...
    key_string = database_functions.get_key(DATABASE_FILE, identity)

    # ...and we need to restore the key to the full PEM format that the RSA functions are expecting.
    restored_key = KeyEx_helpers.fixkey(key_string)

    # Now we can import that restored key string into a full RSA key object, get the SAH256 hash for the
    # message (the device ID), and create a verifier object to check the signature...
    pbkey = serialization.load_pem_public_key(restored_key.encode(),
                                              backend=default_backend())

    # If the verifier passes the device key we have is a valid public key for the private key that the device is using
    try:
        pbkey.verify(
            signature, identity.encode(),
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

        # If we get here without throwing an exception then the signature was valid: so we'll return our own identity,
        # signed with our private key
        with open(SERVER_PRIVATE_KEY_FILE, "rb") as key_file:
            private_key = serialization.load_pem_private_key(
                key_file.read(), password=None, backend=default_backend())

        signature = private_key.sign(
            SERVER_IDENTITY.encode(),
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

        # Note that as before - we must use base64 encoding before we can serialize this into JSON.
        return_data = {
            'identity': SERVER_IDENTITY,
            'signature': base64.encodebytes(signature).decode()
        }

        # Lastly we return the data, with a HTTP 200
        rv = KeyExReturn.OK(json.dumps(return_data))
        return rv()

    # If we threw an exception then the key didn't validate - so we must return a signature validation error (HTTP 400)
    except (InvalidSignature, ValueError, TypeError) as e:
        rv = KeyExReturn.SignatureVerificationError()
        return rv()
Exemple #3
0
def access_keys():
    access_key_data = request.get_json()
    identity = access_key_data['identity']
    csr_data = base64.decodebytes(access_key_data['csr'].encode())
    signature = base64.decodebytes(access_key_data['signature'].encode())

    key_string = database_functions.get_key(DATABASE_FILE, identity)

    # ...and we need to restore the key to the full PEM format that the RSA functions are expecting.
    restored_key = KeyEx_helpers.fixkey(key_string)

    # Now we can import that restored key string into a full RSA key object, get the SAH256 hash for the
    # message (the device ID), and create a verifier object to check the signature...
    pbkey = serialization.load_pem_public_key(restored_key.encode(), backend=default_backend())

    # Validate that the signature is valid for the csr_data signed by this device...
    try:
        pbkey.verify(signature, csr_data,
                     padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
                     hashes.SHA256())

        # We're okay – so sign it...
        with open(CA_KEY, 'rb') as f:
            ca_key_data = f.read()
        ca_key = serialization.load_pem_private_key(ca_key_data, b'rabbit', default_backend())

        csr = x509.load_pem_x509_csr(csr_data, default_backend())

        with open(CA_CRT, 'rb') as f:
            ca_crt_data = f.read()
        ca_crt = x509.load_pem_x509_certificate(ca_crt_data, default_backend())

        if isinstance(csr.signature_hash_algorithm, hashes.SHA256):
            cert = x509.CertificateBuilder().subject_name(csr.subject).issuer_name(ca_crt.issuer).public_key\
                (csr.public_key()).serial_number(x509.random_serial_number()).not_valid_before\
                (datetime.datetime.utcnow()).not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))\
                .sign(ca_key, hashes.SHA256(), default_backend())

            return_data = {'certificate': base64.encodebytes(cert.public_bytes(serialization.Encoding.PEM)).decode(),
                           'CA_certificate': base64.encodebytes(ca_crt_data).decode()}

            rv = KeyExReturn.OK(json.dumps(return_data))
            return rv()

    except (InvalidSignature, ValueError, TypeError) as e:
        rv = KeyExReturn.CSRVerificationError()
        return rv()
Exemple #4
0
def validate():
    validation_data = request.get_json()
    identity = validation_data['identity']
    # Because the signatures are composed of arbitrary byte-streams we need to base64 encode them before trying to put
    # them into a JSON object - and so we must reverse that process here...
    signature = base64.decodebytes(validation_data['signature'].encode())

    # Next we need to get the key string associated with the public key for the device that's claiming to have the
    # specified identity...
    key_string = database_functions.get_key(DATABASE_FILE, identity)

    # ...and we need to restore the key to the full PEM format that the RSA functions are expecting.
    restored_key = KeyEx_helpers.fixkey(key_string)

    # Now we can import that restored key string into a full RSA key object, get the SAH256 hash for the
    # message (the device ID), and create a verifier object to check the signature...
    pbkey = serialization.load_pem_public_key(restored_key.encode(), backend=default_backend())

    # If the verifier passes the device key we have is a valid public key for the private key that the device is using
    try:
        pbkey.verify(signature, identity.encode(),
                                 padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
                                 hashes.SHA256())

        # If we get here without throwing an exception then the signature was valid: so we'll return our own identity,
        # signed with our private key
        with open(SERVER_PRIVATE_KEY_FILE, "rb") as key_file:
            private_key = serialization.load_pem_private_key(key_file.read(), password=None, backend=default_backend())

        signature = private_key.sign(SERVER_IDENTITY.encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                                 salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

        # Note that as before - we must use base64 encoding before we can serialize this into JSON.
        return_data = {'identity': SERVER_IDENTITY, 'signature': base64.encodebytes(signature).decode()}

        # Lastly we return the data, with a HTTP 200
        rv = KeyExReturn.OK(json.dumps(return_data))
        return rv()

    # If we threw an exception then the key didn't validate - so we must return a signature validation error (HTTP 400)
    except (InvalidSignature, ValueError, TypeError) as e:
        rv = KeyExReturn.SignatureVerificationError()
        return rv()
Exemple #5
0
def get_pub_key(identity):
    # Given that we only need to pass one value – we won't use JSON – but rather use a simple
    # argument...e.g. .../get_key/a3ca9020-b2dc-4d4d-bbf9-42320c7730a0

    # Get the key - if we have it...
    key_string = database_functions.get_key(DATABASE_FILE, identity)

    if key_string is None:
        # We don't have a key for this identity...
        rv = KeyExReturn.IDNotFound()

    else:
        # We have the key - so now we need to restore the key to the full PEM format
        # that RSA functions will expecting...
        restored_key = KeyEx_helpers.fixkey(key_string)

        # And to return this complete key to the C2 server we need to first Base64 encode it.
        encoded_key = base64.encodebytes(restored_key.encode())
        rv = KeyExReturn.OK(encoded_key)

    return rv()
Exemple #6
0
def get_pub_key(identity):
    # Given that we only need to pass one value – we won't use JSON – but rather use a simple
    # argument...e.g. .../get_key/a3ca9020-b2dc-4d4d-bbf9-42320c7730a0

    # Get the key - if we have it...
    key_string = database_functions.get_key(DATABASE_FILE, identity)

    if key_string is None:
        # We don't have a key for this identity...
        rv = KeyExReturn.IDNotFound()

    else:
        # We have the key - so now we need to restore the key to the full PEM format
        # that RSA functions will expecting...
        restored_key = KeyEx_helpers.fixkey(key_string)

        # And to return this complete key to the C2 server we need to first Base64 encode it.
        encoded_key = base64.encodebytes(restored_key.encode())
        rv = KeyExReturn.OK(encoded_key)

    return rv()
Exemple #7
0
def main():
    if not path.exists('passwords.db'):
        create_database()

    while True:
        option = main_menu()

        if option not in ['l', 's', 'd', 'e']:
            print('Invalid option\n')

        elif option == 'e':
            exit()

        elif option == 's':
            #  Create new user
            print('''I will need some informations. DO NOT FORGET OR YOU WILL
                    LOSE ACCESS TO ALL YOUR PASSWORDS\n''')

            #  Check if username is valid
            users_list = get_usernames_list()
            valid = False
            while not valid:
                username = input('\nWhat is your username? ')
                for name in users_list:
                    if username == name[0]:
                        print('\nUsername alredy taken')
                        break
                else:
                    valid = True

            master_password = input('\nWhat is your master password? ')
            master_hashed = get_hash(master_password)
            key = generate_key()

            try:
                add_user(username, master_hashed, key)
                print('\nUser added successully!')
            except sqlite3.Error:
                print('\nAn error ocurred, try again later')

        elif option == 'l':
            username = input('\nWhat is your username? ')
            provided_password = input('\nWhat is your master password? ')
            provided_hashed = str(get_hash(provided_password))

            accessed = check_user(username, provided_hashed)

            if accessed:
                print(f'\nWellcome {username}\n')
                user_id = get_user_id(username)
                user_key = get_key(user_id)

                while True:
                    operation = user_menu()

                    if operation not in ['l', 'a', 'g', 'u', 'd', 'e']:
                        print('\nInvalid option!')

                    elif operation == 'e':
                        print(f'\nGoodbye {username}!\n')
                        break

                    elif operation == 'l':
                        services_list = list_saved_services(user_id)

                        if len(services_list) == 0:
                            print("\nThere are no services yet\n")
                        else:
                            print('\nOkay, listing services...\n')
                            for i in range(len(services_list)):
                                print(
                                    f'Service {i + 1}: {services_list[i][0]}\n'
                                )

                    elif operation == 'a':
                        #  Check if service isn't alredy saved
                        services_list = list_saved_services(user_id)
                        valid = False
                        while not valid:
                            service_name = input(
                                '\nWhat is the name of the service? ')
                            for service in services_list:
                                if service_name == service[0]:
                                    print("\nService alredy registered")
                                    break
                            else:
                                valid = True

                        username = input(
                            f"\nWhat is your username in {service_name}? ")
                        password = input(
                            f'\nWhat is your password in {service_name}? ')
                        encrypted_password = encrypt_password(
                            user_key, password)

                        add_service(service_name, username, encrypted_password,
                                    user_id)

                        print('\nService added successfully!')

                    elif operation == 'g':
                        service = input(
                            '\nWhat service do you want to check? ')
                        service_list = list_saved_services(user_id)

                        for existing_service in service_list:
                            if service == existing_service[0]:
                                exists = True
                                break
                        else:
                            exists = False

                        if not exists:
                            print('\nThis is not a registered service')
                        else:
                            username, hashed_password = check_data_from_service(
                                user_id, service)

                            password = decrypt_password(
                                user_key, hashed_password)

                            print(
                                f'\nService: {service}\nUsername: {username}\nPassword: {password}'
                            )

                    elif operation == 'u':
                        service = input(
                            '\nWhat is the service you want to update? ')

                        service_list = list_saved_services(user_id)

                        for name in service_list:
                            if name[0] == service:
                                exists = True
                                break
                        else:
                            exists = False

                        if exists:
                            username = input(
                                '\nWhat will be your new username? (press enter for no changing) '
                            )
                            password = input(
                                '\nWhat will be your new password? (press enter for no changing) '
                            )

                            if username == '' and password == '':
                                print('\nYou must change at least one!')
                                continue

                            elif username == '':

                                encrypted_password = encrypt_password(
                                    user_key, password)
                                update_service_password(
                                    user_id, service, encrypted_password)

                            elif password == '':
                                update_service_username(
                                    user_id, service, username)

                            elif username != '' and password != '':
                                encrypted_password = encrypt_password(
                                    user_key, password)
                                update_service_password(
                                    user_id, service, encrypted_password)
                                update_service_username(
                                    user_id, service, username)

                            print('\nService updated successfully!')

                        else:
                            print("\nThis service isn't registred")

                    elif operation == 'd':
                        service = input(
                            '\nWhat is the service you want to delete? ')

                        service_list = list_saved_services(user_id)

                        for name in service_list:
                            if name[0] == service:
                                exists = True
                                break
                        else:
                            exists = False

                        if exists:
                            delete_service(user_id, service)
                            print('\nService deleted successfully!')

                        else:
                            print("\nThis service isn't registred")

            elif accessed is False:
                print('\nAccess denied!')

            elif accessed is None:
                print('\nUser not found')

        elif option == 'd':
            username = input('\nWhat is your username? ')
            provided_password = input('\nWhat is your master password? ')
            provided_hashed = str(get_hash(provided_password))

            accessed = check_user(username, provided_hashed)

            if accessed:
                user_id = get_user_id(username)
                delete_user(user_id)
                print(f'\nThe user {username} was deleted successfully')

            elif accessed is False:
                print('\nAccess denied!')

            elif accessed is None:
                print("\nThis user doesn't exists")
Exemple #8
0
    def send(self):
        """
        Send data from QLineEdit
        """

        if self.state == ApplicationStates.SIGN_UP:
            self.provided_username = self.username.text()
            self.provided_password = self.password.text()

            if self.provided_username == '' or self.provided_password == '':
                self.warning.setText(
                    'You must type in a username and a password!')
                self.warning.show()
                return

            users_list = get_usernames_list()
            for name in users_list:
                if self.provided_username == name[0]:
                    self.warning.setText('Username alredy taken')
                    self.warning.show()
                    return

            else:
                key = generate_key()
                master_hashed = get_hash(self.provided_password)
                try:
                    add_user(self.provided_username, master_hashed, key)
                    self.info.setText('User registered successully')
                    self.info.show()
                    self.main_menu()
                except sqlite3.Error:
                    self.warning.setText('A problem occurred, try again later')
                    self.warning.show()

        elif self.state == ApplicationStates.LOGIN:

            self.provided_username = self.username.text()
            self.provided_password = self.password.text()

            if self.provided_username == '' or self.provided_password == '':
                self.warning.setText(
                    'You must type in a username and a password!')
                self.warning.show()
                return

            provided_hash = str(get_hash(self.provided_password))

            #  Checking if user exists
            users_list = get_usernames_list()

            for user in users_list:
                if self.provided_username == user[0]:
                    if provided_hash == get_master_hashed(self.provided_username):
                        accessed = True
                        break
                    else:
                        accessed = False
                        break
            else:
                accessed = None

            if accessed:
                self.reset_widgets()
                self.user_id = get_user_id(self.provided_username)
                self.user_key = get_key(self.user_id)
                self.header.setText(f'Welcome {self.provided_username}')
                self.list_button.show()
                self.add_service_button.show()
                self.get_data_button.show()
                self.update_service_button.show()
                self.delete_service_button.show()
                self.delete_user_button.show()
                self.logoff_button.show()

            elif accessed is False:
                self.warning.setText('Access denied!')
                self.warning.show()

            elif accessed is None:
                self.warning.setText('User not found')
                self.warning.show()

        elif self.state == ApplicationStates.ADD_SERVICE:
            service_name = self.service_name.text()
            service_username = self.username.text()
            service_password = self.password.text()

            if service_name == '' or service_username == '' or service_password == '':
                self.warning.setText('All fields are required')
                self.warning.show()
                return

            else:
                services_list = list_saved_services(self.user_id)
                for service in services_list:
                    if service_name == service[0]:
                        self.warning.setText('Service alredy registered')
                        self.warning.show()
                        return

                else:
                    encrypted_password = encrypt_password(
                        self.user_key, service_password)
                    add_service(service_name, service_username,
                                encrypted_password, self.user_id)
                    self.info.setText('Service added successfully')
                    self.info.show()
                    self.cancel()

        elif self.state == ApplicationStates.CHECK_SERVICE:
            service_name = self.service_name.text()

            if service_name == '':
                self.warning.setText('You must type in the service name!')
                self.warning.show()
                return

            services_list = list_saved_services(self.user_id)

            for service in services_list:
                if service_name == service[0]:
                    service_exists = True
                    break
            else:
                service_exists = False

            if not service_exists:
                self.warning.setText('This is not a registered service')
                self.warning.show()

            else:
                username, password = check_data_from_service(
                    self.user_id, service_name)
                password = decrypt_password(self.user_key, password)
                self.info.setText(
                    f'Service: {service[0]}\nUsername: {username}\nPassword: {password}')
                self.info.show()
                self.cancel()

        elif self.state == ApplicationStates.UPDATE_SERVICE:
            service_name = self.service_name.text()
            username = self.username.text()
            password = self.password.text()

            if service_name == '' or (username == '' and password == ''):
                self.warning.setText(
                    'You must choose the service name and at least one of the others!')
                self.warning.show()
                return

            services_list = list_saved_services(self.user_id)

            for name in services_list:
                if name[0] == service_name:
                    service_exists = True
                    break
            else:
                service_exists = False

            if not service_exists:
                self.warning.setText('This is not a registered service')
                self.warning.show()

            else:
                if username == '':
                    encrypted_password = encrypt_password(
                        self.user_key, password)
                    update_service_password(
                        self.user_id, service_name, encrypted_password)

                elif password == '':
                    update_service_username(self.user_id, service_name, username)

                elif username != '' and password != '':
                    encrypted_password = encrypt_password(
                        self.user_key, password)
                    update_service_password(
                        self.user_id, service_name, encrypted_password)
                    update_service_username(
                        self.user_id, service_name, username)

                self.info.setText('Service updated successfully!')
                self.info.show()
                self.cancel()

        elif self.state == ApplicationStates.DELETE_SERVICE:
            service_name = self.service_name.text()

            if service_name == '':
                self.warning.setText('You must type in the service name!')
                self.warning.show()
                return

            services_list = list_saved_services(self.user_id)

            for service in services_list:
                if service_name == service[0]:
                    service_exists = True
                    break
            else:
                service_exists = False

            if not service_exists:
                self.warning.setText('This is not a registered service')
                self.warning.show()

            else:
                delete_service(self.user_id, service_name)
                self.info.setText(
                    f'Service {service_name} was deleted successfully!')
                self.info.show()
                self.cancel()