Ejemplo n.º 1
0
 def test_key_loading(self):
     """Load a key into our test"""
     idobj = IdentityDB()
     idobj.load_keys_from_directory(self.keydir)
     for identity in ('r1', 'r2', 'r3'):
         assert identity in idobj.iddb
         assert idobj.iddb[identity]['uid'] == identity
         assert os.path.isfile(idobj.iddb[identity]['key_path'])
Ejemplo n.º 2
0
 def test_key_loading(self):
     """Load a key into our test"""
     idobj = IdentityDB()
     idobj.args = self.idobj["args"]
     idobj.load_keys_from_directory(self.keydir)
     for identity in ("r1", "r2", "r3"):
         assert identity in [
             x[0] for x in self.session.query(Recipient.name).all()
         ]
         test_id = (self.session.query(Recipient).filter(
             Recipient.name == identity).first())
         assert os.path.isfile(test_id.key)
Ejemplo n.º 3
0
class TestBasicFunction(unittest.TestCase):
    """This Class tests the password entry class"""
    def setUp(self):
        self.certdir = "test/pki/intermediate/certs"
        self.keydir = "test/pki/intermediate/private"
        self.cabundle = "test/pki/intermediate/certs/ca-bundle"
        self.file1 = "test/passwords/testpassword"
        self.file2 = "test/scratch/testpassword"
        self.secret = "Secret"
        self.textblob = "Testing TextField"
        self.sender = "r1"

        self.idobj = IdentityDB()
        self.idobj.identity = self.sender
        self.idobj.recipient_list = ["r2", "r3"]
        db_path = "test/pki/intermediate/certs/rd.db"
        self.idobj.args = {
            "db": {
                "uri": f"sqlite+pysqlite:///{db_path}",
                "engine": create_engine(f"sqlite+pysqlite:///{db_path}"),
            }
        }
        self.session = sessionmaker(bind=self.idobj.args["db"]["engine"])()
        self.idobj.load_certs_from_directory(self.certdir, self.cabundle)
        self.idobj.load_keys_from_directory(self.keydir)

    def test_create_encrypt_decrypt(self):
        """create a password entry"""
        passwordentry = PasswordEntry(name="testcreate",
                                      description=self.textblob,
                                      creator="r1",
                                      authorizer="r1")

        passwordentry.add_recipients(
            secret=self.secret,
            distributor="r1",
            recipients=self.idobj.recipient_list,
            session=self.session,
        )

    def test_read_write(self):
        """Read and write password entry data"""
        passwordentry = PasswordEntry()
        passwordentry.read_password_data(self.file1)
        passwordentry.write_password_data(self.file2, overwrite=True)

        with open(self.file1, "r", encoding="ASCII") as file1:
            with open(self.file2, "r", encoding="ASCII") as file2:
                self.assertTrue(file1.read() == file2.read())
Ejemplo n.º 4
0
class TestBasicFunction(unittest.TestCase):
    """This class tests the crypto class"""
    def setUp(self):
        self.plaintext = "PLAINTEXT"

        self.certdir = 'test/pki/intermediate/certs'
        self.keydir = 'test/pki/intermediate/private'
        self.cabundle = 'test/pki/intermediate/certs/ca-bundle'

        self.identities = IdentityDB()
        self.identities.load_certs_from_directory(self.certdir, self.cabundle)
        self.identities.load_keys_from_directory(self.keydir)

    # Encrypt strings for all test identities and make sure they are different
    def test_encrypt_string(self):
        """Test encrypting a string"""
        results = []
        for _, identity in self.identities.iddb.items():
            results.append(crypto.pk_encrypt_string(self.plaintext, identity))
        self.assertTrue(results[0] != results[1])

        # Encrypt/Decrypt strings for all test identities and make sure we get back what we put in
        for _, identity in self.identities.iddb.items():
            (ciphertext,
             derived_key) = crypto.pk_encrypt_string(self.plaintext, identity)
            plaintext = crypto.pk_decrypt_string(ciphertext, derived_key,
                                                 identity, None)
            self.assertEqual(self.plaintext, plaintext)

    def test_verify_string(self):
        """verify string is correct"""
        results = []
        for _, identity in self.identities.iddb.items():
            results.append(
                crypto.pk_sign_string(self.plaintext, identity, None))
        self.assertTrue(results[0] != results[1])

        for _, identity in self.identities.iddb.items():
            signature = crypto.pk_sign_string(self.plaintext, identity, None)
            self.assertTrue(
                crypto.pk_verify_signature(self.plaintext, signature,
                                           identity))

    def test_cert_fingerprint(self):
        """Verify fingerprint is correct"""
        for _, identity in self.identities.iddb.items():
            fingerprint = crypto.get_cert_fingerprint(identity)
            self.assertTrue(len(fingerprint.split(':')) == 20)
Ejemplo n.º 5
0
class TestBasicFunction(unittest.TestCase):
    """This Class tests the password entry class"""
    def setUp(self):
        self.certdir = 'test/pki/intermediate/certs'
        self.keydir = 'test/pki/intermediate/private'
        self.cabundle = 'test/pki/intermediate/certs/ca-bundle'
        self.file1 = 'test/passwords/testpassword'
        self.file2 = 'test/scratch/testpassword'
        self.secret = 'Secret'
        self.textblob = 'Testing TextField'
        self.sender = 'r1'

        self.idobj = IdentityDB()
        self.idobj.identity = self.sender
        self.idobj.recipient_list = ['r2', 'r3']
        self.idobj.load_certs_from_directory(self.certdir, self.cabundle)
        self.idobj.load_keys_from_directory(self.keydir)

    def test_create_encrypt_decrypt(self):
        """create a password entry"""
        passwordentry = PasswordEntry(name='testcreate',
                                      description=self.textblob,
                                      creator='r1',
                                      authorizer='r1')

        passwordentry.add_recipients(secret=self.secret,
                                     distributor='r1',
                                     recipients=self.idobj.recipient_list,
                                     identitydb=self.idobj)

    def test_read_write(self):
        """Read and write password entry data"""
        passwordentry = PasswordEntry()
        passwordentry.read_password_data(self.file1)
        passwordentry.write_password_data(self.file2, overwrite=True)

        with open(self.file1, 'r') as file1:
            with open(self.file2, 'r') as file2:
                self.assertTrue(file1.read() == file2.read())
Ejemplo n.º 6
0
class Interactive(Cmd, pkinterface.PkInterface):
    """This class implements the interactive interpreter functionality"""
    intro = """Welcome to PKPass (Public Key Based Password Manager) v%s!
Type ? to list commands""" % VERSION
    prompt = 'pkpass> '

    ####################################################################

    ####################################################################
    def __init__(self, args, recipients_database):
        ####################################################################
        Cmd.__init__(self)
        # manually remove interpreter from command line so that argparse doesn't try to use it
        # This needs to be removed before the PkInterace init
        sys.argv.remove('interpreter')

        pkinterface.PkInterface.__init__(self)

        self.recipients_database = recipients_database if recipients_database else IdentityDB(
        )
        self.parser.error = pkparse_error

        # Hold onto args passed on the command line
        self.args = args
        # change our cwd so users can tab complete
        self._change_pwstore()

        # We basically need to grab the first argument and ditch it
        self.parsedargs = {}

        ####################################################################
    def cmdloop_with_keyboard_interrupt(self):
        """handle keyboard interrupts"""
        ####################################################################
        breaker = False
        first = True
        while breaker is not True:
            try:
                if first:
                    self.cmdloop()
                else:
                    self.cmdloop(intro='')
                breaker = True
            except KeyboardInterrupt:
                first = False
                sys.stdout.write('\n')

        ####################################################################
    def _load_iddb(self):
        """load recipient database"""
        ####################################################################
        self.recipients_database = IdentityDB()
        self.recipients_database.cabundle = self.args['cabundle']
        self.recipients_database.load_certs_from_directory(
            self.args['certpath'],
            verify_on_load=True,
            connectmap=self.args['connect'],
            nocache=False)
        if 'keypath' in self.args:
            self.recipients_database.load_keys_from_directory(
                self.args['keypath'])

        ####################################################################
    def _change_pwstore(self):
        """Change directory"""
        ####################################################################
        direc = self.args['pwstore']
        if 'pwstore' in self.args and direc and path.isdir(direc):
            chdir(direc)

        ####################################################################
    def _reload_config(self):
        """Change affected globals in interpreter"""
        ####################################################################
        # We still need to be able to reload other things like recipients
        # database
        config = self.args['config']
        config_args = self.args
        try:
            config_args = collect_args({'config': config})
            if not config_args:
                config_args = self.args
        except ParserError:
            print("Error parsing config file")
            config_args = self.args
        finally:
            self.args = config_args
            self.args['config'] = config
            self.args = handle_filepath_args(self.args)
            self._change_pwstore()
            self._load_iddb()

        ####################################################################
    def precmd(self, line):
        """ Fix command line arguments, this is a hack to allow argparse
        function as we expect """
        ####################################################################
        sys.argv = [sys.argv[0]]
        sys.argv.extend(line.split())
        return line

        ####################################################################
    def postcmd(self, stop, line):
        """ Fix command line arguments, this is a hack to allow argparse
        function as we expect """
        ####################################################################
        if str(line) == "edit" or '--no-cache' in line:
            self._reload_config()
        return Cmd.postcmd(self, stop, line)

        ####################################################################
    def _append_slash_if_dir(self, path_arg):
        """ Appending slashes for autocomplete_file_path """
        ####################################################################
        if path_arg and path.isdir(path_arg) and path_arg[-1] != sep:
            return path_arg + sep
        return path_arg

        ####################################################################
    def autocomplete_file_path(self, _, line, begidx, endidx):
        """ File path autocompletion, used with the cmd module complete_* series functions"""
        ####################################################################
        before_arg = line.rfind(" ", 0, begidx)
        if before_arg == -1:
            return None  # arg not found

        fixed = line[before_arg + 1:begidx]  # fixed portion of the arg
        arg = line[before_arg + 1:endidx]
        pattern = arg + '*'

        completions = []
        for fpath in glob(pattern):
            fpath = self._append_slash_if_dir(fpath)
            completions.append(fpath.replace(fixed, "", 1))
        return completions

        ####################################################################
    def default(self, line):
        """If we don't have a proper subcommand passed"""
        ####################################################################
        print("Command '%s' not found, see help (?) for available commands" %
              line)
        return False

        ####################################################################
    def do_exit(self, _):
        """Exit the application"""
        ####################################################################
        return True

        ####################################################################
    def do_version(self, _):
        """Print the version of PkPass"""
        ####################################################################
        print(VERSION)

        ####################################################################
    def do_edit(self, _):
        """Edit your configuration file, with $EDITOR"""
        ####################################################################
        try:
            call([environ['EDITOR'], self.args['config']])
            return False
        except (IOError, SystemExit):
            return False

        ####################################################################
    def do_git(self, line):
        """If your password store is git back, you can control git from here"""
        ####################################################################
        call(["git"] + line.split())
        return False
Ejemplo n.º 7
0
class TestBasicFunction(unittest.TestCase):
    """This class tests the crypto class"""
    def setUp(self):
        self.plaintext = "PLAINTEXT"

        self.certdir = "test/pki/intermediate/certs"
        self.keydir = "test/pki/intermediate/private"
        self.cabundle = "test/pki/intermediate/certs/ca-bundle"

        self.identities = IdentityDB()
        db_path = "test/pki/intermediate/certs/rd.db"
        self.identities.args = {
            "db": {
                "uri": f"sqlite+pysqlite:///{db_path}",
                "engine": create_engine(f"sqlite+pysqlite:///{db_path}"),
            }
        }
        self.session = sessionmaker(
            bind=self.identities.args["db"]["engine"])()
        self.identities.load_certs_from_directory(self.certdir, self.cabundle)
        self.identities.load_keys_from_directory(self.keydir)

    # Encrypt strings for all test identities and make sure they are different
    def test_encrypt_string(self):
        """Test encrypting a string"""
        results = []
        for identity in self.session.query(Recipient).all():
            cert = (self.session.query(Cert).filter(
                Cert.recipients.contains(identity)).first())
            results.append(pk_encrypt_string(self.plaintext, cert.cert_bytes))
        self.assertTrue(results[0] != results[1])

        # Encrypt/Decrypt strings for all test identities and make sure we get back what we put in
        for identity in self.session.query(Recipient).all():
            cert = (self.session.query(Cert).filter(
                Cert.recipients.contains(identity)).first())
            (ciphertext,
             derived_key) = pk_encrypt_string(self.plaintext, cert.cert_bytes)
            plaintext = pk_decrypt_string(ciphertext, derived_key,
                                          dict(identity), None)
            self.assertEqual(self.plaintext, plaintext)

    def test_verify_string(self):
        """verify string is correct"""
        results = []
        for identity in self.session.query(Recipient).all():
            results.append(pk_sign_string(self.plaintext, dict(identity),
                                          None))
        self.assertTrue(results[0] != results[1])

        for identity in self.session.query(Recipient).all():
            signature = pk_sign_string(self.plaintext, dict(identity), None)
            cert = (self.session.query(Cert).filter(
                Cert.recipients.contains(identity)).first())
            self.assertTrue(
                pk_verify_signature(self.plaintext, signature, [cert]))

    def test_cert_fingerprint(self):
        """Verify fingerprint is correct"""
        for identity in self.session.query(Recipient).all():
            cert = (self.session.query(Cert).filter(
                Cert.recipients.contains(identity)).first())
            fingerprint = get_cert_fingerprint(cert.cert_bytes)
            self.assertTrue(len(fingerprint.split(":")) == 20)