예제 #1
0
    def _process_key_vault(self, key_vault_index, key_vault_name, rg_name,
                           sub_index, sub):
        """Get details of Key Vault in management and data plane.

        Arguments:
            sub_index (int): Subscription index (for logging only).
            sub (Subscription): Azure subscription object.
            rg_name (str): Resource group name.
            key_vault_index (int): Key Vault index (for logging only).
            key_vault_name (str): Name of the Key Vault.

        Yields:
            dict: An Azure Key Vault server record.

        """
        def _auth_callback(server, resource, scope):
            credentials = self._key_vault_credentials
            token = credentials.token
            return token['token_type'], token['access_token']

        _log.info('Working on key_vault #%d: %s; %s', key_vault_index,
                  key_vault_name,
                  util.outline_az_sub(sub_index, sub, self._tenant))
        subscription_id = sub.get('subscription_id')
        creds = self._credentials
        key_vault_mgmt_client = KeyVaultManagementClient(
            creds, subscription_id)
        key_vault_details = key_vault_mgmt_client.vaults.get(
            rg_name, key_vault_name)
        yield from _get_normalized_key_vault_record(key_vault_details, sub)
        try:
            kv_client = \
                KeyVaultClient(KeyVaultAuthentication(_auth_callback))

            secrets = \
                kv_client.get_secrets(key_vault_details.properties.vault_uri)

            keys = \
                kv_client.get_keys(key_vault_details.properties.vault_uri)

            # Retrieve data using each iterator.
            for record in itertools.chain(
                    _get_data_record(secrets, 'key_vault_secret', sub_index,
                                     sub, self._tenant),
                    _get_data_record(keys, 'key_vault_key', sub_index, sub,
                                     self._tenant),
            ):
                yield record

        except CloudError as e:
            _log.error('Failed to fetch key vault details; %s; error: %s: %s',
                       util.outline_az_sub(sub_index, sub, self._tenant),
                       type(e).__name__, e)
예제 #2
0
class KV_Repl(object):

    _repl_break_commands = set(('back', 'b'))

    _repl_quit_commands = set(('quit', 'q'))

    def __init__(self, config):
        self._auth = KeyVaultAuth(config, CLIENT_ID)
        self._config = config
        self._mgmt_client = KeyVaultManagementClient(
            self._auth.get_arm_creds(), config.subscription_id)
        self._data_client = KeyVaultClient(self._auth.get_keyvault_creds())
        self._selected_vault = None
        self._current_index = None

    def start(self):
        try:
            self._vault_index_loop()

        except SystemExit:
            print('\nuser exited\n')

    def _continue_repl(self, display_action, break_commands=()):
        display_action()

        self._selection = input('> ').lower()

        if self._selection in break_commands:
            return None

        elif self._selection in KV_Repl._repl_quit_commands:
            sys.exit()

        try:
            self._selection = int(self._selection)
        except ValueError:
            pass

        return self._selection

    def _display_vault_index(self):

        print('\nAvailable Vaults:\n')

        self._current_index = self._get_vault_list()

        for idx, vault in enumerate(self._current_index):
            print('%d. %s' % (idx, vault.name))

        print('\n#:select | (a)dd | (d)elete | (q)uit')

    def _vault_index_loop(self):
        while self._continue_repl(self._display_vault_index) is not None:
            vaults = self._current_index

            if isinstance(self._selection, int):
                i = self._selection

                if i >= 0 and i < len(vaults):
                    self._selected_vault = self._mgmt_client.vaults.get(
                        self._config.resource_group, vaults[i].name)
                    self._vault_detail_loop()
                else:
                    print('invalid vault index')

            elif self._selection == 'a' or self._selection == 'add':
                self._add_vault()

            else:
                print('invalid input')

    def _add_vault(self):
        name = input('\nenter vault name:')

        all_perms = Permissions()
        all_perms.keys = [KeyPermissions.all]
        all_perms.secrets = [SecretPermissions.all]
        all_perms.certificates = [CertificatePermissions.all]

        user_policy = AccessPolicyEntry(self._config.tenant_id,
                                        self._config.user_oid, all_perms)

        app_policy = AccessPolicyEntry(CLIENT_TENANT_ID, CLIENT_OID, all_perms)

        access_policies = [user_policy, app_policy]

        properties = VaultProperties(self._config.tenant_id,
                                     Sku(name='standard'), access_policies)

        properties.enabled_for_deployment = True
        properties.enabled_for_disk_encryption = True
        properties.enabled_for_template_deployment = True

        vault = VaultCreateOrUpdateParameters(self._config.location,
                                              properties)

        self._mgmt_client.vaults.create_or_update(self._config.resource_group,
                                                  name, vault)

        print('vault %s created\n' % name)

    def _display_selected_vault_detail(self):
        print('\nName:\t%s' % self._selected_vault.name)
        print('Uri:\t%s' % self._selected_vault.properties.vault_uri)
        print('Id:\t%s' % self._selected_vault.id)

        print(
            '\n(s)ecrets | (k)eys | (c)ertificates | (e)ncrypt | (d)ecrypt | (b)ack | (q)uit\n'
        )

    def _vault_detail_loop(self):

        while self._continue_repl(
                self._display_selected_vault_detail,
                break_commands=KV_Repl._repl_break_commands) is not None:

            if self._selection == 's' or self._selection == 'secrets':
                self._secret_index_loop()

            elif self._selection == 'k' or self._selection == 'keys':
                self._key_index_loop()

            elif self._selection == 'c' or self._selection == 'certificates':
                print('\nnot yet implemented\n')

            elif self._selection == 'e' or self._selection == 'encrypt':
                self._encrypt_file()
            else:
                print('invalid input')

    def _encrypt_file(self):
        while True:
            inpath = input('input file: ')

            if os.path.isfile(inpath):
                break
            else:
                print('error: file not found')

        while True:
            outpath = input('output file: ')

    @staticmethod
    def _prompt_for_file_path(prompt, verify_exists):
        inpath = input(prompt)

    def _display_secret_index(self):
        self._current_index = []

        secret_iter = self._data_client.get_secrets(
            self._selected_vault.properties.vault_uri)

        if secret_iter is not None:
            try:
                self._current_index = [secret for secret in secret_iter]
            except TypeError:
                pass

        print('\n%s Secrets:\n' % self._selected_vault.name)

        for idx, s in enumerate(self._current_index):
            print('%d. %s' % (idx, KV_Repl._get_name_from_url(s.id)))

        print('\n#:show secret value (a)dd (d)elete (b)ack (q)uit\n')

    def _secret_index_loop(self):

        while self._continue_repl(
                self._display_secret_index,
                break_commands=KV_Repl._repl_break_commands) is not None:

            secrets = self._current_index

            if isinstance(self._selection, int):
                i = self._selection

                if i >= 0 and i < len(secrets):
                    print('\n%s = %s\n' %
                          (KV_Repl._get_secret_name_from_url(secrets[i].id),
                           self._data_client.get_secret(secrets[i].id).value))
                else:
                    print('invalid secret index')

            elif self._selection == 'a' or self._selection == 'add':
                self._add_secret()

            elif self._selection == 'd' or self._selection == 'delete':
                print('\nnot yet implemented\n')

    def _add_secret(self):
        secret_name = input('\nSecret Name: ')
        secret_value = input('Secret Value: ')
        self._data_client.set_secret(self._selected_vault.properties.vault_uri,
                                     secret_name, secret_value)
        print('\nSecret %s added to vault %s' %
              (secret_name, self._selected_vault.name))

    def _display_key_index(self):
        self._current_index = []

        key_iter = self._data_client.get_keys(
            self._selected_vault.properties.vault_uri)

        if key_iter is not None:
            try:
                self._current_index = [secret for secret in key_iter]
            except TypeError:
                print('warning: caught TypeError')
                pass

        print('\n%s Keys:\n' % self._selected_vault.name)

        for idx, k in enumerate(self._current_index):
            print('%d. %s' % (idx, KV_Repl._get_name_from_url(k.kid)))

        print('\n#:get key | (a)dd | (i)mport | (d)elete | (b)ack | (q)uit\n')

    def _key_index_loop(self):

        while self._continue_repl(
                self._display_key_index,
                break_commands=KV_Repl._repl_break_commands) is not None:

            keys = self._current_index

            if isinstance(self._selection, int):
                i = self._selection

                if i >= 0 and i < len(keys):
                    print('\n%s = %s\n' %
                          (KV_Repl._get_secret_name_from_url(keys[i].id),
                           self._data_client.get_secret(keys[i].id).value))
                else:
                    print('invalid key index')

            elif self._selection == 'a' or self._selection == 'add':
                self._add_key()

            elif self._selection == 'd' or self._selection == 'delete':
                print('\nnot yet implemented\n')

    def _add_key(self):
        key_name = input('\nKey Name: ')

        self._data_client.create_key(self._selected_vault.properties.vault_uri,
                                     key_name,
                                     kty=JsonWebKeyType.rsa.value)
        print('\nSecret %s added to vault %s' %
              (key_name, self._selected_vault.name))

    @staticmethod
    def _get_name_from_url(url):
        split = url.split('/')
        return split[len(split) - 1]

    def _get_vault_list(self):
        vault_list = [vault for vault in self._mgmt_client.vaults.list()]
        return vault_list
예제 #3
0
            level=INFO)

app = Flask(__name__)

config = {
    'kv_name_domain':
    'testhostname',  # this name to be used for the vault domain
    'node_addr': 'http://127.0.0.1:8732',
    'keys': {},  # to be auto-populated
    'bakerid': socket.getfqdn() + '_' + str(uuid4())
}
info("Getting public keys from HSM")
kvurl = 'https://' + config['kv_name_domain'] + '.vault.azure.net'
kvclient = KeyVaultClient(
    MSIAuthentication(resource='https://vault.azure.net'))
keys = kvclient.get_keys(kvurl)
for key in keys:
    keyname = key.kid.split('/')
    keydat = kvclient.get_key(kvurl, keyname[-1], '').key

    parity = bytes([2])
    if int.from_bytes(keydat.y, 'big') % 2 == 1:
        parity = bytes([3])
    shabytes = sha256(sha256(P2PK_MAGIC + parity +
                             keydat.x).digest()).digest()[:4]
    public_key = b58encode(P2PK_MAGIC + parity + keydat.x + shabytes).decode()
    blake2bhash = blake2b(parity + keydat.x, digest_size=20).digest()
    shabytes = sha256(sha256(P2HASH_MAGIC + blake2bhash).digest()).digest()[:4]
    pkhash = b58encode(P2HASH_MAGIC + blake2bhash + shabytes).decode()

    config['keys'].update(