Source code for config_yourself.provider.gpg

# Copyright 2018 Blink Health LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     https://www.apache.org/licenses/LICENSE-2.0

from pgpy import PGPKey, PGPMessage
from pgpy.errors import PGPDecryptionError
import warnings

from config_yourself.provider.datakey import DataKeyService
from config_yourself.exceptions import InvalidConfig, ConfigException


[docs]class Service(DataKeyService): """A GPG CryptoService Provide the ``privateKey`` secret to :py:class:`~config_yourself.Config` when loading to initialize this provider. It should contain the bytes of a GPG private key. Provide the ``privateKeyPassword`` if the key is password protected. """ def __init__(self, config, secrets): try: dataKeyBytes = config.get("key", None) except AttributeError as e: raise InvalidConfig(original=e) if not dataKeyBytes or dataKeyBytes == "": msg = ( "crypto.key is not a string, " "Remove the crypto property if encryption is not needed" ) raise InvalidConfig(message=msg) privateKey = secrets.get("privateKey", None) if not privateKey or privateKey == "": msg = ( "No gpg private key provided for decryption. " "Remove the crypto property if encryption is not needed" ) raise InvalidConfig(message=msg) gpgKey = PGPKey() gpgKey.parse(privateKey) password = secrets.get("privateKeyPassword", None) if password: try: gpgKey.unlock(password) except PGPDecryptionError as err: raise BadGPGKeyPasswordError(gpgKey.userids[0]) with warnings.catch_warnings(): # prevents warning of type `UserWarning: Message was encrypted with this key's subkey: ...` warnings.simplefilter("ignore", category=UserWarning) dataKey = gpgKey.decrypt(PGPMessage.from_blob(dataKeyBytes)).message DataKeyService.__init__(self, dataKey)
[docs]class BadGPGKeyPasswordError(ConfigException): def __init__(self, key): msg = "Invalid password for key <{}>".format(key) self.message = msg super(BadGPGKeyPasswordError, self).__init__(msg)