[Freeipa-devel] [PATCH] 357 Added symmetric and asymmetric vaults.

Endi Sukma Dewata edewata at redhat.com
Tue Nov 4 06:30:47 UTC 2014


The IPA vault has been modified to support symmetric and asymmetric
vaults to allow client to pre-encrypt the data. Due to the status
of the crypto library the actual encryption will be added separately
later.

New LDAP attribute types have been added to store vault type, salt
and public key.

https://fedorahosted.org/freeipa/ticket/3872

-- 
Endi S. Dewata
-------------- next part --------------
From 062d86c4bf4f58eadb863cbcd01bd39ef30691d8 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Fri, 24 Oct 2014 19:53:16 -0400
Subject: [PATCH] Added symmetric and asymmetric vaults.

The IPA vault has been modified to support symmetric and asymmetric
vaults to allow client to pre-encrypt the data. Due to the status
of the crypto library the actual encryption will be added separately
later.

New LDAP attribute types have been added to store vault type, salt
and public key.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt                     |  27 +++-
 VERSION                     |   4 +-
 install/share/60basev4.ldif |   7 +-
 ipalib/plugins/vault.py     | 332 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 358 insertions(+), 12 deletions(-)

diff --git a/API.txt b/API.txt
index 7668e8ceebb1a2b6e6ebcd6d70c9209f5a874627..7c4a87dcab4a523977cc63341801120816088db1 100644
--- a/API.txt
+++ b/API.txt
@@ -4476,14 +4476,20 @@ output: Output('result', <type 'bool'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: vault_add
-args: 1,11,3
+args: 1,17,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Bytes('data?', cli_name='data')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
 option: Str('in?', cli_name='in')
+option: Bytes('ipavaultpublickey', attribute=True, cli_name='public_key', multivalue=False, required=False)
+option: Bytes('ipavaultsalt', attribute=True, cli_name='salt', multivalue=False, required=False)
+option: Str('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'standard', multivalue=False, required=False)
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Str('parent', attribute=False, cli_name='parent', multivalue=False, required=False)
+option: Str('password?', cli_name='password')
+option: Str('password_file?', cli_name='password_file')
+option: Str('public_key_file?', cli_name='public_key_file')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Flag('rights', autofill=True, default=False)
 option: Str('text?', cli_name='text')
@@ -4519,7 +4525,7 @@ output: Output('completed', <type 'int'>, None)
 output: Output('failed', <type 'dict'>, None)
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 command: vault_archive
-args: 1,12,3
+args: 1,14,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Bytes('data?', cli_name='data')
@@ -4528,6 +4534,8 @@ option: Str('in?', cli_name='in')
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Bytes('nonce?', cli_name='nonce')
 option: Str('parent?', cli_name='parent')
+option: Str('password?', cli_name='password')
+option: Str('password_file?', cli_name='password_file')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Flag('rights', autofill=True, default=False)
 option: Str('text?', cli_name='text')
@@ -4546,11 +4554,14 @@ output: Output('result', <type 'dict'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: ListOfPrimaryKeys('value', None, None)
 command: vault_find
-args: 1,11,4
+args: 1,14,4
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('cn', attribute=True, autofill=False, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=False)
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Bytes('ipavaultpublickey', attribute=True, autofill=False, cli_name='public_key', multivalue=False, query=True, required=False)
+option: Bytes('ipavaultsalt', attribute=True, autofill=False, cli_name='salt', multivalue=False, query=True, required=False)
+option: Str('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, query=True, required=False)
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Str('parent', attribute=False, autofill=False, cli_name='parent', multivalue=False, query=True, required=False)
 option: Flag('pkey_only?', autofill=True, default=False)
@@ -4564,12 +4575,15 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: vault_mod
-args: 1,11,3
+args: 1,14,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
+option: Bytes('ipavaultpublickey', attribute=True, autofill=False, cli_name='public_key', multivalue=False, required=False)
+option: Bytes('ipavaultsalt', attribute=True, autofill=False, cli_name='salt', multivalue=False, required=False)
+option: Str('ipavaulttype', attribute=True, autofill=False, cli_name='type', default=u'standard', multivalue=False, required=False)
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Str('parent', attribute=False, autofill=False, cli_name='parent', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
@@ -4607,12 +4621,15 @@ output: Output('completed', <type 'int'>, None)
 output: Output('failed', <type 'dict'>, None)
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 command: vault_retrieve
-args: 1,9,3
+args: 1,12,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Str('out?', cli_name='out')
 option: Str('parent?', cli_name='parent')
+option: Str('password?', cli_name='password')
+option: Str('password_file?', cli_name='password_file')
+option: Str('private_key_file?', cli_name='private_key_file')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Flag('rights', autofill=True, default=False)
 option: Flag('stdout?', autofill=True, default=False)
diff --git a/VERSION b/VERSION
index d0ada131b700e93faa8c4946b811db36d76341a9..e539483c786d255bb3175912d34d0c7649f1fad3 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=111
-# Last change: edewata - added vault transport certificate
+IPA_API_VERSION_MINOR=112
+# Last change: edewata - added symmetric and asymmetric vaults
diff --git a/install/share/60basev4.ldif b/install/share/60basev4.ldif
index 61590562ffa174134e10567be93c18ab437d8008..efe714e47193d97c8c7a27dc8602ac9dd5a60bc0 100644
--- a/install/share/60basev4.ldif
+++ b/install/share/60basev4.ldif
@@ -1,3 +1,6 @@
 dn: cn=schema
-objectClasses: (2.16.840.1.113730.3.8.18.1.1 NAME 'ipaVault' SUP nsContainer STRUCTURAL MAY ( description $ owner $ member ) X-ORIGIN 'IPA v4.1' )
-objectClasses: (2.16.840.1.113730.3.8.18.1.2 NAME 'ipaVaultContainer' SUP nsContainer STRUCTURAL MAY ( description $ owner $ member ) X-ORIGIN 'IPA v4.1' )
+attributeTypes: (2.16.840.1.113730.3.8.18.2.1 NAME 'ipaVaultType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2')
+attributeTypes: (2.16.840.1.113730.3.8.18.2.2 NAME 'ipaVaultSalt' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2')
+attributeTypes: (2.16.840.1.113730.3.8.18.2.3 NAME 'ipaVaultPublicKey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2')
+objectClasses: (2.16.840.1.113730.3.8.18.1.1 NAME 'ipaVault' SUP nsContainer STRUCTURAL MAY ( description $ owner $ member $ ipaVaultType $ ipaVaultSalt $ ipaVaultPublicKey ) X-ORIGIN 'IPA v4.2' )
+objectClasses: (2.16.840.1.113730.3.8.18.1.2 NAME 'ipaVaultContainer' SUP nsContainer STRUCTURAL MAY ( description $ owner $ member ) X-ORIGIN 'IPA v4.2' )
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index 00a7a3471d79eee741a1986224c3ad534ec5ff3d..5e2c000de53892dc6a744a349b97c953baa5a225 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import getpass
 import json
 import os
 import random
@@ -58,15 +59,33 @@ EXAMPLES:
  Add a standard vault:
    ipa vault-add MyVault
 
+ Add a symmetric vault:
+   ipa vault-add MyVault --type symmetric --password-file password.txt
+
+ Add an asymmetric vault:
+   ipa vault-add MyVault --type asymmetric --public-key-file public.pem
+
  Show a vault:
    ipa vault-show MyVault
 
  Archive data into standard vault:
    ipa vault-archive MyVault --in data.bin
 
+ Archive data into symmetric vault:
+   ipa vault-archive MyVault --in data.bin --password-file password.txt
+
+ Archive data into asymmetric vault:
+   ipa vault-archive MyVault --in data.bin
+
  Retrieve data from standard vault:
    ipa vault-retrieve MyVault --out data.bin
 
+ Retrieve data from symmetric vault:
+   ipa vault-retrieve MyVault --out data.bin --password-file password.txt
+
+ Retrieve data from asymmetric vault:
+   ipa vault-retrieve MyVault --out data.bin --private-key-file private.pem
+
  Delete a vault:
    ipa vault-del MyVault
 
@@ -421,10 +440,10 @@ class vault(LDAPObject):
 
     object_class = ['ipaVault']
     default_attributes = [
-        'vault_id', 'cn', 'description', 'owner', 'member',
+        'vault_id', 'cn', 'description', 'ipavaulttype', 'ipavaultsalt', 'ipavaultpublickey', 'owner', 'member',
     ]
     search_display_attributes = [
-        'vault_id', 'cn', 'description',
+        'vault_id', 'cn', 'description', 'ipavaulttype',
     ]
     attribute_members = {
         'owner': ['user', 'group'],
@@ -448,6 +467,23 @@ class vault(LDAPObject):
             label=_('Description'),
             doc=_('Vault description'),
         ),
+        Str('ipavaulttype?',
+            cli_name='type',
+            label=_('Type'),
+            doc=_('Vault type'),
+            default=u'standard',
+            autofill=True,
+        ),
+        Bytes('ipavaultsalt?',
+            cli_name='salt',
+            label=_('Salt'),
+            doc=_('Vault salt'),
+        ),
+        Bytes('ipavaultpublickey?',
+            cli_name='public_key',
+            label=_('Public key'),
+            doc=_('Vault public key'),
+        ),
         Str('parent?',
             cli_name='parent',
             label=_('Parent'),
@@ -510,6 +546,24 @@ class vault(LDAPObject):
         # return vault name and parent ID
         return (parts[1], parts[0] + u'/')
 
+    def generate_symmetric_key(self, password, salt):
+        """
+        Generates symmetric key from password and salt.
+        """
+        return None
+
+    def encrypt(self, data, symmetric_key=None, public_key=None):
+        """
+        Encrypts data with symmetric key or public key.
+        """
+        return data
+
+    def decrypt(self, data, symmetric_key=None, private_key=None):
+        """
+        Decrypts data with symmetric key or public key.
+        """
+        return data
+
 
 @register()
 class vault_add(LDAPCreate):
@@ -528,6 +582,18 @@ class vault_add(LDAPCreate):
             cli_name='in',
             doc=_('File containing data to archive'),
         ),
+        Str('password?',
+            cli_name='password',
+            doc=_('Vault password'),
+        ),
+        Str('password_file?',
+            cli_name='password_file',
+            doc=_('File containing the vault password'),
+        ),
+        Str('public_key_file?',
+            cli_name='public_key_file',
+            doc=_('File containing the vault public key'),
+        ),
     )
 
     msg_summary = _('Added vault "%(value)s"')
@@ -537,9 +603,13 @@ class vault_add(LDAPCreate):
         vault_name = args[0]
         parent_id = api.Object.vaultcontainer.normalize_id(options.get('parent'))
 
+        vault_type = options.get('ipavaulttype')
         data = options.get('data')
         text = options.get('text')
         input_file = options.get('in')
+        password = options.get('password')
+        password_file = options.get('password_file')
+        public_key_file = options.get('public_key_file')
 
         # don't send these parameters to server
         if 'data' in options:
@@ -548,6 +618,12 @@ class vault_add(LDAPCreate):
             del options['text']
         if 'in' in options:
             del options['in']
+        if 'password' in options:
+            del options['password']
+        if 'password_file' in options:
+            del options['password_file']
+        if 'public_key_file' in options:
+            del options['public_key_file']
 
         # get data
         if data:
@@ -560,6 +636,72 @@ class vault_add(LDAPCreate):
             with open(input_file, 'rb') as f:
                 data = f.read()
 
+        # type-specific initialization
+        if vault_type == 'standard':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if public_key_file:
+                raise errors.ValidationError(name='public_key_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+        elif vault_type == 'symmetric':
+
+            if public_key_file:
+                raise errors.ValidationError(name='public_key_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            # get vault password
+            if password:
+                pass
+
+            elif password_file:
+                with open(password_file) as f:
+                    password = unicode(f.read().rstrip('\n'))
+
+            else:
+                while True:
+                    password = unicode(getpass.getpass('New password: '))
+                    password2 = unicode(getpass.getpass('Verify password: '))
+                    if password == password2:
+                        break
+                    print '  ** Passwords do not match! **'
+
+            # generate vault salt
+            salt = base64.b64encode(os.urandom(16))
+            options['ipavaultsalt'] = salt
+
+        elif vault_type == 'asymmetric':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            # get vault public key
+            if public_key_file:
+                with open(public_key_file, 'rb') as f:
+                    public_key = f.read()
+            else:
+                raise errors.ValidationError(name='public_key_file',
+                    error=_('Missing vault public key'))
+
+            # store vault public key
+            options['ipavaultpublickey'] = public_key
+
+        else:
+            raise errors.ValidationError(name='vault_type',
+                error=_('Invalid vault type'))
+
         # create the vault
         response = super(vault_add, self).forward(*args, **options)
 
@@ -567,7 +709,8 @@ class vault_add(LDAPCreate):
         api.Command.vault_archive(
             vault_name,
             parent=parent_id,
-            data=data)
+            data=data,
+            password=password)
 
         return response
 
@@ -783,6 +926,14 @@ class vault_archive(LDAPRetrieve):
             cli_name='nonce',
             doc=_('Nonce encrypted encoded in base-64'),
         ),
+        Str('password?',
+            cli_name='password',
+            doc=_('Vault password'),
+        ),
+        Str('password_file?',
+            cli_name='password_file',
+            doc=_('File containing the vault password'),
+        ),
     )
 
     msg_summary = _('Archived data into vault "%(value)s"')
@@ -792,9 +943,28 @@ class vault_archive(LDAPRetrieve):
         vault_name = args[0]
         parent_id = api.Object.vaultcontainer.normalize_id(options.get('parent'))
 
+        vault_type = 'standard'
+        salt = None
+        public_key = None
+
+        # retrieve vault info
+        response = api.Command.vault_show(vault_name, parent=parent_id)
+        result = response['result']
+
+        if result.has_key('ipavaulttype'):
+            vault_type = result['ipavaulttype'][0]
+
+        if result.has_key('ipavaultsalt'):
+            salt = str(result['ipavaultsalt'][0])
+
+        if result.has_key('ipavaultpublickey'):
+            public_key = str(result['ipavaultpublickey'][0])
+
         data = options.get('data')
         text = options.get('text')
         input_file = options.get('in')
+        password = options.get('password')
+        password_file = options.get('password_file')
 
         # don't send these parameters to server
         if 'data' in options:
@@ -803,6 +973,10 @@ class vault_archive(LDAPRetrieve):
             del options['text']
         if 'in' in options:
             del options['in']
+        if 'password' in options:
+            del options['password']
+        if 'password_file' in options:
+            del options['password_file']
 
         # get data
         if data:
@@ -818,6 +992,61 @@ class vault_archive(LDAPRetrieve):
         else:
             data = ''
 
+        # pre-encrypt data
+        if vault_type == 'standard':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+        elif vault_type == 'symmetric':
+
+            # get vault password
+            if password:
+                pass
+
+            elif password_file:
+                with open(password_file) as f:
+                    password = unicode(f.read().rstrip('\n'))
+            else:
+                password = unicode(getpass.getpass('Password: '))
+
+            try:
+                api.Command.vault_retrieve(
+                    vault_name,
+                    parent=parent_id,
+                    password=password)
+
+            except errors.NotFound:
+                pass
+
+            # generate symmetric key from vault password
+            symmetric_key = self.obj.generate_symmetric_key(password, salt)
+
+            # pre-encrypt data with symmetric key
+            data = self.obj.encrypt(data, symmetric_key=symmetric_key)
+
+        elif vault_type == 'asymmetric':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            # pre-encrypt data with public key
+            data = self.obj.encrypt(data, public_key=public_key)
+
+        else:
+            raise errors.ValidationError(name='vault_type',
+                error=_('Invalid vault type'))
+
         # initialize NSS database
         crypto = pki.crypto.NSSCryptoProvider(paths.IPA_NSSDB_DIR)
         crypto.initialize()
@@ -934,6 +1163,18 @@ class vault_retrieve(LDAPRetrieve):
             cli_name='wrapped_session_key',
             doc=_('Session key wrapped with transport certificate and encoded in base-64'),
         ),
+        Str('password?',
+            cli_name='password',
+            doc=_('Vault password'),
+        ),
+        Str('password_file?',
+            cli_name='password_file',
+            doc=_('File containing the vault password'),
+        ),
+        Str('private_key_file?',
+            cli_name='private_key_file',
+            doc=_('File containing the vault private key'),
+        ),
     )
 
     has_output_params = (
@@ -949,14 +1190,36 @@ class vault_retrieve(LDAPRetrieve):
         vault_name = args[0]
         parent_id = api.Object.vaultcontainer.normalize_id(options.get('parent'))
 
+        vault_type = 'standard'
+        salt = None
+
+        # retrieve vault info
+        response = api.Command.vault_show(vault_name, parent=parent_id)
+        result = response['result']
+
+        if result.has_key('ipavaulttype'):
+            vault_type = result['ipavaulttype'][0]
+
+        if result.has_key('ipavaultsalt'):
+            salt = str(result['ipavaultsalt'][0])
+
         stdout = options.get('stdout')
         output_file = options.get('out')
+        password = options.get('password')
+        password_file = options.get('password_file')
+        private_key_file = options.get('private_key_file')
 
         # don't send these parameters to server
         if 'stdout' in options:
             del options['stdout']
         if 'out' in options:
             del options['out']
+        if 'password' in options:
+            del options['password']
+        if 'password_file' in options:
+            del options['password_file']
+        if 'private_key_file' in options:
+            del options['private_key_file']
 
         # initialize NSS database
         crypto = pki.crypto.NSSCryptoProvider(paths.IPA_NSSDB_DIR)
@@ -997,6 +1260,69 @@ class vault_retrieve(LDAPRetrieve):
             session_key,
             nonce_iv=nonce)
 
+        if vault_type == 'standard':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if private_key_file:
+                raise errors.ValidationError(name='private_key_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+        elif vault_type == 'symmetric':
+
+            if private_key_file:
+                raise errors.ValidationError(name='private_key_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            # get vault password
+            if password:
+                pass
+
+            elif password_file:
+                with open(password_file) as f:
+                    password = unicode(f.read().rstrip('\n'))
+
+            else:
+                password = unicode(getpass.getpass('Password: '))
+
+            # generate symmetric key from vault password
+            symmetric_key = self.obj.generate_symmetric_key(password, salt)
+
+            # post-decrypt data with symmetric key
+            data = self.obj.decrypt(data, symmetric_key=symmetric_key)
+
+        elif vault_type == 'asymmetric':
+
+            if password:
+                raise errors.ValidationError(name='password',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            if password_file:
+                raise errors.ValidationError(name='password_file',
+                    error=_('Invalid parameter for %s vault' % vault_type))
+
+            # get vault private key
+            if private_key_file:
+                with open(private_key_file, 'rb') as f:
+                    private_key = f.read()
+
+            else:
+                raise errors.ValidationError(name='private_key_file',
+                    error=_('Missing vault private key'))
+
+            # post-decrypt data with private key
+            data = self.obj.decrypt(data, private_key=private_key)
+
+        else:
+            raise errors.ValidationError(name='vault_type',
+                error=_('Invalid vault type'))
+
         if stdout:
             print data
             response['result'] = {}
-- 
1.9.0



More information about the Freeipa-devel mailing list