예제 #1
0
 def test_add(self):
     db = Storage()
     keydb = KeyDB(db, load=True)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     keydb.add_key("public1", "private1")
     keydb.add_key("public2", "private2")
     assert len(keydb.get_public_keys()) == 2
     assert keydb.get_public_keys()[0] == "public1"
     assert keydb.get_public_keys()[1] == "public2"
예제 #2
0
 def test_revoking_break(self):
     db = Storage()
     keydb = KeyDB(db, load=False)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     keydb.add_key('public1', 'private1')
     keydb.add_key('public2', 'private2')
     assert keydb.get_revoked_key() is None
     assert len(keydb.get_public_keys()) == 2
     keydb.revoke_key(count=1)
     assert len(keydb.get_public_keys()) == 1
     assert keydb.get_revoked_key()['public'] == 'public1'
예제 #3
0
 def test_get_revoked_key(self):
     db = Storage()
     keydb = KeyDB(db, load=True)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     assert keydb.get_revoked_key() is None
     keydb.add_key('public1', 'private1')
     keydb.add_key('public2', 'private2')
     assert len(keydb.get_public_keys()) == 2
     keydb.revoke_key(count=2)
     assert len(keydb.get_public_keys()) == 0
예제 #4
0
 def test_revoking_break(self):
     db = Storage()
     keydb = KeyDB(db, load=False)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     keydb.add_key("public1", "private1")
     keydb.add_key("public2", "private2")
     assert keydb.get_revoked_key() is None
     assert len(keydb.get_public_keys()) == 2
     keydb.revoke_key(count=1)
     assert len(keydb.get_public_keys()) == 1
     assert keydb.get_revoked_key()["public"] == "public1"
예제 #5
0
 def test_get_revoked_key(self):
     db = Storage()
     keydb = KeyDB(db, load=True)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     assert keydb.get_revoked_key() is None
     keydb.add_key("public1", "private1")
     keydb.add_key("public2", "private2")
     assert len(keydb.get_public_keys()) == 2
     keydb.revoke_key(count=2)
     assert len(keydb.get_public_keys()) == 0
예제 #6
0
    def init_app(self, obj, db):
        """Sets up client with config values from obj

        Args:

            obj (instance): config object
        """
        # Copies and sets all needed config attributes
        # for this object
        self.app_name = obj.get('APP_NAME')
        self.private_key_name = self.app_name + '.pem'
        self.public_key_name = self.app_name + '.pub'
        data_dir = obj.get('DATA_DIR', os.getcwd())
        self.db = db
        self.keysdb = KeyDB(db)
        self.data_dir = os.path.join(data_dir, settings.USER_DATA_FOLDER)
        self.deploy_dir = os.path.join(self.data_dir, 'deploy')
        self.version_file = os.path.join(self.deploy_dir,
                                         settings.VERSION_FILE)
예제 #7
0
 def test_add(self):
     db = Storage()
     keydb = KeyDB(db, load=True)
     db._sync_db()
     assert len(os.listdir(os.getcwd())) == 1
     keydb.add_key('public1', 'private1')
     keydb.add_key('public2', 'private2')
     assert len(keydb.get_public_keys()) == 2
     assert keydb.get_public_keys()[0] == 'public1'
     assert keydb.get_public_keys()[1] == 'public2'
예제 #8
0
    def init_app(self, obj, db):
        """Sets up client with config values from obj

        Args:

            obj (instance): config object
        """
        # Copies and sets all needed config attributes
        # for this object
        self.app_name = obj.get('APP_NAME')
        self.private_key_name = self.app_name + '.pem'
        self.public_key_name = self.app_name + '.pub'
        data_dir = obj.get('DATA_DIR', os.getcwd())
        self.db = db
        self.keysdb = KeyDB(db)
        self.data_dir = os.path.join(data_dir, settings.USER_DATA_FOLDER)
        self.deploy_dir = os.path.join(self.data_dir, 'deploy')
        self.version_file = os.path.join(self.deploy_dir,
                                         settings.VERSION_FILE)
예제 #9
0
class KeyHandler(object):
    """KeyHanlder object is used to manage keys used for signing updates

    Kwargs:

        app (obj): Config object to get config values from

        db (dict): Framework metadata
    """

    def __init__(self, app=None, db=None):
        self.key_encoding = 'base64'
        if app is not None:
            self.init_app(app, db)

    def init_app(self, obj, db):
        """Sets up client with config values from obj

        Args:

            obj (instance): config object
        """
        # Copies and sets all needed config attributes
        # for this object
        self.app_name = obj.get('APP_NAME')
        self.private_key_name = self.app_name + '.pem'
        self.public_key_name = self.app_name + '.pub'
        data_dir = obj.get('DATA_DIR', os.getcwd())
        self.db = db
        self.keysdb = KeyDB(db)
        self.data_dir = os.path.join(data_dir, settings.USER_DATA_FOLDER)
        self.deploy_dir = os.path.join(self.data_dir, 'deploy')
        self.version_file = os.path.join(self.deploy_dir,
                                         settings.VERSION_FILE)

    def make_keys(self, count=3):
        """Makes public and private keys for signing and verification

        Kwargs:

            count (bool): The number of keys to create.
        """
        log.info('Creating {} keys'.format(count))
        c = 0
        while c < count:
            self._make_keys()
            c += 1

    def _make_keys(self):
        # Makes a set of private and public keys
        # Used for authentication
        self.keysdb.load()
        privkey, pubkey = ed25519.create_keypair()
        pri = privkey.to_ascii(encoding=self.key_encoding)
        pub = pubkey.to_ascii(encoding=self.key_encoding)
        self.keysdb.add_key(pub, pri)

    def sign_update(self):
        """Signs version file with private key

        Proxy method for :meth:`_add_sig`
        """
        # Loads private key
        # Loads version file to memory
        # Signs Version file
        # Writes version file back to disk
        self._add_sig()

    def get_public_keys(self):
        "Returns (object): Public Key"
        self.keysdb.load()
        return self.keysdb.get_public_keys()

    def get_recent_revoked_key(self):
        self.keysdb.load()
        return self.keysdb.get_revoked_key()

    def print_public_keys(self):
        "Prints public key data to console"
        keys = self.get_public_key()
        print('Public Key:\n{}\n\n'.format(keys))

    def revoke_key(self, count):
        self.keysdb.revoke_key(count)
        self.make_keys(count)

    def _load_private_keys(self):
        # Loads private key
        log.debug('Loading private key')
        return self.keysdb.get_private_keys()

    def _add_sig(self):
        # Adding new signature to version file
        private_keys = self._load_private_keys()
        # Just making sure we have a least 2 keys so when revoke is
        # called we have a fall back
        if len(private_keys) < 2:
            self.make_keys()
        private_keys = self._load_private_keys()

        update_data = self._load_update_data()
        if 'sigs' in update_data:
            log.debug('Removing signatures from version file')
            del update_data['sigs']
        update_data_str = json.dumps(update_data, sort_keys=True)

        signatures = []
        for p in private_keys:
            if six.PY2 is True and isinstance(p, unicode) is True:
                log.debug('Got type: {}'.format(type(p)))
                p = str(p)
            log.debug('Key type: {}'.format(type(p)))
            privkey = ed25519.SigningKey(p, encoding=self.key_encoding)
            # Signs update data with private key
            sig = privkey.sign(six.b(update_data_str),
                               encoding=self.key_encoding)
            log.debug('Sig: {}'.format(sig))
            signatures.append(sig)

        og_data = json.loads(update_data_str)
        update_data = og_data.copy()
        # Add signatures to update data
        update_data['sigs'] = signatures
        log.info('Adding sig to update data')
        # Write updated version file to filesystem
        self._write_update_data(og_data, update_data)

    def _write_update_data(self, data, version):
        # Save update data to repo database
        self.db.save(settings.CONFIG_DB_KEY_VERSION_META, data)
        log.debug('Saved version meta data')

        # Gzip update date
        with gzip.open(self.version_file, 'wb') as f:
            f.write(json.dumps(version, indent=2, sort_keys=True))
        log.info('Created gzipped version manifest in deploy dir')

    def _load_update_data(self):
        log.debug("Loading version data")
        update_data = self.db.load(settings.CONFIG_DB_KEY_VERSION_META)
        # If update_data is None, create a new one
        if update_data is None:
            update_data = {}
            log.error('Version meta data not found')
            self.db.save(settings.CONFIG_DB_KEY_VERSION_META, update_data)
            log.info('Created new version meta data')
        log.debug('Version file loaded')
        return update_data
예제 #10
0
class KeyHandler(object):
    """KeyHanlder object is used to manage keys used for signing updates

    Kwargs:

        app (obj): Config object to get config values from

        db (dict): Framework metadata
    """
    def __init__(self, app=None, db=None):
        self.key_encoding = 'base64'
        if app is not None:
            self.init_app(app, db)

    def init_app(self, obj, db):
        """Sets up client with config values from obj

        Args:

            obj (instance): config object
        """
        # Copies and sets all needed config attributes
        # for this object
        self.app_name = obj.get('APP_NAME')
        self.private_key_name = self.app_name + '.pem'
        self.public_key_name = self.app_name + '.pub'
        data_dir = obj.get('DATA_DIR', os.getcwd())
        self.db = db
        self.keysdb = KeyDB(db)
        self.data_dir = os.path.join(data_dir, settings.USER_DATA_FOLDER)
        self.deploy_dir = os.path.join(self.data_dir, 'deploy')
        self.version_file = os.path.join(self.deploy_dir,
                                         settings.VERSION_FILE)

    def make_keys(self, count=3):
        """Makes public and private keys for signing and verification

        Kwargs:

            count (bool): The number of keys to create.
        """
        log.info('Creating {} keys'.format(count))
        c = 0
        while c < count:
            self._make_keys()
            c += 1

    def _make_keys(self):
        # Makes a set of private and public keys
        # Used for authentication
        self.keysdb.load()
        privkey, pubkey = ed25519.create_keypair()
        pri = privkey.to_ascii(encoding=self.key_encoding)
        pub = pubkey.to_ascii(encoding=self.key_encoding)
        self.keysdb.add_key(pub, pri)

    def sign_update(self):
        """Signs version file with private key

        Proxy method for :meth:`_add_sig`
        """
        # Loads private key
        # Loads version file to memory
        # Signs Version file
        # Writes version file back to disk
        self._add_sig()

    def get_public_keys(self):
        "Returns (object): Public Key"
        self.keysdb.load()
        return self.keysdb.get_public_keys()

    def get_recent_revoked_key(self):
        self.keysdb.load()
        return self.keysdb.get_revoked_key()

    def print_public_keys(self):
        "Prints public key data to console"
        keys = self.get_public_key()
        print('Public Key:\n{}\n\n'.format(keys))

    def revoke_key(self, count):
        self.keysdb.revoke_key(count)
        self.make_keys(count)

    def _load_private_keys(self):
        # Loads private key
        log.debug('Loading private key')
        return self.keysdb.get_private_keys()

    def _add_sig(self):
        # Adding new signature to version file
        private_keys = self._load_private_keys()
        # Just making sure we have a least 2 keys so when revoke is
        # called we have a fall back
        if len(private_keys) < 2:
            self.make_keys()
        private_keys = self._load_private_keys()

        update_data = self._load_update_data()
        if 'sigs' in update_data:
            log.debug('Removing signatures from version file')
            del update_data['sigs']
        update_data_str = json.dumps(update_data, sort_keys=True)

        signatures = []
        for p in private_keys:
            if six.PY2 is True and isinstance(p, unicode) is True:
                log.debug('Got type: {}'.format(type(p)))
                p = str(p)
            log.debug('Key type: {}'.format(type(p)))
            privkey = ed25519.SigningKey(p, encoding=self.key_encoding)
            # Signs update data with private key
            sig = privkey.sign(six.b(update_data_str),
                               encoding=self.key_encoding)
            log.debug('Sig: {}'.format(sig))
            signatures.append(sig)

        og_data = json.loads(update_data_str)
        update_data = og_data.copy()
        # Add signatures to update data
        update_data['sigs'] = signatures
        log.info('Adding sig to update data')
        # Write updated version file to filesystem
        self._write_update_data(og_data, update_data)

    def _write_update_data(self, data, version):
        # Save update data to repo database
        self.db.save(settings.CONFIG_DB_KEY_VERSION_META, data)
        log.debug('Saved version meta data')

        # Gzip update date
        with gzip.open(self.version_file, 'wb') as f:
            f.write(json.dumps(version, indent=2, sort_keys=True))
        log.info('Created gzipped version manifest in deploy dir')

    def _load_update_data(self):
        log.debug("Loading version data")
        update_data = self.db.load(settings.CONFIG_DB_KEY_VERSION_META)
        # If update_data is None, create a new one
        if update_data is None:
            update_data = {}
            log.error('Version meta data not found')
            self.db.save(settings.CONFIG_DB_KEY_VERSION_META, update_data)
            log.info('Created new version meta data')
        log.debug('Version file loaded')
        return update_data