예제 #1
0
def _get_keyvault_key_url(keyvault_name, key_name):
    from azure.cli.core._profile import Profile

    def get_token(server, resource, scope):  # pylint: disable=unused-argument
        return Profile().get_login_credentials(resource)[0]._token_retriever()  # pylint: disable=protected-access

    from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
    client = KeyVaultClient(KeyVaultAuthentication(get_token))
    result = client.get_key(_get_key_vault_base_url(keyvault_name), key_name, '')
    return result.key.kid  # pylint: disable=no-member
예제 #2
0
def _get_keyvault_key_url(keyvault_name, key_name):
    from azure.cli.core._profile import Profile

    def get_token(server, resource, scope):  # pylint: disable=unused-argument
        return Profile().get_login_credentials(resource)[0]._token_retriever()  # pylint: disable=protected-access

    from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
    client = KeyVaultClient(KeyVaultAuthentication(get_token))
    result = client.get_key(_get_key_vault_base_url(keyvault_name), key_name,
                            '')
    return result.key.kid  # pylint: disable=no-member
예제 #3
0
def run_example():
    """MSI Authentication example."""

    #
    # Create System Assigned MSI Authentication
    #
    credentials = MSIAuthentication()

    client = KeyVaultClient(credentials)

    key_bundle = client.get_key(vault_url, key_name, key_version)
    json_key = key_bundle.key
    print json_key
예제 #4
0
class AzureRMKeyVaultKey(AzureRMModuleBase):
    ''' Module that creates or deletes keys in Azure KeyVault '''

    def __init__(self):

        self.module_arg_spec = dict(
            key_name=dict(type='str', required=True),
            keyvault_uri=dict(type='str', required=True),
            pem_file=dict(type='str'),
            pem_password=dict(type='str'),
            byok_file=dict(type='str'),
            state=dict(type='str', default='present', choices=['present', 'absent'])
        )

        self.results = dict(
            changed=False,
            state=dict()
        )

        self.key_name = None
        self.keyvault_uri = None
        self.pem_file = None
        self.pem_password = None
        self.state = None
        self.client = None
        self.tags = None

        required_if = [
            ('pem_password', 'present', ['pem_file'])
        ]

        super(AzureRMKeyVaultKey, self).__init__(self.module_arg_spec,
                                                 supports_check_mode=True,
                                                 required_if=required_if,
                                                 supports_tags=True)

    def exec_module(self, **kwargs):

        for key in list(self.module_arg_spec.keys()) + ['tags']:
            setattr(self, key, kwargs[key])

        # Create KeyVaultClient
        def auth_callback(server, resource, scope):
            if self.credentials['client_id'] is None or self.credentials['secret'] is None:
                self.fail('Please specify client_id, secret and tenant to access azure Key Vault.')

            tenant = self.credentials.get('tenant')
            if not self.credentials['tenant']:
                tenant = "common"

            authcredential = ServicePrincipalCredentials(
                client_id=self.credentials['client_id'],
                secret=self.credentials['secret'],
                tenant=tenant,
                resource="https://vault.azure.net")

            token = authcredential.token
            return token['token_type'], token['access_token']

        self.client = KeyVaultClient(KeyVaultAuthentication(auth_callback))

        results = dict()
        changed = False

        try:
            results['key_id'] = self.get_key(self.key_name)

            # Key exists and will be deleted
            if self.state == 'absent':
                changed = True

        except KeyVaultErrorException:
            # Key doesn't exist
            if self.state == 'present':
                changed = True

        self.results['changed'] = changed
        self.results['state'] = results

        if not self.check_mode:

            # Create key
            if self.state == 'present' and changed:
                results['key_id'] = self.create_key(self.key_name, self.tags)
                self.results['state'] = results
                self.results['state']['status'] = 'Created'
            # Delete key
            elif self.state == 'absent' and changed:
                results['key_id'] = self.delete_key(self.key_name)
                self.results['state'] = results
                self.results['state']['status'] = 'Deleted'
        else:
            if self.state == 'present' and changed:
                self.results['state']['status'] = 'Created'
            elif self.state == 'absent' and changed:
                self.results['state']['status'] = 'Deleted'

        return self.results

    def get_key(self, name, version=''):
        ''' Gets an existing key '''
        key_bundle = self.client.get_key(self.keyvault_uri, name, version)
        if key_bundle:
            key_id = KeyVaultId.parse_key_id(key_bundle.key.kid)
        return key_id.id

    def create_key(self, name, tags, kty='RSA'):
        ''' Creates a key '''
        key_bundle = self.client.create_key(vault_base_url=self.keyvault_uri, key_name=name, kty=kty, tags=tags)
        key_id = KeyVaultId.parse_key_id(key_bundle.key.kid)
        return key_id.id

    def delete_key(self, name):
        ''' Deletes a key '''
        deleted_key = self.client.delete_key(self.keyvault_uri, name)
        key_id = KeyVaultId.parse_key_id(deleted_key.key.kid)
        return key_id.id

    def import_key(self, key_name, destination=None, key_ops=None, disabled=False, expires=None,
                   not_before=None, tags=None, pem_file=None, pem_password=None, byok_file=None):
        """ Import a private key. Supports importing base64 encoded private keys from PEM files.
            Supports importing BYOK keys into HSM for premium KeyVaults. """

        def _to_bytes(hex_string):
            # zero pads and decodes a hex string
            if len(hex_string) % 2:
                hex_string = '{0}'.format(hex_string)
            return codecs.decode(hex_string, 'hex_codec')

        def _set_rsa_parameters(dest, src):
            # map OpenSSL parameter names to JsonWebKey property names
            conversion_dict = {
                'modulus': 'n',
                'publicExponent': 'e',
                'privateExponent': 'd',
                'prime1': 'p',
                'prime2': 'q',
                'exponent1': 'dp',
                'exponent2': 'dq',
                'coefficient': 'qi'
            }
            # regex: looks for matches that fit the following patterns:
            #   integerPattern: 65537 (0x10001)
            #   hexPattern:
            #      00:a0:91:4d:00:23:4a:c6:83:b2:1b:4c:15:d5:be:
            #      d8:87:bd:c9:59:c2:e5:7a:f5:4a:e7:34:e8:f0:07:
            # The desired match should always be the first component of the match
            regex = re.compile(r'([^:\s]*(:[^\:)]+\))|([^:\s]*(:\s*[0-9A-Fa-f]{2})+))')
            # regex2: extracts the hex string from a format like: 65537 (0x10001)
            regex2 = re.compile(r'(?<=\(0x{1})([0-9A-Fa-f]*)(?=\))')

            key_params = crypto.dump_privatekey(crypto.FILETYPE_TEXT, src).decode('utf-8')
            for match in regex.findall(key_params):
                comps = match[0].split(':', 1)
                name = conversion_dict.get(comps[0], None)
                if name:
                    value = comps[1].replace(' ', '').replace('\n', '').replace(':', '')
                    try:
                        value = _to_bytes(value)
                    except Exception:  # pylint:disable=broad-except
                        # if decoding fails it is because of an integer pattern. Extract the hex
                        # string and retry
                        value = _to_bytes(regex2.findall(value)[0])
                    setattr(dest, name, value)

        key_attrs = KeyAttributes(not disabled, not_before, expires)
        key_obj = JsonWebKey(key_ops=key_ops)
        if pem_file:
            key_obj.kty = 'RSA'
            with open(pem_file, 'r') as f:
                pem_data = f.read()
            # load private key and prompt for password if encrypted
            try:
                pem_password = str(pem_password).encode() if pem_password else None
                # despite documentation saying password should be a string, it needs to actually
                # be UTF-8 encoded bytes
                pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, pem_data, pem_password)
            except crypto.Error:
                pass  # wrong password
            except TypeError:
                pass  # no pass provided
            _set_rsa_parameters(key_obj, pkey)
        elif byok_file:
            with open(byok_file, 'rb') as f:
                byok_data = f.read()
            key_obj.kty = 'RSA-HSM'
            key_obj.t = byok_data

        return self.client.import_key(
            self.keyvault_uri, key_name, key_obj, destination == 'hsm', key_attrs, tags)
###############################################################

from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials

credentials = ServicePrincipalCredentials(
    client_id='YourClientAdd',
    secret='YourSecret',
    tenant='domain.onmicrosoft.com',
)
VAULT_URL = 'https://YourKeyvaultNAME.vault.azure.net'
SECRET_ID = 'mysecret'
client = KeyVaultClient(credentials)
# VAULT_URL must be in the format 'https://<vaultname>.vault.azure.net'
# SECRET_VERSION is required, and can be obtained with the KeyVaultClient.get_secret_versions(self, vault_url, secret_id) API
key_bundle = client.get_key(VAULT_URL, 'key',
                            'e371b887e1f54708a947cc8570272543')
key = key_bundle.key
secret_bundle = client.get_secret(VAULT_URL, SECRET_ID,
                                  '90cdeb79bc494b77920ed2bbdba8139e')
#Create a Secret
my_secret = client.set_secret(VAULT_URL, "secretfrompython2", "pythonvalue2")
#Create a Key
key2 = client.create_key(VAULT_URL, "key2", "RSA")
versions = client.get_key_versions(VAULT_URL, SECRET_ID)
#Delete a Key delete_key(vault_base_url, key_name, custom_headers=None, raw=False, **operation_config)
#client.delete_key(VAULT_URL,"key2")
print(my_secret)
print(secret_bundle)
print(key)
print(key2)
예제 #6
0
class AESKeyWrapper:
    """ Wrapper for key wrapping functions.

    Key is wrapped localy with public key retrieved from Azure KeyVault.
    Uses Azure KeyVault API to unwrap the key.
    """
    def __init__(self, vault, client_id, secret, tenant, key_name,
                 key_version):
        """
        Wrapper constructor.

        :param str vault: Azure KeyVault url.
        :param str client_id: Azure Client Id.
        :param str secret: Azure Client secret.
        :param str tenant: Azure tenant id.
        :param str key_name: Azure KeyVault key name.
        :param str key_version: Azure KeyVault key version.
        """
        self._key_name = key_name
        self._key_version = key_version
        self._vault = vault
        self._client_id = client_id
        self._secret = secret
        self._tenant = tenant
        self._credentials = ServicePrincipalCredentials(
            client_id=self._client_id,
            secret=self._secret,
            tenant=self._tenant)
        self.kvclient = KeyVaultClient(self._credentials)

    def wrap_aes_key_local(self, aes_key, public_key):
        """
        Wraps AES key locally.
        Uses RSA-OAEP algorithm to wrap provided key.

        :param str aes_key: unencrypted AES key.
        :param str public_key: public part of RSA key.

        :return: String with encrypted AES key.
        """
        int_n = self._bytes_to_int(public_key.n)
        int_e = self._bytes_to_int(public_key.e)
        public_numbers = RSAPublicNumbers(int_e, int_n)
        public_key = public_numbers.public_key(default_backend())

        wrapped_key = public_key.encrypt(
            aes_key,
            padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()),
                         algorithm=hashes.SHA1(),
                         label=None))
        return wrapped_key

    def unwrap_aes_key(self, wrapped_key):
        """
        Unwraps AES key with Azure KeyVault.
        Uses RSA-OAEP algorithm to unwrap provided key.

        :param str wrapped_key: encrypted AES key.

        :return: String with unencrypted AES key.
        """
        return self.kvclient.unwrap_key(self._vault, self._key_name,
                                        self._key_version, 'RSA-OAEP',
                                        wrapped_key).result

    def get_public_key(self):
        """ Retrieve public key from Azure KeyVault.

        :return: JsonWebKey with public RSA key.
        """
        key_bundle = self.kvclient.get_key(self._vault, self._key_name,
                                           self._key_version)
        return key_bundle.key

    def _bytes_to_int(self, bytes):
        """ Helper function to convert bytes array to int. """
        result = 0
        for b in bytes:
            result = result * 256 + ord(b)
        return result
예제 #7
0
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(
        {pkhash: {
            'kv_keyname': keyname[-1],
            'public_key': public_key
예제 #8
0
class AzureRMKeyVaultKey(AzureRMModuleBase):
    ''' Module that creates or deletes keys in Azure KeyVault '''

    def __init__(self):

        self.module_arg_spec = dict(
            key_name=dict(type='str', required=True),
            keyvault_uri=dict(type='str', required=True),
            pem_file=dict(type='str'),
            pem_password=dict(type='str'),
            byok_file=dict(type='str'),
            state=dict(type='str', default='present', choices=['present', 'absent'])
        )

        self.results = dict(
            changed=False,
            state=dict()
        )

        self.key_name = None
        self.keyvault_uri = None
        self.pem_file = None
        self.pem_password = None
        self.state = None
        self.client = None
        self.tags = None

        required_if = [
            ('pem_password', 'present', ['pem_file'])
        ]

        super(AzureRMKeyVaultKey, self).__init__(self.module_arg_spec,
                                                 supports_check_mode=True,
                                                 required_if=required_if,
                                                 supports_tags=True)

    def exec_module(self, **kwargs):

        for key in list(self.module_arg_spec.keys()) + ['tags']:
            setattr(self, key, kwargs[key])

        # Create KeyVaultClient
        self.client = KeyVaultClient(self.azure_credentials)

        results = dict()
        changed = False

        try:
            results['key_id'] = self.get_key(self.key_name)

            # Key exists and will be deleted
            if self.state == 'absent':
                changed = True

        except KeyVaultErrorException:
            # Key doesn't exist
            if self.state == 'present':
                changed = True

        self.results['changed'] = changed
        self.results['state'] = results

        if not self.check_mode:

            # Create key
            if self.state == 'present' and changed:
                results['key_id'] = self.create_key(self.key_name, self.tags)
                self.results['state'] = results
                self.results['state']['status'] = 'Created'
            # Delete key
            elif self.state == 'absent' and changed:
                results['key_id'] = self.delete_key(self.key_name)
                self.results['state'] = results
                self.results['state']['status'] = 'Deleted'
        else:
            if self.state == 'present' and changed:
                self.results['state']['status'] = 'Created'
            elif self.state == 'absent' and changed:
                self.results['state']['status'] = 'Deleted'

        return self.results

    def get_key(self, name, version=''):
        ''' Gets an existing key '''
        key_bundle = self.client.get_key(self.keyvault_uri, name, version)
        if key_bundle:
            key_id = KeyVaultId.parse_key_id(key_bundle.key.kid)
        return key_id.id

    def create_key(self, name, tags, kty='RSA'):
        ''' Creates a key '''
        key_bundle = self.client.create_key(self.keyvault_uri, name, kty, tags=tags)
        key_id = KeyVaultId.parse_key_id(key_bundle.key.kid)
        return key_id.id

    def delete_key(self, name):
        ''' Deletes a key '''
        deleted_key = self.client.delete_key(self.keyvault_uri, name)
        key_id = KeyVaultId.parse_key_id(deleted_key.key.kid)
        return key_id.id

    def import_key(self, key_name, destination=None, key_ops=None, disabled=False, expires=None,
                   not_before=None, tags=None, pem_file=None, pem_password=None, byok_file=None):
        """ Import a private key. Supports importing base64 encoded private keys from PEM files.
            Supports importing BYOK keys into HSM for premium KeyVaults. """

        def _to_bytes(hex_string):
            # zero pads and decodes a hex string
            if len(hex_string) % 2:
                hex_string = '{0}'.format(hex_string)
            return codecs.decode(hex_string, 'hex_codec')

        def _set_rsa_parameters(dest, src):
            # map OpenSSL parameter names to JsonWebKey property names
            conversion_dict = {
                'modulus': 'n',
                'publicExponent': 'e',
                'privateExponent': 'd',
                'prime1': 'p',
                'prime2': 'q',
                'exponent1': 'dp',
                'exponent2': 'dq',
                'coefficient': 'qi'
            }
            # regex: looks for matches that fit the following patterns:
            #   integerPattern: 65537 (0x10001)
            #   hexPattern:
            #      00:a0:91:4d:00:23:4a:c6:83:b2:1b:4c:15:d5:be:
            #      d8:87:bd:c9:59:c2:e5:7a:f5:4a:e7:34:e8:f0:07:
            # The desired match should always be the first component of the match
            regex = re.compile(r'([^:\s]*(:[^\:)]+\))|([^:\s]*(:\s*[0-9A-Fa-f]{2})+))')
            # regex2: extracts the hex string from a format like: 65537 (0x10001)
            regex2 = re.compile(r'(?<=\(0x{1})([0-9A-Fa-f]*)(?=\))')

            key_params = crypto.dump_privatekey(crypto.FILETYPE_TEXT, src).decode('utf-8')
            for match in regex.findall(key_params):
                comps = match[0].split(':', 1)
                name = conversion_dict.get(comps[0], None)
                if name:
                    value = comps[1].replace(' ', '').replace('\n', '').replace(':', '')
                    try:
                        value = _to_bytes(value)
                    except Exception:  # pylint:disable=broad-except
                        # if decoding fails it is because of an integer pattern. Extract the hex
                        # string and retry
                        value = _to_bytes(regex2.findall(value)[0])
                    setattr(dest, name, value)

        key_attrs = KeyAttributes(not disabled, not_before, expires)
        key_obj = JsonWebKey(key_ops=key_ops)
        if pem_file:
            key_obj.kty = 'RSA'
            with open(pem_file, 'r') as f:
                pem_data = f.read()
            # load private key and prompt for password if encrypted
            try:
                pem_password = str(pem_password).encode() if pem_password else None
                # despite documentation saying password should be a string, it needs to actually
                # be UTF-8 encoded bytes
                pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, pem_data, pem_password)
            except crypto.Error:
                pass  # wrong password
            except TypeError:
                pass  # no pass provided
            _set_rsa_parameters(key_obj, pkey)
        elif byok_file:
            with open(byok_file, 'rb') as f:
                byok_data = f.read()
            key_obj.kty = 'RSA-HSM'
            key_obj.t = byok_data

        return self.client.import_key(
            self.keyvault_uri, key_name, key_obj, destination == 'hsm', key_attrs, tags)
예제 #9
0
from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials

credential = None


def auth_callback(server, resource, scope):
    credentials = ServicePrincipalCredentials(
        client_id='952370c2-1f28-4256-b8c2-b241dca14159',
        secret='0n6rvVkXf9Q9uoFbKIvCdEGtGvlThri0bMQeA/4qgTk=',
        tenant='97df8ec2-114e-45ae-a59c-1f8c4ae0a138',
        resource="https://vault.azure.net")
    token = credentials.token
    return token['token_type'], token['access_token']


client = KeyVaultClient(KeyVaultAuthentication(auth_callback))

# key_bundle = client.get_key(vault_url, key_name, key_version)

key_bundle = client.get_key('https://kv-dev-hk-peak-di-test.vault.azure.net/',
                            'mykey', 'e46409882744455c8a7ffee227777e09')
secret_bundle = client.get_secret(
    'https://kv-dev-hk-peak-di-test.vault.azure.net/', 'mysecret',
    'fd65e2dada364f9b9211b0a26743bb05')
print(secret_bundle.value)
print(key_bundle.key)
예제 #10
0
#from azure.keyvault import K
credentials = None


def auth_callack(server, resource, scope):

    credentials = ServicePrincipalCredentials(
        client_id='73d64247-3c9e-493c-9ae3-3abae61ee024',
        secret='44QXoAKboDS5AIkXKmjUEsiu2AEneiHXFA6dfUB0i1U=',
        tenant='microsoft.onmicrosoft.com',
        resource=resource)

    token = credentials.token
    return token['token_type'], token['access_token']


client = KeyVaultClient(KeyVaultAuthentication(auth_callack))

vault_url = 'https://contosodemokeyvault.vault.azure.net/'

key_name = 'contosodemokey1'

key_version = '73cc4eca25b9409a83f57fdf8c55c82a'

key_bundle = client.get_key(vault_url, key_name, key_version)

json_key = key_bundle.key

print(json_key)