Exemple #1
0
def import_key(client,
               vault_base_url,
               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. """
    from azure.keyvault.models import KeyAttributes, JsonWebKey

    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'
        logger.info('Reading %s', pem_file)
        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:
            raise CLIError(
                'Import failed: Unable to decrypt private key. --pem-password may be incorrect.'
            )
        except TypeError:
            raise CLIError('Invalid --pem-password.')
        logger.info('setting RSA parameters from PEM data')
        _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 client.import_key(vault_base_url, key_name, key_obj,
                             destination == 'hsm', key_attrs, tags)
Exemple #2
0
def create_key(client, vault_base_url, key_name, destination, key_size=None, key_ops=None,
               disabled=False, expires=None, not_before=None, tags=None):
    from azure.keyvault.models import KeyAttributes
    key_attrs = KeyAttributes(not disabled, not_before, expires)
    return client.create_key(
        vault_base_url, key_name, destination, key_size, key_ops, key_attrs, tags)